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/viewer/src/ffi/src/thermion_dart.g.dart';
|
||||||
import 'package:thermion_dart/src/filament/src/layers.dart';
|
import 'package:thermion_dart/src/filament/src/layers.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
|
||||||
import '../../../../utils/src/matrix.dart';
|
import '../../../../utils/src/matrix.dart';
|
||||||
|
|
||||||
class FFICamera extends Camera {
|
class FFICamera extends Camera {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
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/callbacks.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.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_render_target.dart';
|
||||||
@@ -14,12 +15,12 @@ typedef RenderCallback = Pointer<NativeFunction<Void Function(Pointer<Void>)>>;
|
|||||||
|
|
||||||
class FFIFilamentConfig extends FilamentConfig<RenderCallback, Pointer<Void>> {
|
class FFIFilamentConfig extends FilamentConfig<RenderCallback, Pointer<Void>> {
|
||||||
FFIFilamentConfig(
|
FFIFilamentConfig(
|
||||||
{required super.backend,
|
{required super.resourceLoader,
|
||||||
required super.resourceLoader,
|
super.backend = Backend.DEFAULT,
|
||||||
required super.driver,
|
super.driver = null,
|
||||||
required super.platform,
|
super.platform = null,
|
||||||
required super.sharedContext,
|
super.sharedContext = null,
|
||||||
required super.uberArchivePath});
|
super.uberArchivePath = null});
|
||||||
}
|
}
|
||||||
|
|
||||||
class FFIFilamentApp extends FilamentApp<Pointer> {
|
class FFIFilamentApp extends FilamentApp<Pointer> {
|
||||||
@@ -55,7 +56,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
renderableManager: renderableManager,
|
renderableManager: renderableManager,
|
||||||
ubershaderMaterialProvider: ubershaderMaterialProvider) {}
|
ubershaderMaterialProvider: ubershaderMaterialProvider) {}
|
||||||
|
|
||||||
static Future create(FFIFilamentConfig config) async {
|
static Future create({FFIFilamentConfig? config}) async {
|
||||||
|
config ??= FFIFilamentConfig(resourceLoader: nullptr);
|
||||||
if (FilamentApp.instance != null) {
|
if (FilamentApp.instance != null) {
|
||||||
await FilamentApp.instance!.destroy();
|
await FilamentApp.instance!.destroy();
|
||||||
}
|
}
|
||||||
@@ -65,7 +67,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
|
|
||||||
final engine = await withPointerCallback<TEngine>((cb) =>
|
final engine = await withPointerCallback<TEngine>((cb) =>
|
||||||
Engine_createRenderThread(
|
Engine_createRenderThread(
|
||||||
TBackend.values[config.backend.index].index,
|
TBackend.values[config!.backend.index].index,
|
||||||
config.platform ?? nullptr,
|
config.platform ?? nullptr,
|
||||||
config.sharedContext ?? nullptr,
|
config.sharedContext ?? nullptr,
|
||||||
config.stereoscopicEyeCount,
|
config.stereoscopicEyeCount,
|
||||||
@@ -79,15 +81,13 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
final renderer = await withPointerCallback<TRenderer>(
|
final renderer = await withPointerCallback<TRenderer>(
|
||||||
(cb) => Engine_createRendererRenderThread(engine, cb));
|
(cb) => Engine_createRendererRenderThread(engine, cb));
|
||||||
final ubershaderMaterialProvider =
|
final ubershaderMaterialProvider =
|
||||||
await withPointerCallback<TMaterialProvider>(
|
GltfAssetLoader_getMaterialProvider(gltfAssetLoader);
|
||||||
(cb) => GltfAssetLoader_getMaterialProvider(gltfAssetLoader));
|
|
||||||
|
|
||||||
final transformManager = Engine_getTransformManager(engine);
|
final transformManager = Engine_getTransformManager(engine);
|
||||||
final lightManager = Engine_getLightManager(engine);
|
final lightManager = Engine_getLightManager(engine);
|
||||||
final renderableManager = Engine_getRenderableManager(engine);
|
final renderableManager = Engine_getRenderableManager(engine);
|
||||||
|
|
||||||
final renderTicker = await withPointerCallback<TRenderTicker>(
|
final renderTicker = RenderTicker_create(renderer);
|
||||||
(cb) => RenderTicker_create(renderer));
|
|
||||||
|
|
||||||
final nameComponentManager = NameComponentManager_create();
|
final nameComponentManager = NameComponentManager_create();
|
||||||
|
|
||||||
@@ -210,7 +210,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
TextureSamplerType textureSamplerType = TextureSamplerType.SAMPLER_2D,
|
TextureSamplerType textureSamplerType = TextureSamplerType.SAMPLER_2D,
|
||||||
TextureFormat textureFormat = TextureFormat.RGBA16F,
|
TextureFormat textureFormat = TextureFormat.RGBA16F,
|
||||||
int? importedTextureHandle}) async {
|
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) {
|
final texturePtr = await withPointerCallback<TTexture>((cb) {
|
||||||
Texture_buildRenderThread(
|
Texture_buildRenderThread(
|
||||||
engine,
|
engine,
|
||||||
@@ -218,8 +219,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
height,
|
height,
|
||||||
depth,
|
depth,
|
||||||
levels,
|
levels,
|
||||||
importedTextureHandle ?? 0,
|
|
||||||
bitmask,
|
bitmask,
|
||||||
|
importedTextureHandle ?? 0,
|
||||||
TTextureSamplerType.values[textureSamplerType.index],
|
TTextureSamplerType.values[textureSamplerType.index],
|
||||||
TTextureFormat.values[textureFormat.index],
|
TTextureFormat.values[textureFormat.index],
|
||||||
cb);
|
cb);
|
||||||
@@ -404,7 +405,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
|
|
||||||
FFIMaterial? _gridMaterial;
|
FFIMaterial? _gridMaterial;
|
||||||
Future<FFIMaterial> get gridMaterial async {
|
Future<FFIMaterial> get gridMaterial async {
|
||||||
_gridMaterial ??= FFIMaterial(Material_createGridMaterial(), this);
|
_gridMaterial ??= FFIMaterial(Material_createGridMaterial(engine), this);
|
||||||
return _gridMaterial!;
|
return _gridMaterial!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,8 +426,8 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future render() async {
|
Future render() async {
|
||||||
await withVoidCallback((cb) =>
|
await withVoidCallback(
|
||||||
RenderTicker_renderRenderThread(renderTicker, 0, cb));
|
(cb) => RenderTicker_renderRenderThread(renderTicker, 0, cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -436,6 +437,10 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
Future register(
|
Future register(
|
||||||
covariant FFISwapChain swapChain, covariant FFIView view) async {
|
covariant FFISwapChain swapChain, covariant FFIView view) async {
|
||||||
_viewMappings[view] = swapChain;
|
_viewMappings[view] = swapChain;
|
||||||
|
if (!_views.containsKey(swapChain)) {
|
||||||
|
_views[swapChain] = [];
|
||||||
|
}
|
||||||
|
_views[swapChain]!.add(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
final _hooks = <Future Function()>[];
|
final _hooks = <Future Function()>[];
|
||||||
@@ -531,9 +536,12 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
|
|||||||
|
|
||||||
Material? _imageMaterial;
|
Material? _imageMaterial;
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<MaterialInstance> createImageMaterialInstance() async {
|
Future<MaterialInstance> createImageMaterialInstance() async {
|
||||||
_imageMaterial ??= FFIMaterial(Material_createImageMaterial(),
|
_imageMaterial ??= FFIMaterial(Material_createImageMaterial(engine),
|
||||||
FilamentApp.instance! as FFIFilamentApp);
|
FilamentApp.instance! as FFIFilamentApp);
|
||||||
var instance =
|
var instance =
|
||||||
await _imageMaterial!.createInstance() as FFIMaterialInstance;
|
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_filament_app.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_texture.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
|
||||||
|
|
||||||
class FFIMaterial extends Material {
|
class FFIMaterial extends Material {
|
||||||
final FFIFilamentApp app;
|
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/src/viewer/src/ffi/src/callbacks.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ class FFIView extends View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future setScene(covariant FFIScene scene) async {
|
Future setScene(covariant FFIScene scene) async {
|
||||||
await withVoidCallback((cb) => View_setScene(view, scene.scene));
|
View_setScene(view, scene.scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -25,11 +25,15 @@ external ffi.Pointer<TMaterialInstance> Material_createInstance(
|
|||||||
ffi.Pointer<TMaterial> tMaterial,
|
ffi.Pointer<TMaterial> tMaterial,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Pointer<TMaterial> Function()>(isLeaf: true)
|
@ffi.Native<ffi.Pointer<TMaterial> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
|
||||||
external ffi.Pointer<TMaterial> Material_createImageMaterial();
|
external ffi.Pointer<TMaterial> Material_createImageMaterial(
|
||||||
|
ffi.Pointer<TEngine> tEngine,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Pointer<TMaterial> Function()>(isLeaf: true)
|
@ffi.Native<ffi.Pointer<TMaterial> Function(ffi.Pointer<TEngine>)>(isLeaf: true)
|
||||||
external ffi.Pointer<TMaterial> Material_createGridMaterial();
|
external ffi.Pointer<TMaterial> Material_createGridMaterial(
|
||||||
|
ffi.Pointer<TEngine> tEngine,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Bool Function(ffi.Pointer<TMaterial>, ffi.Pointer<ffi.Char>)>(
|
@ffi.Native<ffi.Bool Function(ffi.Pointer<TMaterial>, ffi.Pointer<ffi.Char>)>(
|
||||||
isLeaf: true)
|
isLeaf: true)
|
||||||
@@ -1491,9 +1495,11 @@ external void RenderLoop_create();
|
|||||||
@ffi.Native<ffi.Void Function()>(isLeaf: true)
|
@ffi.Native<ffi.Void Function()>(isLeaf: true)
|
||||||
external void RenderLoop_destroy();
|
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(
|
external void RenderLoop_requestAnimationFrame(
|
||||||
ffi.Pointer<ffi.Void> onComplete,
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> onComplete,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
@@ -3847,7 +3853,7 @@ enum TGizmoType {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class TPrimitiveType {
|
abstract class TPrimitiveType {
|
||||||
/// !< points
|
/// !< points
|
||||||
static const PRIMITIVETYPE_POINTS = 0;
|
static const PRIMITIVETYPE_POINTS = 0;
|
||||||
|
|
||||||
@@ -4265,7 +4271,7 @@ enum TTextureFormat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// ! Pixel Data Format
|
/// ! Pixel Data Format
|
||||||
sealed class TPixelDataFormat {
|
abstract class TPixelDataFormat {
|
||||||
/// !< One Red channel, float
|
/// !< One Red channel, float
|
||||||
static const PIXELDATAFORMAT_R = 0;
|
static const PIXELDATAFORMAT_R = 0;
|
||||||
|
|
||||||
@@ -4299,7 +4305,7 @@ sealed class TPixelDataFormat {
|
|||||||
static const PIXELDATAFORMAT_ALPHA = 11;
|
static const PIXELDATAFORMAT_ALPHA = 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class TPixelDataType {
|
abstract class TPixelDataType {
|
||||||
/// !< unsigned byte
|
/// !< unsigned byte
|
||||||
static const PIXELDATATYPE_UBYTE = 0;
|
static const PIXELDATATYPE_UBYTE = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
_cameras.add(camera);
|
_cameras.add(camera);
|
||||||
|
|
||||||
await view.setCamera(camera);
|
await view.setCamera(camera);
|
||||||
|
|
||||||
if (renderTarget != null) {
|
if (renderTarget != null) {
|
||||||
await view.setRenderTarget(renderTarget);
|
await view.setRenderTarget(renderTarget);
|
||||||
}
|
}
|
||||||
@@ -149,14 +150,12 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final _onDispose = <Future Function()>[];
|
final _onDispose = <Future Function()>[];
|
||||||
bool _disposing = false;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future dispose() async {
|
Future dispose() async {
|
||||||
_disposing = true;
|
|
||||||
await setRendering(false);
|
await setRendering(false);
|
||||||
await destroyAssets();
|
await destroyAssets();
|
||||||
await destroyLights();
|
await destroyLights();
|
||||||
@@ -166,7 +165,6 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onDispose.clear();
|
_onDispose.clear();
|
||||||
_disposing = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -25,10 +25,6 @@
|
|||||||
namespace thermion
|
namespace thermion
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef std::chrono::time_point time_point_t;
|
|
||||||
|
|
||||||
using namespace std::chrono;
|
|
||||||
|
|
||||||
class RenderTicker
|
class RenderTicker
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ extern "C"
|
|||||||
};
|
};
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TMaterialInstance *Material_createInstance(TMaterial *tMaterial);
|
EMSCRIPTEN_KEEPALIVE TMaterialInstance *Material_createInstance(TMaterial *tMaterial);
|
||||||
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createImageMaterial();
|
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createImageMaterial(TEngine *tEngine);
|
||||||
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createGridMaterial();
|
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createGridMaterial(TEngine *tEngine);
|
||||||
EMSCRIPTEN_KEEPALIVE bool Material_hasParameter(TMaterial *tMaterial, const char *propertyName);
|
EMSCRIPTEN_KEEPALIVE bool Material_hasParameter(TMaterial *tMaterial, const char *propertyName);
|
||||||
EMSCRIPTEN_KEEPALIVE bool MaterialInstance_isStencilWriteEnabled(TMaterialInstance *materialInstance);
|
EMSCRIPTEN_KEEPALIVE bool MaterialInstance_isStencilWriteEnabled(TMaterialInstance *materialInstance);
|
||||||
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setStencilWrite(TMaterialInstance *materialInstance, bool enabled);
|
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setStencilWrite(TMaterialInstance *materialInstance, bool enabled);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace thermion
|
|||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderLoop_create();
|
EMSCRIPTEN_KEEPALIVE void RenderLoop_create();
|
||||||
EMSCRIPTEN_KEEPALIVE void RenderLoop_destroy();
|
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 RenderTicker_renderRenderThread(TRenderTicker *tRenderTicker, uint64_t frameTimeInNanos, void (*onComplete)());
|
||||||
// EMSCRIPTEN_KEEPALIVE void RenderLoop_addTask(TRenderLoop* tRenderLoop, void (*task)());
|
// EMSCRIPTEN_KEEPALIVE void RenderLoop_addTask(TRenderLoop* tRenderLoop, void (*task)());
|
||||||
|
|
||||||
@@ -52,6 +52,7 @@ namespace thermion
|
|||||||
TTextureFormat format,
|
TTextureFormat format,
|
||||||
void (*onComplete)(TTexture*)
|
void (*onComplete)(TTexture*)
|
||||||
);
|
);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyTextureRenderThread(TEngine *engine, TTexture* tTexture, void (*onComplete)());
|
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_createFenceRenderThread(TEngine *tEngine, void (*onComplete)(TFence*));
|
||||||
EMSCRIPTEN_KEEPALIVE void Engine_destroyFenceRenderThread(TEngine *tEngine, TFence *tFence, void (*onComplete)());
|
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_getHeightRenderThread(TLinearImage *tLinearImage, void (*onComplete)(uint32_t));
|
||||||
EMSCRIPTEN_KEEPALIVE void Image_getChannelsRenderThread(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(
|
EMSCRIPTEN_KEEPALIVE void Texture_loadImageRenderThread(
|
||||||
TEngine *tEngine,
|
TEngine *tEngine,
|
||||||
@@ -292,8 +281,6 @@ namespace thermion
|
|||||||
void (*onComplete)()
|
void (*onComplete)()
|
||||||
);
|
);
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_updateBoneMatricesRenderThread(TSceneManager *sceneManager,
|
|
||||||
EntityId asset, void (*callback)(bool));
|
|
||||||
EMSCRIPTEN_KEEPALIVE void AnimationManager_setBoneTransformRenderThread(
|
EMSCRIPTEN_KEEPALIVE void AnimationManager_setBoneTransformRenderThread(
|
||||||
TAnimationManager *tAnimationManager,
|
TAnimationManager *tAnimationManager,
|
||||||
EntityId asset,
|
EntityId asset,
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <utils/Entity.h>
|
#include <utils/Entity.h>
|
||||||
#include <filament/Box.h>
|
#include <filament/Box.h>
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
|
|||||||
@@ -37,10 +37,6 @@ public:
|
|||||||
void addAllEntities(Scene* scene) override;
|
void addAllEntities(Scene* scene) override;
|
||||||
void removeAllEntities(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(); }
|
size_t getInstanceCount() override { return _instances.size(); }
|
||||||
SceneAsset* getInstanceByEntity(utils::Entity entity) override;
|
SceneAsset* getInstanceByEntity(utils::Entity entity) override;
|
||||||
SceneAsset* getInstanceAt(size_t index) override;
|
SceneAsset* getInstanceAt(size_t index) override;
|
||||||
|
|||||||
@@ -228,22 +228,6 @@ namespace thermion
|
|||||||
// scene->remove(_sphereEntity);
|
// 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)
|
SceneAsset *GridOverlay::getInstanceByEntity(utils::Entity entity)
|
||||||
{
|
{
|
||||||
for (auto &instance : _instances)
|
for (auto &instance : _instances)
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ namespace thermion
|
|||||||
using namespace filament;
|
using namespace filament;
|
||||||
using namespace filament::math;
|
using namespace filament::math;
|
||||||
using namespace utils;
|
using namespace utils;
|
||||||
using namespace std::chrono;
|
|
||||||
|
|
||||||
using std::string;
|
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/View.h>
|
||||||
#include <filament/Viewport.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 <utils/Entity.h>
|
||||||
|
|
||||||
#include "c_api/ThermionDartApi.h"
|
|
||||||
#include "c_api/TCamera.h"
|
#include "c_api/TCamera.h"
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
#include "MathUtils.hpp"
|
#include "MathUtils.hpp"
|
||||||
@@ -32,8 +33,8 @@ namespace thermion
|
|||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void Camera_getFrustum(TCamera *tCamera, double *out) {
|
EMSCRIPTEN_KEEPALIVE void Camera_getFrustum(TCamera *tCamera, double *out) {
|
||||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||||
auto &frustum = camera->getFrustum();
|
auto frustum = camera->getFrustum();
|
||||||
auto planes = frustum.getPlanes();
|
auto planes = frustum.getNormalizedPlanes();
|
||||||
for(int i = 0; i < 6; i++) {
|
for(int i = 0; i < 6; i++) {
|
||||||
for(int j = 0; j < 4; j++) {
|
for(int j = 0; j < 4; j++) {
|
||||||
out[(i*4) + j] = planes[i][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)
|
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(TCamera *tCamera, double4x4 projectionMatrix, double near, double far)
|
||||||
{
|
{
|
||||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||||
camera->setCustomProjection(convert_double4x4_to_mat4(projectionMatrix), near, far);
|
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);
|
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||||
return camera->getFocusDistance();
|
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);
|
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||||
return camera->setFocusDistance(distance);
|
return camera->setFocusDistance(distance);
|
||||||
}
|
}
|
||||||
@@ -93,16 +106,16 @@ namespace thermion
|
|||||||
return camera->getCullingFar();
|
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 bottom, double top,
|
||||||
double near, double far)
|
double near, double far)
|
||||||
{
|
{
|
||||||
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
auto *camera = reinterpret_cast<Camera *>(tCamera);
|
||||||
filament::Camera::Projection filamentProjection;
|
filament::Camera::Projection filamentProjection;
|
||||||
switch(projection) {
|
switch(projection) {
|
||||||
case Projection::Orthographic:
|
case TProjection::Orthographic:
|
||||||
filamentProjection = filament::Camera::Projection::ORTHO;
|
filamentProjection = filament::Camera::Projection::ORTHO;
|
||||||
case Projection::Perspective:
|
case TProjection::Perspective:
|
||||||
filamentProjection = filament::Camera::Projection::PERSPECTIVE;
|
filamentProjection = filament::Camera::Projection::PERSPECTIVE;
|
||||||
}
|
}
|
||||||
camera->setProjection(filamentProjection, left, right, bottom, top, near, far);
|
camera->setProjection(filamentProjection, left, right, bottom, top, near, far);
|
||||||
|
|||||||
@@ -47,15 +47,21 @@ namespace thermion
|
|||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TEngine *Engine_create(
|
EMSCRIPTEN_KEEPALIVE TEngine *Engine_create(
|
||||||
TBackend backend,
|
TBackend backend,
|
||||||
void* platform,
|
void* tPlatform,
|
||||||
void* sharedContext,
|
void* tSharedContext,
|
||||||
uint8_t stereoscopicEyeCount,
|
uint8_t stereoscopicEyeCount,
|
||||||
bool disableHandleUseAfterFreeCheck)
|
bool disableHandleUseAfterFreeCheck)
|
||||||
{
|
{
|
||||||
filament::Engine::Config config;
|
filament::Engine::Config config;
|
||||||
config.stereoscopicEyeCount = stereoscopicEyeCount;
|
config.stereoscopicEyeCount = stereoscopicEyeCount;
|
||||||
config.disableHandleUseAfterFreeCheck = disableHandleUseAfterFreeCheck;
|
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);
|
return reinterpret_cast<TEngine *>(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,12 +46,13 @@ EMSCRIPTEN_KEEPALIVE int LightManager_createLight(TEngine *tEngine, TLightManage
|
|||||||
}
|
}
|
||||||
|
|
||||||
filament::LightManager::Builder builder(lightType);
|
filament::LightManager::Builder builder(lightType);
|
||||||
auto entity = utils::EntityManager::create();
|
auto &em = utils::EntityManager::get();
|
||||||
auto result = builder.build(*engine, utils::Entity::import(entity));
|
auto entity = em.create();
|
||||||
|
auto result = builder.build(*engine, entity);
|
||||||
if(result != filament::LightManager::Builder::Result::Success) {
|
if(result != filament::LightManager::Builder::Result::Success) {
|
||||||
Log("Failed to create light");
|
Log("Failed to create light");
|
||||||
}
|
}
|
||||||
return entity;
|
return utils::Entity::smuggle(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void LightManager_destroyLight(TLightManager *tLightManager, EntityId entity) {
|
EMSCRIPTEN_KEEPALIVE void LightManager_destroyLight(TLightManager *tLightManager, EntityId entity) {
|
||||||
|
|||||||
@@ -2,12 +2,16 @@
|
|||||||
|
|
||||||
#include <filament/MaterialInstance.h>
|
#include <filament/MaterialInstance.h>
|
||||||
#include <filament/Material.h>
|
#include <filament/Material.h>
|
||||||
|
|
||||||
#include <math/mat4.h>
|
#include <math/mat4.h>
|
||||||
#include <math/vec4.h>
|
#include <math/vec4.h>
|
||||||
#include <math/vec2.h>
|
#include <math/vec2.h>
|
||||||
|
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
#include "materials/image.h"
|
|
||||||
|
#include "material/image.h"
|
||||||
|
#include "material/grid.h"
|
||||||
|
|
||||||
#include "c_api/TMaterialInstance.h"
|
#include "c_api/TMaterialInstance.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -26,7 +30,7 @@ namespace thermion
|
|||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createImageMaterial(TEngine *tEngine) {
|
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createImageMaterial(TEngine *tEngine) {
|
||||||
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
|
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
|
||||||
auto *material = Material::Builder()
|
auto *material = filament::Material::Builder()
|
||||||
.package(IMAGE_IMAGE_DATA, IMAGE_IMAGE_SIZE)
|
.package(IMAGE_IMAGE_DATA, IMAGE_IMAGE_SIZE)
|
||||||
.build(*engine);
|
.build(*engine);
|
||||||
|
|
||||||
@@ -35,10 +39,9 @@ namespace thermion
|
|||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createGridMaterial(TEngine *tEngine) {
|
EMSCRIPTEN_KEEPALIVE TMaterial *Material_createGridMaterial(TEngine *tEngine) {
|
||||||
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
|
auto *engine = reinterpret_cast<filament::Engine *>(tEngine);
|
||||||
auto *material = Material::Builder()
|
auto *material = filament::Material::Builder()
|
||||||
.package(GRID_GRID_DATA, GRID_GRID_SIZE)
|
.package(GRID_GRID_DATA, GRID_GRID_SIZE)
|
||||||
.build(*engine);
|
.build(*engine);
|
||||||
|
|
||||||
return reinterpret_cast<TMaterial *>(material);
|
return reinterpret_cast<TMaterial *>(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ namespace thermion
|
|||||||
if (!renderableInstance.isValid()) {
|
if (!renderableInstance.isValid()) {
|
||||||
return Aabb3 { };
|
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};
|
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 <vector>
|
||||||
|
|
||||||
#include "c_api/TTexture.h"
|
|
||||||
|
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
#include <filament/Material.h>
|
#include <filament/Material.h>
|
||||||
#include <filament/RenderTarget.h>
|
#include <filament/RenderTarget.h>
|
||||||
@@ -15,6 +14,8 @@
|
|||||||
#include <filament/imageio/ImageDecoder.h>
|
#include <filament/imageio/ImageDecoder.h>
|
||||||
#include <filament/backend/DriverEnums.h>
|
#include <filament/backend/DriverEnums.h>
|
||||||
|
|
||||||
|
#include "c_api/TTexture.h"
|
||||||
|
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -227,7 +228,7 @@ namespace thermion
|
|||||||
auto *engine = reinterpret_cast<::filament::Engine *>(tEngine);
|
auto *engine = reinterpret_cast<::filament::Engine *>(tEngine);
|
||||||
auto format = convertToFilamentFormat(tFormat);
|
auto format = convertToFilamentFormat(tFormat);
|
||||||
auto samplerType = static_cast<::filament::Texture::Sampler>(static_cast<int>(tSamplerType));
|
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) {
|
if ((usage & TextureUsage::UPLOADABLE) == TextureUsage::UPLOADABLE) {
|
||||||
TRACE("UPLOADABLE");
|
TRACE("UPLOADABLE");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "RenderLoop.hpp"
|
#include "rendering/RenderLoop.hpp"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <stdlib.h>
|
#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