From 0b9f3160d948581b6268ee6f1926608fedf57462 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Fri, 15 Nov 2024 22:56:40 +0800 Subject: [PATCH] feat: add MaterialInstance.setDepthFunc --- .../viewer/src/ffi/src/thermion_dart.g.dart | 200 ++++++++++++------ .../src/ffi/src/thermion_viewer_ffi.dart | 5 + .../src/viewer/src/shared_types/material.dart | 21 ++ .../src/web_wasm/src/material_instance.dart | 18 ++ .../native/include/APIBoundaryTypes.h | 72 +++---- .../native/include/TMaterialInstance.h | 19 +- .../native/include/ThermionDartApi.h | 1 + .../native/src/TMaterialInstance.cpp | 6 + thermion_dart/test/material_tests.dart | 28 +++ 9 files changed, 262 insertions(+), 108 deletions(-) diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart index 7e69306f..6891dabe 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_dart.g.dart @@ -7,6 +7,76 @@ library; import 'dart:ffi' as ffi; +@ffi.Native, ffi.Bool)>( + isLeaf: true) +external void MaterialInstance_setDepthWrite( + ffi.Pointer materialInstance, + bool enabled, +); + +@ffi.Native, ffi.Bool)>( + isLeaf: true) +external void MaterialInstance_setDepthCulling( + ffi.Pointer materialInstance, + bool enabled, +); + +@ffi.Native< + ffi.Void Function(ffi.Pointer, ffi.Pointer, + ffi.Double, ffi.Double, ffi.Double, ffi.Double)>(isLeaf: true) +external void MaterialInstance_setParameterFloat4( + ffi.Pointer materialInstance, + ffi.Pointer name, + double x, + double y, + double w, + double z, +); + +@ffi.Native< + ffi.Void Function(ffi.Pointer, ffi.Pointer, + ffi.Double, ffi.Double)>(isLeaf: true) +external void MaterialInstance_setParameterFloat2( + ffi.Pointer materialInstance, + ffi.Pointer name, + double x, + double y, +); + +@ffi.Native< + ffi.Void Function(ffi.Pointer, ffi.Pointer, + ffi.Double)>(isLeaf: true) +external void MaterialInstance_setParameterFloat( + ffi.Pointer materialInstance, + ffi.Pointer name, + double value, +); + +@ffi.Native< + ffi.Void Function(ffi.Pointer, ffi.Pointer, + ffi.Int)>(isLeaf: true) +external void MaterialInstance_setParameterInt( + ffi.Pointer materialInstance, + ffi.Pointer name, + int value, +); + +@ffi.Native, ffi.UnsignedInt)>( + symbol: "MaterialInstance_setDepthFunc", isLeaf: true) +external void _MaterialInstance_setDepthFunc( + ffi.Pointer materialInstance, + int depthFunc, +); + +void MaterialInstance_setDepthFunc( + ffi.Pointer materialInstance, + TDepthFunc depthFunc, +) => + _MaterialInstance_setDepthFunc( + materialInstance, + depthFunc.value, + ); + @ffi.Native< ffi.Pointer Function(LoadFilamentResourceFromOwner, FreeFilamentResourceFromOwner, ffi.Pointer)>(isLeaf: true) @@ -1205,60 +1275,6 @@ external ffi.Pointer get_material_instance_at( int materialIndex, ); -@ffi.Native, ffi.Bool)>( - isLeaf: true) -external void MaterialInstance_setDepthWrite( - ffi.Pointer materialInstance, - bool enabled, -); - -@ffi.Native, ffi.Bool)>( - isLeaf: true) -external void MaterialInstance_setDepthCulling( - ffi.Pointer materialInstance, - bool enabled, -); - -@ffi.Native< - ffi.Void Function(ffi.Pointer, ffi.Pointer, - ffi.Double, ffi.Double, ffi.Double, ffi.Double)>(isLeaf: true) -external void MaterialInstance_setParameterFloat4( - ffi.Pointer materialInstance, - ffi.Pointer name, - double x, - double y, - double w, - double z, -); - -@ffi.Native< - ffi.Void Function(ffi.Pointer, ffi.Pointer, - ffi.Double, ffi.Double)>(isLeaf: true) -external void MaterialInstance_setParameterFloat2( - ffi.Pointer materialInstance, - ffi.Pointer name, - double x, - double y, -); - -@ffi.Native< - ffi.Void Function(ffi.Pointer, ffi.Pointer, - ffi.Double)>(isLeaf: true) -external void MaterialInstance_setParameterFloat( - ffi.Pointer materialInstance, - ffi.Pointer name, - double value, -); - -@ffi.Native< - ffi.Void Function(ffi.Pointer, ffi.Pointer, - ffi.Int)>(isLeaf: true) -external void MaterialInstance_setParameterInt( - ffi.Pointer materialInstance, - ffi.Pointer name, - int value, -); - @ffi.Native)>(isLeaf: true) external TViewport View_getViewport( ffi.Pointer view, @@ -1487,19 +1503,6 @@ external void Viewer_captureRenderTargetRenderThread( ffi.Pointer> onComplete, ); -@ffi.Native< - ffi.Pointer Function( - ffi.Pointer, ffi.IntPtr, ffi.Uint32, ffi.Uint32, - ffi.Pointer)>> - )>(isLeaf: true) -external ffi.Pointer Viewer_createRenderTargetRenderThread( - ffi.Pointer viewer, - int texture, - int width, - int height, - ffi.Pointer)>> onComplete, -); - @ffi.Native< ffi.Void Function(ffi.Pointer, ffi.Pointer>)>(isLeaf: true) @@ -1518,6 +1521,24 @@ external void Viewer_loadIblRenderThread( ffi.Pointer> onComplete, ); +@ffi.Native< + ffi.Void Function( + ffi.Pointer, + ffi.IntPtr, + ffi.Uint32, + ffi.Uint32, + ffi.Pointer< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer)>>)>(isLeaf: true) +external void Viewer_createRenderTargetRenderThread( + ffi.Pointer viewer, + int texture, + int width, + int height, + ffi.Pointer)>> + onComplete, +); + @ffi.Native< ffi.Void Function( ffi.Pointer, ffi.Pointer, ffi.Int)>(isLeaf: true) @@ -2124,10 +2145,51 @@ external void Gizmo_setVisibility( bool visible, ); -final class TCamera extends ffi.Opaque {} - final class TMaterialInstance extends ffi.Opaque {} +enum TDepthFunc { + /// !< Less or equal + LE(0), + + /// !< Greater or equal + GE(1), + + /// !< Strictly less than + L(2), + + /// !< Strictly greater than + G(3), + + /// !< Equal + E(4), + + /// !< Not equal + NE(5), + + /// !< Always. Depth / stencil testing is deactivated. + A(6), + + /// !< Never. The depth / stencil test always fails. + N(7); + + final int value; + const TDepthFunc(this.value); + + static TDepthFunc fromValue(int value) => switch (value) { + 0 => LE, + 1 => GE, + 2 => L, + 3 => G, + 4 => E, + 5 => NE, + 6 => A, + 7 => N, + _ => throw ArgumentError("Unknown value for TDepthFunc: $value"), + }; +} + +final class TCamera extends ffi.Opaque {} + final class TEngine extends ffi.Opaque {} final class TEntityManager extends ffi.Opaque {} diff --git a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart index cd995f1c..0bfb0bcf 100644 --- a/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart +++ b/thermion_dart/lib/src/viewer/src/ffi/src/thermion_viewer_ffi.dart @@ -2277,6 +2277,11 @@ class ThermionFFIMaterialInstance extends MaterialInstance { MaterialInstance_setParameterInt( _pointer, name.toNativeUtf8().cast(), value); } + + @override + Future setDepthFunc(SampleCompareFunction depthFunc) async { + MaterialInstance_setDepthFunc(_pointer, TDepthFunc.values[depthFunc.index]); + } } diff --git a/thermion_dart/lib/src/viewer/src/shared_types/material.dart b/thermion_dart/lib/src/viewer/src/shared_types/material.dart index efd2455e..b4d0bbb2 100644 --- a/thermion_dart/lib/src/viewer/src/shared_types/material.dart +++ b/thermion_dart/lib/src/viewer/src/shared_types/material.dart @@ -1,5 +1,26 @@ +import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart'; + +enum SampleCompareFunction { + /// !< Less or equal + LE, + /// !< Greater or equal + GE, + /// !< Strictly less than + L, + /// !< Strictly greater than + G, + /// !< Equal + E, + /// !< Not equal + NE, + /// !< Always. Depth / stencil testing is deactivated. + A, + /// !< Never. The depth / stencil test always fails. + N; +} abstract class MaterialInstance { Future setDepthWriteEnabled(bool enabled); + Future setDepthFunc(SampleCompareFunction depthFunc); Future setDepthCullingEnabled(bool enabled); Future setParameterFloat4(String name, double x, double y, double z, double w); diff --git a/thermion_dart/lib/src/viewer/src/web_wasm/src/material_instance.dart b/thermion_dart/lib/src/viewer/src/web_wasm/src/material_instance.dart index 3aaabf72..1f29be38 100644 --- a/thermion_dart/lib/src/viewer/src/web_wasm/src/material_instance.dart +++ b/thermion_dart/lib/src/viewer/src/web_wasm/src/material_instance.dart @@ -27,4 +27,22 @@ class ThermionWasmMaterialInstance extends MaterialInstance { // TODO: implement setParameterFloat throw UnimplementedError(); } + + @override + Future setDepthFunc(SampleCompareFunction depthFunc) { + // TODO: implement setDepthFunc + throw UnimplementedError(); + } + + @override + Future setParameterFloat4(String name, double x, double y, double z, double w) { + // TODO: implement setParameterFloat4 + throw UnimplementedError(); + } + + @override + Future setParameterInt(String name, int value) { + // TODO: implement setParameterInt + throw UnimplementedError(); + } } diff --git a/thermion_dart/native/include/APIBoundaryTypes.h b/thermion_dart/native/include/APIBoundaryTypes.h index ee780947..27c599a7 100644 --- a/thermion_dart/native/include/APIBoundaryTypes.h +++ b/thermion_dart/native/include/APIBoundaryTypes.h @@ -6,10 +6,10 @@ extern "C" #endif #include +#include "TMaterialInstance.h" typedef int32_t EntityId; typedef struct TCamera TCamera; - typedef struct TMaterialInstance TMaterialInstance; typedef struct TEngine TEngine; typedef struct TEntityManager TEntityManager; typedef struct TViewer TViewer; @@ -19,18 +19,18 @@ extern "C" typedef struct TView TView; typedef struct TGizmo TGizmo; typedef struct TScene TScene; - + struct TMaterialKey { - bool doubleSided = true; - bool unlit = true; - bool hasVertexColors = true; - bool hasBaseColorTexture = true; - bool hasNormalTexture = true; - bool hasOcclusionTexture = true; - bool hasEmissiveTexture = true; - bool useSpecularGlossiness = true; - int alphaMode = 4; - bool enableDiagnostics = 4; + bool doubleSided; + bool unlit; + bool hasVertexColors; + bool hasBaseColorTexture; + bool hasNormalTexture; + bool hasOcclusionTexture; + bool hasEmissiveTexture; + bool useSpecularGlossiness; + int alphaMode; + bool enableDiagnostics; union { #ifdef __cplusplus struct { @@ -43,42 +43,42 @@ extern "C" }; #else struct { - bool hasMetallicRoughnessTexture = true; - uint8_t metallicRoughnessUV = 7; + bool hasMetallicRoughnessTexture; + uint8_t metallicRoughnessUV; }; struct { - bool hasSpecularGlossinessTexture = true; - uint8_t specularGlossinessUV = 7; + bool hasSpecularGlossinessTexture; + uint8_t specularGlossinessUV; }; #endif }; uint8_t baseColorUV; // -- 32 bit boundary -- - bool hasClearCoatTexture = true; - uint8_t clearCoatUV = 7; - bool hasClearCoatRoughnessTexture = true; - uint8_t clearCoatRoughnessUV = 7; - bool hasClearCoatNormalTexture = true; - uint8_t clearCoatNormalUV = 7; - bool hasClearCoat = true; - bool hasTransmission = true; - bool hasTextureTransforms = 6; + bool hasClearCoatTexture; + uint8_t clearCoatUV; + bool hasClearCoatRoughnessTexture; + uint8_t clearCoatRoughnessUV; + bool hasClearCoatNormalTexture; + uint8_t clearCoatNormalUV; + bool hasClearCoat; + bool hasTransmission; + bool hasTextureTransforms; // -- 32 bit boundary -- uint8_t emissiveUV; uint8_t aoUV; uint8_t normalUV; - bool hasTransmissionTexture = true; - uint8_t transmissionUV = 7; + bool hasTransmissionTexture; + uint8_t transmissionUV; // -- 32 bit boundary -- - bool hasSheenColorTexture = true; - uint8_t sheenColorUV = 7; - bool hasSheenRoughnessTexture = true; - uint8_t sheenRoughnessUV = 7; - bool hasVolumeThicknessTexture = true; - uint8_t volumeThicknessUV = 7; - bool hasSheen = true; - bool hasIOR = true; - bool hasVolume = true; + bool hasSheenColorTexture; + uint8_t sheenColorUV; + bool hasSheenRoughnessTexture; + uint8_t sheenRoughnessUV; + bool hasVolumeThicknessTexture; + uint8_t volumeThicknessUV ; + bool hasSheen; + bool hasIOR; + bool hasVolume; } ; typedef struct TMaterialKey TMaterialKey; diff --git a/thermion_dart/native/include/TMaterialInstance.h b/thermion_dart/native/include/TMaterialInstance.h index 11589ab4..dae73f24 100644 --- a/thermion_dart/native/include/TMaterialInstance.h +++ b/thermion_dart/native/include/TMaterialInstance.h @@ -45,9 +45,21 @@ #include #endif -#include "APIBoundaryTypes.h" -#include "ResourceBuffer.hpp" -#include "ThermionDartAPIUtils.h" +typedef struct TMaterialInstance TMaterialInstance; + +// copied from SamplerCompareFunc in DriverEnums.h +enum TDepthFunc { + // don't change the enums values + LE = 0, //!< Less or equal + GE, //!< Greater or equal + L, //!< Strictly less than + G, //!< Strictly greater than + E, //!< Equal + NE, //!< Not equal + A, //!< Always. Depth / stencil testing is deactivated. + N //!< Never. The depth / stencil test always fails. +}; + #ifdef __cplusplus extern "C" @@ -59,6 +71,7 @@ extern "C" EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance* materialInstance, const char* name, double x, double y); EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat(TMaterialInstance* materialInstance, const char* name, double value); EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterInt(TMaterialInstance* materialInstance, const char* name, int value); + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthFunc(TMaterialInstance* materialInstance, TDepthFunc depthFunc); #ifdef __cplusplus } #endif diff --git a/thermion_dart/native/include/ThermionDartApi.h b/thermion_dart/native/include/ThermionDartApi.h index 06b26bf0..e7303168 100644 --- a/thermion_dart/native/include/ThermionDartApi.h +++ b/thermion_dart/native/include/ThermionDartApi.h @@ -49,6 +49,7 @@ #include "APIBoundaryTypes.h" #include "ResourceBuffer.hpp" #include "ThermionDartAPIUtils.h" +#include "TMaterialInstance.h" #ifdef __cplusplus extern "C" diff --git a/thermion_dart/native/src/TMaterialInstance.cpp b/thermion_dart/native/src/TMaterialInstance.cpp index 514e4e7b..3519999b 100644 --- a/thermion_dart/native/src/TMaterialInstance.cpp +++ b/thermion_dart/native/src/TMaterialInstance.cpp @@ -45,6 +45,12 @@ namespace thermion { reinterpret_cast<::filament::MaterialInstance *>(materialInstance)->setParameter(propertyName, value); } + + EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthFunc(TMaterialInstance *tMaterialInstance, TDepthFunc tDepthFunc) { + auto *materialInstance = reinterpret_cast<::filament::MaterialInstance *>(tMaterialInstance); + auto depthFunc = static_cast(tDepthFunc); + materialInstance->setDepthFunc(depthFunc); + } #ifdef __cplusplus } } diff --git a/thermion_dart/test/material_tests.dart b/thermion_dart/test/material_tests.dart index 667fa9d8..031eb660 100644 --- a/thermion_dart/test/material_tests.dart +++ b/thermion_dart/test/material_tests.dart @@ -146,6 +146,34 @@ void main() async { }); group("MaterialInstance", () { + test('set depth func to always', () async { + var viewer = await testHelper.createViewer( + bg: kRed, cameraPosition: Vector3(0, 0, 6)); + + var materialInstance1 = await viewer.createUnlitMaterialInstance(); + final cube1 = await viewer.createGeometry(GeometryHelper.cube(), + materialInstance: materialInstance1); + + await materialInstance1! + .setParameterFloat4("baseColorFactor", 0.0, 1.0, 0.0, 1.0); + + var materialInstance2 = await viewer.createUnlitMaterialInstance(); + final cube2 = await viewer.createGeometry(GeometryHelper.cube(), + materialInstance: materialInstance2); + await viewer.setPosition(cube2, 1.0, 0.0, -1.0); + + await materialInstance2! + .setParameterFloat4("baseColorFactor", 0.0, 0.0, 1.0, 1.0); + + // with default depth func, blue cube renders behind the green cube + await testHelper.capture(viewer, "material_instance_depth_func_default"); + + await materialInstance2.setDepthFunc(SampleCompareFunction.A); + + await testHelper.capture(viewer, "material_instance_depth_func_always"); + await viewer.dispose(); + }); + test('disable depth write', () async { var viewer = await testHelper.createViewer(); await viewer.setBackgroundColor(1.0, 0.0, 0.0, 1.0);