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();
}
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<RenderTarget?> getRenderTarget() async {

View File

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

View File

@@ -1,8 +1,11 @@
#pragma once
#include <map>
#include <mutex>
#include <vector>
#include <math/mat4.h>
#include <filament/Engine.h>
#include <filament/Material.h>
#include <filament/MaterialInstance.h>
@@ -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<utils::Entity, std::vector<filament::MaterialInstance *>> 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();

View File

@@ -29,13 +29,18 @@ EMSCRIPTEN_KEEPALIVE TOverlayManager *OverlayManager_create(TEngine *tEngine, TR
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) {
auto *overlayManager = reinterpret_cast<OverlayComponentManager *>(tOverlayManager);
auto *materialInstance = reinterpret_cast<filament::MaterialInstance *>(tMaterialInstance);
overlayManager->addOverlayComponent(utils::Entity::import(entityId), materialInstance);
}
EMSCRIPTEN_KEEPALIVE void OverlayManager_removeComponent(TOverlayManager *tOverlayManager, EntityId entityId) {
auto *overlayManager = reinterpret_cast<OverlayComponentManager *>(tOverlayManager);
overlayManager->removeOverlayComponent(utils::Entity::import(entityId));