diff --git a/thermion_dart/native/include/c_api/TEngine.h b/thermion_dart/native/include/c_api/TEngine.h index 6da0a1fd..1d517e30 100644 --- a/thermion_dart/native/include/c_api/TEngine.h +++ b/thermion_dart/native/include/c_api/TEngine.h @@ -58,7 +58,8 @@ EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterial(TEngine *tEngine, TMaterial *tM EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialInstance(TEngine *tEngine, TMaterialInstance *tMaterialInstance); EMSCRIPTEN_KEEPALIVE TScene *Engine_createScene(TEngine *tEngine); EMSCRIPTEN_KEEPALIVE TSkybox *Engine_buildSkybox(TEngine *tEngine, TTexture* tTexture); -EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLight(TEngine *tEngine, TTexture* tTexture, float intensity, float *harmonics); +EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLightFromIrradianceTexture(TEngine *tEngine, TTexture *tReflectionsTexture, TTexture* tIrradianceTexture, float intensity); +EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLightFromIrradianceHarmonics(TEngine *tEngine, TTexture *tReflectionsTexture, float *irradianceHarmonics, float intensity); EMSCRIPTEN_KEEPALIVE void Engine_destroySkybox(TEngine *tEngine, TSkybox *tSkybox); EMSCRIPTEN_KEEPALIVE void Engine_destroyIndirectLight(TEngine *tEngine, TIndirectLight *tIndirectLight); EMSCRIPTEN_KEEPALIVE EntityId EntityManager_createEntity(TEntityManager *tEntityManager); diff --git a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h index 717185bd..22003e90 100644 --- a/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h +++ b/thermion_dart/native/include/c_api/ThermionDartRenderThreadApi.h @@ -68,7 +68,8 @@ namespace thermion void Engine_flushAndWaitRenderThread(TEngine *tEngine, uint32_t requestId, VoidCallback onComplete); void Engine_executeRenderThread(TEngine *tEngine, uint32_t requestId, VoidCallback onComplete); void Engine_buildSkyboxRenderThread(TEngine *tEngine, TTexture *tTexture, void (*onComplete)(TSkybox *)); - void Engine_buildIndirectLightRenderThread(TEngine *tEngine, TTexture *tTexture, float intensity, float *harmonics, void (*onComplete)(TIndirectLight *)); + void Engine_buildIndirectLightFromIrradianceTextureRenderThread(TEngine *tEngine, TTexture *tReflectionsTexture, TTexture* tIrradianceTexture, float intensity, void (*onComplete)(TIndirectLight *)); + void Engine_buildIndirectLightFromIrradianceHarmonicsRenderThread(TEngine *tEngine, TTexture *tReflectionsTexture, float *harmonics, float intensity, void (*onComplete)(TIndirectLight *)); void Renderer_setClearOptionsRenderThread(TRenderer *tRenderer, double clearR, double clearG, double clearB, double clearA, uint8_t clearStencil, bool clear, bool discard, uint32_t requestId, VoidCallback onComplete); void Renderer_beginFrameRenderThread(TRenderer *tRenderer, TSwapChain *tSwapChain, uint64_t frameTimeInNanos, void (*onComplete)(bool)); diff --git a/thermion_dart/native/src/c_api/TEngine.cpp b/thermion_dart/native/src/c_api/TEngine.cpp index fb22b303..0ee68c16 100644 --- a/thermion_dart/native/src/c_api/TEngine.cpp +++ b/thermion_dart/native/src/c_api/TEngine.cpp @@ -316,19 +316,46 @@ namespace thermion return reinterpret_cast(skybox); } - EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLight(TEngine *tEngine, TTexture *tTexture, float intensity, float *harmonics) + EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLightFromIrradianceTexture(TEngine *tEngine, TTexture *tReflectionsTexture, TTexture* tIrradianceTexture, float intensity) { auto *engine = reinterpret_cast(tEngine); - auto *texture = reinterpret_cast(tTexture); + auto *reflectionsTexture = reinterpret_cast(tReflectionsTexture); + auto *irradianceTexture = reinterpret_cast(tIrradianceTexture); - filament::math::float3 sphericalHarmonics[9]; - memcpy(sphericalHarmonics, harmonics, 27 * sizeof(float)); + auto indirectLightBuilder = filament::IndirectLight::Builder().intensity(intensity); - auto *indirectLight = filament::IndirectLight::Builder() - .reflections(texture) - .irradiance(3, sphericalHarmonics) - .intensity(intensity) - .build(*engine); + if(!irradianceTexture) { + Log("Irradiance texture must not be empty"); + return std::nullptr_t(); + } + + if(reflectionsTexture) { + indirectLightBuilder.reflections(reflectionsTexture); + } + + + auto *indirectLight = indirectLightBuilder.build(*engine); + return reinterpret_cast(indirectLight); + } + + EMSCRIPTEN_KEEPALIVE TIndirectLight *Engine_buildIndirectLightFromIrradianceHarmonics(TEngine *tEngine, TTexture *tReflectionsTexture, float *harmonics, float intensity) + { + auto *engine = reinterpret_cast(tEngine); + auto *reflectionsTexture = reinterpret_cast(tReflectionsTexture); + + auto indirectLightBuilder = filament::IndirectLight::Builder().intensity(intensity); + + if(reflectionsTexture) { + indirectLightBuilder.reflections(reflectionsTexture); + } + + if(harmonics) { + filament::math::float3 sphericalHarmonics[9]; + memcpy(sphericalHarmonics, harmonics, 27 * sizeof(float)); + indirectLightBuilder.irradiance(3, sphericalHarmonics); + } + + auto *indirectLight = indirectLightBuilder.build(*engine); return reinterpret_cast(indirectLight); } @@ -344,12 +371,6 @@ namespace thermion EMSCRIPTEN_KEEPALIVE void Engine_destroyIndirectLight(TEngine *tEngine, TIndirectLight *tIndirectLight) { auto *engine = reinterpret_cast(tEngine); auto *indirectLight = reinterpret_cast(tIndirectLight); - if(indirectLight->getReflectionsTexture()) { - engine->destroy(indirectLight->getReflectionsTexture()); - } - if(indirectLight->getIrradianceTexture()) { - engine->destroy(indirectLight->getIrradianceTexture()); - } engine->destroy(indirectLight); } diff --git a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp index c4128a39..58ca6180 100644 --- a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp +++ b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp @@ -361,16 +361,36 @@ extern "C" auto fut = _renderThread->add_task(lambda); } - EMSCRIPTEN_KEEPALIVE void Engine_buildIndirectLightRenderThread(TEngine *tEngine, TTexture *tTexture, float intensity, float *harmonics, void (*onComplete)(TIndirectLight *)) - { - std::packaged_task lambda( - [=]() mutable - { - auto *indirectLight = Engine_buildIndirectLight(tEngine, tTexture, intensity, harmonics); - PROXY(onComplete(indirectLight)); - }); - auto fut = _renderThread->add_task(lambda); + EMSCRIPTEN_KEEPALIVE void Engine_buildIndirectLightFromIrradianceTextureRenderThread( + TEngine *tEngine, + TTexture *tReflectionsTexture, + TTexture* tIrradianceTexture, + float intensity, + void (*onComplete)(TIndirectLight *)) { + std::packaged_task lambda( + [=]() mutable + { + auto *indirectLight = Engine_buildIndirectLightFromIrradianceTexture(tEngine, tReflectionsTexture, tIrradianceTexture, intensity); + PROXY(onComplete(indirectLight)); + }); + auto fut = _renderThread->add_task(lambda); } + + EMSCRIPTEN_KEEPALIVE void Engine_buildIndirectLightFromIrradianceHarmonicsRenderThread( + TEngine *tEngine, + TTexture *tReflectionsTexture, + float *harmonics, + float intensity, + void (*onComplete)(TIndirectLight *)) { + std::packaged_task lambda( + [=]() mutable + { + auto *indirectLight = Engine_buildIndirectLightFromIrradianceHarmonics(tEngine, tReflectionsTexture, harmonics, intensity); + PROXY(onComplete(indirectLight)); + }); + auto fut = _renderThread->add_task(lambda); + } + EMSCRIPTEN_KEEPALIVE void Renderer_beginFrameRenderThread(TRenderer *tRenderer, TSwapChain *tSwapChain, uint64_t frameTimeInNanos, void (*onComplete)(bool)) {