add more Dart-side Texture methods

This commit is contained in:
Nick Fisher
2025-03-17 16:57:22 +08:00
parent f2ce4a4044
commit 09678c6cdc
5 changed files with 835 additions and 224 deletions

View File

@@ -16,4 +16,10 @@ class FFIRenderTarget extends RenderTarget {
final ptr = RenderTarget_getColorTexture(renderTarget);
return FFITexture(engine, ptr);
}
@override
Future<Texture> getDepthTexture() async {
final ptr = RenderTarget_getDepthTexture(renderTarget);
return FFITexture(engine, ptr);
}
}

View File

@@ -9,18 +9,18 @@ class FFITexture extends Texture {
FFITexture(this._engine, this.pointer);
Future<void> setLinearImage(covariant FFILinearImage image, PixelDataFormat format,
PixelDataType type) async {
Future<void> setLinearImage(covariant FFILinearImage image,
PixelDataFormat format, PixelDataType type) async {
final result = await withBoolCallback((cb) {
Texture_loadImageRenderThread(
_engine,
pointer,
image.pointer,
TPixelDataFormat.values[format.index],
TPixelDataType.values[type.index],
cb);
_engine,
pointer,
image.pointer,
format.index,
type.index,
cb);
});
if (!result) {
throw Exception("Failed to set linear image");
}
@@ -40,9 +40,8 @@ class FFITexture extends Texture {
}
@override
Future<int> getDepth([int level = 0]) {
// TODO: implement getDepth
throw UnimplementedError();
Future<int> getDepth([int level = 0]) async {
return Texture_getDepth(pointer, level);
}
@override
@@ -52,9 +51,8 @@ class FFITexture extends Texture {
}
@override
Future<int> getHeight([int level = 0]) {
// TODO: implement getHeight
throw UnimplementedError();
Future<int> getHeight([int level = 0]) async {
return Texture_getHeight(pointer, level);
}
@override
@@ -70,9 +68,8 @@ class FFITexture extends Texture {
}
@override
Future<int> getWidth([int level = 0]) {
// TODO: implement getWidth
throw UnimplementedError();
Future<int> getWidth([int level = 0]) async {
return Texture_getWidth(pointer, level);
}
@override
@@ -86,19 +83,19 @@ class FFITexture extends Texture {
int channels, PixelDataFormat format, PixelDataType type) async {
final success = await withBoolCallback((cb) {
Texture_setImageRenderThread(
_engine,
pointer,
level,
buffer.address,
buffer.lengthInBytes,
width,
height,
channels,
format.index,
type.index,
cb);
_engine,
pointer,
level,
buffer.address,
buffer.lengthInBytes,
width,
height,
channels,
format.index,
type.index,
cb);
});
if (!success) {
throw Exception("Failed to set image");
}
@@ -118,32 +115,39 @@ class FFITexture extends Texture {
PixelDataFormat format,
PixelDataType type) async {
final success = await withBoolCallback((cb) {
Texture_setImageWithDepthRenderThread(
_engine,
pointer,
level,
buffer.address,
buffer.lengthInBytes,
0,
0,
zOffset,
width,
height,
channels,
depth,
format.index,
type.index,
cb);
Texture_setImageWithDepthRenderThread(
_engine,
pointer,
level,
buffer.address,
buffer.lengthInBytes,
0,
0,
zOffset,
width,
height,
channels,
depth,
format.index,
type.index,
cb);
});
if (!success) {
throw Exception("Failed to set image");
}
}
@override
Future<void> setSubImage(int level, int xOffset, int yOffset, int width, int height,
Uint8List buffer, PixelDataFormat format, PixelDataType type) {
Future<void> setSubImage(
int level,
int xOffset,
int yOffset,
int width,
int height,
Uint8List buffer,
PixelDataFormat format,
PixelDataType type) {
// TODO: implement setSubImage
throw UnimplementedError();
}
@@ -154,22 +158,25 @@ class FFILinearImage extends LinearImage {
FFILinearImage(this.pointer);
static Future<FFILinearImage> createEmpty(int width, int height, int channels) async {
static Future<FFILinearImage> createEmpty(
int width, int height, int channels) async {
final imagePtr = await withPointerCallback<TLinearImage>((cb) {
Image_createEmptyRenderThread(width, height, channels, cb);
});
return FFILinearImage(imagePtr);
}
static Future<FFILinearImage> decode(Uint8List data, [String name = "image"]) async {
static Future<FFILinearImage> decode(Uint8List data,
[String name = "image"]) async {
final namePtr = name.toNativeUtf8();
try {
final imagePtr = await withPointerCallback<TLinearImage>((cb) {
Image_decodeRenderThread(data.address, data.lengthInBytes, namePtr.cast(), cb);
Image_decodeRenderThread(
data.address, data.lengthInBytes, namePtr.cast(), cb);
});
return FFILinearImage(imagePtr);
} finally {
calloc.free(namePtr);
@@ -208,11 +215,11 @@ class FFILinearImage extends LinearImage {
final height = await getHeight();
final width = await getWidth();
final channels = await getChannels();
final ptr = await withPointerCallback<Float>((cb) {
Image_getBytesRenderThread(pointer, cb);
});
return ptr.asTypedList(height * width * channels);
}
}
@@ -228,7 +235,7 @@ class FFITextureSampler extends TextureSampler {
final samplerPtr = await withPointerCallback<TTextureSampler>((cb) {
TextureSampler_createRenderThread(cb);
});
return FFITextureSampler(samplerPtr);
}
@@ -247,7 +254,7 @@ class FFITextureSampler extends TextureSampler {
// TSamplerWrapMode.values[wrapR.index],
// cb);
// });
// return FFITextureSampler(samplerPtr);
// }
@@ -260,15 +267,15 @@ class FFITextureSampler extends TextureSampler {
// TTextureSamplerCompareFunc.values[compareFunc.index],
// cb);
// });
// return FFITextureSampler(samplerPtr);
// }
// Future<void> setMinFilter(SamplerMinFilter filter) async {
// await withVoidCallback((cb) {
// TextureSampler_setMinFilterRenderThread(
// pointer,
// TSamplerMinFilter.values[filter.index],
// pointer,
// TSamplerMinFilter.values[filter.index],
// cb);
// });
// }
@@ -276,8 +283,8 @@ class FFITextureSampler extends TextureSampler {
// Future<void> setMagFilter(SamplerMagFilter filter) async {
// await withVoidCallback((cb) {
// TextureSampler_setMagFilterRenderThread(
// pointer,
// TSamplerMagFilter.values[filter.index],
// pointer,
// TSamplerMagFilter.values[filter.index],
// cb);
// });
// }
@@ -285,8 +292,8 @@ class FFITextureSampler extends TextureSampler {
// Future<void> setWrapModeS(SamplerWrapMode mode) async {
// await withVoidCallback((cb) {
// TextureSampler_setWrapModeSRenderThread(
// pointer,
// TSamplerWrapMode.values[mode.index],
// pointer,
// TSamplerWrapMode.values[mode.index],
// cb);
// });
// }
@@ -294,8 +301,8 @@ class FFITextureSampler extends TextureSampler {
// Future<void> setWrapModeT(SamplerWrapMode mode) async {
// await withVoidCallback((cb) {
// TextureSampler_setWrapModeTRenderThread(
// pointer,
// TSamplerWrapMode.values[mode.index],
// pointer,
// TSamplerWrapMode.values[mode.index],
// cb);
// });
// }
@@ -303,8 +310,8 @@ class FFITextureSampler extends TextureSampler {
// Future<void> setWrapModeR(SamplerWrapMode mode) async {
// await withVoidCallback((cb) {
// TextureSampler_setWrapModeRRenderThread(
// pointer,
// TSamplerWrapMode.values[mode.index],
// pointer,
// TSamplerWrapMode.values[mode.index],
// cb);
// });
// }
@@ -325,11 +332,11 @@ class FFITextureSampler extends TextureSampler {
// cb);
// });
// }
@override
Future dispose() async {
await withVoidCallback((cb) {
TextureSampler_destroyRenderThread(pointer, cb);
});
}
}
}

View File

@@ -1,5 +1,6 @@
import 'dart:ffi';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_dart.g.dart';
import 'package:thermion_dart/src/viewer/src/shared_types/shared_types.dart';
import 'callbacks.dart';
@@ -24,8 +25,8 @@ class FFIView extends View {
}
@override
Future updateViewport(int width, int height) async {
View_updateViewport(view, width, height);
Future setViewport(int width, int height) async {
View_setViewport(view, width, height);
}
Future<RenderTarget?> getRenderTarget() async {

View File

@@ -7,6 +7,18 @@ library;
import 'dart:ffi' as ffi;
@ffi.Native<ffi.Uint64>()
external int TSWAP_CHAIN_CONFIG_TRANSPARENT;
@ffi.Native<ffi.Uint64>()
external int TSWAP_CHAIN_CONFIG_READABLE;
@ffi.Native<ffi.Uint64>()
external int TSWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER;
@ffi.Native<ffi.Uint64>()
external int TSWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER;
@ffi.Native<ffi.Pointer<TMaterialInstance> Function(ffi.Pointer<TMaterial>)>(
isLeaf: true)
external ffi.Pointer<TMaterialInstance> Material_createInstance(
@@ -387,6 +399,11 @@ external ffi.Pointer<TViewer> Viewer_create(
ffi.Pointer<ffi.Char> uberArchivePath,
);
@ffi.Native<ffi.Pointer<TRenderer> Function(ffi.Pointer<TViewer>)>(isLeaf: true)
external ffi.Pointer<TRenderer> Viewer_getRenderer(
ffi.Pointer<TViewer> tViewer,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
external void Viewer_destroy(
ffi.Pointer<TViewer> viewer,
@@ -399,11 +416,12 @@ external ffi.Pointer<TSceneManager> Viewer_getSceneManager(
);
@ffi.Native<
ffi.Pointer<TRenderTarget> Function(
ffi.Pointer<TViewer>, ffi.IntPtr, ffi.Uint32, ffi.Uint32)>(isLeaf: true)
ffi.Pointer<TRenderTarget> Function(ffi.Pointer<TViewer>, ffi.IntPtr,
ffi.IntPtr, ffi.Uint32, ffi.Uint32)>(isLeaf: true)
external ffi.Pointer<TRenderTarget> Viewer_createRenderTarget(
ffi.Pointer<TViewer> viewer,
int texture,
int colorTextureId,
int depthTextureId,
int width,
int height,
);
@@ -451,12 +469,14 @@ external void Viewer_render(
ffi.Pointer<TView>,
ffi.Pointer<TSwapChain>,
ffi.Pointer<ffi.Uint8>,
ffi.Bool,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Viewer_capture(
ffi.Pointer<TViewer> viewer,
ffi.Pointer<TView> view,
ffi.Pointer<TSwapChain> swapChain,
ffi.Pointer<ffi.Uint8> pixelBuffer,
bool useFence,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
);
@@ -467,6 +487,7 @@ external void Viewer_capture(
ffi.Pointer<TSwapChain>,
ffi.Pointer<TRenderTarget>,
ffi.Pointer<ffi.Uint8>,
ffi.Bool,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Viewer_captureRenderTarget(
ffi.Pointer<TViewer> viewer,
@@ -474,6 +495,7 @@ external void Viewer_captureRenderTarget(
ffi.Pointer<TSwapChain> swapChain,
ffi.Pointer<TRenderTarget> renderTarget,
ffi.Pointer<ffi.Uint8> pixelBuffer,
bool useFence,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
);
@@ -707,7 +729,7 @@ external TViewport View_getViewport(
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Uint32, ffi.Uint32)>(
isLeaf: true)
external void View_updateViewport(
external void View_setViewport(
ffi.Pointer<TView> view,
int width,
int height,
@@ -859,6 +881,13 @@ external bool View_isDitheringEnabled(
ffi.Pointer<TView> tView,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TView>, ffi.Pointer<TScene>)>(
isLeaf: true)
external void View_setScene(
ffi.Pointer<TView> tView,
ffi.Pointer<TScene> tScene,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TView>, ffi.Uint32, ffi.Uint32, ffi.Uint32,
PickCallback)>(isLeaf: true)
@@ -884,8 +913,8 @@ external ffi.Pointer<ffi.Char> NameComponentManager_getName(
ffi.Pointer<TTexture>,
ffi.Pointer<TLinearImage>,
ffi.UnsignedInt,
ffi.UnsignedInt)>(symbol: "Texture_loadImage", isLeaf: true)
external bool _Texture_loadImage(
ffi.UnsignedInt)>(isLeaf: true)
external bool Texture_loadImage(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TTexture> tTexture,
ffi.Pointer<TLinearImage> tImage,
@@ -893,21 +922,6 @@ external bool _Texture_loadImage(
int pixelDataType,
);
bool Texture_loadImage(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TTexture> tTexture,
ffi.Pointer<TLinearImage> tImage,
TPixelDataFormat bufferFormat,
TPixelDataType pixelDataType,
) =>
_Texture_loadImage(
tEngine,
tTexture,
tImage,
bufferFormat.value,
pixelDataType.value,
);
@ffi.Native<
ffi.Bool Function(
ffi.Pointer<TEngine>,
@@ -966,6 +980,27 @@ external bool Texture_setImageWithDepth(
int pixelDataType,
);
@ffi.Native<ffi.Uint32 Function(ffi.Pointer<TTexture>, ffi.Uint32)>(
isLeaf: true)
external int Texture_getWidth(
ffi.Pointer<TTexture> tTexture,
int level,
);
@ffi.Native<ffi.Uint32 Function(ffi.Pointer<TTexture>, ffi.Uint32)>(
isLeaf: true)
external int Texture_getHeight(
ffi.Pointer<TTexture> tTexture,
int level,
);
@ffi.Native<ffi.Uint32 Function(ffi.Pointer<TTexture>, ffi.Uint32)>(
isLeaf: true)
external int Texture_getDepth(
ffi.Pointer<TTexture> tTexture,
int level,
);
@ffi.Native<
ffi.Pointer<TLinearImage> Function(
ffi.Uint32, ffi.Uint32, ffi.Uint32)>(isLeaf: true)
@@ -1016,6 +1051,12 @@ external ffi.Pointer<TTexture> RenderTarget_getColorTexture(
ffi.Pointer<TRenderTarget> tRenderTarget,
);
@ffi.Native<ffi.Pointer<TTexture> Function(ffi.Pointer<TRenderTarget>)>(
isLeaf: true)
external ffi.Pointer<TTexture> RenderTarget_getDepthTexture(
ffi.Pointer<TRenderTarget> tRenderTarget,
);
@ffi.Native<ffi.Pointer<TTextureSampler> Function()>(isLeaf: true)
external ffi.Pointer<TTextureSampler> TextureSampler_create();
@@ -1215,6 +1256,19 @@ external ffi.Pointer<TMaterialInstance> MaterialProvider_createMaterialInstance(
ffi.Pointer<TMaterialKey> key,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TScene>, EntityId)>(isLeaf: true)
external void Scene_addEntity(
ffi.Pointer<TScene> tScene,
int entityId,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TScene>, ffi.Pointer<TSkybox>)>(
isLeaf: true)
external void Scene_setSkybox(
ffi.Pointer<TScene> tScene,
ffi.Pointer<TSkybox> skybox,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TCamera>, ffi.Float, ffi.Float, ffi.Float)>(isLeaf: true)
@@ -1231,13 +1285,6 @@ external void set_camera_model_matrix(
double4x4 matrix,
);
@ffi.Native<ffi.Pointer<TCamera> Function(ffi.Pointer<TViewer>, EntityId)>(
isLeaf: true)
external ffi.Pointer<TCamera> get_camera(
ffi.Pointer<TViewer> viewer,
int entity,
);
@ffi.Native<double4x4 Function(ffi.Pointer<TCamera>)>(isLeaf: true)
external double4x4 get_camera_model_matrix(
ffi.Pointer<TCamera> camera,
@@ -1316,6 +1363,15 @@ external double4x4 Camera_getModelMatrix(
ffi.Pointer<TCamera> camera,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TCamera>, double3, double3, double3)>(
isLeaf: true)
external void Camera_lookAt(
ffi.Pointer<TCamera> camera,
double3 eye,
double3 focus,
double3 up,
);
@ffi.Native<ffi.Double Function(ffi.Pointer<TCamera>)>(isLeaf: true)
external double get_camera_near(
ffi.Pointer<TCamera> camera,
@@ -1466,6 +1522,65 @@ external int TransformManager_getAncestor(
int childEntityId,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TRenderer>, ffi.Double, ffi.Double,
ffi.Double, ffi.Double, ffi.Uint8, ffi.Bool, ffi.Bool)>(isLeaf: true)
external void Renderer_setClearOptions(
ffi.Pointer<TRenderer> tRenderer,
double clearR,
double clearG,
double clearB,
double clearA,
int clearStencil,
bool clear,
bool discard,
);
@ffi.Native<
ffi.Bool Function(ffi.Pointer<TRenderer>, ffi.Pointer<TSwapChain>,
ffi.Uint64)>(isLeaf: true)
external bool Renderer_beginFrame(
ffi.Pointer<TRenderer> tRenderer,
ffi.Pointer<TSwapChain> tSwapChain,
int frameTimeInNanos,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TRenderer>)>(isLeaf: true)
external void Renderer_endFrame(
ffi.Pointer<TRenderer> tRenderer,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TRenderer>, ffi.Pointer<TView>)>(
isLeaf: true)
external void Renderer_render(
ffi.Pointer<TRenderer> tRenderer,
ffi.Pointer<TView> tView,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TRenderer>, ffi.Pointer<TView>)>(
isLeaf: true)
external void Renderer_renderStandaloneView(
ffi.Pointer<TRenderer> tRenderer,
ffi.Pointer<TView> tView,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TRenderer>,
ffi.Pointer<TView>,
ffi.Pointer<TRenderTarget>,
ffi.Int,
ffi.Int,
ffi.Pointer<ffi.Uint8>)>(isLeaf: true)
external void Renderer_readPixels(
ffi.Pointer<TRenderer> tRenderer,
ffi.Pointer<TView> tView,
ffi.Pointer<TRenderTarget> tRenderTarget,
int tPixelBufferFormat,
int tPixelDataType,
ffi.Pointer<ffi.Uint8> out,
);
@ffi.Native<ffi.Void Function()>(isLeaf: true)
external void RenderLoop_create();
@@ -1500,6 +1615,19 @@ external void Viewer_createOnRenderThread(
callback,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TViewer>,
ffi.Pointer<
ffi
.NativeFunction<ffi.Void Function(ffi.Pointer<TView> tView)>>)>(
isLeaf: true)
external void Viewer_createViewRenderThread(
ffi.Pointer<TViewer> viewer,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TView> tView)>>
onComplete,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TViewer>)>(isLeaf: true)
external void Viewer_destroyOnRenderThread(
ffi.Pointer<TViewer> viewer,
@@ -1561,12 +1689,14 @@ external void Viewer_renderRenderThread(
ffi.Pointer<TView>,
ffi.Pointer<TSwapChain>,
ffi.Pointer<ffi.Uint8>,
ffi.Bool,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Viewer_captureRenderThread(
ffi.Pointer<TViewer> viewer,
ffi.Pointer<TView> view,
ffi.Pointer<TSwapChain> swapChain,
ffi.Pointer<ffi.Uint8> out,
bool useFence,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@@ -1577,6 +1707,7 @@ external void Viewer_captureRenderThread(
ffi.Pointer<TSwapChain>,
ffi.Pointer<TRenderTarget>,
ffi.Pointer<ffi.Uint8>,
ffi.Bool,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Viewer_captureRenderTargetRenderThread(
ffi.Pointer<TViewer> viewer,
@@ -1584,6 +1715,7 @@ external void Viewer_captureRenderTargetRenderThread(
ffi.Pointer<TSwapChain> swapChain,
ffi.Pointer<TRenderTarget> renderTarget,
ffi.Pointer<ffi.Uint8> out,
bool useFence,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@@ -1617,6 +1749,7 @@ external void Viewer_removeIblRenderThread(
ffi.Void Function(
ffi.Pointer<TViewer>,
ffi.IntPtr,
ffi.IntPtr,
ffi.Uint32,
ffi.Uint32,
ffi.Pointer<
@@ -1624,7 +1757,8 @@ external void Viewer_removeIblRenderThread(
ffi.Void Function(ffi.Pointer<TRenderTarget>)>>)>(isLeaf: true)
external void Viewer_createRenderTargetRenderThread(
ffi.Pointer<TViewer> viewer,
int texture,
int colorTexture,
int depthTexture,
int width,
int height,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TRenderTarget>)>>
@@ -1657,6 +1791,91 @@ external void Viewer_removeSkyboxRenderThread(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Int,
ffi.Pointer<
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TEngine>)>>)>(
isLeaf: true)
external void Engine_createRenderThread(
int backend,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TEngine>)>>
onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
ffi.Pointer<
ffi
.NativeFunction<ffi.Void Function(ffi.Pointer<TRenderer>)>>)>(
isLeaf: true)
external void Engine_createRendererRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TRenderer>)>>
onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
ffi.Pointer<ffi.Void>,
ffi.Uint64,
ffi.Pointer<
ffi
.NativeFunction<ffi.Void Function(ffi.Pointer<TSwapChain>)>>)>(
isLeaf: true)
external void Engine_createSwapChainRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.Void> window,
int flags,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TSwapChain>)>>
onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
ffi.Uint32,
ffi.Uint32,
ffi.Uint64,
ffi.Pointer<
ffi
.NativeFunction<ffi.Void Function(ffi.Pointer<TSwapChain>)>>)>(
isLeaf: true)
external void Engine_createHeadlessSwapChainRenderThread(
ffi.Pointer<TEngine> tEngine,
int width,
int height,
int flags,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TSwapChain>)>>
onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
ffi.Pointer<
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TCamera>)>>)>(
isLeaf: true)
external void Engine_createCameraRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TCamera>)>>
onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
ffi.Pointer<
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TView>)>>)>(
isLeaf: true)
external void Engine_createViewRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TView>)>>
onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
@@ -1738,6 +1957,134 @@ external void Engine_destroyTextureRenderThread(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
ffi.Pointer<
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TFence>)>>)>(
isLeaf: true)
external void Engine_createFenceRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TFence>)>>
onComplete,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TEngine>, ffi.Pointer<TFence>,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Engine_destroyFenceRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TFence> tFence,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TEngine>,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Engine_flushAndWaitRenderThead(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
ffi.Pointer<ffi.Uint8>,
ffi.Size,
ffi.Pointer<
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TSkybox>)>>,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Engine_buildSkyboxRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.Uint8> skyboxData,
int length,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TSkybox>)>>
onComplete,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onTextureUploadComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TRenderer>,
ffi.Double,
ffi.Double,
ffi.Double,
ffi.Double,
ffi.Uint8,
ffi.Bool,
ffi.Bool,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Renderer_setClearOptionsRenderThread(
ffi.Pointer<TRenderer> tRenderer,
double clearR,
double clearG,
double clearB,
double clearA,
int clearStencil,
bool clear,
bool discard,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TRenderer>,
ffi.Pointer<TSwapChain>,
ffi.Uint64,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>>)>(
isLeaf: true)
external void Renderer_beginFrameRenderThread(
ffi.Pointer<TRenderer> tRenderer,
ffi.Pointer<TSwapChain> tSwapChain,
int frameTimeInNanos,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>> onComplete,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TRenderer>,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Renderer_endFrameRenderThread(
ffi.Pointer<TRenderer> tRenderer,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TRenderer>, ffi.Pointer<TView>,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Renderer_renderRenderThread(
ffi.Pointer<TRenderer> tRenderer,
ffi.Pointer<TView> tView,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@ffi.Native<
ffi.Void Function(ffi.Pointer<TRenderer>, ffi.Pointer<TView>,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Renderer_renderStandaloneViewRenderThread(
ffi.Pointer<TRenderer> tRenderer,
ffi.Pointer<TView> tView,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TRenderer>,
ffi.Pointer<TView>,
ffi.Pointer<TRenderTarget>,
ffi.UnsignedInt,
ffi.UnsignedInt,
ffi.Pointer<ffi.Uint8>,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external void Renderer_readPixelsRenderThread(
ffi.Pointer<TRenderer> tRenderer,
ffi.Pointer<TView> tView,
ffi.Pointer<TRenderTarget> tRenderTarget,
int tPixelBufferFormat,
int tPixelDataType,
ffi.Pointer<ffi.Uint8> out,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TMaterial>,
@@ -2127,6 +2474,41 @@ external void SceneAsset_createInstanceRenderThread(
callback,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
ffi.Pointer<ffi.Float>,
ffi.Uint32,
ffi.Pointer<ffi.Float>,
ffi.Uint32,
ffi.Pointer<ffi.Float>,
ffi.Uint32,
ffi.Pointer<ffi.Uint16>,
ffi.Uint32,
ffi.UnsignedInt,
ffi.Pointer<ffi.Pointer<TMaterialInstance>>,
ffi.Int,
ffi.Pointer<
ffi
.NativeFunction<ffi.Void Function(ffi.Pointer<TSceneAsset>)>>)>(
isLeaf: true)
external void SceneAsset_createGeometryRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.Float> vertices,
int numVertices,
ffi.Pointer<ffi.Float> normals,
int numNormals,
ffi.Pointer<ffi.Float> uvs,
int numUvs,
ffi.Pointer<ffi.Uint16> indices,
int numIndices,
int tPrimitiveType,
ffi.Pointer<ffi.Pointer<TMaterialInstance>> materialInstances,
int materialInstanceCount,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TSceneAsset>)>>
callback,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TMaterialProvider>,
@@ -2270,8 +2652,8 @@ external void Image_getChannelsRenderThread(
ffi.UnsignedInt,
ffi.UnsignedInt,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>>)>(
symbol: "Texture_loadImageRenderThread", isLeaf: true)
external void _Texture_loadImageRenderThread(
isLeaf: true)
external void Texture_loadImageRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TTexture> tTexture,
ffi.Pointer<TLinearImage> tImage,
@@ -2280,23 +2662,6 @@ external void _Texture_loadImageRenderThread(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>> onComplete,
);
void Texture_loadImageRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TTexture> tTexture,
ffi.Pointer<TLinearImage> tImage,
TPixelDataFormat bufferFormat,
TPixelDataType pixelDataType,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>> onComplete,
) =>
_Texture_loadImageRenderThread(
tEngine,
tTexture,
tImage,
bufferFormat.value,
pixelDataType.value,
onComplete,
);
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
@@ -3065,6 +3430,53 @@ external bool RenderableManager_getFogEnabled(
int entityId,
);
@ffi.Native<ffi.Pointer<TEngine> Function(ffi.UnsignedInt)>(
symbol: "Engine_create", isLeaf: true)
external ffi.Pointer<TEngine> _Engine_create(
int backend,
);
ffi.Pointer<TEngine> Engine_create(
TBackend backend,
) =>
_Engine_create(
backend.value,
);
@ffi.Native<ffi.Pointer<TRenderer> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
external ffi.Pointer<TRenderer> Engine_createRenderer(
ffi.Pointer<TEngine> tEngine,
);
@ffi.Native<
ffi.Pointer<TSwapChain> Function(
ffi.Pointer<TEngine>, ffi.Pointer<ffi.Void>, ffi.Uint64)>(isLeaf: true)
external ffi.Pointer<TSwapChain> Engine_createSwapChain(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.Void> window,
int flags,
);
@ffi.Native<
ffi.Pointer<TSwapChain> Function(
ffi.Pointer<TEngine>, ffi.Uint32, ffi.Uint32, ffi.Uint64)>(isLeaf: true)
external ffi.Pointer<TSwapChain> Engine_createHeadlessSwapChain(
ffi.Pointer<TEngine> tEngine,
int width,
int height,
int flags,
);
@ffi.Native<ffi.Pointer<TCamera> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
external ffi.Pointer<TCamera> Engine_createCamera(
ffi.Pointer<TEngine> tEngine,
);
@ffi.Native<ffi.Pointer<TView> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
external ffi.Pointer<TView> Engine_createView(
ffi.Pointer<TEngine> tEngine,
);
@ffi.Native<ffi.Pointer<TCamera> Function(ffi.Pointer<TEngine>, EntityId)>(
isLeaf: true)
external ffi.Pointer<TCamera> Engine_getCameraComponent(
@@ -3141,6 +3553,23 @@ external void Engine_destroyTexture(
ffi.Pointer<TTexture> tTexture,
);
@ffi.Native<ffi.Pointer<TFence> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
external ffi.Pointer<TFence> Engine_createFence(
ffi.Pointer<TEngine> tEngine,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TEngine>, ffi.Pointer<TFence>)>(
isLeaf: true)
external void Engine_destroyFence(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TFence> tFence,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TEngine>)>(isLeaf: true)
external void Engine_flushAndWait(
ffi.Pointer<TEngine> tEngine,
);
@ffi.Native<
ffi.Pointer<TMaterial> Function(
ffi.Pointer<TEngine>, ffi.Pointer<ffi.Uint8>, ffi.Size)>(isLeaf: true)
@@ -3157,6 +3586,53 @@ external void Engine_destroyMaterial(
ffi.Pointer<TMaterial> tMaterial,
);
@ffi.Native<ffi.Pointer<TScene> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
external ffi.Pointer<TScene> Engine_createScene(
ffi.Pointer<TEngine> tEngine,
);
@ffi.Native<
ffi.Pointer<TSkybox> Function(
ffi.Pointer<TEngine>,
ffi.Pointer<ffi.Uint8>,
ffi.Size,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>(isLeaf: true)
external ffi.Pointer<TSkybox> Engine_buildSkybox(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.Uint8> ktxData,
int length,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onTextureUploadComplete,
);
@ffi.Native<
ffi.Pointer<TSceneAsset> Function(
ffi.Pointer<TEngine>,
ffi.Pointer<ffi.Float>,
ffi.Uint32,
ffi.Pointer<ffi.Float>,
ffi.Uint32,
ffi.Pointer<ffi.Float>,
ffi.Uint32,
ffi.Pointer<ffi.Uint16>,
ffi.Uint32,
ffi.UnsignedInt,
ffi.Pointer<ffi.Pointer<TMaterialInstance>>,
ffi.Int)>(isLeaf: true)
external ffi.Pointer<TSceneAsset> SceneAsset_createGeometry(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<ffi.Float> vertices,
int numVertices,
ffi.Pointer<ffi.Float> normals,
int numNormals,
ffi.Pointer<ffi.Float> uvs,
int numUvs,
ffi.Pointer<ffi.Uint16> indices,
int numIndices,
int tPrimitiveType,
ffi.Pointer<ffi.Pointer<TMaterialInstance>> materialInstances,
int materialInstanceCount,
);
@ffi.Native<ffi.Void Function(ffi.Pointer<TSceneAsset>, ffi.Pointer<TScene>)>(
isLeaf: true)
external void SceneAsset_addToScene(
@@ -3471,6 +3947,10 @@ final class TSceneManager extends ffi.Opaque {}
final class TLightManager extends ffi.Opaque {}
final class TRenderer extends ffi.Opaque {}
final class TFence extends ffi.Opaque {}
final class TRenderTarget extends ffi.Opaque {}
final class TSwapChain extends ffi.Opaque {}
@@ -3481,6 +3961,8 @@ final class TGizmo extends ffi.Opaque {}
final class TScene extends ffi.Opaque {}
final class TSkybox extends ffi.Opaque {}
final class TTransformManager extends ffi.Opaque {}
final class TAnimationManager extends ffi.Opaque {}
@@ -3635,6 +4117,17 @@ final class UnnamedStruct2 extends ffi.Struct {
external int specularGlossinessUV;
}
final class double3 extends ffi.Struct {
@ffi.Double()
external double x;
@ffi.Double()
external double y;
@ffi.Double()
external double z;
}
final class double4 extends ffi.Struct {
@ffi.Double()
external double x;
@@ -3711,6 +4204,23 @@ enum TGizmoType {
};
}
abstract class TPrimitiveType {
/// !< points
static const PRIMITIVETYPE_POINTS = 0;
/// !< lines
static const PRIMITIVETYPE_LINES = 1;
/// !< line strip
static const PRIMITIVETYPE_LINE_STRIP = 3;
/// !< triangles
static const PRIMITIVETYPE_TRIANGLES = 4;
/// !< triangle strip
static const PRIMITIVETYPE_TRIANGLE_STRIP = 5;
}
enum TSamplerCompareFunc {
/// !< Less or equal
LE(0),
@@ -4156,114 +4666,76 @@ enum TTextureFormat {
}
/// ! Pixel Data Format
enum TPixelDataFormat {
abstract class TPixelDataFormat {
/// !< One Red channel, float
PIXELDATAFORMAT_R(0),
static const PIXELDATAFORMAT_R = 0;
/// !< One Red channel, integer
PIXELDATAFORMAT_R_INTEGER(1),
static const PIXELDATAFORMAT_R_INTEGER = 1;
/// !< Two Red and Green channels, float
PIXELDATAFORMAT_RG(2),
static const PIXELDATAFORMAT_RG = 2;
/// !< Two Red and Green channels, integer
PIXELDATAFORMAT_RG_INTEGER(3),
static const PIXELDATAFORMAT_RG_INTEGER = 3;
/// !< Three Red, Green and Blue channels, float
PIXELDATAFORMAT_RGB(4),
static const PIXELDATAFORMAT_RGB = 4;
/// !< Three Red, Green and Blue channels, integer
PIXELDATAFORMAT_RGB_INTEGER(5),
static const PIXELDATAFORMAT_RGB_INTEGER = 5;
/// !< Four Red, Green, Blue and Alpha channels, float
PIXELDATAFORMAT_RGBA(6),
static const PIXELDATAFORMAT_RGBA = 6;
/// !< Four Red, Green, Blue and Alpha channels, integer
PIXELDATAFORMAT_RGBA_INTEGER(7),
PIXELDATAFORMAT_UNUSED(8),
static const PIXELDATAFORMAT_RGBA_INTEGER = 7;
static const PIXELDATAFORMAT_UNUSED = 8;
/// !< Depth, 16-bit or 24-bits usually
PIXELDATAFORMAT_DEPTH_COMPONENT(9),
static const PIXELDATAFORMAT_DEPTH_COMPONENT = 9;
/// !< Two Depth (24-bits) + Stencil (8-bits) channels
PIXELDATAFORMAT_DEPTH_STENCIL(10),
PIXELDATAFORMAT_ALPHA(11);
final int value;
const TPixelDataFormat(this.value);
static TPixelDataFormat fromValue(int value) => switch (value) {
0 => PIXELDATAFORMAT_R,
1 => PIXELDATAFORMAT_R_INTEGER,
2 => PIXELDATAFORMAT_RG,
3 => PIXELDATAFORMAT_RG_INTEGER,
4 => PIXELDATAFORMAT_RGB,
5 => PIXELDATAFORMAT_RGB_INTEGER,
6 => PIXELDATAFORMAT_RGBA,
7 => PIXELDATAFORMAT_RGBA_INTEGER,
8 => PIXELDATAFORMAT_UNUSED,
9 => PIXELDATAFORMAT_DEPTH_COMPONENT,
10 => PIXELDATAFORMAT_DEPTH_STENCIL,
11 => PIXELDATAFORMAT_ALPHA,
_ => throw ArgumentError("Unknown value for TPixelDataFormat: $value"),
};
static const PIXELDATAFORMAT_DEPTH_STENCIL = 10;
static const PIXELDATAFORMAT_ALPHA = 11;
}
enum TPixelDataType {
abstract class TPixelDataType {
/// !< unsigned byte
PIXELDATATYPE_UBYTE(0),
static const PIXELDATATYPE_UBYTE = 0;
/// !< signed byte
PIXELDATATYPE_BYTE(1),
static const PIXELDATATYPE_BYTE = 1;
/// !< unsigned short (16-bit)
PIXELDATATYPE_USHORT(2),
static const PIXELDATATYPE_USHORT = 2;
/// !< signed short (16-bit)
PIXELDATATYPE_SHORT(3),
static const PIXELDATATYPE_SHORT = 3;
/// !< unsigned int (32-bit)
PIXELDATATYPE_UINT(4),
static const PIXELDATATYPE_UINT = 4;
/// !< signed int (32-bit)
PIXELDATATYPE_INT(5),
static const PIXELDATATYPE_INT = 5;
/// !< half-float (16-bit float)
PIXELDATATYPE_HALF(6),
static const PIXELDATATYPE_HALF = 6;
/// !< float (32-bits float)
PIXELDATATYPE_FLOAT(7),
static const PIXELDATATYPE_FLOAT = 7;
/// !< compressed pixels, @see CompressedPixelDataType
PIXELDATATYPE_COMPRESSED(8),
static const PIXELDATATYPE_COMPRESSED = 8;
/// !< three low precision floating-point numbers
PIXELDATATYPE_UINT_10F_11F_11F_REV(9),
static const PIXELDATATYPE_UINT_10F_11F_11F_REV = 9;
/// !< unsigned int (16-bit), encodes 3 RGB channels
PIXELDATATYPE_USHORT_565(10),
static const PIXELDATATYPE_USHORT_565 = 10;
/// !< unsigned normalized 10 bits RGB, 2 bits alpha
PIXELDATATYPE_UINT_2_10_10_10_REV(11);
final int value;
const TPixelDataType(this.value);
static TPixelDataType fromValue(int value) => switch (value) {
0 => PIXELDATATYPE_UBYTE,
1 => PIXELDATATYPE_BYTE,
2 => PIXELDATATYPE_USHORT,
3 => PIXELDATATYPE_SHORT,
4 => PIXELDATATYPE_UINT,
5 => PIXELDATATYPE_INT,
6 => PIXELDATATYPE_HALF,
7 => PIXELDATATYPE_FLOAT,
8 => PIXELDATATYPE_COMPRESSED,
9 => PIXELDATATYPE_UINT_10F_11F_11F_REV,
10 => PIXELDATATYPE_USHORT_565,
11 => PIXELDATATYPE_UINT_2_10_10_10_REV,
_ => throw ArgumentError("Unknown value for TPixelDataType: $value"),
};
static const PIXELDATATYPE_UINT_2_10_10_10_REV = 11;
}
enum TSamplerWrapMode {
@@ -4398,6 +4870,35 @@ typedef FilamentRenderCallbackFunction = ffi.Void Function(
typedef DartFilamentRenderCallbackFunction = void Function(
ffi.Pointer<ffi.Void> owner);
enum TBackend {
/// !< Automatically selects an appropriate driver for the platform.
BACKEND_DEFAULT(0),
/// !< Selects the OpenGL/ES driver (default on Android)
BACKEND_OPENGL(1),
/// !< Selects the Vulkan driver if the platform supports it (default on Linux/Windows)
BACKEND_VULKAN(2),
/// !< Selects the Metal driver if the platform supports it (default on MacOS/iOS).
BACKEND_METAL(3),
/// !< Selects the no-op driver for testing purposes.
BACKEND_NOOP(4);
final int value;
const TBackend(this.value);
static TBackend fromValue(int value) => switch (value) {
0 => BACKEND_DEFAULT,
1 => BACKEND_OPENGL,
2 => BACKEND_VULKAN,
3 => BACKEND_METAL,
4 => BACKEND_NOOP,
_ => throw ArgumentError("Unknown value for TBackend: $value"),
};
}
final class ResourceBuffer extends ffi.Struct {
external ffi.Pointer<ffi.Void> data;

View File

@@ -7,6 +7,7 @@ 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:thermion_dart/src/viewer/src/ffi/src/ffi_render_target.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_swapchain.dart';
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
import 'package:vector_math/vector_math_64.dart';
import 'package:vector_math/vector_math_64.dart' as v64;
@@ -18,6 +19,33 @@ import 'callbacks.dart';
import 'ffi_camera.dart';
import 'ffi_view.dart';
class FFIBindings {
final Pointer<TSceneManager> sceneManager;
final Pointer<TEngine> engine;
final Pointer<TMaterialProvider> unlitMaterialProvider;
final Pointer<TMaterialProvider> ubershaderMaterialProvider;
final Pointer<TTransformManager> transformManager;
final Pointer<TLightManager> lightManager;
final Pointer<TRenderableManager> renderableManager;
final Pointer<TViewer> viewer;
final Pointer<TAnimationManager> animationManager;
final Pointer<TNameComponentManager> nameComponentManager;
final Pointer<TRenderer> renderer;
FFIBindings(
{required this.renderer,
required this.sceneManager,
required this.engine,
required this.unlitMaterialProvider,
required this.ubershaderMaterialProvider,
required this.transformManager,
required this.lightManager,
required this.renderableManager,
required this.viewer,
required this.animationManager,
required this.nameComponentManager});
}
// ignore: constant_identifier_names
const ThermionEntity FILAMENT_ASSET_ERROR = 0;
@@ -37,6 +65,7 @@ class ThermionViewerFFI extends ThermionViewer {
Pointer<TAnimationManager>? _animationManager;
Pointer<TNameComponentManager>? _nameComponentManager;
late FFIBindings bindings;
final String? uberArchivePath;
final _initialized = Completer<bool>();
@@ -78,10 +107,11 @@ class ThermionViewerFFI extends ThermionViewer {
///
///
Future<RenderTarget> createRenderTarget(
int width, int height, int textureHandle) async {
int width, int height, { int? colorTextureHandle,
int? depthTextureHandle}) async {
final renderTarget = await withPointerCallback<TRenderTarget>((cb) {
Viewer_createRenderTargetRenderThread(
_viewer!, textureHandle, width, height, cb);
Viewer_createRenderTargetRenderThread(_viewer!, colorTextureHandle ?? 0,
depthTextureHandle ?? 0, width, height, cb);
});
return FFIRenderTarget(renderTarget, _viewer!, _engine!);
@@ -107,7 +137,9 @@ class ThermionViewerFFI extends ThermionViewer {
///
///
Future<View> createView() async {
var view = Viewer_createView(_viewer!);
var view = await withPointerCallback<TView>((cb) {
Viewer_createViewRenderThread(_viewer!, cb);
});
if (view == nullptr) {
throw Exception("Failed to create view");
}
@@ -117,9 +149,9 @@ class ThermionViewerFFI extends ThermionViewer {
///
///
///
Future updateViewportAndCameraProjection(double width, double height) async {
Future setViewportAndCameraProjection(double width, double height) async {
var mainView = FFIView(Viewer_getViewAt(_viewer!, 0), _viewer!, _engine!);
mainView.updateViewport(width.toInt(), height.toInt());
mainView.setViewport(width.toInt(), height.toInt());
final cameraCount = await getCameraCount();
@@ -212,7 +244,18 @@ class ThermionViewerFFI extends ThermionViewer {
_nameComponentManager =
SceneManager_getNameComponentManager(_sceneManager!);
_renderableManager = Engine_getRenderableManager(_engine!);
bindings = FFIBindings(
sceneManager: _sceneManager!,
engine: _engine!,
unlitMaterialProvider: _unlitMaterialProvider!,
ubershaderMaterialProvider: _ubershaderMaterialProvider!,
transformManager: _transformManager!,
lightManager: _lightManager!,
renderableManager: _renderableManager!,
viewer: _viewer!,
animationManager: _animationManager!,
nameComponentManager: _nameComponentManager!,
renderer: Viewer_getRenderer(_viewer!));
this._initialized.complete(true);
}
@@ -249,27 +292,75 @@ class ThermionViewerFFI extends ThermionViewer {
///
///
@override
Future<Uint8List> capture(
{FFIView? view,
FFISwapChain? swapChain,
FFIRenderTarget? renderTarget}) async {
view ??= (await getViewAt(0)) as FFIView;
final vp = await view.getViewport();
final length = vp.width * vp.height * 4;
final out = Uint8List(length);
Future<List<Uint8List>> capture(
List<({View view, SwapChain? swapChain, RenderTarget? renderTarget})>
targets) async {
var renderer = Viewer_getRenderer(_viewer!);
swapChain ??= FFISwapChain(Viewer_getSwapChainAt(_viewer!, 0), _viewer!);
final fence = await withPointerCallback<TFence>((cb) {
Engine_createFenceRenderThread(_engine!, cb);
});
var pixelBuffers = <Uint8List>[];
for (final entry in targets) {
final view = entry.view as FFIView;
var swapChain = entry.swapChain as FFISwapChain?;
final renderTarget = entry.renderTarget as FFIRenderTarget?;
final vp = await view.getViewport();
final length = vp.width * vp.height * 4;
await withBoolCallback((cb) {
Renderer_beginFrameRenderThread(renderer,
swapChain?.swapChain ?? Viewer_getSwapChainAt(_viewer!, 0), 0, cb);
});
await withVoidCallback((cb) {
Renderer_renderRenderThread(renderer, view.view, cb);
});
final out = Uint8List(length);
await withVoidCallback((cb) {
Renderer_readPixelsRenderThread(
renderer,
view.view,
renderTarget!.renderTarget,
TPixelDataFormat.PIXELDATAFORMAT_RGBA,
TPixelDataType.PIXELDATATYPE_UBYTE,
out.address,
cb);
});
pixelBuffers.add(out);
}
await withVoidCallback((cb) {
if (renderTarget != null) {
Viewer_captureRenderTargetRenderThread(_viewer!, view!.view,
swapChain!.swapChain, renderTarget.renderTarget, out.address, cb);
} else {
Viewer_captureRenderThread(
_viewer!, view!.view, swapChain!.swapChain, out.address, cb);
}
Renderer_endFrameRenderThread(renderer, cb);
});
return out;
await withVoidCallback((cb) {
Engine_flushAndWaitRenderThead(_engine!, cb);
});
await withVoidCallback((cb) {
Engine_destroyFenceRenderThread(_engine!, fence, cb);
});
// await withVoidCallback((cb) {
// if (renderTarget != null) {
// Viewer_captureRenderTargetRenderThread(
// _viewer!,
// view!.view,
// swapChain!.swapChain,
// renderTarget.renderTarget,
// out.address,
// useFence,
// cb);
// } else {
// Viewer_captureRenderThread(_viewer!, view!.view, swapChain!.swapChain,
// out.address, useFence, cb);
// }
// });
return pixelBuffers;
}
double _msPerFrame = 1000.0 / 60.0;
@@ -1830,7 +1921,8 @@ class ThermionViewerFFI extends ThermionViewer {
///
///
Future<Texture> createTexture(int width, int height,
{int depth = 1, int levels = 1,
{int depth = 1,
int levels = 1,
TextureSamplerType textureSamplerType = TextureSamplerType.SAMPLER_2D,
TextureFormat textureFormat = TextureFormat.RGBA16F}) async {
final texturePtr = await withPointerCallback<TTexture>((cb) {
@@ -1862,6 +1954,7 @@ class ThermionViewerFFI extends ThermionViewer {
double anisotropy = 0.0,
TextureCompareMode compareMode = TextureCompareMode.NONE,
TextureCompareFunc compareFunc = TextureCompareFunc.LESS_EQUAL}) async {
return FFITextureSampler(TextureSampler_create());
final samplerPtr = TextureSampler_create();
TextureSampler_setMinFilter(
samplerPtr, TSamplerMinFilter.values[minFilter.index]);
@@ -1876,12 +1969,12 @@ class ThermionViewerFFI extends ThermionViewer {
if (anisotropy > 0) {
TextureSampler_setAnisotropy(samplerPtr, anisotropy);
}
if (compareMode != TextureCompareMode.NONE) {
TextureSampler_setCompareMode(
samplerPtr,
TSamplerCompareMode.values[compareMode.index],
TSamplerCompareFunc.values[compareFunc.index]);
}
TextureSampler_setCompareMode(
samplerPtr,
TSamplerCompareMode.values[compareMode.index],
TSamplerCompareFunc.values[compareFunc.index]);
return FFITextureSampler(samplerPtr);
}
@@ -2216,11 +2309,14 @@ class ThermionViewerFFI extends ThermionViewer {
Future<bool> isReceiveShadowsEnabled(ThermionEntity entity) async {
return RenderableManager_isShadowReceiver(_renderableManager!, entity);
}
}
class FFISwapChain extends SwapChain {
final Pointer<TSwapChain> swapChain;
final Pointer<TViewer> viewer;
FFISwapChain(this.swapChain, this.viewer);
///
///
///
Future setClearOptions(
Vector4 clearColor, int clearStencil, bool clear, bool discard) async {
final renderer = Viewer_getRenderer(_viewer!);
Renderer_setClearOptions(renderer, clearColor.r, clearColor.g, clearColor.b,
clearColor.a, clearStencil, clear, discard);
}
}