replace overlay render target when viewport resizes

This commit is contained in:
Nick Fisher
2025-07-01 16:58:46 +08:00
parent e731556e6f
commit 73e6597301
4 changed files with 51 additions and 3 deletions

View File

@@ -61,10 +61,25 @@ class FFIView extends View<Pointer<TView>> {
await FilamentApp.instance!.updateRenderOrder(); await FilamentApp.instance!.updateRenderOrder();
} }
Timer? _overlayResize;
@override @override
Future setViewport(int width, int height) async { Future setViewport(int width, int height) async {
View_setViewport(view, width, height); 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<RenderTarget?> getRenderTarget() async { Future<RenderTarget?> getRenderTarget() async {

View File

@@ -28,6 +28,10 @@ EMSCRIPTEN_KEEPALIVE void OverlayManager_removeComponent(
EntityId entityId EntityId entityId
); );
EMSCRIPTEN_KEEPALIVE void OverlayManager_setRenderTarget(
TOverlayManager *tOverlayManager,
TRenderTarget *tRenderTarget
);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,8 +1,11 @@
#pragma once #pragma once
#include <map> #include <map>
#include <mutex>
#include <vector> #include <vector>
#include <math/mat4.h> #include <math/mat4.h>
#include <filament/Engine.h> #include <filament/Engine.h>
#include <filament/Material.h> #include <filament/Material.h>
#include <filament/MaterialInstance.h> #include <filament/MaterialInstance.h>
@@ -44,8 +47,24 @@ namespace thermion
mEngine->destroy(mDepthMaterial); 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) void addOverlayComponent(utils::Entity target, filament::MaterialInstance *materialInstance)
{ {
std::lock_guard lock(mMutex);
auto *color = mRenderTarget->getTexture(filament::RenderTarget::AttachmentPoint::COLOR); auto *color = mRenderTarget->getTexture(filament::RenderTarget::AttachmentPoint::COLOR);
materialInstance->setParameter("depth", color, mDepthSampler); materialInstance->setParameter("depth", color, mDepthSampler);
if (!hasComponent(target)) if (!hasComponent(target))
@@ -58,6 +77,8 @@ namespace thermion
void removeOverlayComponent(utils::Entity target) void removeOverlayComponent(utils::Entity target)
{ {
std::lock_guard lock(mMutex);
if (hasComponent(target)) if (hasComponent(target))
{ {
removeComponent(target); removeComponent(target);
@@ -67,10 +88,12 @@ namespace thermion
void update() void update()
{ {
if (!mView || !mScene || getComponentCount() == 0) if (!mView || !mScene || !mRenderTarget || getComponentCount() == 0)
{ {
return; return;
} }
std::lock_guard lock(mMutex);
auto &rm = mEngine->getRenderableManager(); auto &rm = mEngine->getRenderableManager();
std::map<utils::Entity, std::vector<filament::MaterialInstance *>> materials; std::map<utils::Entity, std::vector<filament::MaterialInstance *>> materials;
auto *scene = mView->getScene(); auto *scene = mView->getScene();
@@ -138,6 +161,7 @@ namespace thermion
} }
private: private:
std::mutex mMutex;
filament::Engine *mEngine = std::nullptr_t(); filament::Engine *mEngine = std::nullptr_t();
filament::View *mView = std::nullptr_t(); filament::View *mView = std::nullptr_t();
filament::Scene *mScene = std::nullptr_t(); filament::Scene *mScene = std::nullptr_t();

View File

@@ -29,13 +29,18 @@ EMSCRIPTEN_KEEPALIVE TOverlayManager *OverlayManager_create(TEngine *tEngine, TR
return reinterpret_cast<TOverlayManager *>(overlayManager); return reinterpret_cast<TOverlayManager *>(overlayManager);
} }
EMSCRIPTEN_KEEPALIVE void OverlayManager_setRenderTarget(TOverlayManager *tOverlayManager, TRenderTarget *tRenderTarget) {
auto *overlayManager = reinterpret_cast<OverlayComponentManager *>(tOverlayManager);
auto *renderTarget = reinterpret_cast<filament::RenderTarget *>(tRenderTarget);
overlayManager->setRenderTarget(renderTarget);
}
EMSCRIPTEN_KEEPALIVE void OverlayManager_addComponent(TOverlayManager *tOverlayManager, EntityId entityId, TMaterialInstance *tMaterialInstance) { EMSCRIPTEN_KEEPALIVE void OverlayManager_addComponent(TOverlayManager *tOverlayManager, EntityId entityId, TMaterialInstance *tMaterialInstance) {
auto *overlayManager = reinterpret_cast<OverlayComponentManager *>(tOverlayManager); auto *overlayManager = reinterpret_cast<OverlayComponentManager *>(tOverlayManager);
auto *materialInstance = reinterpret_cast<filament::MaterialInstance *>(tMaterialInstance); auto *materialInstance = reinterpret_cast<filament::MaterialInstance *>(tMaterialInstance);
overlayManager->addOverlayComponent(utils::Entity::import(entityId), materialInstance); overlayManager->addOverlayComponent(utils::Entity::import(entityId), materialInstance);
} }
EMSCRIPTEN_KEEPALIVE void OverlayManager_removeComponent(TOverlayManager *tOverlayManager, EntityId entityId) { EMSCRIPTEN_KEEPALIVE void OverlayManager_removeComponent(TOverlayManager *tOverlayManager, EntityId entityId) {
auto *overlayManager = reinterpret_cast<OverlayComponentManager *>(tOverlayManager); auto *overlayManager = reinterpret_cast<OverlayComponentManager *>(tOverlayManager);
overlayManager->removeOverlayComponent(utils::Entity::import(entityId)); overlayManager->removeOverlayComponent(utils::Entity::import(entityId));