// ignore_for_file: unused_local_variable import 'dart:io'; import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; import 'package:test/test.dart'; import 'package:thermion_dart/src/filament/src/implementation/ffi_asset.dart'; import 'package:thermion_dart/src/filament/src/implementation/ffi_camera.dart'; import 'package:thermion_dart/src/filament/src/implementation/ffi_material.dart'; import 'package:thermion_dart/src/filament/src/implementation/ffi_render_target.dart'; import 'package:thermion_dart/src/filament/src/implementation/ffi_scene.dart'; import 'package:thermion_dart/src/filament/src/implementation/ffi_view.dart'; import 'package:thermion_dart/thermion_dart.dart'; import 'helpers.dart'; void main() async { Logger.root.onRecord.listen((record) { print(record); }); final testHelper = TestHelper("view"); await testHelper.setup(); test('get camera from view', () async { await testHelper.withViewer((viewer) async { final camera = await viewer.view.getCamera(); expect(camera, isNotNull); }); }); test('render to multiple views, same camera', () async { final viewportDimensions = (width: 500, height: 500); final swapChain = await FilamentApp.instance!.createHeadlessSwapChain( viewportDimensions.width, viewportDimensions.height); await FilamentApp.instance!.setClearOptions(0, 0, 0, 0); final views = []; final scene = await FilamentApp.instance!.createScene() as FFIScene; final camera = await FilamentApp.instance!.createCamera() as FFICamera; await camera.setLensProjection(); for (int i = 0; i < 2; i++) { final view = await FilamentApp.instance!.createView() as FFIView; await view.setScene(scene); await view.setCamera(camera); await view.setRenderable(true); await view.setViewport( viewportDimensions.width, viewportDimensions.height); await view.setFrustumCullingEnabled(false); await view.setPostProcessing(false); await FilamentApp.instance!.register(swapChain, view); views.add(view); await view.setRenderTarget(await FilamentApp.instance!.createRenderTarget( viewportDimensions.width, viewportDimensions.height, ) as FFIRenderTarget); } await camera.lookAt(Vector3(0, 0, 10)); var materialInstance = await FilamentApp.instance!.createUnlitMaterialInstance(); await materialInstance.setParameterFloat4("baseColorFactor", 1, 0, 0, 0); var cube = await FilamentApp.instance!.createGeometry( GeometryHelper.cube(flipUvs: true), nullptr, materialInstances: [materialInstance]) as FFIAsset; await scene.add(cube); final results = await FilamentApp.instance!.capture(swapChain); await savePixelBufferToBmp( results.first.$2, viewportDimensions.width, viewportDimensions.height, p.join(testHelper.outDir.path, "multi_view_same_camera_0.bmp"), isFloat: true); await savePixelBufferToBmp( results.last.$2, viewportDimensions.width, viewportDimensions.height, p.join(testHelper.outDir.path, "multi_view_same_camera_1.bmp"), isFloat: true); }); test('render to multiple views, same scene, different camera', () async { final viewportDimensions = (width: 500, height: 500); final swapChain = await FilamentApp.instance!.createHeadlessSwapChain( viewportDimensions.width, viewportDimensions.height); final views = []; final scene = await FilamentApp.instance!.createScene() as FFIScene; final camera1 = await FilamentApp.instance!.createCamera() as FFICamera; await camera1.setLensProjection(); final camera2 = await FilamentApp.instance!.createCamera() as FFICamera; await camera2.setLensProjection(); for (int i = 0; i < 2; i++) { final view = await FilamentApp.instance!.createView() as FFIView; await view.setScene(scene); await view.setRenderable(true); await view.setViewport( viewportDimensions.width, viewportDimensions.height); await view.setFrustumCullingEnabled(false); await view.setPostProcessing(false); await FilamentApp.instance!.register(swapChain, view); views.add(view); } await camera1.lookAt(Vector3(-5, 0, 10)); await camera2.lookAt(Vector3(5, 0, 10)); await views.first.setCamera(camera1); await views.last.setCamera(camera2); var materialInstance = await FilamentApp.instance!.createUnlitMaterialInstance(); await materialInstance.setParameterFloat4("baseColorFactor", 1, 0, 0, 0); var cube = await FilamentApp.instance!.createGeometry( GeometryHelper.cube(flipUvs: true), nullptr, materialInstances: [materialInstance]) as FFIAsset; await scene.add(cube); await testHelper.capture(null, "multiple_view_different_camera"); }); test('render view to render target, used as input for another', () async { final viewportDimensions = (width: 500, height: 500); final swapChain = await FilamentApp.instance!.createHeadlessSwapChain( viewportDimensions.width, viewportDimensions.height); final views = []; final scene = await FilamentApp.instance!.createScene() as FFIScene; final camera = await FilamentApp.instance!.createCamera() as FFICamera; await camera.setLensProjection(); await FilamentApp.instance!.setClearOptions(0, 0, 0, 0); for (int i = 0; i < 2; i++) { final view = await FilamentApp.instance!.createView() as FFIView; await view.setScene(scene); await view.setRenderable(true); await view.setViewport( viewportDimensions.width, viewportDimensions.height); await view.setFrustumCullingEnabled(false); await view.setPostProcessing(false); await view.setRenderTarget(await FilamentApp.instance!.createRenderTarget( viewportDimensions.width, viewportDimensions.height) as FFIRenderTarget); await FilamentApp.instance!.register(swapChain, view); await view.setCamera(camera); views.add(view); } await camera.lookAt(Vector3(0, 4, 12), focus: Vector3(0, -4, 0)); var materialInstance1 = await FilamentApp.instance!.createUnlitMaterialInstance(); await materialInstance1.setParameterFloat4("baseColorFactor", 1, 0, 0, 0); var cube = await FilamentApp.instance!.createGeometry( GeometryHelper.cube(flipUvs: true), nullptr, materialInstances: [materialInstance1]) as FFIAsset; await scene.add(cube); var result = await FilamentApp.instance!.capture(swapChain, view: views.first); await savePixelBufferToBmp( result.first.$2, viewportDimensions.width, viewportDimensions.height, p.join(testHelper.outDir.path, "render_target_output.bmp"), isFloat: true); var materialInstance2 = await FilamentApp.instance! .createUbershaderMaterialInstance( hasBaseColorTexture: true, unlit: false); var light = await FilamentApp.instance!.createDirectLight(DirectLight( type: LightType.SUN, color: 6500, intensity: 100000000, direction: Vector3(0,0,-1), position: Vector3.zero())); await scene.addEntity(light); final texture = await (await views.first.getRenderTarget())!.getColorTexture(); await materialInstance2.setParameterTexture("baseColorMap", texture, await FilamentApp.instance!.createTextureSampler()); await materialInstance2.setParameterInt("baseColorIndex",0); await materialInstance2.setParameterFloat4("baseColorFactor", 1, 1, 1, 1); await cube.setMaterialInstanceAt(materialInstance2 as FFIMaterialInstance); result = await FilamentApp.instance!.capture(swapChain, view: views.last); await savePixelBufferToBmp( result.first.$2, viewportDimensions.width, viewportDimensions.height, p.join(testHelper.outDir.path, "render_target_as_texture.bmp"), isFloat: true); }); test('render depth buffer to render target', () async { final viewportDimensions = (width: 500, height: 500); final swapChain = await FilamentApp.instance!.createHeadlessSwapChain( viewportDimensions.width, viewportDimensions.height); final views = []; final scene = await FilamentApp.instance!.createScene() as FFIScene; final camera = await FilamentApp.instance!.createCamera() as FFICamera; await camera.setLensProjection(); await FilamentApp.instance!.setClearOptions(0, 0, 0, 0); for (int i = 0; i < 2; i++) { final view = await FilamentApp.instance!.createView() as FFIView; await view.setScene(scene); await view.setRenderable(true); await view.setViewport( viewportDimensions.width, viewportDimensions.height); await view.setFrustumCullingEnabled(false); await view.setPostProcessing(false); await view.setRenderTarget(await FilamentApp.instance!.createRenderTarget( viewportDimensions.width, viewportDimensions.height) as FFIRenderTarget); await FilamentApp.instance!.register(swapChain, view); await view.setCamera(camera); views.add(view); } await camera.lookAt(Vector3(0, 4, 12), focus: Vector3(0, -4, 0)); var materialInstance1 = await FilamentApp.instance!.createUnlitMaterialInstance(); await materialInstance1.setParameterFloat4("baseColorFactor", 1, 0, 0, 0); var cube = await FilamentApp.instance!.createGeometry( GeometryHelper.cube(flipUvs: true), nullptr, materialInstances: [materialInstance1]) as FFIAsset; await scene.add(cube); var result = await FilamentApp.instance!.capture(swapChain, view: views.first); await savePixelBufferToBmp( result.first.$2, viewportDimensions.width, viewportDimensions.height, p.join(testHelper.outDir.path, "render_target_output.bmp"), isFloat: true); var materialInstance2 = await FilamentApp.instance! .createUbershaderMaterialInstance( hasBaseColorTexture: true, unlit: false); var light = await FilamentApp.instance!.createDirectLight(DirectLight( type: LightType.SUN, color: 6500, intensity: 100000000, direction: Vector3(0,0,-1), position: Vector3.zero())); await scene.addEntity(light); final texture = await (await views.first.getRenderTarget())!.getColorTexture(); await materialInstance2.setParameterTexture("baseColorMap", texture, await FilamentApp.instance!.createTextureSampler()); await materialInstance2.setParameterInt("baseColorIndex",0); await materialInstance2.setParameterFloat4("baseColorFactor", 1, 1, 1, 1); await cube.setMaterialInstanceAt(materialInstance2 as FFIMaterialInstance); result = await FilamentApp.instance!.capture(swapChain, view: views.last); await savePixelBufferToBmp( result.first.$2, viewportDimensions.width, viewportDimensions.height, p.join(testHelper.outDir.path, "render_target_as_texture.bmp"), isFloat: true); }); } // test('one swapchain, render view to render target', () async { // await testHelper.withViewer((viewer) async { // final texture = await testHelper.createTexture(500, 500); // final renderTarget = await viewer.createRenderTarget( // 500, 500, texture.metalTextureAddress); // final view = await viewer.getViewAt(0); // await view.setRenderTarget(renderTarget); // await viewer.setBackgroundColor(1.0, 0, 0, 1); // final cube = await viewer // .createGeometry(GeometryHelper.cube(normals: false, uvs: false)); // var mainCamera = await viewer.getMainCamera(); // mainCamera.setTransform(Matrix4.translation(Vector3(0, 0, 5))); // await testHelper.capture( // viewer, // renderTarget: renderTarget, // "default_swapchain_default_view_render_target"); // }); // }); // test('create secondary view, default swapchain', () async { // await testHelper.withViewer((viewer) async { // final cube = await viewer // .createGeometry(GeometryHelper.cube(normals: false, uvs: false)); // var mainCamera = await viewer.getMainCamera(); // mainCamera.setTransform(Matrix4.translation(Vector3(0, 0, 5))); // await testHelper.capture(viewer, "default_swapchain_default_view"); // final view = await viewer.createView(); // view.setViewport(500, 500); // view.setCamera(mainCamera); // await testHelper.capture( // viewer, // "default_swapchain_new_view_with_main_camera", // view: view, // ); // var newCamera = await viewer.createCamera(); // newCamera.setTransform(Matrix4.translation(Vector3(0.0, 0.0, 10.0))); // newCamera.setLensProjection(); // view.setCamera(newCamera); // await testHelper.capture( // viewer, // "default_swapchain_new_view_new_camera", // view: view, // ); // await testHelper.capture( // viewer, // "default_swapchain_default_view_main_camera_no_change", // ); // }); // }); // test('create secondary view, different swapchain', () async { // await testHelper.withViewer((viewer) async { // final cube = await viewer.createGeometry(GeometryHelper.cube()); // var mainCamera = await viewer.getMainCamera(); // mainCamera.setTransform(Matrix4.translation(Vector3(0, 0, 5))); // final swapChain = await viewer.createHeadlessSwapChain(1, 1); // await testHelper.capture( // viewer, "create_swapchain_default_view_default_swapchain"); // final view = await viewer.createView(); // final texture = await testHelper.createTexture(200, 400); // final renderTarget = await viewer.createRenderTarget( // 200, 400, texture.metalTextureAddress); // await view.setRenderTarget(renderTarget); // await view.setViewport(200, 400); // view.setCamera(mainCamera); // mainCamera.setLensProjection(aspect: 0.5); // await testHelper.capture( // viewer, // view: view, // swapChain: swapChain, // renderTarget: renderTarget, // "create_swapchain_secondary_view_new_swapchain", // ); // }); // }); // test('pick', () async { // await testHelper.withViewer((viewer) async { // final view = await viewer.getViewAt(0); // await view.setRenderable(true, testHelper.swapChain); // final cube = await viewer // .createGeometry(GeometryHelper.cube(normals: false, uvs: false)); // await testHelper.capture(viewer, "view_pick"); // final completer = Completer(); // await viewer.pick(250, 250, (result) { // completer.complete(result.entity); // print( // "Pick result : ${result.fragX} ${result.fragY} ${result.fragZ}"); // }); // for (int i = 0; i < 10; i++) { // await testHelper.capture(viewer, "view_pick"); // if (completer.isCompleted) { // break; // } // } // expect(completer.isCompleted, true); // expect(await completer.future, cube.entity); // }, cameraPosition: Vector3(0, 0, 3)); // }); // test('dithering', () async { // await testHelper.withViewer((viewer) async { // final view = await viewer.getViewAt(0); // expect(await view.isDitheringEnabled(), true); // final cube = await viewer // .createGeometry(GeometryHelper.cube(normals: false, uvs: false)); // await testHelper.capture(viewer, "dithering_enabled"); // await view.setDithering(false); // expect(await view.isDitheringEnabled(), false); // await testHelper.capture(viewer, "dithering_disabled"); // }, cameraPosition: Vector3(0, 0, 3)); // }); // }); // }