diff --git a/thermion_dart/native/include/c_api/TEngine.h b/thermion_dart/native/include/c_api/TEngine.h index 23728311..dca05f26 100644 --- a/thermion_dart/native/include/c_api/TEngine.h +++ b/thermion_dart/native/include/c_api/TEngine.h @@ -13,8 +13,20 @@ extern "C" { #endif +enum TBackend { + BACKEND_DEFAULT = 0, //!< Automatically selects an appropriate driver for the platform. + BACKEND_OPENGL = 1, //!< Selects the OpenGL/ES driver (default on Android) + BACKEND_VULKAN = 2, //!< Selects the Vulkan driver if the platform supports it (default on Linux/Windows) + BACKEND_METAL = 3, //!< Selects the Metal driver if the platform supports it (default on MacOS/iOS). + BACKEND_NOOP = 4, //!< Selects the no-op driver for testing purposes. +}; - +EMSCRIPTEN_KEEPALIVE TEngine *Engine_create(TBackend backend); +EMSCRIPTEN_KEEPALIVE TRenderer *Engine_createRenderer(TEngine *tEngine); +EMSCRIPTEN_KEEPALIVE TSwapChain *Engine_createSwapChain(TEngine *tEngine, void *window, uint64_t flags); +EMSCRIPTEN_KEEPALIVE TSwapChain *Engine_createHeadlessSwapChain(TEngine *tEngine, uint32_t width, uint32_t height, uint64_t flags); +EMSCRIPTEN_KEEPALIVE TCamera *Engine_createCamera(TEngine* tEngine); +EMSCRIPTEN_KEEPALIVE TView *Engine_createView(TEngine *tEngine); EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine* tEngine, EntityId entityId); EMSCRIPTEN_KEEPALIVE TTransformManager *Engine_getTransformManager(TEngine *engine); EMSCRIPTEN_KEEPALIVE TRenderableManager *Engine_getRenderableManager(TEngine *engine); @@ -29,9 +41,16 @@ EMSCRIPTEN_KEEPALIVE TTexture *Engine_buildTexture(TEngine *engine, TTextureFormat format); EMSCRIPTEN_KEEPALIVE void Engine_destroyTexture(TEngine *tEngine, TTexture *tTexture); +EMSCRIPTEN_KEEPALIVE TFence *Engine_createFence(TEngine *tEngine); +EMSCRIPTEN_KEEPALIVE void Engine_destroyFence(TEngine *tEngine, TFence *tFence); +EMSCRIPTEN_KEEPALIVE void Engine_flushAndWait(TEngine *tEngine); EMSCRIPTEN_KEEPALIVE TMaterial *Engine_buildMaterial(TEngine *tEngine, const uint8_t* materialData, size_t length); EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterial(TEngine *tEngine, TMaterial *tMaterial); +EMSCRIPTEN_KEEPALIVE TScene *Engine_createScene(TEngine *tEngine); +EMSCRIPTEN_KEEPALIVE TSkybox *Engine_buildSkybox(TEngine *tEngine, uint8_t* ktxData, size_t length, void(*onTextureUploadComplete)()); + + #ifdef __cplusplus } diff --git a/thermion_dart/native/src/c_api/TEngine.cpp b/thermion_dart/native/src/c_api/TEngine.cpp index 46de1e9a..31e570af 100644 --- a/thermion_dart/native/src/c_api/TEngine.cpp +++ b/thermion_dart/native/src/c_api/TEngine.cpp @@ -1,13 +1,24 @@ #include "c_api/TEngine.h" #include +#include #include #include +#include #include #include #include #include +#include +#include + +#include +#include +#include + +#include + #include "Log.hpp" #ifdef __cplusplus @@ -18,6 +29,41 @@ namespace thermion using namespace filament; #endif + uint64_t TSWAP_CHAIN_CONFIG_TRANSPARENT = filament::backend::SWAP_CHAIN_CONFIG_TRANSPARENT; + uint64_t TSWAP_CHAIN_CONFIG_READABLE = filament::backend::SWAP_CHAIN_CONFIG_READABLE; + uint64_t TSWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER = filament::backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER; + uint64_t TSWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER = filament::backend::SWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER; + + EMSCRIPTEN_KEEPALIVE TEngine *Engine_create(TBackend backend) { + auto *engine = filament::Engine::create(static_cast(backend)); + return reinterpret_cast(engine); + } + + EMSCRIPTEN_KEEPALIVE TRenderer *Engine_createRenderer(TEngine *tEngine) { + auto *engine = reinterpret_cast(tEngine); + auto *renderer = engine->createRenderer(); + return reinterpret_cast(renderer); + } + + EMSCRIPTEN_KEEPALIVE TSwapChain *Engine_createSwapChain(TEngine *tEngine, void *window, uint64_t flags) { + auto *engine = reinterpret_cast(tEngine); + auto *swapChain = engine->createSwapChain(window, flags); + return reinterpret_cast(swapChain); + } + + EMSCRIPTEN_KEEPALIVE TSwapChain *Engine_createHeadlessSwapChain(TEngine *tEngine, uint32_t width, uint32_t height, uint64_t flags) { + auto *engine = reinterpret_cast(tEngine); + auto *swapChain = engine->createSwapChain(width, height, flags); + return reinterpret_cast(swapChain); + } + + + EMSCRIPTEN_KEEPALIVE TView *Engine_createView(TEngine *tEngine) { + auto *engine = reinterpret_cast(tEngine); + auto *view = engine->createView(); + return reinterpret_cast(view); + } + EMSCRIPTEN_KEEPALIVE TTransformManager *Engine_getTransformManager(TEngine *tEngine) { auto *engine = reinterpret_cast(tEngine); @@ -39,6 +85,13 @@ namespace thermion return reinterpret_cast(&lightManager); } + EMSCRIPTEN_KEEPALIVE TCamera *Engine_createCamera(TEngine* tEngine) { + auto *engine = reinterpret_cast(tEngine); + utils::Entity entity = utils::EntityManager::get().create(); + auto *camera = engine->createCamera(entity); + return reinterpret_cast(camera); + } + EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *tEngine, EntityId entityId) { auto *engine = reinterpret_cast(tEngine); @@ -258,6 +311,78 @@ namespace thermion engine->destroy(texture); } + EMSCRIPTEN_KEEPALIVE TFence *Engine_createFence(TEngine *tEngine) { + auto *engine = reinterpret_cast(tEngine); + auto *fence = engine->createFence(); + return reinterpret_cast(fence); + } + + EMSCRIPTEN_KEEPALIVE void Engine_destroyFence(TEngine *tEngine, TFence *tFence) { + auto *engine = reinterpret_cast(tEngine); + auto *fence = reinterpret_cast(tFence); + Fence::waitAndDestroy(fence); + } + + EMSCRIPTEN_KEEPALIVE void Engine_flushAndWait(TEngine *tEngine) { + auto *engine = reinterpret_cast(tEngine); + #ifdef __EMSCRIPTEN__ + engine->execute(); + emscripten_webgl_commit_frame(); + #else + engine->flushAndWait(); + #endif + } + + EMSCRIPTEN_KEEPALIVE TScene *Engine_createScene(TEngine *tEngine) { + auto *engine = reinterpret_cast(tEngine); + auto *scene = engine->createScene(); + return reinterpret_cast(scene); + } + + EMSCRIPTEN_KEEPALIVE TSkybox *Engine_buildSkybox(TEngine *tEngine, uint8_t* ktxData, size_t length, void(*onTextureUploadComplete)()) { + auto *engine = reinterpret_cast(tEngine); + auto copy = new std::vector(ktxData, ktxData + length); + image::Ktx1Bundle *skyboxBundle = + new image::Ktx1Bundle(static_cast(copy->data()), + static_cast(length)); + + std::vector *callbackData = new std::vector{ + reinterpret_cast(onTextureUploadComplete), + reinterpret_cast(skyboxBundle), + reinterpret_cast(copy) + }; + + auto *texture = + ktxreader::Ktx1Reader::createTexture( + engine, *skyboxBundle, false, [](void *userdata) + { + std::vector* vec = (std::vector*)userdata; + + void *callbackPtr = vec->at(0); + image::Ktx1Bundle *skyboxBundle = reinterpret_cast(vec->at(1)); + std::vector *copy = reinterpret_cast*>(vec->at(2)); + + delete vec; + + if (callbackPtr) + { + Log("NON NULL CLLABCK"); + void (*callback)(void) = (void (*)(void))callbackPtr; + callback(); + } + delete skyboxBundle; + delete copy; + }, + (void*)callbackData); + auto *skybox = + filament::Skybox::Builder() + .environment(texture) + .build(*engine); + + return reinterpret_cast(skybox); + } + + #ifdef __cplusplus } }