fix: move material/instance creation to render thread
This commit is contained in:
@@ -1,124 +0,0 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:ffi/ffi.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||
import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
class ThermionFFIMaterialInstance extends MaterialInstance {
|
||||
final Pointer<TMaterialInstance> pointer;
|
||||
final Pointer<TSceneManager> sceneManager;
|
||||
|
||||
ThermionFFIMaterialInstance(this.pointer, this.sceneManager) {
|
||||
if (pointer == nullptr) {
|
||||
throw Exception("MaterialInstance not found");
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future setDepthCullingEnabled(bool enabled) async {
|
||||
MaterialInstance_setDepthCulling(this.pointer, enabled);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setDepthWriteEnabled(bool enabled) async {
|
||||
MaterialInstance_setDepthWrite(this.pointer, enabled);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParameterFloat4(
|
||||
String name, double x, double y, double z, double w) async {
|
||||
MaterialInstance_setParameterFloat4(
|
||||
pointer, name.toNativeUtf8().cast<Char>(), x, y, z, w);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParameterFloat2(String name, double x, double y) async {
|
||||
MaterialInstance_setParameterFloat2(
|
||||
pointer, name.toNativeUtf8().cast<Char>(), x, y);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParameterFloat(String name, double value) async {
|
||||
MaterialInstance_setParameterFloat(
|
||||
pointer, name.toNativeUtf8().cast<Char>(), value);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParameterInt(String name, int value) async {
|
||||
MaterialInstance_setParameterInt(
|
||||
pointer, name.toNativeUtf8().cast<Char>(), value);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setDepthFunc(SamplerCompareFunction depthFunc) async {
|
||||
MaterialInstance_setDepthFunc(
|
||||
pointer, TSamplerCompareFunc.values[depthFunc.index]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilCompareFunction(SamplerCompareFunction func,
|
||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||
MaterialInstance_setStencilCompareFunction(
|
||||
pointer,
|
||||
TSamplerCompareFunc.values[func.index],
|
||||
TStencilFace.values[face.index]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilOpDepthFail(StencilOperation op,
|
||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||
MaterialInstance_setStencilOpDepthFail(pointer,
|
||||
TStencilOperation.values[op.index], TStencilFace.values[face.index]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilOpDepthStencilPass(StencilOperation op,
|
||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||
MaterialInstance_setStencilOpDepthStencilPass(pointer,
|
||||
TStencilOperation.values[op.index], TStencilFace.values[face.index]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilOpStencilFail(StencilOperation op,
|
||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||
MaterialInstance_setStencilOpStencilFail(pointer,
|
||||
TStencilOperation.values[op.index], TStencilFace.values[face.index]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilReferenceValue(int value,
|
||||
[StencilFace face = StencilFace.FRONT_AND_BACK]) async {
|
||||
MaterialInstance_setStencilReferenceValue(
|
||||
pointer, value, TStencilFace.values[face.index]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilWriteEnabled(bool enabled) async {
|
||||
MaterialInstance_setStencilWrite(pointer, enabled);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setCullingMode(CullingMode cullingMode) async {
|
||||
MaterialInstance_setCullingMode(
|
||||
pointer, TCullingMode.values[cullingMode.index]);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> isStencilWriteEnabled() async {
|
||||
return MaterialInstance_isStencilWriteEnabled(pointer);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilReadMask(int mask) async {
|
||||
MaterialInstance_setStencilReadMask(pointer, mask);
|
||||
}
|
||||
|
||||
@override
|
||||
Future setStencilWriteMask(int mask) async {
|
||||
MaterialInstance_setStencilWriteMask(pointer, mask);
|
||||
}
|
||||
|
||||
Future dispose() async {
|
||||
SceneManager_destroyMaterialInstance(sceneManager, pointer);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,12 @@ library;
|
||||
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
@ffi.Native<ffi.Pointer<TMaterialInstance> Function(ffi.Pointer<TMaterial>)>(
|
||||
isLeaf: true)
|
||||
external ffi.Pointer<TMaterialInstance> Material_createInstance(
|
||||
ffi.Pointer<TMaterial> tMaterial,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Bool Function(ffi.Pointer<TMaterialInstance>)>(isLeaf: true)
|
||||
external bool MaterialInstance_isStencilWriteEnabled(
|
||||
ffi.Pointer<TMaterialInstance> materialInstance,
|
||||
@@ -372,6 +378,40 @@ external ffi.Pointer<TCamera> Engine_getCameraComponent(
|
||||
int entityId,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TTransformManager> Function(ffi.Pointer<TEngine>)>(
|
||||
isLeaf: true)
|
||||
external ffi.Pointer<TTransformManager> Engine_getTransformManager(
|
||||
ffi.Pointer<TEngine> engine,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TRenderableManager> Function(ffi.Pointer<TEngine>)>(
|
||||
isLeaf: true)
|
||||
external ffi.Pointer<TRenderableManager> Engine_getRenderableManager(
|
||||
ffi.Pointer<TEngine> engine,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TEntityManager> Function(ffi.Pointer<TEngine>)>(
|
||||
isLeaf: true)
|
||||
external ffi.Pointer<TEntityManager> Engine_getEntityManager(
|
||||
ffi.Pointer<TEngine> engine,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TMaterial> Function(
|
||||
ffi.Pointer<TEngine>, ffi.Pointer<ffi.Uint8>, ffi.Size)>(isLeaf: true)
|
||||
external ffi.Pointer<TMaterial> Engine_buildMaterial(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
ffi.Pointer<ffi.Uint8> materialData,
|
||||
int length,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TEngine>, ffi.Pointer<TMaterial>)>(
|
||||
isLeaf: true)
|
||||
external void Engine_destroyMaterial(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
ffi.Pointer<TMaterial> tMaterial,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
|
||||
external void clear_background_image(
|
||||
ffi.Pointer<TViewer> viewer,
|
||||
@@ -558,24 +598,6 @@ external void queue_position_update_from_viewport_coords(
|
||||
double viewportY,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TTransformManager> Function(ffi.Pointer<TEngine>)>(
|
||||
isLeaf: true)
|
||||
external ffi.Pointer<TTransformManager> Engine_getTransformManager(
|
||||
ffi.Pointer<TEngine> engine,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TRenderableManager> Function(ffi.Pointer<TEngine>)>(
|
||||
isLeaf: true)
|
||||
external ffi.Pointer<TRenderableManager> Engine_getRenderableManager(
|
||||
ffi.Pointer<TEngine> engine,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TEntityManager> Function(ffi.Pointer<TEngine>)>(
|
||||
isLeaf: true)
|
||||
external ffi.Pointer<TEntityManager> Engine_getEntityManager(
|
||||
ffi.Pointer<TEngine> engine,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Void Function()>(isLeaf: true)
|
||||
external void ios_dummy();
|
||||
|
||||
@@ -1288,6 +1310,46 @@ external void Viewer_createRenderTargetRenderThread(
|
||||
onComplete,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TEngine>,
|
||||
ffi.Pointer<ffi.Uint8>,
|
||||
ffi.Size,
|
||||
ffi.Pointer<
|
||||
ffi
|
||||
.NativeFunction<ffi.Void Function(ffi.Pointer<TMaterial>)>>)>(
|
||||
isLeaf: true)
|
||||
external void Engine_buildMaterialRenderThread(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
ffi.Pointer<ffi.Uint8> materialData,
|
||||
int length,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TMaterial>)>>
|
||||
onComplete,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(ffi.Pointer<TEngine>, ffi.Pointer<TMaterial>,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
|
||||
external void Engine_destroyMaterialRenderThread(
|
||||
ffi.Pointer<TEngine> tEngine,
|
||||
ffi.Pointer<TMaterial> tMaterial,
|
||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TMaterial>,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TMaterialInstance>)>>)>(isLeaf: true)
|
||||
external void Material_createInstanceRenderThread(
|
||||
ffi.Pointer<TMaterial> tMaterial,
|
||||
ffi.Pointer<
|
||||
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TMaterialInstance>)>>
|
||||
onComplete,
|
||||
);
|
||||
|
||||
@ffi.Native<
|
||||
ffi.Void Function(
|
||||
ffi.Pointer<TView>, ffi.Pointer<TEngine>, ffi.Int)>(isLeaf: true)
|
||||
@@ -1956,10 +2018,12 @@ external ffi.Pointer<TNameComponentManager>
|
||||
ffi.Pointer<TSceneManager> tSceneManager,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Pointer<TSceneAsset> Function(ffi.Pointer<TSceneManager>)>(
|
||||
isLeaf: true)
|
||||
@ffi.Native<
|
||||
ffi.Pointer<TSceneAsset> Function(
|
||||
ffi.Pointer<TSceneManager>, ffi.Pointer<TMaterial>)>(isLeaf: true)
|
||||
external ffi.Pointer<TSceneAsset> SceneManager_createGrid(
|
||||
ffi.Pointer<TSceneManager> tSceneManager,
|
||||
ffi.Pointer<TMaterial> tMaterial,
|
||||
);
|
||||
|
||||
@ffi.Native<ffi.Bool Function(ffi.Pointer<TSceneManager>, EntityId)>(
|
||||
@@ -2324,6 +2388,8 @@ final class TSceneAsset extends ffi.Opaque {}
|
||||
|
||||
final class TNameComponentManager extends ffi.Opaque {}
|
||||
|
||||
final class TMaterial extends ffi.Opaque {}
|
||||
|
||||
final class TMaterialInstance extends ffi.Opaque {}
|
||||
|
||||
final class TMaterialProvider extends ffi.Opaque {}
|
||||
|
||||
@@ -5,16 +5,15 @@ import 'dart:typed_data';
|
||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_asset.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_gizmo.dart';
|
||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'package:vector_math/vector_math_64.dart' as v64;
|
||||
import '../../../../utils/src/gizmo.dart';
|
||||
import '../../../../utils/src/matrix.dart';
|
||||
import '../../thermion_viewer_base.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
import 'callbacks.dart';
|
||||
import 'ffi_camera.dart';
|
||||
import 'ffi_material_instance.dart';
|
||||
import 'ffi_view.dart';
|
||||
|
||||
// ignore: constant_identifier_names
|
||||
@@ -282,7 +281,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
final _onDispose = <Future Function()>[];
|
||||
bool _disposing = false;
|
||||
|
||||
final _materialInstances = <ThermionFFIMaterialInstance>[];
|
||||
final _materialInstances = <FFIMaterialInstance>[];
|
||||
|
||||
///
|
||||
///
|
||||
@@ -1626,7 +1625,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
0,
|
||||
materialInstances.length,
|
||||
materialInstances
|
||||
.cast<ThermionFFIMaterialInstance>()
|
||||
.cast<FFIMaterialInstance>()
|
||||
.map((mi) => mi.pointer.address)
|
||||
.toList());
|
||||
}
|
||||
@@ -1760,8 +1759,13 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
///
|
||||
///
|
||||
Future showGridOverlay() async {
|
||||
final ptr = SceneManager_createGrid(_sceneManager!);
|
||||
Future showGridOverlay({FFIMaterial? material}) async {
|
||||
late Pointer<TSceneAsset> ptr;
|
||||
if (material == null) {
|
||||
ptr = SceneManager_createGrid(_sceneManager!, nullptr);
|
||||
} else {
|
||||
ptr = SceneManager_createGrid(_sceneManager!, material.pointer);
|
||||
}
|
||||
_grid ??= FFIAsset(ptr, _sceneManager!, _engine!, _unlitMaterialProvider!);
|
||||
await _grid!.addToScene();
|
||||
}
|
||||
@@ -1819,6 +1823,16 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
destroy_texture(_sceneManager!, texture.pointer);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<Material> createMaterial(Uint8List data) async {
|
||||
var ptr = await withPointerCallback<TMaterial>((cb) {
|
||||
Engine_buildMaterialRenderThread(_engine!, data.address, data.length, cb);
|
||||
});
|
||||
return FFIMaterial(ptr, _engine!, _sceneManager!);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@@ -1905,8 +1919,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
throw Exception("Failed to create material instance");
|
||||
}
|
||||
|
||||
var instance =
|
||||
ThermionFFIMaterialInstance(materialInstance, _sceneManager!);
|
||||
var instance = FFIMaterialInstance(materialInstance, _sceneManager!);
|
||||
_materialInstances.add(instance);
|
||||
return instance;
|
||||
}
|
||||
@@ -1914,8 +1927,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
///
|
||||
///
|
||||
Future destroyMaterialInstance(
|
||||
ThermionFFIMaterialInstance materialInstance) async {
|
||||
Future destroyMaterialInstance(FFIMaterialInstance materialInstance) async {
|
||||
await materialInstance.dispose();
|
||||
_materialInstances.remove(materialInstance);
|
||||
}
|
||||
@@ -1923,11 +1935,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<ThermionFFIMaterialInstance> createUnlitMaterialInstance() async {
|
||||
Future<FFIMaterialInstance> createUnlitMaterialInstance() async {
|
||||
var instancePtr = await withPointerCallback<TMaterialInstance>((cb) {
|
||||
SceneManager_createUnlitMaterialInstanceRenderThread(_sceneManager!, cb);
|
||||
});
|
||||
final instance = ThermionFFIMaterialInstance(instancePtr, _sceneManager!);
|
||||
final instance = FFIMaterialInstance(instancePtr, _sceneManager!);
|
||||
_materialInstances.add(instance);
|
||||
return instance;
|
||||
}
|
||||
@@ -1935,13 +1947,12 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<ThermionFFIMaterialInstance>
|
||||
createUnlitFixedSizeMaterialInstance() async {
|
||||
Future<FFIMaterialInstance> createUnlitFixedSizeMaterialInstance() async {
|
||||
var instancePtr = await withPointerCallback<TMaterialInstance>((cb) {
|
||||
SceneManager_createUnlitFixedSizeMaterialInstanceRenderThread(
|
||||
_sceneManager!, cb);
|
||||
});
|
||||
final instance = ThermionFFIMaterialInstance(instancePtr, _sceneManager!);
|
||||
final instance = FFIMaterialInstance(instancePtr, _sceneManager!);
|
||||
_materialInstances.add(instance);
|
||||
return instance;
|
||||
}
|
||||
@@ -1954,7 +1965,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
final instancePtr = RenderableManager_getMaterialInstanceAt(
|
||||
_renderableManager!, entity, index);
|
||||
|
||||
final instance = ThermionFFIMaterialInstance(instancePtr, _sceneManager!);
|
||||
final instance = FFIMaterialInstance(instancePtr, _sceneManager!);
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -2065,8 +2076,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
Future<GizmoAsset> createGizmo(FFIView view, GizmoType gizmoType) async {
|
||||
var scene = View_getScene(view.view);
|
||||
final gizmo = await withPointerCallback<TGizmo>((cb) {
|
||||
SceneManager_createGizmoRenderThread(
|
||||
_sceneManager!, view.view, scene, TGizmoType.values[gizmoType.index], cb);
|
||||
SceneManager_createGizmoRenderThread(_sceneManager!, view.view, scene,
|
||||
TGizmoType.values[gizmoType.index], cb);
|
||||
});
|
||||
if (gizmo == nullptr) {
|
||||
throw Exception("Failed to create gizmo");
|
||||
|
||||
@@ -72,6 +72,11 @@ enum StencilFace {
|
||||
|
||||
enum AlphaMode { OPAQUE, MASK, BLEND }
|
||||
|
||||
abstract class Material {
|
||||
Future<MaterialInstance> createInstance();
|
||||
Future dispose();
|
||||
}
|
||||
|
||||
abstract class MaterialInstance {
|
||||
Future<bool> isStencilWriteEnabled();
|
||||
Future setDepthWriteEnabled(bool enabled);
|
||||
@@ -110,4 +115,6 @@ abstract class MaterialInstance {
|
||||
Future setStencilReadMask(int mask);
|
||||
Future setStencilWriteMask(int mask);
|
||||
|
||||
Future dispose();
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +40,11 @@ namespace thermion
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_loadIblRenderThread(TViewer *viewer, const char *iblPath, float intensity, void (*onComplete)());
|
||||
EMSCRIPTEN_KEEPALIVE void Viewer_createRenderTargetRenderThread(TViewer *viewer, intptr_t texture, uint32_t width, uint32_t height, void (*onComplete)(TRenderTarget *));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_buildMaterialRenderThread(TEngine *tEngine, const uint8_t* materialData, size_t length, void (*onComplete)(TMaterial *));
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, void (*onComplete)());
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Material_createInstanceRenderThread(TMaterial *tMaterial, void (*onComplete)(TMaterialInstance*));
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, thermion::ToneMapping toneMapping);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, double bloom);
|
||||
EMSCRIPTEN_KEEPALIVE void View_setCameraRenderThread(TView *tView, TCamera *tCamera, void (*callback)());
|
||||
|
||||
@@ -280,6 +280,37 @@ extern "C"
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_buildMaterialRenderThread(TEngine *tEngine, const uint8_t* materialData, size_t length, void (*onComplete)(TMaterial *)) {
|
||||
std::packaged_task<void()> lambda(
|
||||
[=]() mutable
|
||||
{
|
||||
auto material = Engine_buildMaterial(tEngine, materialData, length);
|
||||
onComplete(material);
|
||||
});
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyMaterialRenderThread(TEngine *tEngine, TMaterial *tMaterial, void (*onComplete)()) {
|
||||
std::packaged_task<void()> lambda(
|
||||
[=]() mutable
|
||||
{
|
||||
Engine_destroyMaterial(tEngine, tMaterial);
|
||||
onComplete();
|
||||
});
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Material_createInstanceRenderThread(TMaterial *tMaterial, void (*onComplete)(TMaterialInstance*)) {
|
||||
std::packaged_task<void()> lambda(
|
||||
[=]() mutable
|
||||
{
|
||||
auto *instance = Material_createInstance(tMaterial);
|
||||
onComplete(instance);
|
||||
});
|
||||
auto fut = _rl->add_task(lambda);
|
||||
}
|
||||
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void
|
||||
set_frame_interval_render_thread(TViewer *viewer, float frameIntervalInMilliseconds)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user