From 73e65973010aedc247ded1b89efbbbfa845ef61d Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Tue, 1 Jul 2025 16:58:46 +0800 Subject: [PATCH] replace overlay render target when viewport resizes --- .../filament/src/implementation/ffi_view.dart | 17 +++++++++++- .../native/include/c_api/TOverlayManager.h | 4 +++ .../components/OverlayComponentManager.hpp | 26 ++++++++++++++++++- .../native/src/c_api/TOverlayManager.cpp | 7 ++++- 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/thermion_dart/lib/src/filament/src/implementation/ffi_view.dart b/thermion_dart/lib/src/filament/src/implementation/ffi_view.dart index da922137..26211fa6 100644 --- a/thermion_dart/lib/src/filament/src/implementation/ffi_view.dart +++ b/thermion_dart/lib/src/filament/src/implementation/ffi_view.dart @@ -61,10 +61,25 @@ class FFIView extends View> { await FilamentApp.instance!.updateRenderOrder(); } + Timer? _overlayResize; + @override Future setViewport(int width, int height) async { View_setViewport(view, width, height); - // await overlayView?.setViewport(width, height); + + if (overlayManager != null) { + _overlayResize?.cancel(); + _overlayResize = Timer(Duration(milliseconds: 33), () async { + var oldRenderTarget = overlayRenderTarget; + overlayRenderTarget = + await FilamentApp.instance!.createRenderTarget(width, height); + OverlayManager_setRenderTarget( + overlayManager!, overlayRenderTarget!.getNativeHandle()); + await oldRenderTarget!.destroy(); + print("Resized render target to ${width}x${height}"); + print(StackTrace.current); + }); + } } Future getRenderTarget() async { diff --git a/thermion_dart/native/include/c_api/TOverlayManager.h b/thermion_dart/native/include/c_api/TOverlayManager.h index c602a70b..c2d2c6a1 100644 --- a/thermion_dart/native/include/c_api/TOverlayManager.h +++ b/thermion_dart/native/include/c_api/TOverlayManager.h @@ -28,6 +28,10 @@ EMSCRIPTEN_KEEPALIVE void OverlayManager_removeComponent( EntityId entityId ); +EMSCRIPTEN_KEEPALIVE void OverlayManager_setRenderTarget( + TOverlayManager *tOverlayManager, + TRenderTarget *tRenderTarget +); #ifdef __cplusplus } diff --git a/thermion_dart/native/include/components/OverlayComponentManager.hpp b/thermion_dart/native/include/components/OverlayComponentManager.hpp index 261c07e3..19284fc8 100644 --- a/thermion_dart/native/include/components/OverlayComponentManager.hpp +++ b/thermion_dart/native/include/components/OverlayComponentManager.hpp @@ -1,8 +1,11 @@ #pragma once #include +#include #include + #include + #include #include #include @@ -44,8 +47,24 @@ namespace thermion mEngine->destroy(mDepthMaterial); } + void setRenderTarget(filament::RenderTarget *renderTarget) { + std::lock_guard lock(mMutex); + mRenderTarget = renderTarget; + auto *color = mRenderTarget->getTexture(filament::RenderTarget::AttachmentPoint::COLOR); + for (auto it = begin(); it < end(); it++) + { + const auto &entity = getEntity(it); + auto componentInstance = getInstance(entity); + auto &materialInstance = elementAt<0>(componentInstance); + materialInstance->setParameter("depth", color, mDepthSampler); + } + + } + void addOverlayComponent(utils::Entity target, filament::MaterialInstance *materialInstance) { + std::lock_guard lock(mMutex); + auto *color = mRenderTarget->getTexture(filament::RenderTarget::AttachmentPoint::COLOR); materialInstance->setParameter("depth", color, mDepthSampler); if (!hasComponent(target)) @@ -58,6 +77,8 @@ namespace thermion void removeOverlayComponent(utils::Entity target) { + std::lock_guard lock(mMutex); + if (hasComponent(target)) { removeComponent(target); @@ -67,10 +88,12 @@ namespace thermion void update() { - if (!mView || !mScene || getComponentCount() == 0) + if (!mView || !mScene || !mRenderTarget || getComponentCount() == 0) { return; } + + std::lock_guard lock(mMutex); auto &rm = mEngine->getRenderableManager(); std::map> materials; auto *scene = mView->getScene(); @@ -138,6 +161,7 @@ namespace thermion } private: + std::mutex mMutex; filament::Engine *mEngine = std::nullptr_t(); filament::View *mView = std::nullptr_t(); filament::Scene *mScene = std::nullptr_t(); diff --git a/thermion_dart/native/src/c_api/TOverlayManager.cpp b/thermion_dart/native/src/c_api/TOverlayManager.cpp index 64cc31e9..bae7b427 100644 --- a/thermion_dart/native/src/c_api/TOverlayManager.cpp +++ b/thermion_dart/native/src/c_api/TOverlayManager.cpp @@ -29,13 +29,18 @@ EMSCRIPTEN_KEEPALIVE TOverlayManager *OverlayManager_create(TEngine *tEngine, TR return reinterpret_cast(overlayManager); } +EMSCRIPTEN_KEEPALIVE void OverlayManager_setRenderTarget(TOverlayManager *tOverlayManager, TRenderTarget *tRenderTarget) { + auto *overlayManager = reinterpret_cast(tOverlayManager); + auto *renderTarget = reinterpret_cast(tRenderTarget); + overlayManager->setRenderTarget(renderTarget); +} + EMSCRIPTEN_KEEPALIVE void OverlayManager_addComponent(TOverlayManager *tOverlayManager, EntityId entityId, TMaterialInstance *tMaterialInstance) { auto *overlayManager = reinterpret_cast(tOverlayManager); auto *materialInstance = reinterpret_cast(tMaterialInstance); overlayManager->addOverlayComponent(utils::Entity::import(entityId), materialInstance); } - EMSCRIPTEN_KEEPALIVE void OverlayManager_removeComponent(TOverlayManager *tOverlayManager, EntityId entityId) { auto *overlayManager = reinterpret_cast(tOverlayManager); overlayManager->removeOverlayComponent(utils::Entity::import(entityId));