refactoring
This commit is contained in:
@@ -5,7 +5,7 @@ import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
import 'package:thermion_dart/src/filament/src/layers.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import '../../../../utils/src/matrix.dart';
|
||||
|
||||
class FFICamera extends Camera {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:thermion_dart/src/filament/src/engine.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
|
||||
@@ -14,12 +15,12 @@ typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
|
||||
|
||||
class FFIFilamentConfig extends FilamentConfig<RenderCallback, Pointer<Void>> {
|
||||
FFIFilamentConfig(
|
||||
{required super.backend,
|
||||
required super.resourceLoader,
|
||||
required super.driver,
|
||||
required super.platform,
|
||||
required super.sharedContext,
|
||||
required super.uberArchivePath});
|
||||
{required super.resourceLoader,
|
||||
super.backend = Backend.DEFAULT,
|
||||
super.driver = null,
|
||||
super.platform = null,
|
||||
super.sharedContext = null,
|
||||
super.uberArchivePath = null});
|
||||
}
|
||||
|
||||
class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
@@ -55,7 +56,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
renderableManager: renderableManager,
|
||||
ubershaderMaterialProvider: ubershaderMaterialProvider) {}
|
||||
|
||||
static Future create(FFIFilamentConfig config) async {
|
||||
static Future create({FFIFilamentConfig? config}) async {
|
||||
config ??= FFIFilamentConfig(resourceLoader: nullptr);
|
||||
if (FilamentApp.instance != null) {
|
||||
await FilamentApp.instance!.destroy();
|
||||
}
|
||||
@@ -65,7 +67,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
|
||||
final engine = await withPointerCallback<TEngine>((cb) =>
|
||||
Engine_createRenderThread(
|
||||
TBackend.values[config.backend.index].index,
|
||||
TBackend.values[config!.backend.index].index,
|
||||
config.platform ?? nullptr,
|
||||
config.sharedContext ?? nullptr,
|
||||
config.stereoscopicEyeCount,
|
||||
@@ -79,15 +81,13 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
final renderer = await withPointerCallback<TRenderer>(
|
||||
(cb) => Engine_createRendererRenderThread(engine, cb));
|
||||
final ubershaderMaterialProvider =
|
||||
await withPointerCallback<TMaterialProvider>(
|
||||
(cb) => GltfAssetLoader_getMaterialProvider(gltfAssetLoader));
|
||||
GltfAssetLoader_getMaterialProvider(gltfAssetLoader);
|
||||
|
||||
final transformManager = Engine_getTransformManager(engine);
|
||||
final lightManager = Engine_getLightManager(engine);
|
||||
final renderableManager = Engine_getRenderableManager(engine);
|
||||
|
||||
final renderTicker = await withPointerCallback<TRenderTicker>(
|
||||
(cb) => RenderTicker_create(renderer));
|
||||
final renderTicker = RenderTicker_create(renderer);
|
||||
|
||||
final nameComponentManager = NameComponentManager_create();
|
||||
|
||||
@@ -210,7 +210,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
TextureSamplerType textureSamplerType = TextureSamplerType.SAMPLER_2D,
|
||||
TextureFormat textureFormat = TextureFormat.RGBA16F,
|
||||
int? importedTextureHandle}) async {
|
||||
var bitmask = flags.fold(0, (a, b) => a | b.index);
|
||||
var bitmask = flags.fold(0, (a, b) => a | b.value);
|
||||
print("bitmask $bitmask");
|
||||
final texturePtr = await withPointerCallback<TTexture>((cb) {
|
||||
Texture_buildRenderThread(
|
||||
engine,
|
||||
@@ -218,8 +219,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
height,
|
||||
depth,
|
||||
levels,
|
||||
importedTextureHandle ?? 0,
|
||||
bitmask,
|
||||
importedTextureHandle ?? 0,
|
||||
TTextureSamplerType.values[textureSamplerType.index],
|
||||
TTextureFormat.values[textureFormat.index],
|
||||
cb);
|
||||
@@ -404,7 +405,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
|
||||
FFIMaterial? _gridMaterial;
|
||||
Future<FFIMaterial> get gridMaterial async {
|
||||
_gridMaterial ??= FFIMaterial(Material_createGridMaterial(), this);
|
||||
_gridMaterial ??= FFIMaterial(Material_createGridMaterial(engine), this);
|
||||
return _gridMaterial!;
|
||||
}
|
||||
|
||||
@@ -425,8 +426,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
///
|
||||
@override
|
||||
Future render() async {
|
||||
await withVoidCallback((cb) =>
|
||||
RenderTicker_renderRenderThread(renderTicker, 0, cb));
|
||||
await withVoidCallback(
|
||||
(cb) => RenderTicker_renderRenderThread(renderTicker, 0, cb));
|
||||
}
|
||||
|
||||
///
|
||||
@@ -436,6 +437,10 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
Future register(
|
||||
covariant FFISwapChain swapChain, covariant FFIView view) async {
|
||||
_viewMappings[view] = swapChain;
|
||||
if (!_views.containsKey(swapChain)) {
|
||||
_views[swapChain] = [];
|
||||
}
|
||||
_views[swapChain]!.add(view);
|
||||
}
|
||||
|
||||
final _hooks = <Future Function()>[];
|
||||
@@ -531,9 +536,12 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||
|
||||
Material? _imageMaterial;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future<MaterialInstance> createImageMaterialInstance() async {
|
||||
_imageMaterial ??= FFIMaterial(Material_createImageMaterial(),
|
||||
_imageMaterial ??= FFIMaterial(Material_createImageMaterial(engine),
|
||||
FilamentApp.instance! as FFIFilamentApp);
|
||||
var instance =
|
||||
await _imageMaterial!.createInstance() as FFIMaterialInstance;
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_filament_app.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
class FFIMaterial extends Material {
|
||||
final FFIFilamentApp app;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ class FFIView extends View {
|
||||
}
|
||||
|
||||
Future setScene(covariant FFIScene scene) async {
|
||||
await withVoidCallback((cb) => View_setScene(view, scene.scene));
|
||||
View_setScene(view, scene.scene);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -25,11 +25,15 @@ external ffi.Pointer<TMaterialInstance> Material_createInstance(
|
||||
ffi.Pointer<TMaterial> tMaterial,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TMaterial> Function()>(isLeaf: true)
|
||||
external ffi.Pointer<TMaterial> Material_createImageMaterial();
|
||||
@ffi.Native<ffi.Pointer<TMaterial> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
|
||||
external ffi.Pointer<TMaterial> Material_createImageMaterial(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TMaterial> Function()>(isLeaf: true)
|
||||
external ffi.Pointer<TMaterial> Material_createGridMaterial();
|
||||
@ffi.Native<ffi.Pointer<TMaterial> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
|
||||
external ffi.Pointer<TMaterial> Material_createGridMaterial(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Bool Function(ffi.Pointer<TMaterial>, ffi.Pointer<ffi.Char>)>(
|
||||
isLeaf: true)
|
||||
@@ -1491,9 +1495,11 @@ external void RenderLoop_create();
|
||||
@ffi.Native<ffi.Void Function()>(isLeaf: true)
|
||||
external void RenderLoop_destroy();
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>)>(isLeaf: true)
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
||||
external void RenderLoop_requestAnimationFrame(
|
||||
ffi.Pointer<ffi.Void> onComplete,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
@@ -3847,7 +3853,7 @@ enum TGizmoType {
|
||||
};
|
||||
}
|
||||
|
||||
sealed class TPrimitiveType {
|
||||
abstract class TPrimitiveType {
|
||||
/// !< points
|
||||
static const PRIMITIVETYPE_POINTS = 0;
|
||||
|
||||
@@ -4265,7 +4271,7 @@ enum TTextureFormat {
|
||||
}
|
||||
|
||||
/// ! Pixel Data Format
|
||||
sealed class TPixelDataFormat {
|
||||
abstract class TPixelDataFormat {
|
||||
/// !< One Red channel, float
|
||||
static const PIXELDATAFORMAT_R = 0;
|
||||
|
||||
@@ -4299,7 +4305,7 @@ sealed class TPixelDataFormat {
|
||||
static const PIXELDATAFORMAT_ALPHA = 11;
|
||||
}
|
||||
|
||||
sealed class TPixelDataType {
|
||||
abstract class TPixelDataType {
|
||||
/// !< unsigned byte
|
||||
static const PIXELDATATYPE_UBYTE = 0;
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
_cameras.add(camera);
|
||||
|
||||
await view.setCamera(camera);
|
||||
|
||||
if (renderTarget != null) {
|
||||
await view.setRenderTarget(renderTarget);
|
||||
}
|
||||
@@ -149,14 +150,12 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
}
|
||||
|
||||
final _onDispose = <Future Function()>[];
|
||||
bool _disposing = false;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@override
|
||||
Future dispose() async {
|
||||
_disposing = true;
|
||||
await setRendering(false);
|
||||
await destroyAssets();
|
||||
await destroyLights();
|
||||
@@ -166,7 +165,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
}
|
||||
|
||||
_onDispose.clear();
|
||||
_disposing = false;
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
namespace thermion
|
||||
{
|
||||
|
||||
typedef std::chrono::time_point time_point_t;
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
class RenderTicker
|
||||
{
|
||||
|
||||
|
||||
@@ -68,8 +68,8 @@ extern "C"
|
||||
};
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *Material_createInstance(TMaterial *tMaterial);
|
||||
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createImageMaterial();
|
||||
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createGridMaterial();
|
||||
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createImageMaterial(TEngine *tEngine);
|
||||
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createGridMaterial(TEngine *tEngine);
|
||||
EMSCRIPTEN_KEEPALIVE bool Material_hasParameter(TMaterial *tMaterial, const char *propertyName);
|
||||
EMSCRIPTEN_KEEPALIVE bool MaterialInstance_isStencilWriteEnabled(TMaterialInstance *materialInstance);
|
||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setStencilWrite(TMaterialInstance *materialInstance, bool enabled);
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace thermion
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void RenderLoop_create();
|
||||
EMSCRIPTEN_KEEPALIVE void RenderLoop_destroy();
|
||||
EMSCRIPTEN_KEEPALIVE void RenderLoop_requestAnimationFrame(void (*onComplete));
|
||||
EMSCRIPTEN_KEEPALIVE void RenderLoop_requestAnimationFrame(void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void RenderTicker_renderRenderThread(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos, void (*onComplete)());
|
||||
// EMSCRIPTEN_KEEPALIVE void RenderLoop_addTask(TRenderLoop* tRenderLoop, void (*task)());
|
||||
|
||||
@@ -52,6 +52,7 @@ namespace thermion
|
||||
TTextureFormat format,
|
||||
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)());
|
||||
@@ -175,18 +176,6 @@ namespace thermion
|
||||
EMSCRIPTEN_KEEPALIVE void Image_getHeightRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
||||
EMSCRIPTEN_KEEPALIVE void Image_getChannelsRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
||||
|
||||
// Texture methods
|
||||
EMSCRIPTEN_KEEPALIVE void Texture_buildRenderThread(TEngine *engine,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t depth,
|
||||
uint8_t levels,
|
||||
uint16_t tUsage,
|
||||
intptr_t import,
|
||||
TTextureSamplerType sampler,
|
||||
TTextureFormat format,
|
||||
void (*onComplete)(TTexture *)
|
||||
);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Texture_loadImageRenderThread(
|
||||
TEngine *tEngine,
|
||||
@@ -292,8 +281,6 @@ namespace thermion
|
||||
void (*onComplete)()
|
||||
);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_updateBoneMatricesRenderThread(TSceneManager *sceneManager,
|
||||
EntityId asset, void (*callback)(bool));
|
||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_setBoneTransformRenderThread(
|
||||
TAnimationManager *tAnimationManager,
|
||||
EntityId asset,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
#include <filament/Box.h>
|
||||
#include <filament/Engine.h>
|
||||
|
||||
@@ -37,10 +37,6 @@ public:
|
||||
void addAllEntities(Scene* scene) override;
|
||||
void removeAllEntities(Scene* scene) override;
|
||||
|
||||
void setPriority(RenderableManager& rm, int priority) override;
|
||||
void setLayer(RenderableManager& rm, int layer) override;
|
||||
|
||||
|
||||
size_t getInstanceCount() override { return _instances.size(); }
|
||||
SceneAsset* getInstanceByEntity(utils::Entity entity) override;
|
||||
SceneAsset* getInstanceAt(size_t index) override;
|
||||
|
||||
@@ -227,23 +227,7 @@ namespace thermion
|
||||
scene->remove(_gridEntity);
|
||||
// scene->remove(_sphereEntity);
|
||||
}
|
||||
|
||||
void GridOverlay::setPriority(RenderableManager &rm, int priority)
|
||||
{
|
||||
auto gridInstance = rm.getInstance(_gridEntity);
|
||||
rm.setPriority(gridInstance, priority);
|
||||
// auto sphereInstance = rm.getInstance(_sphereEntity);
|
||||
// rm.setPriority(sphereInstance, priority);
|
||||
}
|
||||
|
||||
void GridOverlay::setLayer(RenderableManager &rm, int layer)
|
||||
{
|
||||
auto gridInstance = rm.getInstance(_gridEntity);
|
||||
rm.setLayerMask(gridInstance, 0xFF, 1u << (uint8_t)layer);
|
||||
// auto sphereInstance = rm.getInstance(_sphereEntity);
|
||||
// rm.setLayerMask(sphereInstance, 0xFF, 1u << (uint8_t)layer);
|
||||
}
|
||||
|
||||
|
||||
SceneAsset *GridOverlay::getInstanceByEntity(utils::Entity entity)
|
||||
{
|
||||
for (auto &instance : _instances)
|
||||
|
||||
@@ -42,7 +42,6 @@ namespace thermion
|
||||
using namespace filament;
|
||||
using namespace filament::math;
|
||||
using namespace utils;
|
||||
using namespace std::chrono;
|
||||
|
||||
using std::string;
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#include <filament/Camera.h>
|
||||
#include <filament/ColorGrading.h>
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Frustum.h>
|
||||
#include <filament/ToneMapper.h>
|
||||
#include <filament/View.h>
|
||||
#include <filament/Viewport.h>
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/ToneMapper.h>
|
||||
#include <filament/ColorGrading.h>
|
||||
#include <filament/Camera.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
|
||||
#include "c_api/ThermionDartApi.h"
|
||||
#include "c_api/TCamera.h"
|
||||
#include "Log.hpp"
|
||||
#include "MathUtils.hpp"
|
||||
@@ -32,8 +33,8 @@ namespace thermion
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_getFrustum(TCamera *tCamera, double *out) {
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
auto &frustum = camera->getFrustum();
|
||||
auto planes = frustum.getPlanes();
|
||||
auto frustum = camera->getFrustum();
|
||||
auto planes = frustum.getNormalizedPlanes();
|
||||
for(int i = 0; i < 6; i++) {
|
||||
for(int j = 0; j < 4; j++) {
|
||||
out[(i*4) + j] = planes[i][j];
|
||||
@@ -41,18 +42,30 @@ namespace thermion
|
||||
}
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setLensProjection(TCamera *tCamera, double near, double far, double aspect, double focalLength) {
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
camera->setLensProjection(near, far, aspect, focalLength);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera *tCamera, double4x4 tModelMatrix) {
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
auto modelMatrix = convert_double4x4_to_mat4(tModelMatrix);
|
||||
camera->setModelMatrix(modelMatrix);
|
||||
}
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(TCamera *tCamera, double4x4 projectionMatrix, double near, double far)
|
||||
{
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
camera->setCustomProjection(convert_double4x4_to_mat4(projectionMatrix), near, far);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getFocusDistance(TCamera *camera) {
|
||||
EMSCRIPTEN_KEEPALIVE double Camera_getFocusDistance(TCamera *tCamera) {
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
return camera->getFocusDistance();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setFocusDistance(TCamera *camera, float distance) {
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setFocusDistance(TCamera *tCamera, float distance) {
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
return camera->setFocusDistance(distance);
|
||||
}
|
||||
@@ -93,16 +106,16 @@ namespace thermion
|
||||
return camera->getCullingFar();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setProjection(TCamera *const tCamera, Projection projection, double left, double right,
|
||||
EMSCRIPTEN_KEEPALIVE void Camera_setProjection(TCamera *const tCamera, TProjection projection, double left, double right,
|
||||
double bottom, double top,
|
||||
double near, double far)
|
||||
{
|
||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||
filament::Camera::Projection filamentProjection;
|
||||
switch(projection) {
|
||||
case Projection::Orthographic:
|
||||
case TProjection::Orthographic:
|
||||
filamentProjection = filament::Camera::Projection::ORTHO;
|
||||
case Projection::Perspective:
|
||||
case TProjection::Perspective:
|
||||
filamentProjection = filament::Camera::Projection::PERSPECTIVE;
|
||||
}
|
||||
camera->setProjection(filamentProjection, left, right, bottom, top, near, far);
|
||||
|
||||
@@ -47,15 +47,21 @@ namespace thermion
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TEngine *Engine_create(
|
||||
TBackend backend,
|
||||
void* platform,
|
||||
void* sharedContext,
|
||||
void* tPlatform,
|
||||
void* tSharedContext,
|
||||
uint8_t stereoscopicEyeCount,
|
||||
bool disableHandleUseAfterFreeCheck)
|
||||
{
|
||||
filament::Engine::Config config;
|
||||
config.stereoscopicEyeCount = stereoscopicEyeCount;
|
||||
config.disableHandleUseAfterFreeCheck = disableHandleUseAfterFreeCheck;
|
||||
auto *engine = filament::Engine::create(static_cast<filament::Engine::Backend>(backend), platform, sharedContext, &config);
|
||||
auto *platform = reinterpret_cast<filament::backend::Platform *>(tPlatform);
|
||||
auto *engine = filament::Engine::create(
|
||||
static_cast<filament::Engine::Backend>(backend),
|
||||
platform,
|
||||
tSharedContext,
|
||||
&config
|
||||
);
|
||||
return reinterpret_cast<TEngine *>(engine);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,12 +46,13 @@ EMSCRIPTEN_KEEPALIVE int LightManager_createLight(TEngine *tEngine, TLightManage
|
||||
}
|
||||
|
||||
filament::LightManager::Builder builder(lightType);
|
||||
auto entity = utils::EntityManager::create();
|
||||
auto result = builder.build(*engine, utils::Entity::import(entity));
|
||||
auto &em = utils::EntityManager::get();
|
||||
auto entity = em.create();
|
||||
auto result = builder.build(*engine, entity);
|
||||
if(result != filament::LightManager::Builder::Result::Success) {
|
||||
Log("Failed to create light");
|
||||
}
|
||||
return entity;
|
||||
return utils::Entity::smuggle(entity);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void LightManager_destroyLight(TLightManager *tLightManager, EntityId entity) {
|
||||
|
||||
@@ -2,12 +2,16 @@
|
||||
|
||||
#include <filament/MaterialInstance.h>
|
||||
#include <filament/Material.h>
|
||||
|
||||
#include <math/mat4.h>
|
||||
#include <math/vec4.h>
|
||||
#include <math/vec2.h>
|
||||
|
||||
#include "Log.hpp"
|
||||
#include "materials/image.h"
|
||||
|
||||
#include "material/image.h"
|
||||
#include "material/grid.h"
|
||||
|
||||
#include "c_api/TMaterialInstance.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -26,7 +30,7 @@ namespace thermion
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createImageMaterial(TEngine *tEngine) {
|
||||
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
|
||||
auto *material = Material::Builder()
|
||||
auto *material = filament::Material::Builder()
|
||||
.package(IMAGE_IMAGE_DATA, IMAGE_IMAGE_SIZE)
|
||||
.build(*engine);
|
||||
|
||||
@@ -35,10 +39,9 @@ namespace thermion
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createGridMaterial(TEngine *tEngine) {
|
||||
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
|
||||
auto *material = Material::Builder()
|
||||
.package(GRID_GRID_DATA, GRID_GRID_SIZE)
|
||||
.build(*engine);
|
||||
|
||||
auto *material = filament::Material::Builder()
|
||||
.package(GRID_GRID_DATA, GRID_GRID_SIZE)
|
||||
.build(*engine);
|
||||
return reinterpret_cast<TMaterial *>(material);
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace thermion
|
||||
if (!renderableInstance.isValid()) {
|
||||
return Aabb3 { };
|
||||
}
|
||||
auto box = renderableManager.getAxisAlignedBoundingBox(renderableInstance);
|
||||
auto box = renderableManager->getAxisAlignedBoundingBox(renderableInstance);
|
||||
return Aabb3{box.center.x, box.center.y, box.center.z, box.halfExtent.x, box.halfExtent.y, box.halfExtent.z};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include "c_api/TTexture.h"
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Material.h>
|
||||
#include <filament/RenderTarget.h>
|
||||
@@ -15,6 +14,8 @@
|
||||
#include <filament/imageio/ImageDecoder.h>
|
||||
#include <filament/backend/DriverEnums.h>
|
||||
|
||||
#include "c_api/TTexture.h"
|
||||
|
||||
#include "Log.hpp"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -227,7 +228,7 @@ namespace thermion
|
||||
auto *engine = reinterpret_cast<::filament::Engine *>(tEngine);
|
||||
auto format = convertToFilamentFormat(tFormat);
|
||||
auto samplerType = static_cast<::filament::Texture::Sampler>(static_cast<int>(tSamplerType));
|
||||
auto usage = static_cast<::filament::Texture::Usage>(tUsage);
|
||||
auto usage = static_cast<TextureUsage>(tUsage);
|
||||
|
||||
if ((usage & TextureUsage::UPLOADABLE) == TextureUsage::UPLOADABLE) {
|
||||
TRACE("UPLOADABLE");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "RenderLoop.hpp"
|
||||
#include "rendering/RenderLoop.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <stdlib.h>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,201 +0,0 @@
|
||||
import Foundation
|
||||
import GLKit
|
||||
|
||||
@objc public class ThermionTextureSwift : NSObject {
|
||||
|
||||
public var pixelBuffer: CVPixelBuffer?
|
||||
|
||||
var pixelBufferAttrs = [
|
||||
kCVPixelBufferPixelFormatTypeKey: NSNumber(value: kCVPixelFormatType_32ABGR ),
|
||||
kCVPixelBufferIOSurfacePropertiesKey: [:] as CFDictionary
|
||||
] as [CFString : Any] as CFDictionary
|
||||
|
||||
@objc public var cvMetalTextureCache:CVMetalTextureCache?
|
||||
@objc public var metalDevice:MTLDevice?
|
||||
|
||||
@objc public var cvMetalTexture:CVMetalTexture?
|
||||
@objc public var metalTexture:MTLTexture?
|
||||
@objc public var metalTextureAddress:Int = -1
|
||||
|
||||
@objc override public init() {
|
||||
|
||||
}
|
||||
|
||||
@objc public init(width:Int64, height:Int64, isDepth:Bool) {
|
||||
if(self.metalDevice == nil) {
|
||||
self.metalDevice = MTLCreateSystemDefaultDevice()!
|
||||
}
|
||||
|
||||
if isDepth {
|
||||
// Create a proper depth texture without IOSurface backing
|
||||
let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(
|
||||
pixelFormat: .depth32Float,
|
||||
width: Int(width),
|
||||
height: Int(height),
|
||||
mipmapped: false)
|
||||
textureDescriptor.usage = [.renderTarget, .shaderRead]
|
||||
textureDescriptor.storageMode = .private // Best performance for GPU-only access
|
||||
|
||||
metalTexture = metalDevice?.makeTexture(descriptor: textureDescriptor)
|
||||
let metalTexturePtr = Unmanaged.passRetained(metalTexture!).toOpaque()
|
||||
metalTextureAddress = Int(bitPattern: metalTexturePtr)
|
||||
return
|
||||
}
|
||||
|
||||
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) {
|
||||
print("Error allocating pixel buffer")
|
||||
metalTextureAddress = -1;
|
||||
return
|
||||
}
|
||||
|
||||
if self.cvMetalTextureCache == nil {
|
||||
let cacheCreationResult = CVMetalTextureCacheCreate(
|
||||
kCFAllocatorDefault,
|
||||
nil,
|
||||
self.metalDevice!,
|
||||
nil,
|
||||
&self.cvMetalTextureCache)
|
||||
if(cacheCreationResult != kCVReturnSuccess) {
|
||||
print("Error creating Metal texture cache")
|
||||
metalTextureAddress = -1
|
||||
return
|
||||
}
|
||||
}
|
||||
let cvret = CVMetalTextureCacheCreateTextureFromImage(
|
||||
kCFAllocatorDefault,
|
||||
self.cvMetalTextureCache!,
|
||||
pixelBuffer!, nil,
|
||||
MTLPixelFormat.bgra8Unorm,
|
||||
Int(width), Int(height),
|
||||
0,
|
||||
&cvMetalTexture)
|
||||
if(cvret != kCVReturnSuccess) {
|
||||
print("Error creating texture from image")
|
||||
metalTextureAddress = -1
|
||||
return
|
||||
}
|
||||
metalTexture = CVMetalTextureGetTexture(cvMetalTexture!)
|
||||
let metalTexturePtr = Unmanaged.passRetained(metalTexture!).toOpaque()
|
||||
metalTextureAddress = Int(bitPattern:metalTexturePtr)
|
||||
}
|
||||
|
||||
@objc public func destroyTexture() {
|
||||
CVMetalTextureCacheFlush(self.cvMetalTextureCache!, 0)
|
||||
self.metalTexture = nil
|
||||
self.cvMetalTexture = nil
|
||||
self.pixelBuffer = nil
|
||||
self.metalDevice = nil
|
||||
self.cvMetalTextureCache = nil
|
||||
}
|
||||
|
||||
@objc public func fillColor() {
|
||||
CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
|
||||
let bufferWidth = Int(CVPixelBufferGetWidth(pixelBuffer!))
|
||||
let bufferHeight = Int(CVPixelBufferGetHeight(pixelBuffer!))
|
||||
let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer!)
|
||||
|
||||
guard let baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer!) else {
|
||||
return
|
||||
}
|
||||
|
||||
for row in 0..<bufferHeight {
|
||||
var pixel = baseAddress + row * bytesPerRow
|
||||
for _ in 0..<bufferWidth {
|
||||
let blue = pixel
|
||||
blue.storeBytes(of: 255, as: UInt8.self)
|
||||
|
||||
let red = pixel + 1
|
||||
red.storeBytes(of: 0, as: UInt8.self)
|
||||
|
||||
let green = pixel + 2
|
||||
green.storeBytes(of: 0, as: UInt8.self)
|
||||
|
||||
let alpha = pixel + 3
|
||||
alpha.storeBytes(of: 255, as: UInt8.self)
|
||||
|
||||
pixel += 4;
|
||||
}
|
||||
}
|
||||
|
||||
CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
|
||||
}
|
||||
|
||||
@objc public func getTextureBytes() -> NSData? {
|
||||
guard let texture = self.metalTexture else {
|
||||
print("Metal texture is not available")
|
||||
return nil
|
||||
}
|
||||
|
||||
let width = texture.width
|
||||
let height = texture.height
|
||||
|
||||
// Check what type of texture we're dealing with
|
||||
let isDepthTexture = texture.pixelFormat == .depth32Float ||
|
||||
texture.pixelFormat == .depth16Unorm
|
||||
print("Using texture pixel format : \(texture.pixelFormat) isDepthTexture \(isDepthTexture) (depth32Float \(MTLPixelFormat.depth32Float)) (depth16Unorm \(MTLPixelFormat.depth16Unorm))")
|
||||
// Determine bytes per pixel based on format
|
||||
let bytesPerPixel = isDepthTexture ?
|
||||
(texture.pixelFormat == .depth32Float ? 4 : 2) : 4
|
||||
let bytesPerRow = width * bytesPerPixel
|
||||
let byteCount = bytesPerRow * height
|
||||
|
||||
// Create a staging buffer that is CPU-accessible
|
||||
guard let stagingBuffer = self.metalDevice?.makeBuffer(
|
||||
length: byteCount,
|
||||
options: .storageModeShared) else {
|
||||
print("Failed to create staging buffer")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create command buffer and encoder for copying
|
||||
guard let cmdQueue = self.metalDevice?.makeCommandQueue(),
|
||||
let cmdBuffer = cmdQueue.makeCommandBuffer(),
|
||||
let blitEncoder = cmdBuffer.makeBlitCommandEncoder() else {
|
||||
print("Failed to create command objects")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Copy from texture to buffer
|
||||
blitEncoder.copy(
|
||||
from: texture,
|
||||
sourceSlice: 0,
|
||||
sourceLevel: 0,
|
||||
sourceOrigin: MTLOrigin(x: 0, y: 0, z: 0),
|
||||
sourceSize: MTLSize(width: width, height: height, depth: 1),
|
||||
to: stagingBuffer,
|
||||
destinationOffset: 0,
|
||||
destinationBytesPerRow: bytesPerRow,
|
||||
destinationBytesPerImage: byteCount
|
||||
)
|
||||
|
||||
blitEncoder.endEncoding()
|
||||
cmdBuffer.commit()
|
||||
cmdBuffer.waitUntilCompleted()
|
||||
|
||||
// Now the data is in the staging buffer, accessible to CPU
|
||||
if isDepthTexture {
|
||||
// For depth textures, just return the raw data
|
||||
return NSData(bytes: stagingBuffer.contents(), length: byteCount)
|
||||
} else {
|
||||
// For color textures, do the BGRA to RGBA swizzling
|
||||
let bytes = stagingBuffer.contents().bindMemory(to: UInt8.self, capacity: byteCount)
|
||||
let data = NSMutableData(bytes: bytes, length: byteCount)
|
||||
|
||||
let mutableBytes = data.mutableBytes.bindMemory(to: UInt8.self, capacity: byteCount)
|
||||
for i in stride(from: 0, to: byteCount, by: 4) {
|
||||
let blue = mutableBytes[i]
|
||||
let red = mutableBytes[i+2]
|
||||
mutableBytes[i] = red
|
||||
mutableBytes[i+2] = blue
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user