fix: store reference to material instances in ThermionViewer so they can be cleaned up on dispose
This commit is contained in:
@@ -122,7 +122,7 @@ class FFIAsset extends ThermionAsset {
|
||||
}
|
||||
var sourceMaterialInstance = ThermionFFIMaterialInstance(
|
||||
RenderableManager_getMaterialInstanceAt(
|
||||
renderableManager, targetEntity, 0));
|
||||
renderableManager, targetEntity, 0), sceneManager);
|
||||
|
||||
await sourceMaterialInstance.setStencilWriteEnabled(true);
|
||||
await sourceMaterialInstance.setDepthWriteEnabled(true);
|
||||
@@ -138,7 +138,7 @@ class FFIAsset extends ThermionAsset {
|
||||
_unlitMaterialProvider, key.address, cb);
|
||||
});
|
||||
final highlightMaterialInstance =
|
||||
ThermionFFIMaterialInstance(materialInstancePtr);
|
||||
ThermionFFIMaterialInstance(materialInstancePtr, sceneManager);
|
||||
await highlightMaterialInstance
|
||||
.setStencilCompareFunction(SamplerCompareFunction.NE);
|
||||
await highlightMaterialInstance.setStencilReferenceValue(1);
|
||||
|
||||
@@ -6,8 +6,9 @@ import 'package:thermion_dart/thermion_dart.dart';
|
||||
|
||||
class ThermionFFIMaterialInstance extends MaterialInstance {
|
||||
final Pointer<TMaterialInstance> pointer;
|
||||
final Pointer<TSceneManager> sceneManager;
|
||||
|
||||
ThermionFFIMaterialInstance(this.pointer) {
|
||||
ThermionFFIMaterialInstance(this.pointer, this.sceneManager) {
|
||||
if (pointer == nullptr) {
|
||||
throw Exception("MaterialInstance not found");
|
||||
}
|
||||
@@ -50,14 +51,17 @@ class ThermionFFIMaterialInstance extends MaterialInstance {
|
||||
|
||||
@override
|
||||
Future setDepthFunc(SamplerCompareFunction depthFunc) async {
|
||||
MaterialInstance_setDepthFunc(pointer, TSamplerCompareFunc.values[depthFunc.index]);
|
||||
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]);
|
||||
pointer,
|
||||
TSamplerCompareFunc.values[func.index],
|
||||
TStencilFace.values[face.index]);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -113,4 +117,8 @@ class ThermionFFIMaterialInstance extends MaterialInstance {
|
||||
Future setStencilWriteMask(int mask) async {
|
||||
MaterialInstance_setStencilWriteMask(pointer, mask);
|
||||
}
|
||||
|
||||
Future dispose() async {
|
||||
SceneManager_destroyMaterialInstance(sceneManager, pointer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,6 +282,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
final _onDispose = <Future Function()>[];
|
||||
bool _disposing = false;
|
||||
|
||||
final _materialInstances = <ThermionFFIMaterialInstance>[];
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
@@ -291,12 +293,13 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
throw Exception("Viewer has already been disposed.");
|
||||
}
|
||||
_disposing = true;
|
||||
|
||||
await setRendering(false);
|
||||
await clearEntities();
|
||||
for (final mInstance in _materialInstances) {
|
||||
await mInstance.dispose();
|
||||
}
|
||||
await clearLights();
|
||||
|
||||
// await _sceneUpdateEventController.close();
|
||||
Viewer_destroyOnRenderThread(_viewer!);
|
||||
_sceneManager = null;
|
||||
_viewer = null;
|
||||
@@ -984,9 +987,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
_sceneManager!, asset.pointer, callback));
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
@@ -1880,7 +1880,10 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
throw Exception("Failed to create material instance");
|
||||
}
|
||||
|
||||
return ThermionFFIMaterialInstance(materialInstance);
|
||||
var instance =
|
||||
ThermionFFIMaterialInstance(materialInstance, _sceneManager!);
|
||||
_materialInstances.add(instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1888,21 +1891,20 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
Future destroyMaterialInstance(
|
||||
ThermionFFIMaterialInstance materialInstance) async {
|
||||
SceneManager_destroyMaterialInstance(
|
||||
_sceneManager!, materialInstance.pointer);
|
||||
await materialInstance.dispose();
|
||||
_materialInstances.remove(materialInstance);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
Future<ThermionFFIMaterialInstance> createUnlitMaterialInstance() async {
|
||||
var instance = await withPointerCallback<TMaterialInstance>((cb) {
|
||||
var instancePtr = await withPointerCallback<TMaterialInstance>((cb) {
|
||||
SceneManager_createUnlitMaterialInstanceRenderThread(_sceneManager!, cb);
|
||||
});
|
||||
if (instance == nullptr) {
|
||||
throw Exception("Failed to create material instance");
|
||||
}
|
||||
return ThermionFFIMaterialInstance(instance);
|
||||
final instance = ThermionFFIMaterialInstance(instancePtr, _sceneManager!);
|
||||
_materialInstances.add(instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1910,14 +1912,13 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
Future<ThermionFFIMaterialInstance>
|
||||
createUnlitFixedSizeMaterialInstance() async {
|
||||
var instance = await withPointerCallback<TMaterialInstance>((cb) {
|
||||
var instancePtr = await withPointerCallback<TMaterialInstance>((cb) {
|
||||
SceneManager_createUnlitFixedSizeMaterialInstanceRenderThread(
|
||||
_sceneManager!, cb);
|
||||
});
|
||||
if (instance == nullptr) {
|
||||
throw Exception("Failed to create material instance");
|
||||
}
|
||||
return ThermionFFIMaterialInstance(instance);
|
||||
final instance = ThermionFFIMaterialInstance(instancePtr, _sceneManager!);
|
||||
_materialInstances.add(instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -1925,12 +1926,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
///
|
||||
Future<MaterialInstance> getMaterialInstanceAt(
|
||||
ThermionEntity entity, int index) async {
|
||||
final instance = RenderableManager_getMaterialInstanceAt(
|
||||
final instancePtr = RenderableManager_getMaterialInstanceAt(
|
||||
_renderableManager!, entity, index);
|
||||
if (instance == nullptr) {
|
||||
throw Exception("Failed to get material instance");
|
||||
}
|
||||
return ThermionFFIMaterialInstance(instance);
|
||||
|
||||
final instance = ThermionFFIMaterialInstance(instancePtr, _sceneManager!);
|
||||
return instance;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2036,8 +2036,8 @@ class ThermionViewerFFI extends ThermionViewer {
|
||||
SceneManager_getOverlayEntityCount(_sceneManager!);
|
||||
final overlayEntities = List<ThermionEntity>.generate(overlayEntityCount,
|
||||
(i) => SceneManager_getOverlayEntityAt(_sceneManager!, i)).toSet();
|
||||
return FFIGizmo(
|
||||
view, gizmo.cast<TSceneAsset>(), _sceneManager!, _engine!, nullptr, overlayEntities);
|
||||
return FFIGizmo(view, gizmo.cast<TSceneAsset>(), _sceneManager!, _engine!,
|
||||
nullptr, overlayEntities);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ enum StencilFace {
|
||||
BACK,
|
||||
|
||||
/// Both front and back faces
|
||||
FRONT_AND_BACK
|
||||
FRONT_AND_BACK
|
||||
}
|
||||
|
||||
enum AlphaMode { OPAQUE, MASK, BLEND }
|
||||
@@ -109,4 +109,5 @@ abstract class MaterialInstance {
|
||||
|
||||
Future setStencilReadMask(int mask);
|
||||
Future setStencilWriteMask(int mask);
|
||||
|
||||
}
|
||||
|
||||
@@ -792,28 +792,28 @@ abstract class ThermionViewer {
|
||||
AlphaMode alphaMode = AlphaMode.OPAQUE,
|
||||
bool enableDiagnostics = false,
|
||||
bool hasMetallicRoughnessTexture = false,
|
||||
int metallicRoughnessUV = 0,
|
||||
int baseColorUV = 0,
|
||||
int metallicRoughnessUV = -1,
|
||||
int baseColorUV = -1,
|
||||
bool hasClearCoatTexture = false,
|
||||
int clearCoatUV = 0,
|
||||
int clearCoatUV = -1,
|
||||
bool hasClearCoatRoughnessTexture = false,
|
||||
int clearCoatRoughnessUV = 0,
|
||||
int clearCoatRoughnessUV = -1,
|
||||
bool hasClearCoatNormalTexture = false,
|
||||
int clearCoatNormalUV = 0,
|
||||
int clearCoatNormalUV = -1,
|
||||
bool hasClearCoat = false,
|
||||
bool hasTransmission = false,
|
||||
bool hasTextureTransforms = false,
|
||||
int emissiveUV = 0,
|
||||
int aoUV = 0,
|
||||
int normalUV = 0,
|
||||
int emissiveUV = -1,
|
||||
int aoUV = -1,
|
||||
int normalUV = -1,
|
||||
bool hasTransmissionTexture = false,
|
||||
int transmissionUV = 0,
|
||||
int transmissionUV = -1,
|
||||
bool hasSheenColorTexture = false,
|
||||
int sheenColorUV = 0,
|
||||
int sheenColorUV = -1,
|
||||
bool hasSheenRoughnessTexture = false,
|
||||
int sheenRoughnessUV = 0,
|
||||
int sheenRoughnessUV = -1,
|
||||
bool hasVolumeThicknessTexture = false,
|
||||
int volumeThicknessUV = 0,
|
||||
int volumeThicknessUV = -1,
|
||||
bool hasSheen = false,
|
||||
bool hasIOR = false,
|
||||
bool hasVolume = false,
|
||||
|
||||
Reference in New Issue
Block a user