Restructure webgl demo folders and Update readme

This commit is contained in:
shrekshao
2019-05-14 17:12:51 -07:00
parent cec4c0e651
commit c4cc4e4e2b
14 changed files with 206 additions and 459 deletions

View File

@@ -59,11 +59,9 @@ If you are doing rate distortion comparisons vs. other similar systems, be sure
### WebGL test ### WebGL test
The "WebGL" directory contains a very simple WebGL demo that uses the transcoder compiled to asm.js with [emscripten](https://emscripten.org/). It currently only supports transcoding to the BC1 and BC3 texture formats. The file `WebGL/basis_wrappers.cpp` contains a simple C-style API that the Javascript code calls to interface with the C++ Basis transcoder. The "WebGL" directory contains two very simple WebGL demos that use the transcoder compiled to wasm with [emscripten](https://emscripten.org/).
On browsers that don't support BC1 (Firefox is one), there's a low-quality fallback code path for opaque textures (but no fallback for BC3 yet). Note that the fallback path only converts to 16-bit RGB images at the moment, so the quality isn't as good as it should be. See more details [here](webgl/README.md).
Note that I was unable to disable assertions when compiling the transcoder in release (-O2), and I'm not sure why yet. Currently, basisu.h forcefully #undef's the assert() macro, which is ugly but works. Including assert()'s in release will slow transcoding down.
### Transcoder details ### Transcoder details

View File

@@ -1,7 +1,15 @@
# glTF Demo # WebGL Demo
A WebGL demo rendering a glTF 3D model with `.basis` texture files, transcoded into one of the following compressed texture formats: ### Texture Demo
`index.html` uses the transcoder compiled to wasm with emscripten and renders the texture. Currently supporting following texture formats:
* BC1
* BC3
On browsers that don't support BC1 (Firefox is one), there's a low-quality fallback code path for opaque textures (but no fallback for BC3 yet). Note that the fallback path only converts to 16-bit RGB images at the moment, so the quality isn't as good as it should be.
### glTF 3D Model Demo
`gltf-demo/index.html` renders a glTF 3D model with `.basis` texture files, transcoded into one of the following compressed texture formats:
* DTX (BC1) * DTX (BC1)
* Tested in Chrome (Linux and macOS) and Firefox (macOS). * Tested in Chrome (Linux and macOS) and Firefox (macOS).
* ETC1 * ETC1
@@ -9,11 +17,11 @@ A WebGL demo rendering a glTF 3D model with `.basis` texture files, transcoded i
* PVRTC (COMPRESSED_RGB_PVRTC_4BPPV1_IMG) * PVRTC (COMPRESSED_RGB_PVRTC_4BPPV1_IMG)
* Tested in Chrome and Safari on iOS iPhone 6 Plus. * Tested in Chrome and Safari on iOS iPhone 6 Plus.
Requires WebAssembly and WebGL support.
The glTF model in this demo uses a hypothetical `GOOGLE_texture_basis` extension. That extension is defined for the sake of example only the glTF format will officially embed Basis files within a KTX2 wrapper, through a new The glTF model in this demo uses a hypothetical `GOOGLE_texture_basis` extension. That extension is defined for the sake of example only the glTF format will officially embed Basis files within a KTX2 wrapper, through a new
extension that is currently in development. extension that is currently in development.
Both demos requires WebAssembly and WebGL support.
## Testing locally ## Testing locally
See [how to run things locally](https://threejs.org/docs/#manual/en/introduction/How-to-run-things-locally), or (with [Node.js](https://nodejs.org/en/) installed), run: See [how to run things locally](https://threejs.org/docs/#manual/en/introduction/How-to-run-things-locally), or (with [Node.js](https://nodejs.org/en/) installed), run:
@@ -29,7 +37,7 @@ The console will display a `localhost` URL for local testing, and (on supported
Prebuilt versions of `basis_transcoder.js` and `basis_transcoder.wasm` are included in the `wasm/build/` folder, and are sufficient for local demos. To build the transcoder yourself, first install emscripten ([tutorial](https://webassembly.org/getting-started/developers-guide/)) and cmake ([download](https://cmake.org/download/)). Then run: Prebuilt versions of `basis_transcoder.js` and `basis_transcoder.wasm` are included in the `wasm/build/` folder, and are sufficient for local demos. To build the transcoder yourself, first install emscripten ([tutorial](https://webassembly.org/getting-started/developers-guide/)) and cmake ([download](https://cmake.org/download/)). Then run:
```shell ```shell
cd webgl/gltf-demo/wasm/build/ cd webgl/wasm/build/
emcmake cmake ../ emcmake cmake ../
make make
``` ```

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -1,228 +1,205 @@
// basis_wrappers.cpp - Simple C-style wrappers to the C++ transcoder for WebGL use. // basis_wrappers.cpp - Simple C-style wrappers to the C++ transcoder for WebGL use.
#include "basisu_transcoder.h" #include "basisu_transcoder.h"
#include <emscripten/bind.h>
#include <iostream>
using namespace emscripten;
using namespace basist; using namespace basist;
static basist::etc1_global_selector_codebook *g_pGlobal_codebook; static basist::etc1_global_selector_codebook *g_pGlobal_codebook;
typedef unsigned int uint;
extern "C"
{
void basis_init();
void *basis_open(void *src, uint src_size);
void basis_close(void *h);
uint basis_get_has_alpha(void *h);
uint basis_get_num_images(void *h);
uint basis_get_num_levels(void *h, uint image_index);
uint basis_get_image_width(void *h, uint image_index, uint level_index);
uint basis_get_image_height(void *h, uint image_index, uint level_index);
uint basis_get_image_transcoded_size_in_bytes(void *h, uint image_index, uint level_index, uint format);
uint basis_start_transcoding(void *h);
uint basis_transcode_image(void *h, void *dst, uint dst_size_in_bytes,
uint image_index, uint level_index, uint format,
uint pvrtc_wrap_addressing, uint get_alpha_for_opaque_formats);
}
void basis_init() void basis_init()
{ {
basisu_transcoder_init(); basisu_transcoder_init();
if (!g_pGlobal_codebook) if (!g_pGlobal_codebook)
g_pGlobal_codebook = new basist::etc1_global_selector_codebook(g_global_selector_cb_size, g_global_selector_cb); g_pGlobal_codebook = new basist::etc1_global_selector_codebook(g_global_selector_cb_size, g_global_selector_cb);
} }
#define MAGIC 0xDEADBEE1 #define MAGIC 0xDEADBEE1
struct basis_file struct basis_file
{ {
int m_magic; int m_magic = 0;
basisu_transcoder m_transcoder; basisu_transcoder m_transcoder;
void *m_pFile; std::vector<uint8_t> m_file;
uint m_file_size;
basis_file() : basis_file(const emscripten::val& jsBuffer)
m_transcoder(g_pGlobal_codebook) : 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;
}
}; };
void *basis_open(void *src, uint src_size) EMSCRIPTEN_BINDINGS(basis_transcoder) {
{
if ((!src) || (!src_size)) function("initializeBasis", &basis_init);
return nullptr;
class_<basis_file>("BasisFile")
basis_file *f = new basis_file; .constructor<const emscripten::val&>()
f->m_pFile = src; .function("close", optional_override([](basis_file& self) {
f->m_file_size = src_size; return self.close();
}))
if (!f->m_transcoder.validate_header(f->m_pFile, f->m_file_size)) .function("getHasAlpha", optional_override([](basis_file& self) {
{ return self.getHasAlpha();
delete f; }))
return nullptr; .function("getNumImages", optional_override([](basis_file& self) {
} return self.getNumImages();
f->m_magic = MAGIC; }))
.function("getNumLevels", optional_override([](basis_file& self, uint32_t imageIndex) {
return f; return self.getNumLevels(imageIndex);
} }))
.function("getImageWidth", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex) {
void basis_close(void *h) return self.getImageWidth(imageIndex, levelIndex);
{ }))
basis_file *f = static_cast<basis_file *>(h); .function("getImageHeight", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex) {
if (!f) return self.getImageHeight(imageIndex, levelIndex);
return; }))
.function("getImageTranscodedSizeInBytes", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex, uint32_t format) {
assert(f->m_magic == MAGIC); return self.getImageTranscodedSizeInBytes(imageIndex, levelIndex, format);
if (f->m_magic != MAGIC) }))
return; .function("startTranscoding", optional_override([](basis_file& self) {
return self.startTranscoding();
delete f; }))
} .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);
uint basis_get_has_alpha(void *h) }))
{ ;
basis_file *f = static_cast<basis_file *>(h);
if (!f)
return 0;
assert(f->m_magic == MAGIC);
if (f->m_magic != MAGIC)
return 0;
basisu_image_level_info li;
if (!f->m_transcoder.get_image_level_info(f->m_pFile, f->m_file_size, li, 0, 0))
return 0;
return li.m_alpha_flag;
}
uint basis_get_num_images(void *h)
{
basis_file *f = static_cast<basis_file *>(h);
if (!f)
return 0;
assert(f->m_magic == MAGIC);
if (f->m_magic != MAGIC)
return 0;
return f->m_transcoder.get_total_images(f->m_pFile, f->m_file_size);
}
uint basis_get_num_levels(void *h, uint image_index)
{
basis_file *f = static_cast<basis_file *>(h);
if (!f)
return 0;
assert(f->m_magic == MAGIC);
if (f->m_magic != MAGIC)
return 0;
basisu_image_info ii;
if (!f->m_transcoder.get_image_info(f->m_pFile, f->m_file_size, ii, image_index))
return 0;
return ii.m_total_levels;
}
uint basis_get_image_width(void *h, uint image_index, uint level_index)
{
basis_file *f = static_cast<basis_file *>(h);
if (!f)
return 0;
assert(f->m_magic == MAGIC);
if (f->m_magic != MAGIC)
return 0;
uint orig_width, orig_height, total_blocks;
if (!f->m_transcoder.get_image_level_desc(f->m_pFile, f->m_file_size, image_index, level_index, orig_width, orig_height, total_blocks))
return 0;
return orig_width;
}
uint basis_get_image_height(void *h, uint image_index, uint level_index)
{
basis_file *f = static_cast<basis_file *>(h);
if (!f)
return 0;
assert(f->m_magic == MAGIC);
if (f->m_magic != MAGIC)
return 0;
uint orig_width, orig_height, total_blocks;
if (!f->m_transcoder.get_image_level_desc(f->m_pFile, f->m_file_size, image_index, level_index, orig_width, orig_height, total_blocks))
return 0;
return orig_height;
}
uint basis_get_image_transcoded_size_in_bytes(void *h, uint image_index, uint level_index, uint format)
{
basis_file *f = static_cast<basis_file *>(h);
if (!f)
return 0;
assert(f->m_magic == MAGIC);
if (f->m_magic != MAGIC)
return 0;
if (format >= cTFTotalTextureFormats)
return 0;
uint bytes_per_block = basis_get_bytes_per_block((transcoder_texture_format)format);
uint orig_width, orig_height, total_blocks;
if (!f->m_transcoder.get_image_level_desc(f->m_pFile, f->m_file_size, image_index, level_index, orig_width, orig_height, total_blocks))
return 0;
return total_blocks * bytes_per_block;
}
uint basis_start_transcoding(void *h)
{
basis_file *f = static_cast<basis_file *>(h);
if (!f)
return 0;
assert(f->m_magic == MAGIC);
if (f->m_magic != MAGIC)
return 0;
return f->m_transcoder.start_transcoding(f->m_pFile, f->m_file_size);
}
uint basis_transcode_image(void *h, void *dst, uint dst_size_in_bytes,
uint image_index, uint level_index, uint format,
uint pvrtc_wrap_addressing, uint get_alpha_for_opaque_formats)
{
basis_file *f = static_cast<basis_file *>(h);
if (!f)
return 0;
assert(f->m_magic == MAGIC);
if (f->m_magic != MAGIC)
return 0;
if (format >= cTFTotalTextureFormats)
return 0;
uint bytes_per_block = basis_get_bytes_per_block((transcoder_texture_format)format);
return f->m_transcoder.transcode_image_level(f->m_pFile, f->m_file_size, image_index, level_index,
dst, dst_size_in_bytes / bytes_per_block,
(basist::transcoder_texture_format)format,
(pvrtc_wrap_addressing ? basisu_transcoder::cDecodeFlagsPVRTCWrapAddressing : 0) | (get_alpha_for_opaque_formats ? basisu_transcoder::cDecodeFlagsTranscodeAlphaDataToOpaqueFormats : 0));
} }

