feat! js_interop improvements

This commit is contained in:
Nick Fisher
2025-05-07 17:06:38 +08:00
parent 63e2dcd0ca
commit 2f16908992
159 changed files with 12989 additions and 8377 deletions
+8 -8
View File
@@ -1,8 +1,8 @@
#pragma once
#ifndef FLUTTER_FILAMENT_LOG_H
#define FLUTTER_FILAMENT_LOG_H
#ifdef __EMSCRIPTEN__
#include <emscripten/console.h>
#endif
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#elif defined __ANDROID__
@@ -14,6 +14,9 @@
#include <iostream>
#endif
#ifdef __EMSCRIPTEN__
#define Log(...) emscripten_console_logf(__VA_ARGS__);
#else
static void Log(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
@@ -26,11 +29,10 @@ static void Log(const char *fmt, ...) {
#else
vprintf(fmt, args);
std::cout << std::endl;
#endif
#endif
va_end(args);
}
#endif
#if defined(_WIN32) || defined(_WIN64)
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
@@ -61,5 +63,3 @@ static void Log(const char *fmt, ...) {
#endif
#define ERROR(fmt, ...) Log("Error: %s:%d " fmt, __FILENAME__, __LINE__, ##__VA_ARGS__)
#endif
+1 -1
View File
@@ -17,7 +17,7 @@ static filament::math::mat4f convert_double_to_mat4f(double* data)
// Helper function to convert filament::math::mat4 to double4x4
static double4x4 convert_mat4_to_double4x4(const filament::math::mat4 &mat)
{
return double4x4{
return double4x4 {
{mat[0][0], mat[0][1], mat[0][2], mat[0][3]},
{mat[1][0], mat[1][1], mat[1][2], mat[1][3]},
{mat[2][0], mat[2][1], mat[2][2], mat[2][3]},
@@ -29,7 +29,9 @@ namespace thermion
{
public:
RenderTicker(filament::Renderer *renderer) : mRenderer(renderer) { }
RenderTicker(
filament::Engine *engine,
filament::Renderer *renderer) : mEngine(engine), mRenderer(renderer) { }
~RenderTicker();
/// @brief
@@ -55,6 +57,7 @@ namespace thermion
private:
std::mutex mMutex;
filament::Engine *mEngine = nullptr;
filament::Renderer *mRenderer = nullptr;
std::vector<AnimationManager*> mAnimationManagers;
std::vector<std::pair<filament::SwapChain*, std::vector<filament::View*>>> mRenderable;
@@ -5,6 +5,7 @@ extern "C"
{
#endif
#include <stddef.h>
#include <stdint.h>
#include "APIExport.h"
@@ -156,6 +157,7 @@ extern "C"
GIZMO_TYPE_TRANSLATION,
GIZMO_TYPE_ROTATION
};
typedef enum TGizmoType TGizmoType;
enum TPrimitiveType {
// don't change the enums values (made to match GL)
@@ -165,11 +167,12 @@ extern "C"
PRIMITIVETYPE_TRIANGLES = 4, //!< triangles
PRIMITIVETYPE_TRIANGLE_STRIP = 5 //!< triangle strip
};
typedef enum TPrimitiveType TPrimitiveType;
EMSCRIPTEN_KEEPALIVE extern uint64_t TSWAP_CHAIN_CONFIG_TRANSPARENT;
EMSCRIPTEN_KEEPALIVE extern uint64_t TSWAP_CHAIN_CONFIG_READABLE;
EMSCRIPTEN_KEEPALIVE extern uint64_t TSWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER;
EMSCRIPTEN_KEEPALIVE extern uint64_t TSWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER;
extern uint64_t TSWAP_CHAIN_CONFIG_TRANSPARENT;
extern uint64_t TSWAP_CHAIN_CONFIG_READABLE;
extern uint64_t TSWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER;
extern uint64_t TSWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER;
#ifdef __cplusplus
}
@@ -1,5 +1,5 @@
#ifndef _API_EXPORT_H
#define _API_EXPORT_H
#pragma once
#ifdef _WIN32
#ifdef IS_DLL
#define EMSCRIPTEN_KEEPALIVE __declspec(dllimport)
@@ -44,4 +44,3 @@
#if defined(__APPLE__) || defined(__EMSCRIPTEN__)
#include <stddef.h>
#endif
#endif
+23 -22
View File
@@ -13,37 +13,38 @@ enum TProjection {
Perspective,
Orthographic
};
typedef enum TProjection TProjection;
// Camera methods
EMSCRIPTEN_KEEPALIVE void Camera_setExposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity);
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getProjectionMatrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getCullingProjectionMatrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE void Camera_getFrustum(TCamera *camera, double* out);
EMSCRIPTEN_KEEPALIVE void Camera_setProjectionMatrix(TCamera *camera, double *matrix, double near, double far);
EMSCRIPTEN_KEEPALIVE void Camera_setProjectionFromFov(TCamera *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal);
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera* camera);
EMSCRIPTEN_KEEPALIVE void Camera_lookAt(TCamera* camera, double3 eye, double3 focus, double3 up);
void Camera_setExposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity);
double4x4 Camera_getModelMatrix(TCamera *const camera);
double4x4 Camera_getViewMatrix(TCamera *const camera);
double4x4 Camera_getProjectionMatrix(TCamera *const camera);
double4x4 Camera_getCullingProjectionMatrix(TCamera *const camera);
void Camera_getFrustum(TCamera *camera, double* out);
void Camera_setProjectionMatrix(TCamera *camera, double *matrix, double near, double far);
void Camera_setProjectionFromFov(TCamera *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal);
double Camera_getFocalLength(TCamera *const camera);
double4x4 Camera_getViewMatrix(TCamera *const camera);
double4x4 Camera_getModelMatrix(TCamera* camera);
void Camera_lookAt(TCamera* camera, double3 eye, double3 focus, double3 up);
EMSCRIPTEN_KEEPALIVE double Camera_getNear(TCamera *camera);
EMSCRIPTEN_KEEPALIVE double Camera_getCullingFar(TCamera *camera);
EMSCRIPTEN_KEEPALIVE float Camera_getFov(TCamera *camera, bool horizontal);
EMSCRIPTEN_KEEPALIVE double Camera_getFocusDistance(TCamera *camera);
EMSCRIPTEN_KEEPALIVE void Camera_setFocusDistance(TCamera *camera, float focusDistance);
double Camera_getNear(TCamera *camera);
double Camera_getCullingFar(TCamera *camera);
float Camera_getFov(TCamera *camera, bool horizontal);
double Camera_getFocusDistance(TCamera *camera);
void Camera_setFocusDistance(TCamera *camera, float focusDistance);
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(
void Camera_setCustomProjectionWithCulling(
TCamera* camera,
double4x4 projectionMatrix,
double near,
double far
);
EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera* camera, double *tModelMatrix);
EMSCRIPTEN_KEEPALIVE void Camera_setLensProjection(TCamera *camera, double near, double far, double aspect, double focalLength);
EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera* camera);
EMSCRIPTEN_KEEPALIVE void Camera_setProjection(TCamera *const tCamera, TProjection projection, double left, double right,
void Camera_setModelMatrix(TCamera* camera, double *tModelMatrix);
void Camera_setLensProjection(TCamera *camera, double near, double far, double aspect, double focalLength);
EntityId Camera_getEntity(TCamera* camera);
void Camera_setProjection(TCamera *const tCamera, TProjection projection, double left, double right,
double bottom, double top,
double near, double far);
@@ -18,6 +18,7 @@ enum TBackend {
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.
};
typedef enum TBackend TBackend;
EMSCRIPTEN_KEEPALIVE TEngine *Engine_create(
TBackend backend,
@@ -50,6 +51,7 @@ EMSCRIPTEN_KEEPALIVE void Engine_destroyTexture(TEngine *tEngine, TTexture *tTex
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 void Engine_execute(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);
+3 -1
View File
@@ -13,9 +13,11 @@ extern "C"
enum TGizmoAxis { X, Y, Z };
enum TGizmoPickResultType { AxisX, AxisY, AxisZ, Parent, None };
typedef enum TGizmoPickResultType TGizmoPickResultType;
typedef enum TGizmoAxis TGizmoAxis;
typedef void (*GizmoPickCallback)(TGizmoPickResultType resultType, float x, float y, float z);
void Gizmo_dummy(TGizmoPickResultType t);
EMSCRIPTEN_KEEPALIVE TGizmo *Gizmo_create(
TEngine *tEngine,
TGltfAssetLoader *assetLoader,
@@ -16,6 +16,7 @@ extern "C"
LIGHT_TYPE_FOCUSED_SPOT,
LIGHT_TYPE_SPOT
};
typedef enum TLightType TLightType;
EMSCRIPTEN_KEEPALIVE void LightManager_setPosition(TLightManager *tLightManager, EntityId light, double x, double y, double z);
EMSCRIPTEN_KEEPALIVE void LightManager_setDirection(TLightManager *tLightManager, EntityId light, double x, double y, double z);
@@ -21,6 +21,7 @@ extern "C"
A, //!< Always. Depth / stencil testing is deactivated.
N //!< Never. The depth / stencil test always fails.
};
typedef enum TSamplerCompareFunc TSamplerCompareFunc;
// StencilOperation equivalent
enum TStencilOperation
@@ -34,6 +35,7 @@ extern "C"
DECR_WRAP, // Decrement the current value without saturation
INVERT // Invert the current value
};
typedef enum TStencilOperation TStencilOperation;
enum TStencilFace
{
@@ -41,6 +43,7 @@ extern "C"
STENCIL_FACE_BACK = 2,
STENCIL_FACE_FRONT_AND_BACK = 3
};
typedef enum TStencilFace TStencilFace;
enum TCullingMode
{
@@ -49,6 +52,7 @@ extern "C"
CULLING_MODE_BACK,
CULLING_MODE_FRONT_AND_BACK
};
typedef enum TCullingMode TCullingMode;
enum TTransparencyMode {
//! the transparent object is drawn honoring the raster state
@@ -66,6 +70,7 @@ extern "C"
*/
TWO_PASSES_TWO_SIDES
};
typedef enum TTransparencyMode TTransparencyMode;
EMSCRIPTEN_KEEPALIVE TMaterialInstance *Material_createInstance(TMaterial *tMaterial);
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createImageMaterial(TEngine *tEngine);
@@ -8,7 +8,7 @@ extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE TRenderTicker *RenderTicker_create(TRenderer *tRenderer);
EMSCRIPTEN_KEEPALIVE TRenderTicker *RenderTicker_create(TEngine *tEngine, TRenderer *tRenderer);
EMSCRIPTEN_KEEPALIVE void RenderTicker_destroy(TRenderTicker *tRenderTicker);
EMSCRIPTEN_KEEPALIVE void RenderTicker_addAnimationManager(TRenderTicker *tRenderTicker, TAnimationManager *tAnimationManager);
EMSCRIPTEN_KEEPALIVE void RenderTicker_removeAnimationManager(TRenderTicker *tRenderTicker, TAnimationManager *tAnimationManager);
@@ -3,6 +3,7 @@
#include "APIExport.h"
#include "APIBoundaryTypes.h"
#include "TMaterialInstance.h"
#include "TTexture.h"
#ifdef __cplusplus
extern "C"
@@ -20,6 +20,8 @@ enum TTextureSamplerType
SAMPLER_CUBEMAP_ARRAY=5
};
typedef enum TTextureSamplerType TTextureSamplerType;
enum TTextureFormat
{
// 8-bits per element
@@ -157,6 +159,7 @@ enum TTextureFormat
TEXTUREFORMAT_RGBA_BPTC_UNORM, // BC7
TEXTUREFORMAT_SRGB_ALPHA_BPTC_UNORM // BC7 sRGB
};
typedef enum TTextureFormat TTextureFormat;
//! Pixel Data Format
enum TPixelDataFormat {
@@ -173,6 +176,7 @@ enum TPixelDataFormat {
PIXELDATAFORMAT_DEPTH_STENCIL, //!< Two Depth (24-bits) + Stencil (8-bits) channels
PIXELDATAFORMAT_ALPHA //! One Alpha channel, float
};
typedef enum TPixelDataFormat TPixelDataFormat;
enum TPixelDataType {
PIXELDATATYPE_UBYTE, //!< unsigned byte
@@ -188,6 +192,7 @@ enum TPixelDataType {
PIXELDATATYPE_USHORT_565, //!< unsigned int (16-bit), encodes 3 RGB channels
PIXELDATATYPE_UINT_2_10_10_10_REV, //!< unsigned normalized 10 bits RGB, 2 bits alpha
};
typedef enum TPixelDataType TPixelDataType;
enum TTextureUsage {
TEXTURE_USAGE_NONE = 0x0000,
@@ -202,6 +207,7 @@ enum TTextureUsage {
TEXTURE_USAGE_PROTECTED = 0x0100, //!< Texture can be used the destination of a blit()
TEXTURE_USAGE_DEFAULT = TEXTURE_USAGE_UPLOADABLE | TEXTURE_USAGE_SAMPLEABLE //!< Default texture usage
};
typedef enum TTextureUsage TTextureUsage;
EMSCRIPTEN_KEEPALIVE TTexture *Texture_build(TEngine *engine,
uint32_t width,
@@ -268,6 +274,7 @@ enum TSamplerWrapMode {
WRAP_REPEAT, // Repeat wrapping mode
WRAP_MIRRORED_REPEAT // Mirrored repeat wrapping mode
};
typedef enum TSamplerWrapMode TSamplerWrapMode;
enum TSamplerMinFilter {
FILTER_NEAREST, // Nearest filtering
@@ -277,16 +284,19 @@ enum TSamplerMinFilter {
FILTER_NEAREST_MIPMAP_LINEAR, // Nearest mipmap linear filtering
FILTER_LINEAR_MIPMAP_LINEAR // Linear mipmap linear filtering
};
typedef enum TSamplerMinFilter TSamplerMinFilter;
enum TSamplerMagFilter {
MAG_FILTER_NEAREST, // Nearest filtering
MAG_FILTER_LINEAR // Linear filtering
};
typedef enum TSamplerMagFilter TSamplerMagFilter;
enum TSamplerCompareMode {
COMPARE_MODE_NONE, // No comparison
COMPARE_MODE_COMPARE_TO_TEXTURE // Compare to texture
};
typedef enum TSamplerCompareMode TSamplerCompareMode;
typedef TSamplerCompareFunc TTextureSamplerCompareFunc ;
@@ -23,6 +23,7 @@ enum TToneMapping
FILMIC,
LINEAR
};
typedef enum TToneMapping TToneMapping;
// copied from Options.h
enum TQualityLevel {
@@ -31,11 +32,13 @@ enum TQualityLevel {
HIGH,
ULTRA
};
typedef enum TQualityLevel TQualityLevel;
enum TBlendMode {
OPAQUE,
TRANSLUCENT
};
typedef enum TBlendMode TBlendMode;
// View
EMSCRIPTEN_KEEPALIVE TViewport View_getViewport(TView *view);
@@ -1,5 +1,6 @@
#pragma once
#include "TEngine.h"
#include "TView.h"
#include "TTexture.h"
#include "TMaterialProvider.h"
@@ -10,20 +11,20 @@ namespace thermion
extern "C"
{
#endif
typedef void (*VoidCallback)();
typedef int32_t EntityId;
typedef void (*FilamentRenderCallback)(void *const owner);
EMSCRIPTEN_KEEPALIVE void RenderThread_create();
EMSCRIPTEN_KEEPALIVE void RenderThread_destroy();
EMSCRIPTEN_KEEPALIVE void RenderThread_requestFrame(void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void RenderThread_setRenderTicker(TRenderTicker *tRenderTicker);
EMSCRIPTEN_KEEPALIVE void RenderThread_addTask(void (*task)());
void RenderThread_create();
void RenderThread_destroy();
void RenderThread_requestFrameAsync();
void RenderThread_setRenderTicker(TRenderTicker *tRenderTicker);
void RenderThread_addTask(void (*task)());
EMSCRIPTEN_KEEPALIVE void RenderTicker_renderRenderThread(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void AnimationManager_createRenderThread(TEngine *tEngine, TScene *tScene, void (*onComplete)(TAnimationManager *));
void RenderTicker_renderRenderThread(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos, VoidCallback onComplete);
void AnimationManager_createRenderThread(TEngine *tEngine, TScene *tScene, void (*onComplete)(TAnimationManager *));
EMSCRIPTEN_KEEPALIVE void Engine_createRenderThread(
void Engine_createRenderThread(
TBackend backend,
void* platform,
void* sharedContext,
@@ -31,22 +32,22 @@ namespace thermion
bool disableHandleUseAfterFreeCheck,
void (*onComplete)(TEngine *)
);
EMSCRIPTEN_KEEPALIVE void Engine_createRendererRenderThread(TEngine *tEngine, void (*onComplete)(TRenderer *));
EMSCRIPTEN_KEEPALIVE void Engine_createSwapChainRenderThread(TEngine *tEngine, void *window, uint64_t flags, void (*onComplete)(TSwapChain *));
EMSCRIPTEN_KEEPALIVE void Engine_createHeadlessSwapChainRenderThread(TEngine *tEngine, uint32_t width, uint32_t height, uint64_t flags, void (*onComplete)(TSwapChain *));
EMSCRIPTEN_KEEPALIVE void Engine_createCameraRenderThread(TEngine* tEngine, void (*onComplete)(TCamera *));
EMSCRIPTEN_KEEPALIVE void Engine_createViewRenderThread(TEngine *tEngine, void (*onComplete)(TView *));
EMSCRIPTEN_KEEPALIVE void Engine_buildMaterialRenderThread(TEngine *tEngine, const uint8_t *materialData, size_t length, void (*onComplete)(TMaterial *));
EMSCRIPTEN_KEEPALIVE void Engine_destroyRenderThread(TEngine *tEngine, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Engine_destroySwapChainRenderThread(TEngine *tEngine, TSwapChain *tSwapChain, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Engine_destroyViewRenderThread(TEngine *tEngine, TView *tView, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Engine_destroySceneRenderThread(TEngine *tEngine, TScene *tScene, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Engine_destroyColorGradingRenderThread(TEngine *tEngine, TColorGrading *tColorGrading, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialInstanceRenderThread(TEngine *tEngine, TMaterialInstance *tMaterialInstance, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Engine_destroySkyboxRenderThread(TEngine *tEngine, TSkybox *tSkybox, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Engine_destroyIndirectLightRenderThread(TEngine *tEngine, TIndirectLight *tIndirectLight, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Texture_buildRenderThread(TEngine *engine,
void Engine_createRendererRenderThread(TEngine *tEngine, void (*onComplete)(TRenderer *));
void Engine_createSwapChainRenderThread(TEngine *tEngine, void *window, uint64_t flags, void (*onComplete)(TSwapChain *));
void Engine_createHeadlessSwapChainRenderThread(TEngine *tEngine, uint32_t width, uint32_t height, uint64_t flags, void (*onComplete)(TSwapChain *));
void Engine_createCameraRenderThread(TEngine* tEngine, void (*onComplete)(TCamera *));
void Engine_createViewRenderThread(TEngine *tEngine, void (*onComplete)(TView *));
void Engine_buildMaterialRenderThread(TEngine *tEngine, const uint8_t *materialData, size_t length, void (*onComplete)(TMaterial *));
void Engine_destroyRenderThread(TEngine *tEngine, VoidCallback onComplete);
void Engine_destroySwapChainRenderThread(TEngine *tEngine, TSwapChain *tSwapChain, VoidCallback onComplete);
void Engine_destroyViewRenderThread(TEngine *tEngine, TView *tView, VoidCallback onComplete);
void Engine_destroySceneRenderThread(TEngine *tEngine, TScene *tScene, VoidCallback onComplete);
void Engine_destroyColorGradingRenderThread(TEngine *tEngine, TColorGrading *tColorGrading, VoidCallback onComplete);
void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, VoidCallback onComplete);
void Engine_destroyMaterialInstanceRenderThread(TEngine *tEngine, TMaterialInstance *tMaterialInstance, VoidCallback onComplete);
void Engine_destroySkyboxRenderThread(TEngine *tEngine, TSkybox *tSkybox, VoidCallback onComplete);
void Engine_destroyIndirectLightRenderThread(TEngine *tEngine, TIndirectLight *tIndirectLight, VoidCallback onComplete);
void Texture_buildRenderThread(TEngine *engine,
uint32_t width,
uint32_t height,
uint32_t depth,
@@ -58,19 +59,20 @@ namespace thermion
void (*onComplete)(TTexture*)
);
EMSCRIPTEN_KEEPALIVE void Engine_destroyTextureRenderThread(TEngine *engine, TTexture* tTexture, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Engine_createFenceRenderThread(TEngine *tEngine, void (*onComplete)(TFence*));
EMSCRIPTEN_KEEPALIVE void Engine_destroyFenceRenderThread(TEngine *tEngine, TFence *tFence, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Engine_flushAndWaitRenderThead(TEngine *tEngine, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Engine_buildSkyboxRenderThread(TEngine *tEngine, uint8_t *skyboxData, size_t length, void (*onComplete)(TSkybox *), void (*onTextureUploadComplete)());
EMSCRIPTEN_KEEPALIVE void Engine_buildIndirectLightRenderThread(TEngine *tEngine, uint8_t *iblData, size_t length, float intensity, void (*onComplete)(TIndirectLight *), void (*onTextureUploadComplete)());
void Engine_destroyTextureRenderThread(TEngine *engine, TTexture* tTexture, VoidCallback onComplete);
void Engine_createFenceRenderThread(TEngine *tEngine, void (*onComplete)(TFence*));
void Engine_destroyFenceRenderThread(TEngine *tEngine, TFence *tFence, VoidCallback onComplete);
void Engine_flushAndWaitRenderThread(TEngine *tEngine, VoidCallback onComplete);
void Engine_executeRenderThread(TEngine *tEngine, VoidCallback onComplete);
void Engine_buildSkyboxRenderThread(TEngine *tEngine, uint8_t *skyboxData, size_t length, void (*onComplete)(TSkybox *), void (*onTextureUploadComplete)());
void Engine_buildIndirectLightRenderThread(TEngine *tEngine, uint8_t *iblData, size_t length, float intensity, void (*onComplete)(TIndirectLight *), void (*onTextureUploadComplete)());
EMSCRIPTEN_KEEPALIVE void Renderer_setClearOptionsRenderThread(TRenderer *tRenderer, double clearR, double clearG, double clearB, double clearA, uint8_t clearStencil, bool clear, bool discard, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Renderer_beginFrameRenderThread(TRenderer *tRenderer, TSwapChain *tSwapChain, uint64_t frameTimeInNanos, void (*onComplete)(bool));
EMSCRIPTEN_KEEPALIVE void Renderer_endFrameRenderThread(TRenderer *tRenderer, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Renderer_renderRenderThread(TRenderer *tRenderer, TView *tView, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Renderer_renderStandaloneViewRenderThread(TRenderer *tRenderer, TView *tView, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Renderer_readPixelsRenderThread(
void Renderer_setClearOptionsRenderThread(TRenderer *tRenderer, double clearR, double clearG, double clearB, double clearA, uint8_t clearStencil, bool clear, bool discard, VoidCallback onComplete);
void Renderer_beginFrameRenderThread(TRenderer *tRenderer, TSwapChain *tSwapChain, uint64_t frameTimeInNanos, void (*onComplete)(bool));
void Renderer_endFrameRenderThread(TRenderer *tRenderer, VoidCallback onComplete);
void Renderer_renderRenderThread(TRenderer *tRenderer, TView *tView, VoidCallback onComplete);
void Renderer_renderStandaloneViewRenderThread(TRenderer *tRenderer, TView *tView, VoidCallback onComplete);
void Renderer_readPixelsRenderThread(
TRenderer *tRenderer,
TView *tView,
TRenderTarget *tRenderTarget,
@@ -78,29 +80,29 @@ namespace thermion
TPixelDataType tPixelDataType,
uint8_t *out,
size_t outLength,
void (*onComplete)());
VoidCallback onComplete);
EMSCRIPTEN_KEEPALIVE void Material_createInstanceRenderThread(TMaterial *tMaterial, void (*onComplete)(TMaterialInstance *));
EMSCRIPTEN_KEEPALIVE void Material_createImageMaterialRenderThread(TEngine *tEngine, void (*onComplete)(TMaterial *));
EMSCRIPTEN_KEEPALIVE void Material_createGizmoMaterialRenderThread(TEngine *tEngine, void (*onComplete)(TMaterial *));
void Material_createInstanceRenderThread(TMaterial *tMaterial, void (*onComplete)(TMaterialInstance *));
void Material_createImageMaterialRenderThread(TEngine *tEngine, void (*onComplete)(TMaterial *));
void Material_createGizmoMaterialRenderThread(TEngine *tEngine, void (*onComplete)(TMaterial *));
EMSCRIPTEN_KEEPALIVE void ColorGrading_createRenderThread(TEngine *tEngine, TToneMapping toneMapping, void (*callback)(TColorGrading *));
EMSCRIPTEN_KEEPALIVE void View_setColorGradingRenderThread(TView *tView, TColorGrading *tColorGrading, void (*callback)());
EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, bool enabled, double strength, void (*callback)());
EMSCRIPTEN_KEEPALIVE void View_setCameraRenderThread(TView *tView, TCamera *tCamera, void (*callback)());
void ColorGrading_createRenderThread(TEngine *tEngine, TToneMapping toneMapping, void (*callback)(TColorGrading *));
void View_setColorGradingRenderThread(TView *tView, TColorGrading *tColorGrading, VoidCallback onComplete);
void View_setBloomRenderThread(TView *tView, bool enabled, double strength, VoidCallback onComplete);
void View_setCameraRenderThread(TView *tView, TCamera *tCamera, VoidCallback onComplete);
FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback);
EMSCRIPTEN_KEEPALIVE void SceneAsset_destroyRenderThread(TSceneAsset *tSceneAsset, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
void SceneAsset_destroyRenderThread(TSceneAsset *tSceneAsset, VoidCallback onComplete);
void SceneAsset_createFromFilamentAssetRenderThread(
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TNameComponentManager *tNameComponentManager,
TFilamentAsset *tFilamentAsset,
void (*onComplete)(TSceneAsset *)
);
EMSCRIPTEN_KEEPALIVE void SceneAsset_createInstanceRenderThread(TSceneAsset *asset, TMaterialInstance **tMaterialInstances, int materialInstanceCount, void (*callback)(TSceneAsset *));
EMSCRIPTEN_KEEPALIVE void SceneAsset_createGeometryRenderThread(
void SceneAsset_createInstanceRenderThread(TSceneAsset *asset, TMaterialInstance **tMaterialInstances, int materialInstanceCount, void (*callback)(TSceneAsset *));
void SceneAsset_createGeometryRenderThread(
TEngine *tEngine,
float *vertices,
uint32_t numVertices,
@@ -115,14 +117,14 @@ namespace thermion
int materialInstanceCount,
void (*callback)(TSceneAsset *)
);
EMSCRIPTEN_KEEPALIVE void MaterialProvider_createMaterialInstanceRenderThread(TMaterialProvider *tMaterialProvider, TMaterialKey *tKey, void (*callback)(TMaterialInstance *));
void MaterialProvider_createMaterialInstanceRenderThread(TMaterialProvider *tMaterialProvider, TMaterialKey *tKey, void (*callback)(TMaterialInstance *));
EMSCRIPTEN_KEEPALIVE void AnimationManager_updateBoneMatricesRenderThread(
void AnimationManager_updateBoneMatricesRenderThread(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
void (*callback)(bool));
EMSCRIPTEN_KEEPALIVE void AnimationManager_setMorphTargetWeightsRenderThread(
void AnimationManager_setMorphTargetWeightsRenderThread(
TAnimationManager *tAnimationManager,
EntityId entityId,
const float *const morphData,
@@ -130,16 +132,16 @@ namespace thermion
void (*callback)(bool));
// Image methods
EMSCRIPTEN_KEEPALIVE void Image_createEmptyRenderThread(uint32_t width, uint32_t height, uint32_t channel, void (*onComplete)(TLinearImage *));
EMSCRIPTEN_KEEPALIVE void Image_decodeRenderThread(uint8_t* data, size_t length, const char* name, void (*onComplete)(TLinearImage *));
EMSCRIPTEN_KEEPALIVE void Image_getBytesRenderThread(TLinearImage *tLinearImage, void (*onComplete)(float *));
EMSCRIPTEN_KEEPALIVE void Image_destroyRenderThread(TLinearImage *tLinearImage, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Image_getWidthRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
EMSCRIPTEN_KEEPALIVE void Image_getHeightRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
EMSCRIPTEN_KEEPALIVE void Image_getChannelsRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
void Image_createEmptyRenderThread(uint32_t width, uint32_t height, uint32_t channel, void (*onComplete)(TLinearImage *));
void Image_decodeRenderThread(uint8_t* data, size_t length, const char* name, void (*onComplete)(TLinearImage *));
void Image_getBytesRenderThread(TLinearImage *tLinearImage, void (*onComplete)(float *));
void Image_destroyRenderThread(TLinearImage *tLinearImage, VoidCallback onComplete);
void Image_getWidthRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
void Image_getHeightRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
void Image_getChannelsRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
EMSCRIPTEN_KEEPALIVE void Texture_loadImageRenderThread(
void Texture_loadImageRenderThread(
TEngine *tEngine,
TTexture *tTexture,
TLinearImage *tImage,
@@ -147,7 +149,7 @@ namespace thermion
TPixelDataType pixelDataType,
void (*onComplete)(bool)
);
EMSCRIPTEN_KEEPALIVE void Texture_setImageRenderThread(
void Texture_setImageRenderThread(
TEngine *tEngine,
TTexture *tTexture,
uint32_t level,
@@ -160,7 +162,7 @@ namespace thermion
uint32_t pixelDataType,
void (*onComplete)(bool)
);
EMSCRIPTEN_KEEPALIVE void Texture_setImageWithDepthRenderThread(
void Texture_setImageWithDepthRenderThread(
TEngine *tEngine,
TTexture *tTexture,
uint32_t level,
@@ -177,8 +179,8 @@ namespace thermion
uint32_t pixelDataType,
void (*onComplete)(bool)
);
EMSCRIPTEN_KEEPALIVE void RenderTarget_getColorTextureRenderThread(TRenderTarget *tRenderTarget, void (*onComplete)(TTexture *));
EMSCRIPTEN_KEEPALIVE void RenderTarget_createRenderThread(
void RenderTarget_getColorTextureRenderThread(TRenderTarget *tRenderTarget, void (*onComplete)(TTexture *));
void RenderTarget_createRenderThread(
TEngine *tEngine,
uint32_t width,
uint32_t height,
@@ -186,16 +188,16 @@ namespace thermion
TTexture *depth,
void (*onComplete)(TRenderTarget *)
);
EMSCRIPTEN_KEEPALIVE void RenderTarget_destroyRenderThread(
void RenderTarget_destroyRenderThread(
TEngine *tEngine,
TRenderTarget *tRenderTarget,
void (*onComplete)()
VoidCallback onComplete
);
// TextureSampler methods
EMSCRIPTEN_KEEPALIVE void TextureSampler_createRenderThread(void (*onComplete)(TTextureSampler*));
EMSCRIPTEN_KEEPALIVE void TextureSampler_createWithFilteringRenderThread(
void TextureSampler_createRenderThread(void (*onComplete)(TTextureSampler*));
void TextureSampler_createWithFilteringRenderThread(
TSamplerMinFilter minFilter,
TSamplerMagFilter magFilter,
TSamplerWrapMode wrapS,
@@ -203,53 +205,53 @@ namespace thermion
TSamplerWrapMode wrapR,
void (*onComplete)(TTextureSampler*)
);
EMSCRIPTEN_KEEPALIVE void TextureSampler_createWithComparisonRenderThread(
void TextureSampler_createWithComparisonRenderThread(
TSamplerCompareMode compareMode,
TSamplerCompareFunc compareFunc,
void (*onComplete)(TTextureSampler*)
);
EMSCRIPTEN_KEEPALIVE void TextureSampler_setMinFilterRenderThread(
void TextureSampler_setMinFilterRenderThread(
TTextureSampler* sampler,
TSamplerMinFilter filter,
void (*onComplete)()
VoidCallback onComplete
);
EMSCRIPTEN_KEEPALIVE void TextureSampler_setMagFilterRenderThread(
void TextureSampler_setMagFilterRenderThread(
TTextureSampler* sampler,
TSamplerMagFilter filter,
void (*onComplete)()
VoidCallback onComplete
);
EMSCRIPTEN_KEEPALIVE void TextureSampler_setWrapModeSRenderThread(
void TextureSampler_setWrapModeSRenderThread(
TTextureSampler* sampler,
TSamplerWrapMode mode,
void (*onComplete)()
VoidCallback onComplete
);
EMSCRIPTEN_KEEPALIVE void TextureSampler_setWrapModeTRenderThread(
void TextureSampler_setWrapModeTRenderThread(
TTextureSampler* sampler,
TSamplerWrapMode mode,
void (*onComplete)()
VoidCallback onComplete
);
EMSCRIPTEN_KEEPALIVE void TextureSampler_setWrapModeRRenderThread(
void TextureSampler_setWrapModeRRenderThread(
TTextureSampler* sampler,
TSamplerWrapMode mode,
void (*onComplete)()
VoidCallback onComplete
);
EMSCRIPTEN_KEEPALIVE void TextureSampler_setAnisotropyRenderThread(
void TextureSampler_setAnisotropyRenderThread(
TTextureSampler* sampler,
double anisotropy,
void (*onComplete)()
VoidCallback onComplete
);
EMSCRIPTEN_KEEPALIVE void TextureSampler_setCompareModeRenderThread(
void TextureSampler_setCompareModeRenderThread(
TTextureSampler* sampler,
TSamplerCompareMode mode,
TTextureSamplerCompareFunc func,
void (*onComplete)()
VoidCallback onComplete
);
EMSCRIPTEN_KEEPALIVE void TextureSampler_destroyRenderThread(
void TextureSampler_destroyRenderThread(
TTextureSampler* sampler,
void (*onComplete)()
VoidCallback onComplete
);
EMSCRIPTEN_KEEPALIVE void AnimationManager_setBoneTransformRenderThread(
void AnimationManager_setBoneTransformRenderThread(
TAnimationManager *tAnimationManager,
EntityId asset,
int skinIndex,
@@ -257,18 +259,18 @@ namespace thermion
const float *const transform,
void (*callback)(bool));
EMSCRIPTEN_KEEPALIVE void AnimationManager_resetToRestPoseRenderThread(TAnimationManager *tAnimationManager, EntityId entityId, void (*callback)());
void AnimationManager_resetToRestPoseRenderThread(TAnimationManager *tAnimationManager, EntityId entityId, VoidCallback onComplete);
EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_createRenderThread(TEngine *tEngine, TMaterialProvider *tMaterialProvider, void (*callback)(TGltfAssetLoader *));
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_createRenderThread(TEngine *tEngine, const char* relativeResourcePath, void (*callback)(TGltfResourceLoader *));
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_destroyRenderThread(TEngine *tEngine, TGltfResourceLoader *tResourceLoader, void (*callback)());
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_loadResourcesRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_addResourceDataRenderThread(TGltfResourceLoader *tGltfResourceLoader, const char *uri, uint8_t *data, size_t length, void (*callback)());
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncBeginLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncUpdateLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader);
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_asyncGetLoadProgressRenderThread(TGltfResourceLoader *tGltfResourceLoader, void (*callback)(float));
void GltfAssetLoader_createRenderThread(TEngine *tEngine, TMaterialProvider *tMaterialProvider, void (*callback)(TGltfAssetLoader *));
void GltfResourceLoader_createRenderThread(TEngine *tEngine, const char* relativeResourcePath, void (*callback)(TGltfResourceLoader *));
void GltfResourceLoader_destroyRenderThread(TEngine *tEngine, TGltfResourceLoader *tResourceLoader, VoidCallback onComplete);
void GltfResourceLoader_loadResourcesRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
void GltfResourceLoader_addResourceDataRenderThread(TGltfResourceLoader *tGltfResourceLoader, const char *uri, uint8_t *data, size_t length, VoidCallback onComplete);
void GltfResourceLoader_asyncBeginLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader, TFilamentAsset *tFilamentAsset, void (*callback)(bool));
void GltfResourceLoader_asyncUpdateLoadRenderThread(TGltfResourceLoader *tGltfResourceLoader);
void GltfResourceLoader_asyncGetLoadProgressRenderThread(TGltfResourceLoader *tGltfResourceLoader, void (*callback)(float));
EMSCRIPTEN_KEEPALIVE void GltfAssetLoader_loadRenderThread(
void GltfAssetLoader_loadRenderThread(
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
uint8_t *data,
@@ -276,8 +278,8 @@ namespace thermion
uint8_t numInstances,
void (*callback)(TFilamentAsset *)
);
EMSCRIPTEN_KEEPALIVE void Scene_addFilamentAssetRenderThread(TScene* tScene, TFilamentAsset *tAsset, void (*callback)());
EMSCRIPTEN_KEEPALIVE void Gizmo_createRenderThread(
void Scene_addFilamentAssetRenderThread(TScene* tScene, TFilamentAsset *tAsset, VoidCallback onComplete);
void Gizmo_createRenderThread(
TEngine *tEngine,
TGltfAssetLoader *tAssetLoader,
TGltfResourceLoader *tGltfResourceLoader,
@@ -3,11 +3,15 @@
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern const uint8_t CAPTURE_UV_PACKAGE[];
extern int CAPTURE_UV_CAPTURE_UV_OFFSET;
extern int CAPTURE_UV_CAPTURE_UV_SIZE;
#ifdef __cplusplus
}
#endif
#define CAPTURE_UV_CAPTURE_UV_DATA (CAPTURE_UV_PACKAGE + CAPTURE_UV_CAPTURE_UV_OFFSET)
#endif
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -3,11 +3,15 @@
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern const uint8_t GRID_PACKAGE[];
extern int GRID_GRID_OFFSET;
extern int GRID_GRID_SIZE;
#ifdef __cplusplus
}
#endif
#define GRID_GRID_DATA (GRID_PACKAGE + GRID_GRID_OFFSET)
#endif
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -3,11 +3,15 @@
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern const uint8_t IMAGE_PACKAGE[];
extern int IMAGE_IMAGE_OFFSET;
extern int IMAGE_IMAGE_SIZE;
#ifdef __cplusplus
}
#endif
#define IMAGE_IMAGE_DATA (IMAGE_PACKAGE + IMAGE_IMAGE_OFFSET)
#endif
@@ -49,8 +49,8 @@ const uint8_t UNLIT_FIXED_SIZE_PACKAGE[] = {
0x4d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x43, 0x32, 0x41, 0x5f, 0x54, 0x41, 0x4d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
0x4d, 0x55, 0x43, 0x5f, 0x54, 0x41, 0x4d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4f, 0x52, 0x50, 0x5f, 0x54, 0x41, 0x4d,
0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x45, 0x54, 0x53, 0x5f, 0x54, 0x41, 0x4d,
0x01, 0x00, 0x00, 0x00, 0x01, 0x44, 0x49, 0x55, 0x55, 0x5f, 0x54, 0x41, 0x4d, 0x08, 0x00, 0x00, 0x00, 0x90, 0x9b, 0xc8,
0x3e, 0x15, 0x57, 0x3f, 0xd6, 0x44, 0x41, 0x48, 0x53, 0x5f, 0x54, 0x41, 0x4d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x4d,
0x01, 0x00, 0x00, 0x00, 0x01, 0x44, 0x49, 0x55, 0x55, 0x5f, 0x54, 0x41, 0x4d, 0x08, 0x00, 0x00, 0x00, 0xa3, 0xd7, 0xb6,
0x04, 0x28, 0x9a, 0x19, 0x19, 0x44, 0x41, 0x48, 0x53, 0x5f, 0x54, 0x41, 0x4d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x4d,
0x48, 0x53, 0x5f, 0x54, 0x41, 0x4d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x41, 0x4d, 0x01,
0x00, 0x00, 0x00, 0x00, 0x54, 0x46, 0x45, 0x52, 0x5f, 0x54, 0x41, 0x4d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52, 0x4f, 0x49,
0x43, 0x5f, 0x54, 0x41, 0x4d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x41, 0x51, 0x45, 0x52, 0x5f, 0x54, 0x41, 0x4d, 0x04, 0x00,
@@ -3,11 +3,15 @@
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern const uint8_t UNLIT_FIXED_SIZE_PACKAGE[];
extern int UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET;
extern int UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE;
#ifdef __cplusplus
}
#endif
#define UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_DATA (UNLIT_FIXED_SIZE_PACKAGE + UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET)
#endif
@@ -9,6 +9,12 @@
#include "RenderTicker.hpp"
#ifdef __EMSCRIPTEN__
#include <emscripten/threading.h>
#include <emscripten/proxying.h>
#include <emscripten/eventloop.h>
#endif
namespace thermion {
/**
@@ -34,7 +40,7 @@ public:
*
* @param callback Callback function to be called after rendering completes
*/
void requestFrame(void (*callback)());
void requestFrame();
/**
* @brief Sets the render ticker used.
@@ -52,15 +58,27 @@ public:
template <class Rt>
auto add_task(std::packaged_task<Rt()>& pt) -> std::future<Rt>;
private:
/**
* @brief Main iteration of the render loop.
*/
void iter();
void (*_requestFrameRenderCallback)() = nullptr;
/**
*
*/
bool _stop = false;
std::mutex _mutex;
#ifdef __EMSCRIPTEN__
emscripten::ProxyingQueue queue;
pthread_t outer;
#endif
bool mRendered = false;
private:
bool mRender = false;
std::mutex _taskMutex;
std::condition_variable _cv;
std::deque<std::function<void()>> _tasks;
@@ -68,19 +86,30 @@ private:
int _frameCount = 0;
float _accumulatedTime = 0.0f;
float _fps = 0.0f;
#ifdef __EMSCRIPTEN__
pthread_t t;
#else
std::thread* t = nullptr;
#endif
RenderTicker* mRenderTicker = nullptr;
};
// Template implementation
template <class Rt>
auto RenderThread::add_task(std::packaged_task<Rt()>& pt) -> std::future<Rt> {
std::unique_lock<std::mutex> lock(_taskMutex);
auto ret = pt.get_future();
_tasks.push_back([pt = std::make_shared<std::packaged_task<Rt()>>(
std::move(pt))]
{ (*pt)(); });
_cv.notify_one();
return ret;
}
@@ -3,11 +3,15 @@
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern const uint8_t ROTATION_GIZMO_GLB_PACKAGE[];
extern int ROTATION_GIZMO_GLB_ROTATION_GIZMO_OFFSET;
extern int ROTATION_GIZMO_GLB_ROTATION_GIZMO_SIZE;
#ifdef __cplusplus
}
#endif
#define ROTATION_GIZMO_GLB_ROTATION_GIZMO_DATA (ROTATION_GIZMO_GLB_PACKAGE + ROTATION_GIZMO_GLB_ROTATION_GIZMO_OFFSET)
#endif
@@ -3,11 +3,15 @@
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern const uint8_t TRANSLATION_GIZMO_GLB_PACKAGE[];
extern int TRANSLATION_GIZMO_GLB_TRANSLATION_GIZMO_OFFSET;
extern int TRANSLATION_GIZMO_GLB_TRANSLATION_GIZMO_SIZE;
#ifdef __cplusplus
}
#endif
#define TRANSLATION_GIZMO_GLB_TRANSLATION_GIZMO_DATA (TRANSLATION_GIZMO_GLB_PACKAGE + TRANSLATION_GIZMO_GLB_TRANSLATION_GIZMO_OFFSET)
#endif
@@ -46,8 +46,8 @@ import GLKit
print("Creating color texture")
let pixelFormat: MTLPixelFormat = isDepth ? .depth32Float : .bgra8Unorm
let cvPixelFormat = isDepth ? kCVPixelFormatType_DepthFloat32 : kCVPixelFormatType_32BGRA
// let pixelFormat: MTLPixelFormat = isDepth ? .depth32Float : .bgra8Unorm
// let cvPixelFormat = isDepth ? kCVPixelFormatType_DepthFloat32 : kCVPixelFormatType_32BGRA
if(CVPixelBufferCreate(kCFAllocatorDefault, Int(width), Int(height),
kCVPixelFormatType_32BGRA, pixelBufferAttrs, &pixelBuffer) != kCVReturnSuccess) {
+15 -7
View File
@@ -11,11 +11,8 @@
#include <utils/Panic.h>
#include <utils/Systrace.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#include <emscripten/html5.h>
#include <emscripten/threading.h>
#include <filament/webgl/WebEngine.h>
#include <sys/types.h>
#endif
#include <filament/Box.h>
#include <filament/Camera.h>
@@ -36,6 +33,8 @@
#include "RenderTicker.hpp"
#include <chrono>
namespace thermion
{
@@ -61,16 +60,18 @@ namespace thermion
} else {
mRenderable.emplace_back(swapChain, swapChainViews);
}
TRACE("Set %d views as renderable", numViews);
}
void RenderTicker::render(uint64_t frameTimeInNanos)
{
auto startTime = std::chrono::high_resolution_clock::now();
std::lock_guard lock(mMutex);
for (auto animationManager : mAnimationManagers) {
animationManager->update(frameTimeInNanos);
TRACE("Updated AnimationManager");
}
#ifdef ENABLE_TRACING
@@ -91,6 +92,8 @@ namespace thermion
{
mRenderer->render(view);
}
} else {
Log("Skipping frame");
}
mRenderer->endFrame();
#ifdef ENABLE_TRACING
@@ -103,9 +106,14 @@ namespace thermion
}
#endif
}
#ifdef __EMSCRIPTEN__
_engine->execute();
#endif
#ifdef __EMSCRIPTEN__
mEngine->execute();
#endif
auto endTime = std::chrono::high_resolution_clock::now();
auto durationNs = std::chrono::duration_cast<std::chrono::nanoseconds>(endTime - startTime).count();
float durationMs = durationNs / 1e6f;
TRACE("Total render() time: %.3f ms", durationMs);
}
void RenderTicker::addAnimationManager(AnimationManager* animationManager) {
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include "Log.hpp"
#include "c_api/APIExport.h"
+4 -1
View File
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <filament/Camera.h>
#include <filament/ColorGrading.h>
#include <filament/Engine.h>
@@ -13,7 +17,6 @@
#include "Log.hpp"
#include "MathUtils.hpp"
#ifdef __cplusplus
namespace thermion
{
+23 -7
View File
@@ -1,6 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#include <emscripten/html5.h>
#include "ThermionWebApi.h"
#include <backend/platforms/PlatformWebGL.h>
#endif
#include "c_api/TEngine.h"
@@ -58,6 +59,11 @@ namespace thermion
uint8_t stereoscopicEyeCount,
bool disableHandleUseAfterFreeCheck)
{
#ifdef __EMSCRIPTEN__
auto handle = Thermion_createGLContext();
tSharedContext = (void*)handle;
tPlatform = (backend::Platform *)new filament::backend::PlatformWebGL();
#endif
filament::Engine::Config config;
config.stereoscopicEyeCount = stereoscopicEyeCount;
config.disableHandleUseAfterFreeCheck = disableHandleUseAfterFreeCheck;
@@ -263,12 +269,22 @@ namespace thermion
EMSCRIPTEN_KEEPALIVE void Engine_flushAndWait(TEngine *tEngine)
{
auto *engine = reinterpret_cast<Engine *>(tEngine);
#ifdef __EMSCRIPTEN__
engine->execute();
emscripten_webgl_commit_frame();
#else
engine->flushAndWait();
#endif
engine->flushAndWait();
}
EMSCRIPTEN_KEEPALIVE void Engine_execute(TEngine *tEngine) {
#ifdef __EMSCRIPTEN__
// auto startTime = std::chrono::high_resolution_clock::now();
auto *engine = reinterpret_cast<Engine *>(tEngine);
engine->execute();
// auto endTime = std::chrono::high_resolution_clock::now();
// auto durationNs = std::chrono::duration_cast<std::chrono::nanoseconds>(endTime - startTime).count();
// float durationMs = durationNs / 1e6f;
// Log("Total Engine_execute() time: %.3f ms", durationMs);
#else
Log("WARNING - ignored on non-WASM");
#endif
}
EMSCRIPTEN_KEEPALIVE TScene *Engine_createScene(TEngine *tEngine)
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <gltfio/FilamentAsset.h>
#include "c_api/TSceneAsset.h"
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <filament/View.h>
#include <filament/Engine.h>
#include <filament/Scene.h>
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include "c_api/TGltfAssetLoader.h"
#include <filament/Engine.h>
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include "c_api/TGltfResourceLoader.h"
#include <filament/Engine.h>
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include "c_api/TScene.h"
#include <filament/Engine.h>
@@ -1,3 +1,6 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <filament/LightManager.h>
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <vector>
#include <filament/MaterialInstance.h>
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <filament/MaterialInstance.h>
#include <gltfio/MaterialProvider.h>
#include <math/mat4.h>
@@ -1,5 +1,10 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <utils/NameComponentManager.h>
#include "Log.hpp"
#include "c_api/APIExport.h"
#include "c_api/APIBoundaryTypes.h"
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include "c_api/TScene.h"
#include <filament/Engine.h>
@@ -2,7 +2,7 @@
#include "ThermionWin32.h"
#endif
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#include <emscripten.h>
#endif
#include <thread>
@@ -19,9 +19,10 @@ extern "C"
{
#include "c_api/TRenderTicker.h"
EMSCRIPTEN_KEEPALIVE TRenderTicker *RenderTicker_create(TRenderer *tRenderer) {
EMSCRIPTEN_KEEPALIVE TRenderTicker *RenderTicker_create(TEngine *tEngine, TRenderer *tRenderer) {
auto engine = reinterpret_cast<filament::Engine *>(tEngine);
auto *renderer = reinterpret_cast<filament::Renderer *>(tRenderer);
auto *renderTicker = new RenderTicker(renderer);
auto *renderTicker = new RenderTicker(engine, renderer);
return reinterpret_cast<TRenderTicker *>(renderTicker);
}
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <filament/MaterialInstance.h>
#include <filament/RenderableManager.h>
#include <utils/Entity.h>
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#ifdef _WIN32
#include "ThermionWin32.h"
#endif
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include "c_api/TScene.h"
#include <filament/Engine.h>
@@ -1,3 +1,6 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <gltfio/AssetLoader.h>
#include <gltfio/ResourceLoader.h>
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <sstream>
#include <vector>
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <utils/Entity.h>
#include <filament/TransformManager.h>
#include <filament/math/mat4.h>
+4
View File
@@ -1,3 +1,7 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include <filament/View.h>
#include <filament/Viewport.h>
#include <filament/Engine.h>
@@ -23,10 +23,43 @@
#include "rendering/RenderThread.hpp"
#include "Log.hpp"
#ifdef __EMSCRIPTEN__
#include <emscripten/proxying.h>
#include <emscripten/eventloop.h>
#include <emscripten/console.h>
#endif
using namespace thermion;
using namespace std::chrono_literals;
#include <time.h>
#include <cinttypes>
//auto innerStartTime = std::chrono::high_resolution_clock::now();\
//Log("inner proxy start time time: % " PRId64 "ms", std::chrono::duration_cast<std::chrono::milliseconds>(innerStartTime.time_since_epoch()).count());\
//auto endTime = std::chrono::high_resolution_clock::now(); \
//auto durationNs = std::chrono::duration_cast<std::chrono::nanoseconds>(endTime - startTime).count();\
//float durationMs = durationNs / 1e6f;\
//Log("proxySync time: %.3f ms", durationMs);\
//startTime = std::chrono::high_resolution_clock::now(); \
//_renderThread->queue.execute(); \
//endTime = std::chrono::high_resolution_clock::now(); \
//durationNs = std::chrono::duration_cast<std::chrono::nanoseconds>(endTime - startTime).count();\
//durationMs = durationNs / 1e6f;\
//TRACE("queue execute time: %.3f ms", durationMs);
//auto innerEndTime = std::chrono::high_resolution_clock::now(); \
//auto innerDurationNs = std::chrono::duration_cast<std::chrono::nanoseconds>(innerEndTime - innerStartTime).count();\
//float innerDurationMs = innerDurationNs / 1e6f;\
//Log("inner proxy fn time: %.3f ms", innerDurationMs);\
#if defined __EMSCRIPTEN__
#define PROXY(call) \
auto startTime = std::chrono::high_resolution_clock::now(); \
TRACE("PROXYING"); \
_renderThread->queue.proxySync(_renderThread->outer, [=]() { \
call; \
});
#else
#define PROXY(call) call
#endif
extern "C"
{
@@ -39,6 +72,7 @@ extern "C"
Log("WARNING - you are attempting to create a RenderThread when the previous one has not been disposed.");
}
_renderThread = std::make_unique<RenderThread>();
TRACE("RenderThread created");
}
EMSCRIPTEN_KEEPALIVE void RenderThread_destroy() {
@@ -63,17 +97,16 @@ extern "C"
_renderThread->setRenderTicker(renderTicker);
}
EMSCRIPTEN_KEEPALIVE void RenderThread_requestFrame(void (*onComplete)()) {
_renderThread->requestFrame(onComplete);
EMSCRIPTEN_KEEPALIVE void RenderThread_requestFrameAsync() {
_renderThread->requestFrame();
}
EMSCRIPTEN_KEEPALIVE void RenderTicker_renderRenderThread(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void RenderTicker_renderRenderThread(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
RenderTicker_render(tRenderTicker, frameTimeInNanos);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -84,22 +117,24 @@ extern "C"
void* sharedContext,
uint8_t stereoscopicEyeCount,
bool disableHandleUseAfterFreeCheck,
void (*onComplete)(TEngine *)) {
void (*onComplete)(TEngine *)) {
std::packaged_task<void()> lambda(
[=]() mutable
{
auto engine = Engine_create(backend, platform, sharedContext, stereoscopicEyeCount, disableHandleUseAfterFreeCheck);
onComplete(engine);
auto *engine = Engine_create(backend, platform, sharedContext, stereoscopicEyeCount, disableHandleUseAfterFreeCheck);
PROXY(onComplete(engine));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_createRendererRenderThread(TEngine *tEngine, void (*onComplete)(TRenderer *)) {
std::packaged_task<void()> lambda(
[=]() mutable
{
auto renderer = Engine_createRenderer(tEngine);
onComplete(renderer);
auto *renderer = Engine_createRenderer(tEngine);
PROXY(onComplete(renderer));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -109,7 +144,7 @@ extern "C"
[=]() mutable
{
auto swapChain = Engine_createSwapChain(tEngine, window, flags);
onComplete(swapChain);
PROXY(onComplete(swapChain));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -119,37 +154,37 @@ extern "C"
[=]() mutable
{
auto swapChain = Engine_createHeadlessSwapChain(tEngine, width, height, flags);
onComplete(swapChain);
PROXY(onComplete(swapChain));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_destroySwapChainRenderThread(TEngine *tEngine, TSwapChain *tSwapChain, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void Engine_destroySwapChainRenderThread(TEngine *tEngine, TSwapChain *tSwapChain, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Engine_destroySwapChain(tEngine, tSwapChain);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_destroyViewRenderThread(TEngine *tEngine, TView *tView, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void Engine_destroyViewRenderThread(TEngine *tEngine, TView *tView, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Engine_destroyView(tEngine, tView);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_destroySceneRenderThread(TEngine *tEngine, TScene *tScene, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void Engine_destroySceneRenderThread(TEngine *tEngine, TScene *tScene, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Engine_destroyScene(tEngine, tScene);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -159,7 +194,7 @@ extern "C"
[=]() mutable
{
auto camera = Engine_createCamera(tEngine);
onComplete(camera);
PROXY(onComplete(camera));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -169,48 +204,48 @@ extern "C"
[=]() mutable
{
auto * view = Engine_createView(tEngine);
onComplete(view);
PROXY(onComplete(view));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_destroyRenderThread(TEngine *tEngine, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void Engine_destroyRenderThread(TEngine *tEngine, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Engine_destroy(tEngine);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_destroyTextureRenderThread(TEngine *engine, TTexture *tTexture, void (*onComplete)())
EMSCRIPTEN_KEEPALIVE void Engine_destroyTextureRenderThread(TEngine *engine, TTexture *tTexture, VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]() mutable
{
Engine_destroyTexture(engine, tTexture);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_destroySkyboxRenderThread(TEngine *tEngine, TSkybox *tSkybox, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void Engine_destroySkyboxRenderThread(TEngine *tEngine, TSkybox *tSkybox, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Engine_destroySkybox(tEngine, tSkybox);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_destroyIndirectLightRenderThread(TEngine *tEngine, TIndirectLight *tIndirectLight, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void Engine_destroyIndirectLightRenderThread(TEngine *tEngine, TIndirectLight *tIndirectLight, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Engine_destroyIndirectLight(tEngine, tIndirectLight);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -221,29 +256,29 @@ extern "C"
[=]() mutable
{
auto material = Engine_buildMaterial(tEngine, materialData, length);
onComplete(material);
PROXY(onComplete(material));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, void (*onComplete)())
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]() mutable
{
Engine_destroyMaterial(tEngine, tMaterial);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialInstanceRenderThread(TEngine *tEngine, TMaterialInstance *tMaterialInstance, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialInstanceRenderThread(TEngine *tEngine, TMaterialInstance *tMaterialInstance, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Engine_destroyMaterialInstance(tEngine, tMaterialInstance);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -253,37 +288,57 @@ extern "C"
[=]() mutable
{
auto *fence = Engine_createFence(tEngine);
onComplete(fence);
PROXY(onComplete(fence));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_destroyFenceRenderThread(TEngine *tEngine, TFence *tFence, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void Engine_destroyFenceRenderThread(TEngine *tEngine, TFence *tFence, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Engine_destroyFence(tEngine, tFence);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_flushAndWaitRenderThead(TEngine *tEngine, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void Engine_flushAndWaitRenderThread(TEngine *tEngine, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Engine_flushAndWait(tEngine);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_executeRenderThread(TEngine *tEngine, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
// auto executeStartTime = std::chrono::high_resolution_clock::now();
// Log("started Engine_execute at : % " PRId64 "ms", std::chrono::duration_cast<std::chrono::milliseconds>(executeStartTime.time_since_epoch()).count());
// / _renderThread->queue.execute();
Engine_execute(tEngine);
// PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
onComplete();
}
EMSCRIPTEN_KEEPALIVE void execute_queue() {
#ifdef __EMSCRIPTEN__
_renderThread->queue.execute();
#endif
}
EMSCRIPTEN_KEEPALIVE void Engine_buildSkyboxRenderThread(TEngine *tEngine, uint8_t *skyboxData, size_t length, void (*onComplete)(TSkybox *), void (*onTextureUploadComplete)()) {
std::packaged_task<void()> lambda(
[=]() mutable
{
auto *skybox = Engine_buildSkybox(tEngine, skyboxData, length, onTextureUploadComplete);
onComplete(skybox);
PROXY(onComplete(skybox));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -293,7 +348,7 @@ extern "C"
[=]() mutable
{
auto *indirectLight = Engine_buildIndirectLight(tEngine, iblData, length, intensity, onTextureUploadComplete);
onComplete(indirectLight);
PROXY(onComplete(indirectLight));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -303,36 +358,36 @@ extern "C"
[=]() mutable
{
auto result = Renderer_beginFrame(tRenderer, tSwapChain, frameTimeInNanos);
onComplete(result);
PROXY(onComplete(result));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Renderer_endFrameRenderThread(TRenderer *tRenderer, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void Renderer_endFrameRenderThread(TRenderer *tRenderer, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Renderer_endFrame(tRenderer);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Renderer_renderRenderThread(TRenderer *tRenderer, TView *tView, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void Renderer_renderRenderThread(TRenderer *tRenderer, TView *tView, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Renderer_render(tRenderer, tView);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Renderer_renderStandaloneViewRenderThread(TRenderer *tRenderer, TView *tView, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void Renderer_renderStandaloneViewRenderThread(TRenderer *tRenderer, TView *tView, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Renderer_renderStandaloneView(tRenderer, tView);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -345,12 +400,12 @@ extern "C"
double clearA,
uint8_t clearStencil,
bool clear,
bool discard, void (*onComplete)()) {
bool discard, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Renderer_setClearOptions(tRenderer, clearR, clearG, clearB, clearA, clearStencil, clear, discard);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -363,12 +418,12 @@ extern "C"
TPixelDataType tPixelDataType,
uint8_t *out,
size_t outLength,
void (*onComplete)()) {
VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Renderer_readPixels(tRenderer, tView, tRenderTarget, tPixelBufferFormat, tPixelDataType, out, outLength);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -378,7 +433,7 @@ extern "C"
[=]() mutable
{
auto *instance = Material_createImageMaterial(tEngine);
onComplete(instance);
PROXY(onComplete(instance));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -388,7 +443,7 @@ extern "C"
[=]() mutable
{
auto *instance = Material_createGizmoMaterial(tEngine);
onComplete(instance);
PROXY(onComplete(instance));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -400,17 +455,17 @@ extern "C"
[=]() mutable
{
auto *instance = Material_createInstance(tMaterial);
onComplete(instance);
PROXY(onComplete(instance));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void SceneAsset_destroyRenderThread(TSceneAsset *tSceneAsset, void (*onComplete)()) {
EMSCRIPTEN_KEEPALIVE void SceneAsset_destroyRenderThread(TSceneAsset *tSceneAsset, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
SceneAsset_destroy(tSceneAsset);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -435,7 +490,7 @@ extern "C"
[=]
{
auto sceneAsset = SceneAsset_createGeometry(tEngine, vertices, numVertices, normals, numNormals, uvs, numUvs, indices, numIndices, tPrimitiveType, materialInstances, materialInstanceCount);
callback(sceneAsset);
PROXY(callback(sceneAsset));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -451,7 +506,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]
{
auto sceneAsset = SceneAsset_createFromFilamentAsset(tEngine, tAssetLoader, tNameComponentManager, tFilamentAsset);
onComplete(sceneAsset);
PROXY(onComplete(sceneAsset));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -465,7 +520,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]
{
auto instanceAsset = SceneAsset_createInstance(asset, tMaterialInstances, materialInstanceCount);
callback(instanceAsset);
PROXY(callback(instanceAsset));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -476,7 +531,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]
{
auto materialInstance = MaterialProvider_createMaterialInstance(tMaterialProvider, tKey);
callback(materialInstance);
PROXY(callback(materialInstance));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -487,51 +542,51 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]
{
auto cg = ColorGrading_create(tEngine, toneMapping);
callback(cg);
PROXY(callback(cg));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Engine_destroyColorGradingRenderThread(TEngine *tEngine, TColorGrading *tColorGrading, void (*callback)())
EMSCRIPTEN_KEEPALIVE void Engine_destroyColorGradingRenderThread(TEngine *tEngine, TColorGrading *tColorGrading, VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]
{
Engine_destroyColorGrading(tEngine, tColorGrading);
callback();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void View_setColorGradingRenderThread(TView *tView, TColorGrading *tColorGrading, void (*callback)())
EMSCRIPTEN_KEEPALIVE void View_setColorGradingRenderThread(TView *tView, TColorGrading *tColorGrading, VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]
{
View_setColorGrading(tView, tColorGrading);
callback();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, bool enabled, double strength, void (*callback)())
EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, bool enabled, double strength, VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]
{
View_setBloom(tView, enabled, strength);
callback();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void View_setCameraRenderThread(TView *tView, TCamera *tCamera, void (*callback)())
EMSCRIPTEN_KEEPALIVE void View_setCameraRenderThread(TView *tView, TCamera *tCamera, VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]
{
View_setCamera(tView, tCamera);
callback();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -541,7 +596,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto *animationManager = AnimationManager_create(tEngine, tScene);
onComplete(animationManager);
PROXY(onComplete(animationManager));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -555,7 +610,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
bool result = AnimationManager_updateBoneMatrices(tAnimationManager, sceneAsset);
callback(result);
PROXY(callback(result));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -571,7 +626,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
bool result = AnimationManager_setMorphTargetWeights(tAnimationManager, entityId, morphData, numWeights);
callback(result);
PROXY(callback(result));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -585,7 +640,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto image = Image_createEmpty(width, height, channel);
onComplete(image);
PROXY(onComplete(image));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -596,7 +651,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto image = Image_decode(data, length, name);
onComplete(image);
PROXY(onComplete(image));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -607,18 +662,18 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto bytes = Image_getBytes(tLinearImage);
onComplete(bytes);
PROXY(onComplete(bytes));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Image_destroyRenderThread(TLinearImage *tLinearImage, void (*onComplete)())
EMSCRIPTEN_KEEPALIVE void Image_destroyRenderThread(TLinearImage *tLinearImage, VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]() mutable
{
Image_destroy(tLinearImage);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -629,7 +684,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto width = Image_getWidth(tLinearImage);
onComplete(width);
PROXY(onComplete(width));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -640,7 +695,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto height = Image_getHeight(tLinearImage);
onComplete(height);
PROXY(onComplete(height));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -651,7 +706,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto channels = Image_getChannels(tLinearImage);
onComplete(channels);
PROXY(onComplete(channels));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -670,7 +725,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto *texture = Texture_build(tEngine, width, height, depth, levels, tUsage, import, sampler, format);
onComplete(texture);
PROXY(onComplete(texture));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -684,7 +739,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
bool result = Texture_loadImage(tEngine, tTexture, tImage, bufferFormat, pixelDataType);
onComplete(result);
PROXY(onComplete(result));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -707,7 +762,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
{
bool result = Texture_setImage(tEngine, tTexture, level, data, size, width, height, channels,
bufferFormat, pixelDataType);
onComplete(result);
PROXY(onComplete(result));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -748,7 +803,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
bufferFormat,
pixelDataType
);
onComplete(result);
PROXY(onComplete(result));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -759,7 +814,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto texture = RenderTarget_getColorTexture(tRenderTarget);
onComplete(texture);
PROXY(onComplete(texture));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -779,7 +834,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto texture = RenderTarget_create(tEngine, width, height, tColor, tDepth);
onComplete(texture);
PROXY(onComplete(texture));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -787,13 +842,13 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
EMSCRIPTEN_KEEPALIVE void RenderTarget_destroyRenderThread(
TEngine *tEngine,
TRenderTarget *tRenderTarget,
void (*onComplete)()
VoidCallback onComplete
) {
std::packaged_task<void()> lambda(
[=]() mutable
{
RenderTarget_destroy(tEngine, tRenderTarget);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -805,7 +860,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto sampler = TextureSampler_create();
onComplete(sampler);
PROXY(onComplete(sampler));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -822,7 +877,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto sampler = TextureSampler_createWithFiltering(minFilter, magFilter, wrapS, wrapT, wrapR);
onComplete(sampler);
PROXY(onComplete(sampler));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -836,7 +891,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto sampler = TextureSampler_createWithComparison(compareMode, compareFunc);
onComplete(sampler);
PROXY(onComplete(sampler));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -844,13 +899,13 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
EMSCRIPTEN_KEEPALIVE void TextureSampler_setMinFilterRenderThread(
TTextureSampler *sampler,
TSamplerMinFilter filter,
void (*onComplete)())
VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]() mutable
{
TextureSampler_setMinFilter(sampler, filter);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -858,13 +913,13 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
EMSCRIPTEN_KEEPALIVE void TextureSampler_setMagFilterRenderThread(
TTextureSampler *sampler,
TSamplerMagFilter filter,
void (*onComplete)())
VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]() mutable
{
TextureSampler_setMagFilter(sampler, filter);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -872,13 +927,13 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
EMSCRIPTEN_KEEPALIVE void TextureSampler_setWrapModeSRenderThread(
TTextureSampler *sampler,
TSamplerWrapMode mode,
void (*onComplete)())
VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]() mutable
{
TextureSampler_setWrapModeS(sampler, mode);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -886,13 +941,13 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
EMSCRIPTEN_KEEPALIVE void TextureSampler_setWrapModeTRenderThread(
TTextureSampler *sampler,
TSamplerWrapMode mode,
void (*onComplete)())
VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]() mutable
{
TextureSampler_setWrapModeT(sampler, mode);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -900,13 +955,13 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
EMSCRIPTEN_KEEPALIVE void TextureSampler_setWrapModeRRenderThread(
TTextureSampler *sampler,
TSamplerWrapMode mode,
void (*onComplete)())
VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]() mutable
{
TextureSampler_setWrapModeR(sampler, mode);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -914,13 +969,13 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
EMSCRIPTEN_KEEPALIVE void TextureSampler_setAnisotropyRenderThread(
TTextureSampler *sampler,
double anisotropy,
void (*onComplete)())
VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]() mutable
{
TextureSampler_setAnisotropy(sampler, anisotropy);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -929,26 +984,26 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
TTextureSampler *sampler,
TSamplerCompareMode mode,
TTextureSamplerCompareFunc func,
void (*onComplete)())
VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]() mutable
{
TextureSampler_setCompareMode(sampler, mode, func);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void TextureSampler_destroyRenderThread(
TTextureSampler *sampler,
void (*onComplete)())
VoidCallback onComplete)
{
std::packaged_task<void()> lambda(
[=]() mutable
{
TextureSampler_destroy(sampler);
onComplete();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -958,7 +1013,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto loader = GltfAssetLoader_create(tEngine, tMaterialProvider);
callback(loader);
PROXY(callback(loader));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -968,17 +1023,17 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto loader = GltfResourceLoader_create(tEngine, relativeResourcePath);
callback(loader);
PROXY(callback(loader));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_destroyRenderThread(TEngine *tEngine, TGltfResourceLoader *tResourceLoader, void (*callback)()) {
EMSCRIPTEN_KEEPALIVE void GltfResourceLoader_destroyRenderThread(TEngine *tEngine, TGltfResourceLoader *tResourceLoader, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
GltfResourceLoader_destroy(tEngine, tResourceLoader);
callback();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -988,7 +1043,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto result = GltfResourceLoader_loadResources(tGltfResourceLoader, tFilamentAsset);
callback(result);
PROXY(callback(result));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -998,12 +1053,12 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
const char *uri,
uint8_t *data,
size_t length,
void (*callback)()) {
VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
GltfResourceLoader_addResourceData(tGltfResourceLoader, uri, data, length);
callback();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -1016,7 +1071,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto result = GltfResourceLoader_asyncBeginLoad(tGltfResourceLoader, tFilamentAsset);
callback(result);
PROXY(callback(result));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -1038,7 +1093,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto result = GltfResourceLoader_asyncGetLoadProgress(tGltfResourceLoader);
callback(result);
PROXY(callback(result));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -1055,17 +1110,17 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto loader = GltfAssetLoader_load(tEngine, tAssetLoader, data, length, numInstances);
callback(loader);
PROXY(callback(loader));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Scene_addFilamentAssetRenderThread(TScene* tScene, TFilamentAsset *tAsset, void (*callback)()) {
EMSCRIPTEN_KEEPALIVE void Scene_addFilamentAssetRenderThread(TScene* tScene, TFilamentAsset *tAsset, VoidCallback onComplete) {
std::packaged_task<void()> lambda(
[=]() mutable
{
Scene_addFilamentAsset(tScene, tAsset);
callback();
PROXY(onComplete());
});
auto fut = _renderThread->add_task(lambda);
}
@@ -1084,7 +1139,7 @@ EMSCRIPTEN_KEEPALIVE void SceneAsset_createFromFilamentAssetRenderThread(
[=]() mutable
{
auto *gizmo = Gizmo_create(tEngine, tAssetLoader,tGltfResourceLoader, tNameComponentManager, tView, tMaterial, tGizmoType);
callback(gizmo);
PROXY(callback(gizmo));
});
auto fut = _renderThread->add_task(lambda);
}
@@ -3,21 +3,79 @@
#include <functional>
#include <stdlib.h>
#include <time.h>
#include <chrono>
#include "Log.hpp"
namespace thermion {
#ifdef __EMSCRIPTEN__
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glext.h>
#include <emscripten/html5.h>
#include <emscripten/threading.h>
#include <emscripten/proxying.h>
#include <emscripten/eventloop.h>
#include "ThermionWebApi.h"
std::chrono::high_resolution_clock::time_point loopStart;
static void mainLoop(void* arg) {
auto *rt = static_cast<RenderThread *>(arg);
auto startTime = std::chrono::high_resolution_clock::now();
auto timeSinceLastLoopStart = std::chrono::duration_cast<std::chrono::milliseconds>(startTime - loopStart).count();
if(timeSinceLastLoopStart > 20) {
Log("%dms elapsed since last loop", timeSinceLastLoopStart);
}
loopStart = startTime;
rt->mRendered = false;
long long elapsed = 0;
int numIters = 0;
while (!rt->_stop && elapsed < 10) {
rt->iter();
numIters++;
auto now = std::chrono::high_resolution_clock::now();
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - startTime).count();
}
// Log("Spent %lldms processing, %d iters", elapsed, numIters);
if(rt->_stop) {
Log("RenderThread stopped")
}
}
static void *startHelper(void * parm) {
loopStart = std::chrono::high_resolution_clock::now();
emscripten_set_main_loop_arg(&mainLoop, parm, 0, true);
return nullptr;
}
#endif
RenderThread::RenderThread()
{
srand(time(NULL));
#ifdef __EMSCRIPTEN__
outer = pthread_self();
pthread_attr_t attr;
pthread_attr_init(&attr);
emscripten_pthread_attr_settransferredcanvases(&attr, "#thermion_canvas");
pthread_create(&t, &attr, startHelper, this);
#else
t = new std::thread([this]() {
while (!_stop) {
iter();
mRendered = false;
}
});
#endif
}
RenderThread::~RenderThread()
{
Log("Destroying RenderThread (%d tasks remaining)", _tasks.size());
@@ -31,48 +89,52 @@ RenderThread::~RenderThread()
_tasks.pop_front();
task();
}
#ifdef __EMSCRIPTEN__
pthread_join(t, NULL);
#else
t->join();
delete t;
#endif
TRACE("RenderThread destructor complete");
}
void RenderThread::requestFrame(void (*callback)())
void RenderThread::requestFrame()
{
TRACE("Request frame");
std::unique_lock<std::mutex> lock(_mutex);
this->_requestFrameRenderCallback = callback;
if(mRendered) {
return;
}
if(mRender) {
Log("Warning - frame requested before previous frame has completed rendering");
}
mRender = true;
_cv.notify_one();
}
void RenderThread::iter()
{
if (mRender && !mRendered)
{
std::unique_lock<std::mutex> lock(_mutex);
if (_requestFrameRenderCallback)
mRenderTicker->render(0);
mRender = false;
mRendered = true;
// Calculate and print FPS
auto currentTime = std::chrono::high_resolution_clock::now();
float deltaTime = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - _lastFrameTime).count();
_lastFrameTime = currentTime;
_frameCount++;
_accumulatedTime += deltaTime;
if (_accumulatedTime >= 1.0f) // Update FPS every second
{
mRenderTicker->render(0);
lock.unlock();
this->_requestFrameRenderCallback();
this->_requestFrameRenderCallback = nullptr;
// Calculate and print FPS
auto currentTime = std::chrono::high_resolution_clock::now();
float deltaTime = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - _lastFrameTime).count();
_lastFrameTime = currentTime;
_frameCount++;
_accumulatedTime += deltaTime;
if (_accumulatedTime >= 1.0f) // Update FPS every second
{
_fps = _frameCount / _accumulatedTime;
_frameCount = 0;
_accumulatedTime = 0.0f;
}
_fps = _frameCount / _accumulatedTime;
_frameCount = 0;
_accumulatedTime = 0.0f;
}
}
std::unique_lock<std::mutex> taskLock(_taskMutex);
if (!_tasks.empty())
@@ -83,11 +145,12 @@ void RenderThread::iter()
task();
taskLock.lock();
}
#ifndef __EMSCRIPTEN__
_cv.wait_for(taskLock, std::chrono::microseconds(2000), [this]
{ return !_tasks.empty() || _stop; });
#endif
}
} // namespace thermion
} // namespace thermion
+53 -45
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.27)
cmake_minimum_required(VERSION 3.22)
set(PROJECT_NAME "thermion_dart")
project(${PROJECT_NAME})
@@ -11,64 +11,79 @@ set(MODULE_NAME "thermion_dart")
set(EMCC_CFLAGS --bind)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sALLOW_TABLE_GROWTH=1)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sALLOW_MEMORY_GROWTH=1)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sALLOW_MEMORY_GROWTH=0)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORT_NAME=${MODULE_NAME})
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORT_ALL=1)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sLINKABLE=1)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sSIDE_MODULE)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sINITIAL_MEMORY=512mb)
#set(EMCC_CFLAGS ${EMCC_CFLAGS} -sENVIRONMENT=shell,node,web)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sENVIRONMENT=worker)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sMODULARIZE)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sERROR_ON_UNDEFINED_SYMBOLS=0 )
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORTED_RUNTIME_METHODS=wasmExports,wasmTable,addFunction,removeFunction,ccall,cwrap,allocate,intArrayFromString,intArrayToString,getValue,setValue,UTF8ToString,stringToUTF8,writeArrayToMemory)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORTED_FUNCTIONS=_malloc,stackAlloc,_free)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORTED_RUNTIME_METHODS=wasmExports,wasmTable,addFunction,removeFunction,ccall,cwrap,allocate,intArrayFromString,intArrayToString,getValue,setValue,UTF8ToString,stringToUTF8,writeArrayToMemory,lengthBytesUTF8,HEAPU8)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORTED_FUNCTIONS=_malloc,stackAlloc,_free,stackSave,stackRestore)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sFULL_ES3)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sASSERTIONS)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sPTHREAD_POOL_SIZE=1)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sALLOW_BLOCKING_ON_MAIN_THREAD=0)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sOFFSCREEN_FRAMEBUFFER=1)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sOFFSCREENCANVAS_SUPPORT=1)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
#add_compile_definitions(ENABLE_TRACING=1)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sASSERTIONS=2)
endif()
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sPTHREAD_POOL_SIZE=1)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sALLOW_BLOCKING_ON_MAIN_THREAD=1)
#set(EMCC_CFLAGS ${EMCC_CFLAGS} -sOFFSCREEN_FRAMEBUFFER=1)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sOFFSCREENCANVAS_SUPPORT=1)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sNO_DISABLE_EXCEPTION_CATCHING)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sASYNCIFY=1)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sSAFE_HEAP=1)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sASYNCIFY=0)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sMIN_WEBGL_VERSION=2)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sMAX_WEBGL_VERSION=2)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sFETCH=1)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sUSE_PTHREADS)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sFETCH=0)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sUSE_PTHREADS)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sGL_ASSERTIONS=1)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sGL_DEBUG=1)
endif()
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sPROXY_TO_PTHREAD)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sPROXY_TO_WORKER=1)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sSHARED_MEMORY=0)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -lidbfs.js)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sSHARED_MEMORY=1)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -lidbfs.js)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sFORCE_FILESYSTEM=1)
set(EMCC_CFLAGS ${EMCC_CFLAGS} -matomics -mbulk-memory)
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -pie)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers -Wno-deprecated-literal-operator -stdlib=libc++ -std=c++17 -fPIC --no-entry")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pie")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers -Wno-deprecated-literal-operator -stdlib=libc++ -std=c++17 -fPIC -O3 --no-entry ")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -pie")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O1") #-fsanitize=undefined
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O1")
endif()
add_link_options(${EMCC_CFLAGS})
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O1") #-fsanitize=undefined
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O1")
endif()
add_link_options(${EMCC_CFLAGS} -pthread -lGL)
link_directories("${CMAKE_CURRENT_SOURCE_DIR}/lib")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build/out)
add_executable(${MODULE_NAME}
"${CMAKE_CURRENT_SOURCE_DIR}/../src/SceneManager.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/FilamentViewer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/ThermionDartApi.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/ThermionDartFFIApi.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/Gizmo.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/GridOverlay.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/StreamBufferAdapter.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/TimeIt.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/camutils/Manipulator.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/camutils/Bookmark.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../include/material/image.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../include/material/unlit_fixed_size.c"
"${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/ThermionDartWebApi.cpp"
)
file(GLOB SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/../src/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../src/**/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/../include/resources/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../include/material/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/ThermionWebApi.cpp"
# "${CMAKE_CURRENT_SOURCE_DIR}/../src/rendering/EmscriptenTest.cpp"
)
add_executable(${MODULE_NAME} ${SOURCES})
set_target_properties(${MODULE_NAME} PROPERTIES
CXX_VISIBILITY_PRESET hidden)
target_compile_definitions(${MODULE_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
target_compile_options(${MODULE_NAME} PRIVATE -matomics -mbulk-memory)
target_compile_features(${MODULE_NAME} PRIVATE cxx_std_17)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
@@ -89,12 +104,12 @@ set_property(TARGET geometry PROPERTY IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT
add_library(filament STATIC IMPORTED)
set_property(TARGET filament PROPERTY IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/lib/debug/libfilament.a")
set_property(TARGET filament PROPERTY IMPORTED_IMPLIB_PROFILE "${CMAKE_CURRENT_SOURCE_DIR}/lib/release/libfilament.a")
set_property(TARGET filament PROPERTY IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/libfilament.a")
set_property(TARGET filament PROPERTY IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lib/release/libfilament.a")
add_library(filameshio STATIC IMPORTED)
set_property(TARGET filameshio PROPERTY IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/lib/debug/libfilameshio.a")
set_property(TARGET filameshio PROPERTY IMPORTED_IMPLIB_PROFILE "${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/libfilameshio.a")
set_property(TARGET filameshio PROPERTY IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/libfilameshio.a")
set_property(TARGET filameshio PROPERTY IMPORTED_IMPLIB_PROFILE "${CMAKE_CURRENT_SOURCE_DIR}/lib/release/libfilameshio.a")
set_property(TARGET filameshio PROPERTY IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lib/release/libfilameshio.a")
add_library(filamat STATIC IMPORTED)
set_property(TARGET filamat PROPERTY IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/lib/debug/libfilamat.a")
@@ -226,10 +241,3 @@ target_link_libraries(${MODULE_NAME}
tinyexr
)
# add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
# COMMAND dart --enable-experiment=native-assets run ffigen --config ffigen/web.yaml WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../
# COMMAND ${CMAKE_COMMAND} -DINPUTFILE=${CMAKE_CURRENT_SOURCE_DIR}/../../lib/thermion_dart/compatibility/web/thermion_dart.g.dart -DOUTPUTFILE=${CMAKE_CURRENT_SOURCE_DIR}/../../lib/thermion_dart/compatibility/web/thermion_dart.g.dart "-DTO_REPLACE=symbol: '" "-DREPLACEMENT=symbol: '_" -P ${CMAKE_CURRENT_SOURCE_DIR}/replace_in_file.cmake
# # COMMAND ${CMAKE_COMMAND} -DINPUTFILE=${CMAKE_CURRENT_SOURCE_DIR}/build/build/out/thermion_dart.js -DOUTPUTFILE=${CMAKE_CURRENT_SOURCE_DIR}/build/build/out/thermion_dart.js "-DTO_REPLACE=var moduleRtn" "-DREPLACEMENT=var moduleRtn\;GLctx=moduleArg.ctx" -P ${CMAKE_CURRENT_SOURCE_DIR}/replace_in_file.cmake
# VERBATIM
# )
@@ -1,41 +0,0 @@
#ifndef _FLUTTER_FILAMENT_WEB_RESOURCE_LOADER_H
#define _FLUTTER_FILAMENT_WEB_RESOURCE_LOADER_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <emscripten/emscripten.h>
#include <emscripten/html5_webgl.h>
#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default")))
#ifdef __cplusplus
extern "C" {
#endif
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_load_resource_callback(void* data, int32_t length, void* context);
FLUTTER_PLUGIN_EXPORT char thermion_flutter_web_get(char* ptr, int32_t offset);
FLUTTER_PLUGIN_EXPORT float thermion_flutter_web_get_float(float* ptr, int32_t offset);
FLUTTER_PLUGIN_EXPORT double thermion_flutter_web_get_double(double* ptr, int32_t offset);
FLUTTER_PLUGIN_EXPORT void* thermion_flutter_web_get_pointer(void** ptr, int32_t offset);
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_set(char* ptr, int32_t offset, int32_t val);
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_set_float(float* ptr, int32_t offset, float val);
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_set_double(double* ptr, int32_t offset, double val);
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_set_pointer(void** ptr, int32_t offset, void* val);
FLUTTER_PLUGIN_EXPORT int32_t thermion_flutter_web_get_int32(int32_t* ptr, int32_t offset);
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_set_int32(int32_t* ptr, int32_t offset, int32_t value);
FLUTTER_PLUGIN_EXPORT long thermion_flutter_web_get_address(void** out);
FLUTTER_PLUGIN_EXPORT void* thermion_flutter_web_allocate(int32_t size);
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_free(void* ptr);
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE thermion_dart_web_create_gl_context();
FLUTTER_PLUGIN_EXPORT void* thermion_dart_web_get_resource_loader_wrapper();
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,16 @@
#pragma once
#include <emscripten/html5_webgl.h>
#ifdef __cplusplus
extern "C" {
#endif
void Thermion_resizeCanvas(int width, int height);
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE Thermion_createGLContext();
#ifdef __cplusplus
}
#endif
@@ -1,225 +0,0 @@
#include "ThermionFlutterWebApi.h"
#include "ResourceBuffer.hpp"
#include <thread>
#include <mutex>
#include <future>
#include <iostream>
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glext.h>
#include <emscripten/emscripten.h>
#include <emscripten/html5.h>
#include <emscripten/threading.h>
#include <emscripten/val.h>
#include <emscripten/fetch.h>
using emscripten::val;
extern "C"
{
//
// Since are using -sMAIN_MODULE with -sPTHREAD_POOL_SIZE=1, main will be called when the first worker is spawned
//
// EMSCRIPTEN_KEEPALIVE int main() {
// std::cout << "WEBAPI MAIN " << std::endl;
// return 0;
// }
std::string _assetPathPrefix;
EMSCRIPTEN_KEEPALIVE void thermion_dart_web_set_asset_path_prefix(const char* prefix) {
_assetPathPrefix = std::string(prefix);
}
EMSCRIPTEN_KEEPALIVE EMSCRIPTEN_WEBGL_CONTEXT_HANDLE thermion_dart_web_create_gl_context() {
EM_ASM(
FS.mkdir('/indexed');
FS.mount(IDBFS, {}, '/indexed');
FS.syncfs(true, function (err) {
if (err) {
console.error('Error mounting IDBFS:', err);
} else {
console.log('IDBFS mounted successfully');
}
});
);
std::cout << "Creating WebGL context." << std::endl;
EmscriptenWebGLContextAttributes attr;
emscripten_webgl_init_context_attributes(&attr);
attr.alpha = EM_TRUE;
attr.depth = EM_TRUE;
attr.stencil = EM_FALSE;
attr.antialias = EM_FALSE;
attr.explicitSwapControl = EM_FALSE;
attr.preserveDrawingBuffer = EM_TRUE;
attr.proxyContextToMainThread = EMSCRIPTEN_WEBGL_CONTEXT_PROXY_DISALLOW;
attr.enableExtensionsByDefault = EM_TRUE;
attr.renderViaOffscreenBackBuffer = EM_FALSE;
attr.majorVersion = 2;
auto context = emscripten_webgl_create_context("#canvas", &attr);
std::cout << "Created WebGL context " << attr.majorVersion << "." << attr.minorVersion << std::endl;
auto success = emscripten_webgl_make_context_current((EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)context);
if(success != EMSCRIPTEN_RESULT_SUCCESS) {
std::cout << "Failed to make WebGL context current"<< std::endl;
} else {
std::cout << "Made WebGL context current"<< std::endl;
// glClearColor(0.0, 0.0, 1.0, 1.0);
// glClear(GL_COLOR_BUFFER_BIT);
// emscripten_webgl_commit_frame();
}
return context;
}
int _lastResourceId = 0;
ResourceBuffer thermion_filament_web_load_resource(const char* path)
{
// ideally we should bounce the call to Flutter then wait for callback
// this isn't working for large assets though - seems like it's deadlocked
// will leave this here commented out so we can revisit later if needed
// auto pendingCall = new PendingCall();
// loadFlutterAsset(path, (void*)pendingCall);
// pendingCall->Wait();
// auto rb = ResourceBuffer { pendingCall->data, (int32_t) pendingCall->length, _lastResourceId } ;
_lastResourceId++;
// delete pendingCall;
// std::cout << "Deleted pending call" << std::endl;
// emscripten_fetch_attr_t attr;
// emscripten_fetch_attr_init(&attr);
// attr.onsuccess = [](emscripten_fetch_t* fetch) {
// };
// attr.onerror = [](emscripten_fetch_t* fetch) {
// std::cout << "Error" << std::endl;
// };
// attr.onprogress = [](emscripten_fetch_t* fetch) {
// };
// attr.onreadystatechange = [](emscripten_fetch_t* fetch) {
// };
// attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
// const char* headers[] = {"Accept-Encoding", "gzip, deflate", NULL};
// attr.requestHeaders = headers;
// auto pathString = std::string(path);
// if(pathString.rfind("/",0) != 0) {
// pathString = std::string("/") + pathString;
// }
// std::cout << "Fetching from path " << pathString.c_str() << std::endl;
// auto request = emscripten_fetch(&attr, pathString.c_str());
// if(!request) {
// std::cout << "Request failed?" << std::endl;
// return ResourceBuffer { nullptr, 0, -1 } ;
// }
// auto data = malloc(request->numBytes);
// memcpy(data, request->data, request->numBytes);
// emscripten_fetch_close(request);
// return ResourceBuffer { data, (int32_t) request->numBytes, _lastResourceId } ;
auto pathString = _assetPathPrefix + std::string(path);
void* data = nullptr;
int32_t numBytes = 0;
// Check if the file exists in IndexedDB first
bool fileExists = EM_ASM_INT({
var filename = UTF8ToString($0);
try {
var stat = FS.stat('/indexed/' + filename);
return stat.size > 0;
} catch (e) {
return false;
}
}, pathString.c_str());
if (fileExists) {
// File exists in IndexedDB, read it
EM_ASM({
var filename = UTF8ToString($0);
var content = FS.readFile('/indexed/' + filename);
var numBytes = content.length;
var ptr = _malloc(numBytes);
HEAPU8.set(content, ptr);
setValue($1, ptr, 'i32');
setValue($2, numBytes, 'i32');
}, pathString.c_str(), &data, &numBytes);
} else {
void** pBuffer = (void**)malloc(sizeof(void*));
int* pNum = (int*) malloc(sizeof(int*));
int* pError = (int*)malloc(sizeof(int*));
emscripten_wget_data(pathString.c_str(), pBuffer, pNum, pError);
data = *pBuffer;
numBytes = *pNum;
// Save the file to IndexedDB filesystem
EM_ASM({
var filename = UTF8ToString($0);
var data = new Uint8Array(HEAPU8.subarray($1, $1 + $2));
// Ensure the '/indexed' directory exists
if (!FS.analyzePath('/indexed').exists) {
FS.mkdir('/indexed');
}
// Create all parent directories
var parts = filename.split('/');
var currentPath = '/indexed';
for (var i = 0; i < parts.length - 1; i++) {
currentPath += '/' + parts[i];
if (!FS.analyzePath(currentPath).exists) {
FS.mkdir(currentPath);
}
}
// Write the file
FS.writeFile('/indexed/' + filename, data);
FS.syncfs(false, function (err) {
if (err) {
console.error('Failed to save file to IndexedDB:', err);
} else {
console.log('File saved to IndexedDB successfully');
}
});
}, pathString.c_str(), data, numBytes);
free(pBuffer);
free(pNum);
free(pError);
}
return ResourceBuffer { data, numBytes, _lastResourceId } ;
}
void thermion_filament_web_free_resource(ResourceBuffer rb) {
free((void*)rb.data);
}
EMSCRIPTEN_KEEPALIVE void thermion_filament_web_free(void* ptr) {
free(ptr);
}
EMSCRIPTEN_KEEPALIVE void* thermion_dart_web_get_resource_loader_wrapper() {
ResourceLoaderWrapper *rlw = (ResourceLoaderWrapper *)malloc(sizeof(ResourceLoaderWrapper));
rlw->loadResource = thermion_filament_web_load_resource;
rlw->loadFromOwner = nullptr;
rlw->freeResource = thermion_filament_web_free_resource;
rlw->freeFromOwner = nullptr;
rlw->loadToOut = nullptr;
rlw->owner = nullptr;
return rlw;
}
}
@@ -0,0 +1,123 @@
#include "ThermionWebApi.h"
#include <thread>
#include <mutex>
#include <future>
#include <iostream>
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glext.h>
#include <emscripten/emscripten.h>
#include <emscripten/html5.h>
#include <emscripten/threading.h>
#include <emscripten/val.h>
#include <emscripten/fetch.h>
#include <emscripten/console.h>
#include <emscripten/bind.h>
using emscripten::val;
extern "C"
{
EMSCRIPTEN_KEEPALIVE void Thermion_resizeCanvas(int width, int height) {
emscripten_set_canvas_element_size("#thermion_canvas", width, height);
}
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE EMSCRIPTEN_KEEPALIVE Thermion_createGLContext() {
std::cout << "Creating WebGL context." << std::endl;
EmscriptenWebGLContextAttributes attr;
emscripten_webgl_init_context_attributes(&attr);
attr.alpha = EM_TRUE;
attr.depth = EM_TRUE;
attr.stencil = EM_TRUE;
attr.antialias = EM_FALSE;
attr.explicitSwapControl = EM_FALSE;
attr.preserveDrawingBuffer = EM_FALSE;
attr.proxyContextToMainThread = EMSCRIPTEN_WEBGL_CONTEXT_PROXY_DISALLOW;
attr.enableExtensionsByDefault = EM_TRUE;
attr.renderViaOffscreenBackBuffer = EM_FALSE;
attr.majorVersion = 2;
auto context = emscripten_webgl_create_context("#thermion_canvas", &attr);
std::cout << "Created WebGL context " << attr.majorVersion << "." << attr.minorVersion << std::endl;
auto success = emscripten_webgl_make_context_current((EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)context);
if(success != EMSCRIPTEN_RESULT_SUCCESS) {
std::cout << "Failed to make WebGL context current"<< std::endl;
} else {
std::cout << "Made WebGL context current"<< std::endl;
try {
glClearColor(0.0, 0.0, 1.0, 1.0);
} catch(...) {
std::cout << "Caught err"<< std::endl;
}
glClear(GL_COLOR_BUFFER_BIT);
}
std::cout << "Returning context" << std::endl;
return context;
}
emscripten::val emscripten_make_uint8_buffer(int ptr, int length) {
uint8_t *buffer = (uint8_t*)ptr;
auto v = emscripten::val(emscripten::typed_memory_view(length, buffer));
emscripten_console_logf("offset %d", v["byteOffset"].as<int>());
return v;
}
emscripten::val emscripten_make_int16_buffer(int ptr, int length) {
int16_t *buffer = (int16_t*)ptr;
auto v = emscripten::val(emscripten::typed_memory_view(length, buffer));
emscripten_console_logf("offset %d", v["byteOffset"].as<int>());
return v;
}
emscripten::val emscripten_make_uint16_buffer(int ptr, int length) {
uint16_t *buffer = (uint16_t*)ptr;
auto v = emscripten::val(emscripten::typed_memory_view(length, buffer));
emscripten_console_logf("offset %d", v["byteOffset"].as<int>());
return v;
}
emscripten::val emscripten_make_int32_buffer(int ptr, int length) {
int32_t *buffer = (int32_t*)ptr;
auto v = emscripten::val(emscripten::typed_memory_view(length, buffer));
emscripten_console_logf("offset %d", v["byteOffset"].as<int>());
return v;
}
emscripten::val emscripten_make_f32_buffer(int ptr, int length) {
float *buffer = (float*)ptr;
auto v = emscripten::val(emscripten::typed_memory_view(length, buffer));
emscripten_console_logf("offset %d", v["byteOffset"].as<int>());
return v;
}
emscripten::val emscripten_make_f64_buffer(int ptr, int length) {
double *buffer = (double*)ptr;
auto v = emscripten::val(emscripten::typed_memory_view(length, buffer));
emscripten_console_logf("offset %d", v["byteOffset"].as<int>());
return v;
}
intptr_t emscripten_get_byte_offset(emscripten::val v) {
return v["byteOffset"].as<int>();
}
EMSCRIPTEN_BINDINGS(module) {
emscripten::function("_emscripten_make_uint8_buffer", &emscripten_make_uint8_buffer, emscripten::allow_raw_pointers());
emscripten::function("_emscripten_make_uint16_buffer", &emscripten_make_uint16_buffer, emscripten::allow_raw_pointers());
emscripten::function("_emscripten_make_int16_buffer", &emscripten_make_int16_buffer, emscripten::allow_raw_pointers());
emscripten::function("_emscripten_make_int32_buffer", &emscripten_make_int32_buffer, emscripten::allow_raw_pointers());
emscripten::function("_emscripten_make_f32_buffer", &emscripten_make_f32_buffer, emscripten::allow_raw_pointers());
emscripten::function("_emscripten_make_f64_buffer", &emscripten_make_f64_buffer, emscripten::allow_raw_pointers());
emscripten::function("_emscripten_get_byte_offset", &emscripten_get_byte_offset, emscripten::allow_raw_pointers());
}
}