feat: add capture() function and expose viewportDimensions on ThermionViewer (allows easier saving of captured images to PNG)

This commit is contained in:
Nick Fisher
2024-08-21 14:33:48 +08:00
parent 0153b5be22
commit 0a720fae72
10 changed files with 119 additions and 20 deletions

View File

@@ -1186,6 +1186,49 @@ namespace thermion_filament
#endif
}
void FilamentViewer::capture(uint8_t *out, void (*onComplete)()) {
Viewport const &vp = _view->getViewport();
size_t pixelBufferSize = vp.width * vp.height * 4;
auto *pixelBuffer = new uint8_t[pixelBufferSize];
auto callback = [](void *buf, size_t size, void *data)
{
auto frameCallbackData = (std::vector<void*>*)data;
uint8_t *out = (uint8_t *)(frameCallbackData->at(0));
void* callbackPtr = frameCallbackData->at(1);
void (*callback)(void) = (void (*)(void))callbackPtr;
memcpy(out, buf, size);
delete frameCallbackData;
callback();
};
auto userData = new std::vector<void*> { out, (void*)onComplete } ;
auto pbd = Texture::PixelBufferDescriptor(
pixelBuffer, pixelBufferSize,
Texture::Format::RGBA,
Texture::Type::UBYTE, nullptr, callback, userData);
_renderer->beginFrame(_swapChain, 0);
_renderer->render(_view);
if(_rt) {
_renderer->readPixels(_rt, 0, 0, vp.width, vp.height, std::move(pbd));
} else {
_renderer->readPixels(0, 0, vp.width, vp.height, std::move(pbd));
}
_renderer->endFrame();
#ifdef __EMSCRIPTEN__
_engine->execute();
emscripten_webgl_commit_frame();
#endif
}
void FilamentViewer::savePng(void *buf, size_t size, int frameNumber)
{
// std::lock_guard lock(_recordingMutex);

View File

@@ -329,6 +329,13 @@ extern "C"
((FilamentViewer *)viewer)->render(frameTimeInNanos, pixelBuffer, callback, data);
}
EMSCRIPTEN_KEEPALIVE void capture(
const void *const viewer,
uint8_t *pixelBuffer,
void (*callback)(void)) {
((FilamentViewer *)viewer)->capture(pixelBuffer, callback);
};
EMSCRIPTEN_KEEPALIVE void set_frame_interval(
const void *const viewer,
float frameInterval)

View File

@@ -373,6 +373,12 @@ extern "C"
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void capture_ffi(void *const viewer, uint8_t* pixelBuffer, void (*onComplete)()) {
std::packaged_task<void()> lambda([=]() mutable
{ capture(viewer, pixelBuffer, onComplete); });
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void
set_background_color_ffi(void *const viewer, const float r, const float g,
const float b, const float a)