View File

@@ -1,3 +0,0 @@
@REM -O0 -s ASSERTIONS=1 -s DEMANGLE_SUPPORT=1
@REM -O2 -s ASSERTIONS=0
emcc -s EXPORTED_FUNCTIONS="['allocate', '_malloc', '_free', '_basis_init','_basis_open','_basis_close','_basis_get_has_alpha','_basis_get_num_images','_basis_get_num_levels','_basis_get_image_width','_basis_get_image_height','_basis_get_image_transcoded_size_in_bytes','_basis_transcode_image','_basis_start_transcoding']" -o basis.js ../transcoder/basisu_transcoder.cpp basis_wrappers.cpp -s TOTAL_MEMORY=60000000 -O2 -s ASSERTIONS=0 -I ../transcoder

View File

@@ -1,10 +0,0 @@
#!/bin/bash
# rg - I haven't tested this shell script yet (I use build.bat on Windows)
emcc \
-s EXPORTED_FUNCTIONS="['allocate', '_malloc', '_free', '_basis_init','_basis_open','_basis_close','_basis_get_has_alpha','_basis_get_num_images','_basis_get_num_levels','_basis_get_image_width','_basis_get_image_height','_basis_get_image_transcoded_size_in_bytes','_basis_transcode_image','_basis_start_transcoding']" \
-s TOTAL_MEMORY=640MB -O2 -s ASSERTIONS=0 -I ../transcoder \
-o basis.js \
../transcoder/basisu_transcoder.cpp basis_wrappers.cpp && \
chmod -R a+rX .

