mirror of
https://github.com/BinomialLLC/basis_universal.git
synced 2026-09-29 21:56:05 +00:00
WIP: glTF demo
This commit is contained in:
281
webgl/gltf-demo/AGI_HQ/AgiHQ.gltf
Normal file
281
webgl/gltf-demo/AGI_HQ/AgiHQ.gltf
Normal file
@@ -0,0 +1,281 @@
|
||||
{
|
||||
"accessors": [
|
||||
{
|
||||
"name": "Node-Mesh_0_positions",
|
||||
"componentType": 5126,
|
||||
"count": 426519,
|
||||
"min": [
|
||||
-263.67950439453125,
|
||||
-280.67950439453125,
|
||||
-52.20021438598633
|
||||
],
|
||||
"max": [
|
||||
299.67950439453125,
|
||||
247.67950439453125,
|
||||
-13.959484100341797
|
||||
],
|
||||
"type": "VEC3",
|
||||
"bufferView": 0,
|
||||
"byteOffset": 0
|
||||
},
|
||||
{
|
||||
"name": "Node-Mesh_0_texcoords",
|
||||
"componentType": 5126,
|
||||
"count": 426519,
|
||||
"min": [
|
||||
0.001038654474541545,
|
||||
0.0010396799771115184
|
||||
],
|
||||
"max": [
|
||||
0.9990835189819336,
|
||||
0.9990107417106628
|
||||
],
|
||||
"type": "VEC2",
|
||||
"bufferView": 1,
|
||||
"byteOffset": 0
|
||||
},
|
||||
{
|
||||
"name": "Node-Mesh_0_indices",
|
||||
"componentType": 5125,
|
||||
"count": 2055249,
|
||||
"min": [
|
||||
0
|
||||
],
|
||||
"max": [
|
||||
426518
|
||||
],
|
||||
"type": "SCALAR",
|
||||
"bufferView": 2,
|
||||
"byteOffset": 0
|
||||
},
|
||||
{
|
||||
"name": "Node-Mesh_1_positions",
|
||||
"componentType": 5126,
|
||||
"count": 513603,
|
||||
"min": [
|
||||
-263.67950439453125,
|
||||
-280.67950439453125,
|
||||
-52.742218017578125
|
||||
],
|
||||
"max": [
|
||||
299.67950439453125,
|
||||
247.67950439453125,
|
||||
-12.004308700561523
|
||||
],
|
||||
"type": "VEC3",
|
||||
"bufferView": 0,
|
||||
"byteOffset": 5118228
|
||||
},
|
||||
{
|
||||
"name": "Node-Mesh_1_texcoords",
|
||||
"componentType": 5126,
|
||||
"count": 513603,
|
||||
"min": [
|
||||
0.0010405026841908693,
|
||||
0.0010377200087532401
|
||||
],
|
||||
"max": [
|
||||
0.999070942401886,
|
||||
0.9744246006011963
|
||||
],
|
||||
"type": "VEC2",
|
||||
"bufferView": 1,
|
||||
"byteOffset": 3412152
|
||||
},
|
||||
{
|
||||
"name": "Node-Mesh_1_indices",
|
||||
"componentType": 5125,
|
||||
"count": 2128626,
|
||||
"min": [
|
||||
0
|
||||
],
|
||||
"max": [
|
||||
513602
|
||||
],
|
||||
"type": "SCALAR",
|
||||
"bufferView": 2,
|
||||
"byteOffset": 8220996
|
||||
}
|
||||
],
|
||||
"asset": {
|
||||
"generator": "obj2gltf",
|
||||
"version": "2.0"
|
||||
},
|
||||
"buffers": [
|
||||
{
|
||||
"name": "Model",
|
||||
"byteLength": 35537940,
|
||||
"uri": "Model.bin"
|
||||
}
|
||||
],
|
||||
"bufferViews": [
|
||||
{
|
||||
"name": "bufferView_0",
|
||||
"buffer": 0,
|
||||
"byteLength": 11281464,
|
||||
"byteOffset": 0,
|
||||
"byteStride": 12,
|
||||
"target": 34962
|
||||
},
|
||||
{
|
||||
"name": "bufferView_1",
|
||||
"buffer": 0,
|
||||
"byteLength": 7520976,
|
||||
"byteOffset": 11281464,
|
||||
"byteStride": 8,
|
||||
"target": 34962
|
||||
},
|
||||
{
|
||||
"name": "bufferView_2",
|
||||
"buffer": 0,
|
||||
"byteLength": 16735500,
|
||||
"byteOffset": 18802440,
|
||||
"target": 34963
|
||||
}
|
||||
],
|
||||
"materials": [
|
||||
{
|
||||
"name": "Model_0",
|
||||
"pbrMetallicRoughness": {
|
||||
"baseColorTexture": {
|
||||
"index": 0
|
||||
},
|
||||
"baseColorFactor": [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"metallicFactor": 0,
|
||||
"roughnessFactor": 1
|
||||
},
|
||||
"emissiveFactor": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"alphaMode": "OPAQUE",
|
||||
"doubleSided": false
|
||||
},
|
||||
{
|
||||
"name": "Model_1",
|
||||
"pbrMetallicRoughness": {
|
||||
"baseColorTexture": {
|
||||
"index": 1
|
||||
},
|
||||
"baseColorFactor": [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"metallicFactor": 0,
|
||||
"roughnessFactor": 1
|
||||
},
|
||||
"emissiveFactor": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"alphaMode": "OPAQUE",
|
||||
"doubleSided": false
|
||||
}
|
||||
],
|
||||
"meshes": [
|
||||
{
|
||||
"name": "Node-Mesh",
|
||||
"primitives": [
|
||||
{
|
||||
"attributes": {
|
||||
"POSITION": 0,
|
||||
"TEXCOORD_0": 1
|
||||
},
|
||||
"indices": 2,
|
||||
"material": 0,
|
||||
"mode": 4
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
"POSITION": 3,
|
||||
"TEXCOORD_0": 4
|
||||
},
|
||||
"indices": 5,
|
||||
"material": 1,
|
||||
"mode": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"rotation": [
|
||||
0.7071067811865476,
|
||||
0,
|
||||
0,
|
||||
-0.7071067811865476
|
||||
],
|
||||
"name": "Node",
|
||||
"mesh": 0
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
0
|
||||
],
|
||||
"name": "Root"
|
||||
}
|
||||
],
|
||||
"samplers": [
|
||||
{
|
||||
"magFilter": 9729,
|
||||
"minFilter": 9729,
|
||||
"wrapS": 10497,
|
||||
"wrapT": 10497
|
||||
}
|
||||
],
|
||||
"scene": 0,
|
||||
"scenes": [
|
||||
{
|
||||
"nodes": [
|
||||
1
|
||||
]
|
||||
}
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"name": "Model_0",
|
||||
"mimeType": "image/basis",
|
||||
"uri": "Model_0_4096.basis"
|
||||
},
|
||||
{
|
||||
"name": "Model_1",
|
||||
"mimeType": "image/basis",
|
||||
"uri": "Model_1_4096.basis"
|
||||
}
|
||||
],
|
||||
"textures": [
|
||||
{
|
||||
"name": "Model_0",
|
||||
"sampler": 0,
|
||||
"extensions": {
|
||||
"GOOGLE_texture_basis": {
|
||||
"source": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Model_1",
|
||||
"sampler": 0,
|
||||
"extensions": {
|
||||
"GOOGLE_texture_basis": {
|
||||
"source": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"extensionsUsed": [
|
||||
"GOOGLE_texture_basis"
|
||||
],
|
||||
"extensionsRequired": [
|
||||
"GOOGLE_texture_basis"
|
||||
]
|
||||
}
|
||||
BIN
webgl/gltf-demo/AGI_HQ/Model.bin
Normal file
BIN
webgl/gltf-demo/AGI_HQ/Model.bin
Normal file
Binary file not shown.
BIN
webgl/gltf-demo/AGI_HQ/Model_0_4096.basis
Normal file
BIN
webgl/gltf-demo/AGI_HQ/Model_0_4096.basis
Normal file
Binary file not shown.
BIN
webgl/gltf-demo/AGI_HQ/Model_1_4096.basis
Normal file
BIN
webgl/gltf-demo/AGI_HQ/Model_1_4096.basis
Normal file
Binary file not shown.
3203
webgl/gltf-demo/GLTFLoader.js
Normal file
3203
webgl/gltf-demo/GLTFLoader.js
Normal file
File diff suppressed because it is too large
Load Diff
1
webgl/gltf-demo/LICENSE
Normal file
1
webgl/gltf-demo/LICENSE
Normal file
@@ -0,0 +1 @@
|
||||
TODO: third party license (Three.js)
|
||||
0
webgl/gltf-demo/README.md
Normal file
0
webgl/gltf-demo/README.md
Normal file
216
webgl/gltf-demo/index.html
Normal file
216
webgl/gltf-demo/index.html
Normal file
@@ -0,0 +1,216 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<script src="https://cdn.jsdelivr.net/npm/three@v0.104.0"></script>
|
||||
<script src="GLTFLoader.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/three@v0.104.0/examples/js/controls/OrbitControls.js"></script>
|
||||
<style>
|
||||
html, body { width:100%; height:100%; margin:0; padding:0; }
|
||||
canvas { display:block; }
|
||||
#pannel { position: absolute; top: 10px; left: 10px; color: white; background-color:rgba(0.3, 0.3, 0.3, 0.3); padding: 0.5em; max-width: 25%;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script src="./wasm/build/basis_transcoder.js"></script>
|
||||
<script>
|
||||
function log(s) {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = s;
|
||||
document.getElementById('log').appendChild(div);
|
||||
}
|
||||
|
||||
function logTime(desc, t) {
|
||||
log(desc + t.toFixed(1) + ' ms');
|
||||
}
|
||||
|
||||
Module.onRuntimeInitialized = () => {
|
||||
const { BasisFile, initializeBasis } = Module;
|
||||
|
||||
// DXT formats, from:
|
||||
// http://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/
|
||||
COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0;
|
||||
COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
|
||||
COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
|
||||
COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
|
||||
|
||||
const BASIS_FORMAT = {
|
||||
cTFETC1: 0,
|
||||
cTFBC1: 1,
|
||||
cTFBC4: 2,
|
||||
cTFPVRTC1_4_OPAQUE_ONLY: 3,
|
||||
cTFBC7_M6_OPAQUE_ONLY: 4,
|
||||
cTFETC2: 5,
|
||||
cTFBC3: 6,
|
||||
cTFBC5: 7,
|
||||
};
|
||||
|
||||
BASIS_FORMAT_NAMES = {};
|
||||
for (var name in BASIS_FORMAT) {
|
||||
BASIS_FORMAT_NAMES[BASIS_FORMAT[name]] = name;
|
||||
}
|
||||
|
||||
DXT_FORMAT_MAP = {};
|
||||
DXT_FORMAT_MAP[BASIS_FORMAT.cTFBC1] = COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
DXT_FORMAT_MAP[BASIS_FORMAT.cTFBC3] = COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
|
||||
initializeBasis();
|
||||
|
||||
|
||||
/**
|
||||
* ThreeJS glTF demo created by donmccurdy@, austin@, shrekshao@ below.
|
||||
*/
|
||||
|
||||
(function () {
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({ antialias: true });
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
renderer.gammaOutput = true;
|
||||
renderer.gammaFactor = 2.2;
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0xf0f0f0);
|
||||
|
||||
const light = new THREE.AmbientLight();
|
||||
scene.add(light);
|
||||
|
||||
const light2 = new THREE.PointLight();
|
||||
scene.add(light2);
|
||||
|
||||
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100);
|
||||
camera.position.set(12, 8, 10);
|
||||
camera.lookAt(new THREE.Vector3(0, -2, 0));
|
||||
|
||||
const controls = new THREE.OrbitControls( camera, renderer.domElement );
|
||||
controls.autoRotate = true;
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
}, false);
|
||||
|
||||
const etcSupported = renderer.context.getExtension('WEBGL_compressed_texture_etc1');
|
||||
const dxtSupported = renderer.context.getExtension('WEBGL_compressed_texture_s3tc');
|
||||
|
||||
let format = etcSupported ? BASIS_FORMAT.cTFETC1 : BASIS_FORMAT.cTFBC1;
|
||||
|
||||
log('Transcode to Compressed Texture Format: <strong>' + BASIS_FORMAT_NAMES[format] + '</strong>');
|
||||
|
||||
class BasisTextureLoader {
|
||||
constructor() {
|
||||
this.count = 0;
|
||||
}
|
||||
|
||||
load(url, onLoad, onProgress, onError) {
|
||||
|
||||
fetch(url).then(res => res.arrayBuffer()).then(buf => {
|
||||
|
||||
log('<strong> Texture ' + (this.count++) + '</strong>');
|
||||
|
||||
const startTime = performance.now();
|
||||
|
||||
const basisFile = new BasisFile(new Uint8Array(buf));
|
||||
|
||||
const width = basisFile.getImageWidth(0, 0);
|
||||
const height = basisFile.getImageHeight(0, 0);
|
||||
const images = basisFile.getNumImages();
|
||||
const levels = basisFile.getNumLevels(0);
|
||||
|
||||
if (!width || !height || !images || !levels) {
|
||||
console.warn('Invalid .basis file');
|
||||
basisFile.close();
|
||||
basisFile.delete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!basisFile.startTranscoding()) {
|
||||
console.warn('startTranscoding failed');
|
||||
basisFile.close();
|
||||
basisFile.delete();
|
||||
return;
|
||||
}
|
||||
|
||||
const dst = new Uint8Array(basisFile.getImageTranscodedSizeInBytes(0, 0, format));
|
||||
|
||||
if (!basisFile.transcodeImage(dst, 0, 0, format, etcSupported ? 0 : (dxtSupported ? 1 : 0), 0)) {
|
||||
console.warn('transcodeImage failed');
|
||||
basisFile.close();
|
||||
basisFile.delete();
|
||||
return;
|
||||
}
|
||||
|
||||
const elapsed = performance.now() - startTime;
|
||||
|
||||
basisFile.close();
|
||||
basisFile.delete();
|
||||
|
||||
console.log('Transcode success!', dst);
|
||||
console.log('Time:', elapsed, 'ms');
|
||||
|
||||
logTime('Transcode Time: ', elapsed);
|
||||
|
||||
const mipmaps = [ { data: dst, width, height } ];
|
||||
let texture;
|
||||
if (!etcSupported) {
|
||||
const type = dxtSupported ? THREE.UnsignedByteType : THREE.UnsignedShort565Type;
|
||||
|
||||
const f = dxtSupported ? DXT_FORMAT_MAP[ format ] : THREE.RGBFormat;
|
||||
|
||||
texture = new THREE.CompressedTexture( mipmaps, width, height, f, type );
|
||||
} else {
|
||||
texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.RGB_ETC1_Format );
|
||||
}
|
||||
|
||||
texture.minFilter = THREE.LinearFilter;
|
||||
texture.magFilter = THREE.LinearFilter;
|
||||
texture.encoding = THREE.sRGBEncoding;
|
||||
texture.generateMipmaps = false;
|
||||
texture.flipY = false;
|
||||
texture.needsUpdate = true;
|
||||
|
||||
onLoad( texture );
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
THREE.Loader.Handlers.add(/\.basis$/, new BasisTextureLoader());
|
||||
|
||||
const loader = new THREE.GLTFLoader();
|
||||
|
||||
function animate() {
|
||||
requestAnimationFrame(animate);
|
||||
controls.update();
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
|
||||
loader.load('AGI_HQ/AgiHQ.gltf', (gltf) => {
|
||||
|
||||
const model = gltf.scene;
|
||||
model.scale.set(0.01, 0.01, 0.01);
|
||||
|
||||
const bbox = new THREE.Box3();
|
||||
bbox.setFromObject(model);
|
||||
console.log(bbox);
|
||||
|
||||
scene.add(model);
|
||||
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
animate();
|
||||
|
||||
}, undefined, (e) => console.error(e));
|
||||
|
||||
}());
|
||||
}
|
||||
</script>
|
||||
<div id="pannel">
|
||||
<strong>Basis Texture Transcoder glTF Demo</strong>
|
||||
<div id="log"></div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
19
webgl/gltf-demo/wasm/CMakeLists.txt
Normal file
19
webgl/gltf-demo/wasm/CMakeLists.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
project(basisu_transcoder_js)
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
add_executable(basis_transcoder.js
|
||||
../../../transcoder/basisu_transcoder.cpp
|
||||
basis_wrappers.cpp
|
||||
)
|
||||
|
||||
target_include_directories(basis_transcoder.js PRIVATE ../transcoder)
|
||||
|
||||
set_target_properties(basis_transcoder.js PROPERTIES
|
||||
OUTPUT_NAME "basis_transcoder"
|
||||
SUFFIX ".js"
|
||||
LINK_FLAGS "--bind -s ALLOW_MEMORY_GROWTH=1 -s ASSERTIONS=0")
|
||||
endif()
|
||||
205
webgl/gltf-demo/wasm/basis_wrappers.cpp
Normal file
205
webgl/gltf-demo/wasm/basis_wrappers.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
// basis_wrappers.cpp - Simple C-style wrappers to the C++ transcoder for WebGL use.
|
||||
#include "basisu_transcoder.h"
|
||||
#include <emscripten/bind.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace emscripten;
|
||||
using namespace basist;
|
||||
|
||||
static basist::etc1_global_selector_codebook *g_pGlobal_codebook;
|
||||
|
||||
void basis_init()
|
||||
{
|
||||
basisu_transcoder_init();
|
||||
|
||||
if (!g_pGlobal_codebook)
|
||||
g_pGlobal_codebook = new basist::etc1_global_selector_codebook(g_global_selector_cb_size, g_global_selector_cb);
|
||||
}
|
||||
|
||||
#define MAGIC 0xDEADBEE1
|
||||
|
||||
struct basis_file
|
||||
{
|
||||
int m_magic = 0;
|
||||
basisu_transcoder m_transcoder;
|
||||
std::vector<uint8_t> m_file;
|
||||
|
||||
basis_file(const emscripten::val& jsBuffer)
|
||||
: m_file([&]() {
|
||||
size_t byteLength = jsBuffer["byteLength"].as<size_t>();
|
||||
return std::vector<uint8_t>(byteLength);
|
||||
}()),
|
||||
m_transcoder(g_pGlobal_codebook)
|
||||
{
|
||||
unsigned int length = jsBuffer["length"].as<unsigned int>();
|
||||
emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
|
||||
emscripten::val memoryView = jsBuffer["constructor"].new_(memory, reinterpret_cast<uintptr_t>(m_file.data()), length);
|
||||
memoryView.call<void>("set", jsBuffer);
|
||||
|
||||
if (!m_transcoder.validate_header(m_file.data(), m_file.size())) {
|
||||
m_file.clear();
|
||||
std::cerr << "Invalid Basis header" << std::endl;
|
||||
}
|
||||
|
||||
// Initialized after validation
|
||||
m_magic = MAGIC;
|
||||
}
|
||||
|
||||
void close() {
|
||||
assert(m_magic == MAGIC);
|
||||
m_file.clear();
|
||||
}
|
||||
|
||||
uint32_t getHasAlpha() {
|
||||
assert(m_magic == MAGIC);
|
||||
if (m_magic != MAGIC)
|
||||
return 0;
|
||||
|
||||
basisu_image_level_info li;
|
||||
if (!m_transcoder.get_image_level_info(m_file.data(), m_file.size(), li, 0, 0))
|
||||
return 0;
|
||||
|
||||
return li.m_alpha_flag;
|
||||
}
|
||||
|
||||
uint32_t getNumImages() {
|
||||
assert(m_magic == MAGIC);
|
||||
if (m_magic != MAGIC)
|
||||
return 0;
|
||||
|
||||
return m_transcoder.get_total_images(m_file.data(), m_file.size());
|
||||
}
|
||||
|
||||
uint32_t getNumLevels(uint32_t image_index) {
|
||||
assert(m_magic == MAGIC);
|
||||
if (m_magic != MAGIC)
|
||||
return 0;
|
||||
|
||||
basisu_image_info ii;
|
||||
if (!m_transcoder.get_image_info(m_file.data(), m_file.size(), ii, image_index))
|
||||
return 0;
|
||||
|
||||
return ii.m_total_levels;
|
||||
}
|
||||
|
||||
uint32_t getImageWidth(uint32_t image_index, uint32_t level_index) {
|
||||
assert(m_magic == MAGIC);
|
||||
if (m_magic != MAGIC)
|
||||
return 0;
|
||||
|
||||
uint32_t orig_width, orig_height, total_blocks;
|
||||
if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
|
||||
return 0;
|
||||
|
||||
return orig_width;
|
||||
}
|
||||
|
||||
uint32_t getImageHeight(uint32_t image_index, uint32_t level_index) {
|
||||
assert(m_magic == MAGIC);
|
||||
if (m_magic != MAGIC)
|
||||
return 0;
|
||||
|
||||
uint32_t orig_width, orig_height, total_blocks;
|
||||
if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
|
||||
return 0;
|
||||
|
||||
return orig_height;
|
||||
}
|
||||
|
||||
uint32_t getImageTranscodedSizeInBytes(uint32_t image_index, uint32_t level_index, uint32_t format) {
|
||||
assert(m_magic == MAGIC);
|
||||
if (m_magic != MAGIC)
|
||||
return 0;
|
||||
|
||||
if (format >= cTFTotalTextureFormats)
|
||||
return 0;
|
||||
|
||||
uint32_t bytes_per_block = basis_get_bytes_per_block(static_cast<transcoder_texture_format>(format));
|
||||
|
||||
uint32_t orig_width, orig_height, total_blocks;
|
||||
if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
|
||||
return 0;
|
||||
|
||||
return total_blocks * bytes_per_block;
|
||||
}
|
||||
|
||||
uint32_t startTranscoding() {
|
||||
assert(m_magic == MAGIC);
|
||||
if (m_magic != MAGIC)
|
||||
return 0;
|
||||
|
||||
return m_transcoder.start_transcoding(m_file.data(), m_file.size());
|
||||
}
|
||||
|
||||
uint32_t transcodeImage(const emscripten::val& dst, uint32_t image_index, uint32_t level_index, uint32_t format, uint32_t pvrtc_wrap_addressing, uint32_t get_alpha_for_opaque_formats) {
|
||||
assert(m_magic == MAGIC);
|
||||
if (m_magic != MAGIC)
|
||||
return 0;
|
||||
|
||||
if (format >= cTFTotalTextureFormats)
|
||||
return 0;
|
||||
|
||||
uint32_t bytes_per_block = basis_get_bytes_per_block(static_cast<transcoder_texture_format>(format));
|
||||
|
||||
uint32_t orig_width, orig_height, total_blocks;
|
||||
if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
|
||||
return 0;
|
||||
|
||||
uint32_t required_size = total_blocks * bytes_per_block;
|
||||
|
||||
std::vector<uint8_t> dst_data(required_size);
|
||||
|
||||
uint32_t status = m_transcoder.transcode_image_level(
|
||||
m_file.data(), m_file.size(), image_index, level_index,
|
||||
dst_data.data(), dst_data.size() / bytes_per_block,
|
||||
static_cast<basist::transcoder_texture_format>(format),
|
||||
(
|
||||
(pvrtc_wrap_addressing ? basisu_transcoder::cDecodeFlagsPVRTCWrapAddressing : 0) |
|
||||
(get_alpha_for_opaque_formats ? basisu_transcoder::cDecodeFlagsTranscodeAlphaDataToOpaqueFormats : 0)
|
||||
));
|
||||
|
||||
emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
|
||||
emscripten::val memoryView = emscripten::val::global("Uint8Array").new_(memory, reinterpret_cast<uintptr_t>(dst_data.data()), dst_data.size());
|
||||
|
||||
dst.call<void>("set", memoryView);
|
||||
return status;
|
||||
}
|
||||
};
|
||||
|
||||
EMSCRIPTEN_BINDINGS(basis_transcoder) {
|
||||
|
||||
function("initializeBasis", &basis_init);
|
||||
|
||||
class_<basis_file>("BasisFile")
|
||||
.constructor<const emscripten::val&>()
|
||||
.function("close", optional_override([](basis_file& self) {
|
||||
return self.close();
|
||||
}))
|
||||
.function("getHasAlpha", optional_override([](basis_file& self) {
|
||||
return self.getHasAlpha();
|
||||
}))
|
||||
.function("getNumImages", optional_override([](basis_file& self) {
|
||||
return self.getNumImages();
|
||||
}))
|
||||
.function("getNumLevels", optional_override([](basis_file& self, uint32_t imageIndex) {
|
||||
return self.getNumLevels(imageIndex);
|
||||
}))
|
||||
.function("getImageWidth", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex) {
|
||||
return self.getImageWidth(imageIndex, levelIndex);
|
||||
}))
|
||||
.function("getImageHeight", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex) {
|
||||
return self.getImageHeight(imageIndex, levelIndex);
|
||||
}))
|
||||
.function("getImageTranscodedSizeInBytes", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex, uint32_t format) {
|
||||
return self.getImageTranscodedSizeInBytes(imageIndex, levelIndex, format);
|
||||
}))
|
||||
.function("startTranscoding", optional_override([](basis_file& self) {
|
||||
return self.startTranscoding();
|
||||
}))
|
||||
.function("transcodeImage", optional_override([](basis_file& self, const emscripten::val& dst, uint32_t imageIndex, uint32_t levelIndex, uint32_t format, uint32_t pvrtcWrapAddressing, uint32_t getAlphaForOpaqueFormats) {
|
||||
return self.transcodeImage(dst, imageIndex, levelIndex, format, pvrtcWrapAddressing, getAlphaForOpaqueFormats);
|
||||
}))
|
||||
;
|
||||
|
||||
}
|
||||
7632
webgl/gltf-demo/wasm/build/basis_transcoder.js
Normal file
7632
webgl/gltf-demo/wasm/build/basis_transcoder.js
Normal file
File diff suppressed because it is too large
Load Diff
BIN
webgl/gltf-demo/wasm/build/basis_transcoder.wasm
Normal file
BIN
webgl/gltf-demo/wasm/build/basis_transcoder.wasm
Normal file
Binary file not shown.
Reference in New Issue
Block a user