From bff76f184e40a36522c6b08e58f60a97e3ea948f Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Mon, 17 Mar 2025 18:53:36 +0800 Subject: [PATCH] add gltfio FFI methods and expose texture/render target creation directly --- .../src/viewer/src/shared_types/texture.dart | 55 ++++- .../native/include/c_api/APIBoundaryTypes.h | 10 + thermion_dart/native/include/c_api/TEngine.h | 9 +- .../native/include/c_api/TGltfAssetLoader.h | 30 +++ .../native/include/c_api/TRenderTarget.h | 28 +++ thermion_dart/native/include/c_api/TScene.h | 2 + thermion_dart/native/include/c_api/TTexture.h | 24 ++ .../native/include/c_api/ThermionDartApi.h | 6 +- .../c_api/ThermionDartRenderThreadApi.h | 25 ++- thermion_dart/native/src/c_api/TEngine.cpp | 183 +--------------- .../native/src/c_api/TGltfAssetLoader.cpp | 97 +++++++++ .../native/src/c_api/TRenderTarget.cpp | 41 ++++ thermion_dart/native/src/c_api/TScene.cpp | 10 + thermion_dart/native/src/c_api/TTexture.cpp | 205 ++++++++++++++++++ .../src/c_api/ThermionDartRenderThreadApi.cpp | 99 ++++++++- 15 files changed, 622 insertions(+), 202 deletions(-) create mode 100644 thermion_dart/native/include/c_api/TGltfAssetLoader.h create mode 100644 thermion_dart/native/include/c_api/TRenderTarget.h create mode 100644 thermion_dart/native/src/c_api/TGltfAssetLoader.cpp create mode 100644 thermion_dart/native/src/c_api/TRenderTarget.cpp diff --git a/thermion_dart/lib/src/viewer/src/shared_types/texture.dart b/thermion_dart/lib/src/viewer/src/shared_types/texture.dart index e021f56e..6e9423e2 100644 --- a/thermion_dart/lib/src/viewer/src/shared_types/texture.dart +++ b/thermion_dart/lib/src/viewer/src/shared_types/texture.dart @@ -148,19 +148,56 @@ enum TextureFormat { SRGB_ALPHA_BPTC_UNORM, // BC7 sRGB } -/// Defines texture usage flags that affect memory allocation enum TextureUsage { - /// Default texture usage, optimized for general use - DEFAULT, + TEXTURE_USAGE_NONE(0), - /// Optimized for textures that will be used as color attachments - COLOR_ATTACHMENT, + /// !< Texture can be used as a color attachment + TEXTURE_USAGE_COLOR_ATTACHMENT(1), - /// Optimized for textures that will be used as depth attachments - DEPTH_ATTACHMENT, + /// !< Texture can be used as a depth attachment + TEXTURE_USAGE_DEPTH_ATTACHMENT(2), - /// Optimized for textures that will be sampled from shaders - SAMPLEABLE + /// !< Texture can be used as a stencil attachment + TEXTURE_USAGE_STENCIL_ATTACHMENT(4), + + /// !< Data can be uploaded into this texture (default) + TEXTURE_USAGE_UPLOADABLE(8), + + /// !< Texture can be sampled (default) + TEXTURE_USAGE_SAMPLEABLE(16), + + /// !< Texture can be used as a subpass input + TEXTURE_USAGE_SUBPASS_INPUT(32), + + /// !< Texture can be used the source of a blit() + TEXTURE_USAGE_BLIT_SRC(64), + + /// !< Texture can be used the destination of a blit() + TEXTURE_USAGE_BLIT_DST(128), + + /// !< Texture can be used the destination of a blit() + TEXTURE_USAGE_PROTECTED(256), + + /// !< Default texture usage + TEXTURE_USAGE_DEFAULT(24); + + final int value; + const TextureUsage(this.value); + + static TextureUsage fromValue(int value) => switch (value) { + 0 => TEXTURE_USAGE_NONE, + 1 => TEXTURE_USAGE_COLOR_ATTACHMENT, + 2 => TEXTURE_USAGE_DEPTH_ATTACHMENT, + 4 => TEXTURE_USAGE_STENCIL_ATTACHMENT, + 8 => TEXTURE_USAGE_UPLOADABLE, + 16 => TEXTURE_USAGE_SAMPLEABLE, + 32 => TEXTURE_USAGE_SUBPASS_INPUT, + 64 => TEXTURE_USAGE_BLIT_SRC, + 128 => TEXTURE_USAGE_BLIT_DST, + 256 => TEXTURE_USAGE_PROTECTED, + 24 => TEXTURE_USAGE_DEFAULT, + _ => throw ArgumentError("Unknown value for TTextureUsage: $value"), + }; } /// Defines texture wrapping modes for texture coordinates diff --git a/thermion_dart/native/include/c_api/APIBoundaryTypes.h b/thermion_dart/native/include/c_api/APIBoundaryTypes.h index 2b207cec..96428e0d 100644 --- a/thermion_dart/native/include/c_api/APIBoundaryTypes.h +++ b/thermion_dart/native/include/c_api/APIBoundaryTypes.h @@ -37,6 +37,9 @@ extern "C" typedef struct TTexture TTexture; typedef struct TTextureSampler TTextureSampler; typedef struct TLinearImage TLinearImage; + typedef struct TGltfAssetLoader TGltfAssetLoader; + typedef struct TGltfResourceLoader TGltfResourceLoader; + typedef struct TFilamentAsset TFilamentAsset; struct TMaterialKey { bool doubleSided; @@ -160,6 +163,13 @@ extern "C" extern uint64_t TSWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER; extern uint64_t TSWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER; + extern uint64_t TSWAP_CHAIN_CONFIG_TRANSPARENT; + extern uint64_t TSWAP_CHAIN_CONFIG_READABLE; + extern uint64_t TSWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER; + extern uint64_t TSWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER; + + + #ifdef __cplusplus } diff --git a/thermion_dart/native/include/c_api/TEngine.h b/thermion_dart/native/include/c_api/TEngine.h index dca05f26..f117e857 100644 --- a/thermion_dart/native/include/c_api/TEngine.h +++ b/thermion_dart/native/include/c_api/TEngine.h @@ -25,6 +25,7 @@ EMSCRIPTEN_KEEPALIVE TEngine *Engine_create(TBackend backend); EMSCRIPTEN_KEEPALIVE TRenderer *Engine_createRenderer(TEngine *tEngine); EMSCRIPTEN_KEEPALIVE TSwapChain *Engine_createSwapChain(TEngine *tEngine, void *window, uint64_t flags); EMSCRIPTEN_KEEPALIVE TSwapChain *Engine_createHeadlessSwapChain(TEngine *tEngine, uint32_t width, uint32_t height, uint64_t flags); + EMSCRIPTEN_KEEPALIVE TCamera *Engine_createCamera(TEngine* tEngine); EMSCRIPTEN_KEEPALIVE TView *Engine_createView(TEngine *tEngine); EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine* tEngine, EntityId entityId); @@ -32,13 +33,7 @@ EMSCRIPTEN_KEEPALIVE TTransformManager *Engine_getTransformManager(TEngine *engi EMSCRIPTEN_KEEPALIVE TRenderableManager *Engine_getRenderableManager(TEngine *engine); EMSCRIPTEN_KEEPALIVE TLightManager *Engine_getLightManager(TEngine *engine); EMSCRIPTEN_KEEPALIVE TEntityManager *Engine_getEntityManager(TEngine *engine); -EMSCRIPTEN_KEEPALIVE TTexture *Engine_buildTexture(TEngine *engine, - uint32_t width, - uint32_t height, - uint32_t depth, - uint8_t levels, - TTextureSamplerType sampler, - TTextureFormat format); + EMSCRIPTEN_KEEPALIVE void Engine_destroyTexture(TEngine *tEngine, TTexture *tTexture); EMSCRIPTEN_KEEPALIVE TFence *Engine_createFence(TEngine *tEngine); diff --git a/thermion_dart/native/include/c_api/TGltfAssetLoader.h b/thermion_dart/native/include/c_api/TGltfAssetLoader.h new file mode 100644 index 00000000..a9e7d694 --- /dev/null +++ b/thermion_dart/native/include/c_api/TGltfAssetLoader.h @@ -0,0 +1,30 @@ +#ifndef _T_GLTF_ASSET_LOADER_H +#define _T_GLTF_ASSET_LOADER_H + +#include "APIExport.h" +#include "APIBoundaryTypes.h" +#include "TMaterialInstance.h" +#include "TTexture.h" +#include "ResourceBuffer.hpp" +#include "MathUtils.hpp" + +#ifdef __cplusplus +extern "C" +{ +#endif + +EMSCRIPTEN_KEEPALIVE TGltfAssetLoader *GltfAssetLoader_create(TEngine *tEngine, TMaterialProvider *tMaterialProvider); +EMSCRIPTEN_KEEPALIVE TGltfResourceLoader *GltfResourceLoader_create(TEngine *tEngine); +EMSCRIPTEN_KEEPALIVE TFilamentAsset *GltfAssetLoader_load( + TGltfAssetLoader *tAssetLoader, + TGltfResourceLoader *tResourceLoader, + uint8_t *data, + size_t length, + uint8_t numInstances +); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/thermion_dart/native/include/c_api/TRenderTarget.h b/thermion_dart/native/include/c_api/TRenderTarget.h new file mode 100644 index 00000000..04775929 --- /dev/null +++ b/thermion_dart/native/include/c_api/TRenderTarget.h @@ -0,0 +1,28 @@ +#ifndef _T_RENDERTARGET_H +#define _T_RENDERTARGET_H + +#include "APIExport.h" +#include "APIBoundaryTypes.h" +#include "TMaterialInstance.h" +#include "TTexture.h" +#include "ResourceBuffer.hpp" +#include "MathUtils.hpp" + +#ifdef __cplusplus +extern "C" +{ +#endif + +EMSCRIPTEN_KEEPALIVE TRenderTarget *RenderTarget_create( + TEngine *tEngine, + uint32_t width, + uint32_t height, + TTexture *color, + TTexture *depth +); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/thermion_dart/native/include/c_api/TScene.h b/thermion_dart/native/include/c_api/TScene.h index 2c747c7a..85561976 100644 --- a/thermion_dart/native/include/c_api/TScene.h +++ b/thermion_dart/native/include/c_api/TScene.h @@ -17,6 +17,8 @@ extern "C" EMSCRIPTEN_KEEPALIVE void Scene_addEntity(TScene* tScene, EntityId entityId); EMSCRIPTEN_KEEPALIVE void Scene_setSkybox(TScene* tScene, TSkybox *skybox); +EMSCRIPTEN_KEEPALIVE void Scene_addFilamentAsset(TScene* tScene, TFilamentAsset *asset); + #ifdef __cplusplus diff --git a/thermion_dart/native/include/c_api/TTexture.h b/thermion_dart/native/include/c_api/TTexture.h index a959e4b8..e9b54f42 100644 --- a/thermion_dart/native/include/c_api/TTexture.h +++ b/thermion_dart/native/include/c_api/TTexture.h @@ -192,6 +192,29 @@ enum TPixelDataType { PIXELDATATYPE_UINT_2_10_10_10_REV, //!< unsigned normalized 10 bits RGB, 2 bits alpha }; +enum TTextureUsage { + TEXTURE_USAGE_NONE = 0x0000, + TEXTURE_USAGE_COLOR_ATTACHMENT = 0x0001, //!< Texture can be used as a color attachment + TEXTURE_USAGE_DEPTH_ATTACHMENT = 0x0002, //!< Texture can be used as a depth attachment + TEXTURE_USAGE_STENCIL_ATTACHMENT = 0x0004, //!< Texture can be used as a stencil attachment + TEXTURE_USAGE_UPLOADABLE = 0x0008, //!< Data can be uploaded into this texture (default) + TEXTURE_USAGE_SAMPLEABLE = 0x0010, //!< Texture can be sampled (default) + TEXTURE_USAGE_SUBPASS_INPUT = 0x0020, //!< Texture can be used as a subpass input + TEXTURE_USAGE_BLIT_SRC = 0x0040, //!< Texture can be used the source of a blit() + TEXTURE_USAGE_BLIT_DST = 0x0080, //!< Texture can be used the destination of a blit() + TEXTURE_USAGE_PROTECTED = 0x0100, //!< Texture can be used the destination of a blit() + TEXTURE_USAGE_DEFAULT = TEXTURE_USAGE_UPLOADABLE | TEXTURE_USAGE_SAMPLEABLE //!< Default texture usage +}; + +EMSCRIPTEN_KEEPALIVE TTexture *Texture_build(TEngine *engine, + uint32_t width, + uint32_t height, + uint32_t depth, + uint8_t levels, + uint16_t tUsage, + intptr_t import, + TTextureSamplerType sampler, + TTextureFormat format); EMSCRIPTEN_KEEPALIVE bool Texture_loadImage(TEngine *tEngine, TTexture *tTexture, TLinearImage *tImage, TPixelDataFormat bufferFormat, TPixelDataType pixelDataType); EMSCRIPTEN_KEEPALIVE bool Texture_setImage( TEngine *tEngine, @@ -224,6 +247,7 @@ EMSCRIPTEN_KEEPALIVE bool Texture_setImageWithDepth( EMSCRIPTEN_KEEPALIVE uint32_t Texture_getWidth(TTexture *tTexture, uint32_t level); EMSCRIPTEN_KEEPALIVE uint32_t Texture_getHeight(TTexture *tTexture, uint32_t level); EMSCRIPTEN_KEEPALIVE uint32_t Texture_getDepth(TTexture *tTexture, uint32_t level); +EMSCRIPTEN_KEEPALIVE TTextureUsage Texture_getUsage(TTexture *tTexture, uint32_t level); EMSCRIPTEN_KEEPALIVE TLinearImage *Image_createEmpty(uint32_t width,uint32_t height,uint32_t channel); EMSCRIPTEN_KEEPALIVE TLinearImage *Image_decode(uint8_t* data, size_t length, const char* name = "image"); diff --git a/thermion_dart/native/include/c_api/ThermionDartApi.h b/thermion_dart/native/include/c_api/ThermionDartApi.h index 214e6324..0fa0306c 100644 --- a/thermion_dart/native/include/c_api/ThermionDartApi.h +++ b/thermion_dart/native/include/c_api/ThermionDartApi.h @@ -14,9 +14,11 @@ extern "C" #endif EMSCRIPTEN_KEEPALIVE TViewer *Viewer_create(const void *const context, const void *const loader, void *const platform, const char *uberArchivePath); + EMSCRIPTEN_KEEPALIVE TRenderer *Viewer_getRenderer(TViewer *tViewer); + EMSCRIPTEN_KEEPALIVE void Viewer_destroy(TViewer *viewer); EMSCRIPTEN_KEEPALIVE TSceneManager *Viewer_getSceneManager(TViewer *viewer); - EMSCRIPTEN_KEEPALIVE TRenderTarget* Viewer_createRenderTarget(TViewer *viewer, intptr_t texture, uint32_t width, uint32_t height); + EMSCRIPTEN_KEEPALIVE TRenderTarget* Viewer_createRenderTarget(TViewer *viewer, intptr_t colorTextureId, intptr_t depthTextureId, uint32_t width, uint32_t height); EMSCRIPTEN_KEEPALIVE void Viewer_destroyRenderTarget(TViewer *viewer, TRenderTarget* tRenderTarget); EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *viewer, const void *const window); EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createHeadlessSwapChain(TViewer *viewer, uint32_t width, uint32_t height); @@ -28,6 +30,7 @@ extern "C" TView *view, TSwapChain *swapChain, uint8_t *pixelBuffer, + bool useFence, void (*callback)(void)); EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTarget( TViewer *viewer, @@ -35,6 +38,7 @@ extern "C" TSwapChain *swapChain, TRenderTarget *renderTarget, uint8_t *pixelBuffer, + bool useFence, void (*callback)(void)); EMSCRIPTEN_KEEPALIVE TView* Viewer_createView(TViewer *viewer); EMSCRIPTEN_KEEPALIVE TView* Viewer_getViewAt(TViewer *viewer, int index); diff --git a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h index 5a914ad6..e36fc23f 100644 --- a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h +++ b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h @@ -57,11 +57,13 @@ namespace thermion EMSCRIPTEN_KEEPALIVE void Engine_createViewRenderThread(TEngine *tEngine, void (*onComplete)(TView *)); EMSCRIPTEN_KEEPALIVE void Engine_buildMaterialRenderThread(TEngine *tEngine, const uint8_t *materialData, size_t length, void (*onComplete)(TMaterial *)); EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, void (*onComplete)()); - EMSCRIPTEN_KEEPALIVE void Engine_buildTextureRenderThread(TEngine *engine, + EMSCRIPTEN_KEEPALIVE void Texture_buildRenderThread(TEngine *engine, uint32_t width, uint32_t height, uint32_t depth, uint8_t levels, + uint16_t tUsage, + intptr_t import, TTextureSamplerType sampler, TTextureFormat format, void (*onComplete)(TTexture*) @@ -228,6 +230,14 @@ namespace thermion void (*onComplete)(bool) ); EMSCRIPTEN_KEEPALIVE void RenderTarget_getColorTextureRenderThread(TRenderTarget *tRenderTarget, void (*onComplete)(TTexture *)); + EMSCRIPTEN_KEEPALIVE void RenderTarget_createRenderThread( + TEngine *tEngine, + uint32_t width, + uint32_t height, + TTexture *color, + TTexture *depth, + void (*onComplete)(TRenderTarget *) + ); // TextureSampler methods EMSCRIPTEN_KEEPALIVE void TextureSampler_createRenderThread(void (*onComplete)(TTextureSampler*)); @@ -297,6 +307,19 @@ namespace thermion EMSCRIPTEN_KEEPALIVE void set_post_processing_render_thread(TViewer *viewer, bool enabled); EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)()); + EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_createRenderThread(TEngine *tEngine, TMaterialProvider *tMaterialProvider, void (*callback)(TGltfAssetLoader *)); + EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_createRenderThread(TEngine *tEngine, void (*callback)(TGltfResourceLoader *)); + EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_loadRenderThread( + TGltfAssetLoader *tAssetLoader, + TGltfResourceLoader *tResourceLoader, + uint8_t *data, + size_t length, + uint8_t numInstances, + void (*callback)(TFilamentAsset *) + ); + EMSCRIPTEN_KEEPALIVE void Scene_addFilamentAssetRenderThread(TScene* tScene, TFilamentAsset *tAsset, void (*callback)()); + + #ifdef __cplusplus } diff --git a/thermion_dart/native/src/c_api/TEngine.cpp b/thermion_dart/native/src/c_api/TEngine.cpp index 5526ee21..972f95bd 100644 --- a/thermion_dart/native/src/c_api/TEngine.cpp +++ b/thermion_dart/native/src/c_api/TEngine.cpp @@ -10,6 +10,14 @@ #include #include +#include +#include +#include +#include +#include +#include +#include + #include #include @@ -18,6 +26,7 @@ #include #include +#include #include "Log.hpp" @@ -133,178 +142,6 @@ namespace thermion engine->destroy(material); } - ::filament::Texture::InternalFormat convertToFilamentFormat(TTextureFormat tFormat) { - switch (tFormat) { - // 8-bits per element - case TEXTUREFORMAT_R8: return ::filament::Texture::InternalFormat::R8; - case TEXTUREFORMAT_R8_SNORM: return ::filament::Texture::InternalFormat::R8_SNORM; - case TEXTUREFORMAT_R8UI: return ::filament::Texture::InternalFormat::R8UI; - case TEXTUREFORMAT_R8I: return ::filament::Texture::InternalFormat::R8I; - case TEXTUREFORMAT_STENCIL8: return ::filament::Texture::InternalFormat::STENCIL8; - - // 16-bits per element - case TEXTUREFORMAT_R16F: return ::filament::Texture::InternalFormat::R16F; - case TEXTUREFORMAT_R16UI: return ::filament::Texture::InternalFormat::R16UI; - case TEXTUREFORMAT_R16I: return ::filament::Texture::InternalFormat::R16I; - case TEXTUREFORMAT_RG8: return ::filament::Texture::InternalFormat::RG8; - case TEXTUREFORMAT_RG8_SNORM: return ::filament::Texture::InternalFormat::RG8_SNORM; - case TEXTUREFORMAT_RG8UI: return ::filament::Texture::InternalFormat::RG8UI; - case TEXTUREFORMAT_RG8I: return ::filament::Texture::InternalFormat::RG8I; - case TEXTUREFORMAT_RGB565: return ::filament::Texture::InternalFormat::RGB565; - case TEXTUREFORMAT_RGB9_E5: return ::filament::Texture::InternalFormat::RGB9_E5; - case TEXTUREFORMAT_RGB5_A1: return ::filament::Texture::InternalFormat::RGB5_A1; - case TEXTUREFORMAT_RGBA4: return ::filament::Texture::InternalFormat::RGBA4; - case TEXTUREFORMAT_DEPTH16: return ::filament::Texture::InternalFormat::DEPTH16; - - // 24-bits per element - case TEXTUREFORMAT_RGB8: return ::filament::Texture::InternalFormat::RGB8; - case TEXTUREFORMAT_SRGB8: return ::filament::Texture::InternalFormat::SRGB8; - case TEXTUREFORMAT_RGB8_SNORM: return ::filament::Texture::InternalFormat::RGB8_SNORM; - case TEXTUREFORMAT_RGB8UI: return ::filament::Texture::InternalFormat::RGB8UI; - case TEXTUREFORMAT_RGB8I: return ::filament::Texture::InternalFormat::RGB8I; - case TEXTUREFORMAT_DEPTH24: return ::filament::Texture::InternalFormat::DEPTH24; - - // 32-bits per element - case TEXTUREFORMAT_R32F: return ::filament::Texture::InternalFormat::R32F; - case TEXTUREFORMAT_R32UI: return ::filament::Texture::InternalFormat::R32UI; - case TEXTUREFORMAT_R32I: return ::filament::Texture::InternalFormat::R32I; - case TEXTUREFORMAT_RG16F: return ::filament::Texture::InternalFormat::RG16F; - case TEXTUREFORMAT_RG16UI: return ::filament::Texture::InternalFormat::RG16UI; - case TEXTUREFORMAT_RG16I: return ::filament::Texture::InternalFormat::RG16I; - case TEXTUREFORMAT_R11F_G11F_B10F: return ::filament::Texture::InternalFormat::R11F_G11F_B10F; - case TEXTUREFORMAT_RGBA8: return ::filament::Texture::InternalFormat::RGBA8; - case TEXTUREFORMAT_SRGB8_A8: return ::filament::Texture::InternalFormat::SRGB8_A8; - case TEXTUREFORMAT_RGBA8_SNORM: return ::filament::Texture::InternalFormat::RGBA8_SNORM; - case TEXTUREFORMAT_UNUSED: return ::filament::Texture::InternalFormat::UNUSED; - case TEXTUREFORMAT_RGB10_A2: return ::filament::Texture::InternalFormat::RGB10_A2; - case TEXTUREFORMAT_RGBA8UI: return ::filament::Texture::InternalFormat::RGBA8UI; - case TEXTUREFORMAT_RGBA8I: return ::filament::Texture::InternalFormat::RGBA8I; - case TEXTUREFORMAT_DEPTH32F: return ::filament::Texture::InternalFormat::DEPTH32F; - case TEXTUREFORMAT_DEPTH24_STENCIL8: return ::filament::Texture::InternalFormat::DEPTH24_STENCIL8; - case TEXTUREFORMAT_DEPTH32F_STENCIL8: return ::filament::Texture::InternalFormat::DEPTH32F_STENCIL8; - - // 48-bits per element - case TEXTUREFORMAT_RGB16F: return ::filament::Texture::InternalFormat::RGB16F; - case TEXTUREFORMAT_RGB16UI: return ::filament::Texture::InternalFormat::RGB16UI; - case TEXTUREFORMAT_RGB16I: return ::filament::Texture::InternalFormat::RGB16I; - - // 64-bits per element - case TEXTUREFORMAT_RG32F: return ::filament::Texture::InternalFormat::RG32F; - case TEXTUREFORMAT_RG32UI: return ::filament::Texture::InternalFormat::RG32UI; - case TEXTUREFORMAT_RG32I: return ::filament::Texture::InternalFormat::RG32I; - case TEXTUREFORMAT_RGBA16F: return ::filament::Texture::InternalFormat::RGBA16F; - case TEXTUREFORMAT_RGBA16UI: return ::filament::Texture::InternalFormat::RGBA16UI; - case TEXTUREFORMAT_RGBA16I: return ::filament::Texture::InternalFormat::RGBA16I; - - // 96-bits per element - case TEXTUREFORMAT_RGB32F: return ::filament::Texture::InternalFormat::RGB32F; - case TEXTUREFORMAT_RGB32UI: return ::filament::Texture::InternalFormat::RGB32UI; - case TEXTUREFORMAT_RGB32I: return ::filament::Texture::InternalFormat::RGB32I; - - // 128-bits per element - case TEXTUREFORMAT_RGBA32F: return ::filament::Texture::InternalFormat::RGBA32F; - case TEXTUREFORMAT_RGBA32UI: return ::filament::Texture::InternalFormat::RGBA32UI; - case TEXTUREFORMAT_RGBA32I: return ::filament::Texture::InternalFormat::RGBA32I; - - // Compressed formats - case TEXTUREFORMAT_EAC_R11: return ::filament::Texture::InternalFormat::EAC_R11; - case TEXTUREFORMAT_EAC_R11_SIGNED: return ::filament::Texture::InternalFormat::EAC_R11_SIGNED; - case TEXTUREFORMAT_EAC_RG11: return ::filament::Texture::InternalFormat::EAC_RG11; - case TEXTUREFORMAT_EAC_RG11_SIGNED: return ::filament::Texture::InternalFormat::EAC_RG11_SIGNED; - case TEXTUREFORMAT_ETC2_RGB8: return ::filament::Texture::InternalFormat::ETC2_RGB8; - case TEXTUREFORMAT_ETC2_SRGB8: return ::filament::Texture::InternalFormat::ETC2_SRGB8; - case TEXTUREFORMAT_ETC2_RGB8_A1: return ::filament::Texture::InternalFormat::ETC2_RGB8_A1; - case TEXTUREFORMAT_ETC2_SRGB8_A1: return ::filament::Texture::InternalFormat::ETC2_SRGB8_A1; - case TEXTUREFORMAT_ETC2_EAC_RGBA8: return ::filament::Texture::InternalFormat::ETC2_EAC_RGBA8; - case TEXTUREFORMAT_ETC2_EAC_SRGBA8: return ::filament::Texture::InternalFormat::ETC2_EAC_SRGBA8; - - // DXT formats - case TEXTUREFORMAT_DXT1_RGB: return ::filament::Texture::InternalFormat::DXT1_RGB; - case TEXTUREFORMAT_DXT1_RGBA: return ::filament::Texture::InternalFormat::DXT1_RGBA; - case TEXTUREFORMAT_DXT3_RGBA: return ::filament::Texture::InternalFormat::DXT3_RGBA; - case TEXTUREFORMAT_DXT5_RGBA: return ::filament::Texture::InternalFormat::DXT5_RGBA; - case TEXTUREFORMAT_DXT1_SRGB: return ::filament::Texture::InternalFormat::DXT1_SRGB; - case TEXTUREFORMAT_DXT1_SRGBA: return ::filament::Texture::InternalFormat::DXT1_SRGBA; - case TEXTUREFORMAT_DXT3_SRGBA: return ::filament::Texture::InternalFormat::DXT3_SRGBA; - case TEXTUREFORMAT_DXT5_SRGBA: return ::filament::Texture::InternalFormat::DXT5_SRGBA; - - // ASTC formats - case TEXTUREFORMAT_RGBA_ASTC_4x4: return ::filament::Texture::InternalFormat::RGBA_ASTC_4x4; - case TEXTUREFORMAT_RGBA_ASTC_5x4: return ::filament::Texture::InternalFormat::RGBA_ASTC_5x4; - case TEXTUREFORMAT_RGBA_ASTC_5x5: return ::filament::Texture::InternalFormat::RGBA_ASTC_5x5; - case TEXTUREFORMAT_RGBA_ASTC_6x5: return ::filament::Texture::InternalFormat::RGBA_ASTC_6x5; - case TEXTUREFORMAT_RGBA_ASTC_6x6: return ::filament::Texture::InternalFormat::RGBA_ASTC_6x6; - case TEXTUREFORMAT_RGBA_ASTC_8x5: return ::filament::Texture::InternalFormat::RGBA_ASTC_8x5; - case TEXTUREFORMAT_RGBA_ASTC_8x6: return ::filament::Texture::InternalFormat::RGBA_ASTC_8x6; - case TEXTUREFORMAT_RGBA_ASTC_8x8: return ::filament::Texture::InternalFormat::RGBA_ASTC_8x8; - case TEXTUREFORMAT_RGBA_ASTC_10x5: return ::filament::Texture::InternalFormat::RGBA_ASTC_10x5; - case TEXTUREFORMAT_RGBA_ASTC_10x6: return ::filament::Texture::InternalFormat::RGBA_ASTC_10x6; - case TEXTUREFORMAT_RGBA_ASTC_10x8: return ::filament::Texture::InternalFormat::RGBA_ASTC_10x8; - case TEXTUREFORMAT_RGBA_ASTC_10x10: return ::filament::Texture::InternalFormat::RGBA_ASTC_10x10; - case TEXTUREFORMAT_RGBA_ASTC_12x10: return ::filament::Texture::InternalFormat::RGBA_ASTC_12x10; - case TEXTUREFORMAT_RGBA_ASTC_12x12: return ::filament::Texture::InternalFormat::RGBA_ASTC_12x12; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_4x4: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_4x4; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_5x4: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_5x4; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_5x5: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_5x5; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_6x5: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_6x5; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_6x6: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_6x6; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_8x5: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_8x5; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_8x6: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_8x6; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_8x8: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_8x8; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_10x5: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_10x5; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_10x6: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_10x6; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_10x8: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_10x8; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_10x10:return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_10x10; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_12x10:return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_12x10; - case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_12x12:return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_12x12; - - // RGTC formats - case TEXTUREFORMAT_RED_RGTC1: return ::filament::Texture::InternalFormat::RED_RGTC1; - case TEXTUREFORMAT_SIGNED_RED_RGTC1: return ::filament::Texture::InternalFormat::SIGNED_RED_RGTC1; - case TEXTUREFORMAT_RED_GREEN_RGTC2: return ::filament::Texture::InternalFormat::RED_GREEN_RGTC2; - case TEXTUREFORMAT_SIGNED_RED_GREEN_RGTC2: return ::filament::Texture::InternalFormat::SIGNED_RED_GREEN_RGTC2; - - // BPTC formats - case TEXTUREFORMAT_RGB_BPTC_SIGNED_FLOAT: return ::filament::Texture::InternalFormat::RGB_BPTC_SIGNED_FLOAT; - case TEXTUREFORMAT_RGB_BPTC_UNSIGNED_FLOAT:return ::filament::Texture::InternalFormat::RGB_BPTC_UNSIGNED_FLOAT; - case TEXTUREFORMAT_RGBA_BPTC_UNORM: return ::filament::Texture::InternalFormat::RGBA_BPTC_UNORM; - case TEXTUREFORMAT_SRGB_ALPHA_BPTC_UNORM: return ::filament::Texture::InternalFormat::SRGB_ALPHA_BPTC_UNORM; - - default: - // Fallback to a common format if an unknown format is provided - return ::filament::Texture::InternalFormat::RGBA8; - } - } - - EMSCRIPTEN_KEEPALIVE TTexture *Engine_buildTexture(TEngine *tEngine, - uint32_t width, - uint32_t height, - uint32_t depth, - uint8_t levels, - TTextureSamplerType tSamplerType, - TTextureFormat tFormat) - { - TRACE("Creating texture %dx%d (depth %d), sampler type %d, format %d", width, height, depth, static_cast(tSamplerType), static_cast(tFormat)); - auto *engine = reinterpret_cast(tEngine); - auto format = convertToFilamentFormat(tFormat); - auto samplerType = static_cast<::filament::Texture::Sampler>(static_cast(tSamplerType)); - auto *texture = Texture::Builder() - .width(width) - .height(height) - .depth(depth) - .levels(levels) - .sampler(samplerType) - .format(format) - .build(*engine); - if(texture) { - TRACE("Texture successfully created"); - } else { - Log("Error: failed to created texture"); - } - - return reinterpret_cast(texture); - } - EMSCRIPTEN_KEEPALIVE void Engine_destroyTexture(TEngine *tEngine, TTexture *tTexture) { auto *engine = reinterpret_cast(tEngine); auto *texture = reinterpret_cast(tTexture); @@ -381,6 +218,8 @@ namespace thermion return reinterpret_cast(skybox); } + + #ifdef __cplusplus } diff --git a/thermion_dart/native/src/c_api/TGltfAssetLoader.cpp b/thermion_dart/native/src/c_api/TGltfAssetLoader.cpp new file mode 100644 index 00000000..f74b7fa5 --- /dev/null +++ b/thermion_dart/native/src/c_api/TGltfAssetLoader.cpp @@ -0,0 +1,97 @@ +#include "c_api/TGltfAssetLoader.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "Log.hpp" + +#ifdef __cplusplus +namespace thermion +{ + extern "C" + { + using namespace filament; + +#endif + +EMSCRIPTEN_KEEPALIVE TGltfResourceLoader *GltfResourceLoader_create(TEngine *tEngine) { + auto *engine = reinterpret_cast(tEngine); + auto *gltfResourceLoader = new gltfio::ResourceLoader({.engine = engine, + .normalizeSkinningWeights = true}); + auto stbDecoder = gltfio::createStbProvider(engine); + auto ktxDecoder = gltfio::createKtx2Provider(engine); + gltfResourceLoader->addTextureProvider("image/ktx2", ktxDecoder); + gltfResourceLoader->addTextureProvider("image/png", stbDecoder); + gltfResourceLoader->addTextureProvider("image/jpeg", stbDecoder); + + return reinterpret_cast(gltfResourceLoader); +} + +EMSCRIPTEN_KEEPALIVE TGltfAssetLoader *GltfAssetLoader_create(TEngine *tEngine, TMaterialProvider *tMaterialProvider) { + auto *engine = reinterpret_cast(tEngine); + auto *materialProvider = reinterpret_cast(tMaterialProvider); + + if(!materialProvider) { + materialProvider = gltfio::createUbershaderProvider( + engine, + UBERARCHIVE_DEFAULT_DATA, + UBERARCHIVE_DEFAULT_SIZE + ); + } + + utils::EntityManager &em = utils::EntityManager::get(); + auto ncm = new utils::NameComponentManager(em); + auto *assetLoader = gltfio::AssetLoader::create({engine, materialProvider, ncm, &em}); + return reinterpret_cast(assetLoader); +} + +EMSCRIPTEN_KEEPALIVE TFilamentAsset *GltfAssetLoader_load( + TGltfAssetLoader *tAssetLoader, + TGltfResourceLoader *tGltfResourceLoader, + uint8_t *data, + size_t length, + uint8_t numInstances) +{ + auto *assetLoader = reinterpret_cast(tAssetLoader); + auto *resourceLoader = reinterpret_cast(tGltfResourceLoader); + + std::vector instances(numInstances); + + gltfio::FilamentAsset *asset = assetLoader->createInstancedAsset((const uint8_t *)data, length, instances.data(), numInstances); + + if (!asset) + { + Log("Unknown error loading GLB asset."); + return std::nullptr_t(); + } + + if (!resourceLoader->loadResources(asset)) + { + Log("Unknown error loading glb asset"); + return std::nullptr_t(); + } + return reinterpret_cast(asset); +} + +#ifdef __cplusplus + } +} +#endif diff --git a/thermion_dart/native/src/c_api/TRenderTarget.cpp b/thermion_dart/native/src/c_api/TRenderTarget.cpp new file mode 100644 index 00000000..2f161c56 --- /dev/null +++ b/thermion_dart/native/src/c_api/TRenderTarget.cpp @@ -0,0 +1,41 @@ +#include "c_api/TScene.h" + +#include +#include +#include +#include +#include + +#include "Log.hpp" + +#ifdef __cplusplus +namespace thermion +{ + extern "C" + { + using namespace filament; +#endif + + EMSCRIPTEN_KEEPALIVE TRenderTarget *RenderTarget_create( + TEngine *tEngine, + uint32_t width, + uint32_t height, + TTexture *tColor, + TTexture *tDepth) + { + auto engine = reinterpret_cast(tEngine); + auto color = reinterpret_cast(tColor); + auto depth = reinterpret_cast(tDepth); + + auto rt = filament::RenderTarget::Builder() + .texture(RenderTarget::AttachmentPoint::COLOR, color) + .texture(RenderTarget::AttachmentPoint::DEPTH, depth) + .build(*engine); + return reinterpret_cast(rt); + } + + +#ifdef __cplusplus + } +} +#endif diff --git a/thermion_dart/native/src/c_api/TScene.cpp b/thermion_dart/native/src/c_api/TScene.cpp index e6fe59dc..d1432e4c 100644 --- a/thermion_dart/native/src/c_api/TScene.cpp +++ b/thermion_dart/native/src/c_api/TScene.cpp @@ -10,6 +10,9 @@ #include #include +#include +#include + #include "Log.hpp" #ifdef __cplusplus @@ -32,6 +35,13 @@ namespace thermion scene->setSkybox(skybox); } + EMSCRIPTEN_KEEPALIVE void Scene_addFilamentAsset(TScene* tScene, TFilamentAsset *tAsset) { + auto *scene = reinterpret_cast(tScene); + auto *asset = reinterpret_cast(tAsset); + scene->addEntities(asset->getEntities(), asset->getEntityCount()); + } + + #ifdef __cplusplus } } diff --git a/thermion_dart/native/src/c_api/TTexture.cpp b/thermion_dart/native/src/c_api/TTexture.cpp index 9a8047b6..d93ad7b2 100644 --- a/thermion_dart/native/src/c_api/TTexture.cpp +++ b/thermion_dart/native/src/c_api/TTexture.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,210 @@ namespace thermion delete linearImage; } + ::filament::Texture::InternalFormat convertToFilamentFormat(TTextureFormat tFormat) { + switch (tFormat) { + // 8-bits per element + case TEXTUREFORMAT_R8: return ::filament::Texture::InternalFormat::R8; + case TEXTUREFORMAT_R8_SNORM: return ::filament::Texture::InternalFormat::R8_SNORM; + case TEXTUREFORMAT_R8UI: return ::filament::Texture::InternalFormat::R8UI; + case TEXTUREFORMAT_R8I: return ::filament::Texture::InternalFormat::R8I; + case TEXTUREFORMAT_STENCIL8: return ::filament::Texture::InternalFormat::STENCIL8; + + // 16-bits per element + case TEXTUREFORMAT_R16F: return ::filament::Texture::InternalFormat::R16F; + case TEXTUREFORMAT_R16UI: return ::filament::Texture::InternalFormat::R16UI; + case TEXTUREFORMAT_R16I: return ::filament::Texture::InternalFormat::R16I; + case TEXTUREFORMAT_RG8: return ::filament::Texture::InternalFormat::RG8; + case TEXTUREFORMAT_RG8_SNORM: return ::filament::Texture::InternalFormat::RG8_SNORM; + case TEXTUREFORMAT_RG8UI: return ::filament::Texture::InternalFormat::RG8UI; + case TEXTUREFORMAT_RG8I: return ::filament::Texture::InternalFormat::RG8I; + case TEXTUREFORMAT_RGB565: return ::filament::Texture::InternalFormat::RGB565; + case TEXTUREFORMAT_RGB9_E5: return ::filament::Texture::InternalFormat::RGB9_E5; + case TEXTUREFORMAT_RGB5_A1: return ::filament::Texture::InternalFormat::RGB5_A1; + case TEXTUREFORMAT_RGBA4: return ::filament::Texture::InternalFormat::RGBA4; + case TEXTUREFORMAT_DEPTH16: return ::filament::Texture::InternalFormat::DEPTH16; + + // 24-bits per element + case TEXTUREFORMAT_RGB8: return ::filament::Texture::InternalFormat::RGB8; + case TEXTUREFORMAT_SRGB8: return ::filament::Texture::InternalFormat::SRGB8; + case TEXTUREFORMAT_RGB8_SNORM: return ::filament::Texture::InternalFormat::RGB8_SNORM; + case TEXTUREFORMAT_RGB8UI: return ::filament::Texture::InternalFormat::RGB8UI; + case TEXTUREFORMAT_RGB8I: return ::filament::Texture::InternalFormat::RGB8I; + case TEXTUREFORMAT_DEPTH24: return ::filament::Texture::InternalFormat::DEPTH24; + + // 32-bits per element + case TEXTUREFORMAT_R32F: return ::filament::Texture::InternalFormat::R32F; + case TEXTUREFORMAT_R32UI: return ::filament::Texture::InternalFormat::R32UI; + case TEXTUREFORMAT_R32I: return ::filament::Texture::InternalFormat::R32I; + case TEXTUREFORMAT_RG16F: return ::filament::Texture::InternalFormat::RG16F; + case TEXTUREFORMAT_RG16UI: return ::filament::Texture::InternalFormat::RG16UI; + case TEXTUREFORMAT_RG16I: return ::filament::Texture::InternalFormat::RG16I; + case TEXTUREFORMAT_R11F_G11F_B10F: return ::filament::Texture::InternalFormat::R11F_G11F_B10F; + case TEXTUREFORMAT_RGBA8: return ::filament::Texture::InternalFormat::RGBA8; + case TEXTUREFORMAT_SRGB8_A8: return ::filament::Texture::InternalFormat::SRGB8_A8; + case TEXTUREFORMAT_RGBA8_SNORM: return ::filament::Texture::InternalFormat::RGBA8_SNORM; + case TEXTUREFORMAT_UNUSED: return ::filament::Texture::InternalFormat::UNUSED; + case TEXTUREFORMAT_RGB10_A2: return ::filament::Texture::InternalFormat::RGB10_A2; + case TEXTUREFORMAT_RGBA8UI: return ::filament::Texture::InternalFormat::RGBA8UI; + case TEXTUREFORMAT_RGBA8I: return ::filament::Texture::InternalFormat::RGBA8I; + case TEXTUREFORMAT_DEPTH32F: return ::filament::Texture::InternalFormat::DEPTH32F; + case TEXTUREFORMAT_DEPTH24_STENCIL8: return ::filament::Texture::InternalFormat::DEPTH24_STENCIL8; + case TEXTUREFORMAT_DEPTH32F_STENCIL8: return ::filament::Texture::InternalFormat::DEPTH32F_STENCIL8; + + // 48-bits per element + case TEXTUREFORMAT_RGB16F: return ::filament::Texture::InternalFormat::RGB16F; + case TEXTUREFORMAT_RGB16UI: return ::filament::Texture::InternalFormat::RGB16UI; + case TEXTUREFORMAT_RGB16I: return ::filament::Texture::InternalFormat::RGB16I; + + // 64-bits per element + case TEXTUREFORMAT_RG32F: return ::filament::Texture::InternalFormat::RG32F; + case TEXTUREFORMAT_RG32UI: return ::filament::Texture::InternalFormat::RG32UI; + case TEXTUREFORMAT_RG32I: return ::filament::Texture::InternalFormat::RG32I; + case TEXTUREFORMAT_RGBA16F: return ::filament::Texture::InternalFormat::RGBA16F; + case TEXTUREFORMAT_RGBA16UI: return ::filament::Texture::InternalFormat::RGBA16UI; + case TEXTUREFORMAT_RGBA16I: return ::filament::Texture::InternalFormat::RGBA16I; + + // 96-bits per element + case TEXTUREFORMAT_RGB32F: return ::filament::Texture::InternalFormat::RGB32F; + case TEXTUREFORMAT_RGB32UI: return ::filament::Texture::InternalFormat::RGB32UI; + case TEXTUREFORMAT_RGB32I: return ::filament::Texture::InternalFormat::RGB32I; + + // 128-bits per element + case TEXTUREFORMAT_RGBA32F: return ::filament::Texture::InternalFormat::RGBA32F; + case TEXTUREFORMAT_RGBA32UI: return ::filament::Texture::InternalFormat::RGBA32UI; + case TEXTUREFORMAT_RGBA32I: return ::filament::Texture::InternalFormat::RGBA32I; + + // Compressed formats + case TEXTUREFORMAT_EAC_R11: return ::filament::Texture::InternalFormat::EAC_R11; + case TEXTUREFORMAT_EAC_R11_SIGNED: return ::filament::Texture::InternalFormat::EAC_R11_SIGNED; + case TEXTUREFORMAT_EAC_RG11: return ::filament::Texture::InternalFormat::EAC_RG11; + case TEXTUREFORMAT_EAC_RG11_SIGNED: return ::filament::Texture::InternalFormat::EAC_RG11_SIGNED; + case TEXTUREFORMAT_ETC2_RGB8: return ::filament::Texture::InternalFormat::ETC2_RGB8; + case TEXTUREFORMAT_ETC2_SRGB8: return ::filament::Texture::InternalFormat::ETC2_SRGB8; + case TEXTUREFORMAT_ETC2_RGB8_A1: return ::filament::Texture::InternalFormat::ETC2_RGB8_A1; + case TEXTUREFORMAT_ETC2_SRGB8_A1: return ::filament::Texture::InternalFormat::ETC2_SRGB8_A1; + case TEXTUREFORMAT_ETC2_EAC_RGBA8: return ::filament::Texture::InternalFormat::ETC2_EAC_RGBA8; + case TEXTUREFORMAT_ETC2_EAC_SRGBA8: return ::filament::Texture::InternalFormat::ETC2_EAC_SRGBA8; + + // DXT formats + case TEXTUREFORMAT_DXT1_RGB: return ::filament::Texture::InternalFormat::DXT1_RGB; + case TEXTUREFORMAT_DXT1_RGBA: return ::filament::Texture::InternalFormat::DXT1_RGBA; + case TEXTUREFORMAT_DXT3_RGBA: return ::filament::Texture::InternalFormat::DXT3_RGBA; + case TEXTUREFORMAT_DXT5_RGBA: return ::filament::Texture::InternalFormat::DXT5_RGBA; + case TEXTUREFORMAT_DXT1_SRGB: return ::filament::Texture::InternalFormat::DXT1_SRGB; + case TEXTUREFORMAT_DXT1_SRGBA: return ::filament::Texture::InternalFormat::DXT1_SRGBA; + case TEXTUREFORMAT_DXT3_SRGBA: return ::filament::Texture::InternalFormat::DXT3_SRGBA; + case TEXTUREFORMAT_DXT5_SRGBA: return ::filament::Texture::InternalFormat::DXT5_SRGBA; + + // ASTC formats + case TEXTUREFORMAT_RGBA_ASTC_4x4: return ::filament::Texture::InternalFormat::RGBA_ASTC_4x4; + case TEXTUREFORMAT_RGBA_ASTC_5x4: return ::filament::Texture::InternalFormat::RGBA_ASTC_5x4; + case TEXTUREFORMAT_RGBA_ASTC_5x5: return ::filament::Texture::InternalFormat::RGBA_ASTC_5x5; + case TEXTUREFORMAT_RGBA_ASTC_6x5: return ::filament::Texture::InternalFormat::RGBA_ASTC_6x5; + case TEXTUREFORMAT_RGBA_ASTC_6x6: return ::filament::Texture::InternalFormat::RGBA_ASTC_6x6; + case TEXTUREFORMAT_RGBA_ASTC_8x5: return ::filament::Texture::InternalFormat::RGBA_ASTC_8x5; + case TEXTUREFORMAT_RGBA_ASTC_8x6: return ::filament::Texture::InternalFormat::RGBA_ASTC_8x6; + case TEXTUREFORMAT_RGBA_ASTC_8x8: return ::filament::Texture::InternalFormat::RGBA_ASTC_8x8; + case TEXTUREFORMAT_RGBA_ASTC_10x5: return ::filament::Texture::InternalFormat::RGBA_ASTC_10x5; + case TEXTUREFORMAT_RGBA_ASTC_10x6: return ::filament::Texture::InternalFormat::RGBA_ASTC_10x6; + case TEXTUREFORMAT_RGBA_ASTC_10x8: return ::filament::Texture::InternalFormat::RGBA_ASTC_10x8; + case TEXTUREFORMAT_RGBA_ASTC_10x10: return ::filament::Texture::InternalFormat::RGBA_ASTC_10x10; + case TEXTUREFORMAT_RGBA_ASTC_12x10: return ::filament::Texture::InternalFormat::RGBA_ASTC_12x10; + case TEXTUREFORMAT_RGBA_ASTC_12x12: return ::filament::Texture::InternalFormat::RGBA_ASTC_12x12; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_4x4: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_4x4; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_5x4: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_5x4; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_5x5: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_5x5; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_6x5: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_6x5; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_6x6: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_6x6; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_8x5: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_8x5; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_8x6: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_8x6; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_8x8: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_8x8; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_10x5: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_10x5; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_10x6: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_10x6; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_10x8: return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_10x8; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_10x10:return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_10x10; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_12x10:return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_12x10; + case TEXTUREFORMAT_SRGB8_ALPHA8_ASTC_12x12:return ::filament::Texture::InternalFormat::SRGB8_ALPHA8_ASTC_12x12; + + // RGTC formats + case TEXTUREFORMAT_RED_RGTC1: return ::filament::Texture::InternalFormat::RED_RGTC1; + case TEXTUREFORMAT_SIGNED_RED_RGTC1: return ::filament::Texture::InternalFormat::SIGNED_RED_RGTC1; + case TEXTUREFORMAT_RED_GREEN_RGTC2: return ::filament::Texture::InternalFormat::RED_GREEN_RGTC2; + case TEXTUREFORMAT_SIGNED_RED_GREEN_RGTC2: return ::filament::Texture::InternalFormat::SIGNED_RED_GREEN_RGTC2; + + // BPTC formats + case TEXTUREFORMAT_RGB_BPTC_SIGNED_FLOAT: return ::filament::Texture::InternalFormat::RGB_BPTC_SIGNED_FLOAT; + case TEXTUREFORMAT_RGB_BPTC_UNSIGNED_FLOAT:return ::filament::Texture::InternalFormat::RGB_BPTC_UNSIGNED_FLOAT; + case TEXTUREFORMAT_RGBA_BPTC_UNORM: return ::filament::Texture::InternalFormat::RGBA_BPTC_UNORM; + case TEXTUREFORMAT_SRGB_ALPHA_BPTC_UNORM: return ::filament::Texture::InternalFormat::SRGB_ALPHA_BPTC_UNORM; + + default: + // Fallback to a common format if an unknown format is provided + return ::filament::Texture::InternalFormat::RGBA8; + } + } + + EMSCRIPTEN_KEEPALIVE TTexture *Texture_build( + TEngine *tEngine, + uint32_t width, + uint32_t height, + uint32_t depth, + uint8_t levels, + uint16_t tUsage, + intptr_t import, + TTextureSamplerType tSamplerType, + TTextureFormat tFormat + ) + { + TRACE("Creating texture %dx%d (depth %d), sampler type %d, format %d tUsage %d", width, height, depth, static_cast(tSamplerType), static_cast(tFormat), tUsage); + auto *engine = reinterpret_cast<::filament::Engine *>(tEngine); + auto format = convertToFilamentFormat(tFormat); + auto samplerType = static_cast<::filament::Texture::Sampler>(static_cast(tSamplerType)); + auto usage = static_cast<::filament::Texture::Usage>(tUsage); + + if ((usage & TextureUsage::UPLOADABLE) == TextureUsage::UPLOADABLE) { + TRACE("UPLOADABLE"); + } + + if ((usage & TextureUsage::SAMPLEABLE) == TextureUsage::SAMPLEABLE) { + TRACE("SAMPLEABLE"); + } + + if ((usage & TextureUsage::COLOR_ATTACHMENT) == TextureUsage::COLOR_ATTACHMENT) { + TRACE("COLOR_ATTACHMENT"); + } + + if ((usage & TextureUsage::DEPTH_ATTACHMENT) == TextureUsage::DEPTH_ATTACHMENT) { + TRACE("DEPTH_ATTACHMENT"); + } + + if ((usage & TextureUsage::BLIT_SRC) == TextureUsage::BLIT_SRC) { + TRACE("BLIT_SRC"); + } + + auto builder = ::filament::Texture::Builder() + .width(width) + .height(height) + .depth(depth) + .levels(levels) + .sampler(samplerType) + .format(format) + .usage(usage); + if(import) { + TRACE("IMPORTING"); + builder.import(import); + } + auto *texture = builder + .build(*engine); + if(texture) { + TRACE("Texture successfully created"); + } else { + Log("Error: failed to created texture"); + } + + return reinterpret_cast(texture); + } + EMSCRIPTEN_KEEPALIVE bool Texture_loadImage(TEngine *tEngine, TTexture *tTexture, TLinearImage *tImage, TPixelDataFormat tBufferFormat, TPixelDataType tPixelDataType) { auto engine = reinterpret_cast(tEngine); diff --git a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp index af01558a..da80b10b 100644 --- a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp +++ b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp @@ -6,13 +6,17 @@ #include #include "c_api/APIBoundaryTypes.h" + +#include "c_api/TAnimationManager.h" #include "c_api/TEngine.h" -#include "c_api/TView.h" +#include "c_api/TGltfAssetLoader.h" #include "c_api/TRenderer.h" +#include "c_api/TRenderTarget.h" +#include "c_api/TScene.h" #include "c_api/TSceneAsset.h" #include "c_api/TSceneManager.h" #include "c_api/TTexture.h" -#include "c_api/TAnimationManager.h" +#include "c_api/TView.h" #include "c_api/ThermionDartRenderThreadApi.h" #include "FilamentViewer.hpp" @@ -400,19 +404,21 @@ extern "C" auto fut = _rl->add_task(lambda); } - EMSCRIPTEN_KEEPALIVE void Engine_buildTextureRenderThread(TEngine *engine, - uint32_t width, - uint32_t height, - uint32_t depth, - uint8_t levels, - TTextureSamplerType sampler, - TTextureFormat format, - void (*onComplete)(TTexture *)) + EMSCRIPTEN_KEEPALIVE void Texture_buildRenderThread(TEngine *engine, + uint32_t width, + uint32_t height, + uint32_t depth, + uint8_t levels, + uint16_t tUsage, + intptr_t import, + TTextureSamplerType sampler, + TTextureFormat format, + void (*onComplete)(TTexture *)) { std::packaged_task lambda( [=]() mutable { - auto texture = Engine_buildTexture(engine, width, height, depth, levels, sampler, format); + auto texture = Texture_build(engine, width, height, depth, levels, tUsage, import, sampler, format); onComplete(texture); }); auto fut = _rl->add_task(lambda); @@ -1171,7 +1177,29 @@ extern "C" auto fut = _rl->add_task(lambda); } - // TextureSampler methods + EMSCRIPTEN_KEEPALIVE void RenderTarget_createRenderThread( + TEngine *tEngine, + uint32_t width, + uint32_t height, + TTexture *tColor, + TTexture *tDepth, + void (*onComplete)(TRenderTarget *)) + { + auto color = reinterpret_cast(tColor); + auto depth = reinterpret_cast(tDepth); + + std::packaged_task lambda( + [=]() mutable + { + auto texture = RenderTarget_create(tEngine, width, height, tColor, tDepth); + onComplete(texture); + }); + auto fut = _rl->add_task(lambda); + } + + + + EMSCRIPTEN_KEEPALIVE void TextureSampler_createRenderThread(void (*onComplete)(TTextureSampler *)) { std::packaged_task lambda( @@ -1325,4 +1353,51 @@ extern "C" }); auto fut = _rl->add_task(lambda); } + + EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_createRenderThread(TEngine *tEngine, TMaterialProvider *tMaterialProvider, void (*callback)(TGltfAssetLoader *)) { + std::packaged_task lambda( + [=]() mutable + { + auto loader = GltfAssetLoader_create(tEngine, tMaterialProvider); + callback(loader); + }); + auto fut = _rl->add_task(lambda); + } + + EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_createRenderThread(TEngine *tEngine, void (*callback)(TGltfResourceLoader *)) { + std::packaged_task lambda( + [=]() mutable + { + auto loader = GltfResourceLoader_create(tEngine); + callback(loader); + }); + auto fut = _rl->add_task(lambda); + } + + EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_loadRenderThread( + TGltfAssetLoader *tAssetLoader, + TGltfResourceLoader *tResourceLoader, + uint8_t *data, + size_t length, + uint8_t numInstances, + void (*callback)(TFilamentAsset *) + ) { + std::packaged_task lambda( + [=]() mutable + { + auto loader = GltfAssetLoader_load(tAssetLoader, tResourceLoader, data, length, numInstances); + callback(loader); + }); + auto fut = _rl->add_task(lambda); + } + + EMSCRIPTEN_KEEPALIVE void Scene_addFilamentAssetRenderThread(TScene* tScene, TFilamentAsset *tAsset, void (*callback)()) { + std::packaged_task lambda( + [=]() mutable + { + Scene_addFilamentAsset(tScene, tAsset); + callback(); + }); + auto fut = _rl->add_task(lambda); + } }