View File

@@ -5,7 +5,7 @@
<script src="GLTFLoader.js"></script> <script src="GLTFLoader.js"></script>
<script src="BasisTextureLoader.js"></script> <script src="BasisTextureLoader.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@v0.104.0/examples/js/controls/OrbitControls.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@v0.104.0/examples/js/controls/OrbitControls.js"></script>
<script src="./wasm/build/basis_transcoder.js"></script> <script src="../wasm/build/basis_transcoder.js"></script>
<style> <style>
html, body { width:100%; height:100%; margin:0; padding:0; } html, body { width:100%; height:100%; margin:0; padding:0; }
canvas { display:block; } canvas { display:block; }

View File

@@ -1,205 +0,0 @@
// 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);
}))
;
}

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,7 @@
<head> <head>
<script src="renderer.js"></script> <script src="renderer.js"></script>
<script src="dxt-to-rgb565.js"></script> <script src="dxt-to-rgb565.js"></script>
<script src="./gltf-demo/wasm/build/basis_transcoder.js"></script> <script src="./wasm/build/basis_transcoder.js"></script>
<script type="text/javascript"> <script type="text/javascript">
function log(s) { function log(s) {
var div = document.createElement('div'); var div = document.createElement('div');

View File

@@ -6,11 +6,11 @@ if (EMSCRIPTEN)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
add_executable(basis_transcoder.js add_executable(basis_transcoder.js
../../../transcoder/basisu_transcoder.cpp ../../transcoder/basisu_transcoder.cpp
basis_wrappers.cpp ../basis_wrappers.cpp
) )
target_include_directories(basis_transcoder.js PRIVATE ../../../transcoder) target_include_directories(basis_transcoder.js PRIVATE ../../transcoder)
set_target_properties(basis_transcoder.js PROPERTIES set_target_properties(basis_transcoder.js PROPERTIES
OUTPUT_NAME "basis_transcoder" OUTPUT_NAME "basis_transcoder"