diff --git a/assets/default.uberz b/assets/default.uberz new file mode 100644 index 00000000..a19003d2 --- /dev/null +++ b/assets/default.uberz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f3968531385d8ba9db3e8460451ccf55c5e80108caeae813fcfb8f32230dbd2e +size 3607448 diff --git a/assets/materials.uberz b/assets/materials.uberz deleted file mode 100644 index 50a940b3..00000000 --- a/assets/materials.uberz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7f198192ece625049c5ef37e088906f520c5ea4af6871c434610ede5c6c29371 -size 293937 diff --git a/example/lib/main.dart b/example/lib/main.dart index f5cd2cdb..f3e9b4e4 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -7,6 +7,8 @@ import 'package:polyvox_filament/filament_gesture_detector.dart'; import 'package:polyvox_filament/filament_widget.dart'; import 'package:polyvox_filament/animations/animation_builder.dart'; +import 'package:path_provider/path_provider.dart'; + void main() { runApp(const MyApp()); } @@ -24,7 +26,7 @@ class _MyAppState extends State with SingleTickerProviderStateMixin { return MaterialApp( // showPerformanceOverlay: true, color: Colors.white, - home: Scaffold(backgroundColor: Colors.lightBlue, body: ExampleWidget())); + home: Scaffold(backgroundColor: Colors.white, body: ExampleWidget())); } } @@ -56,9 +58,12 @@ class _ExampleWidgetState extends State { @override void initState() { + getApplicationSupportDirectory().then((dir) { + print(dir); + }); super.initState(); } - + Widget _item(void Function() onTap, String text) { return GestureDetector( onTap: onTap, @@ -247,7 +252,7 @@ class _ExampleWidgetState extends State { return Stack(children: [ Positioned( bottom: 100, - height:400, width:400, + height:768, width:1024, child: FilamentGestureDetector( showControlOverlay: true, controller: _filamentController, diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index f9707e5e..164ab2ff 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,8 +5,10 @@ import FlutterMacOS import Foundation +import path_provider_foundation import polyvox_filament func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SwiftPolyvoxFilamentPlugin.register(with: registry.registrar(forPlugin: "SwiftPolyvoxFilamentPlugin")) } diff --git a/example/pubspec.lock b/example/pubspec.lock index 35e58870..15dbc9a7 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -57,6 +57,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + url: "https://pub.dev" + source: hosted + version: "2.1.0" flutter: dependency: "direct main" description: flutter @@ -128,6 +136,62 @@ packages: url: "https://pub.dev" source: hosted version: "1.8.3" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + url: "https://pub.dev" + source: hosted + version: "2.1.1" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + url: "https://pub.dev" + source: hosted + version: "2.3.1" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + platform: + dependency: transitive + description: + name: platform + sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 + url: "https://pub.dev" + source: hosted + version: "3.1.2" plugin_platform_interface: dependency: transitive description: @@ -228,6 +292,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.4-beta" + win32: + dependency: transitive + description: + name: win32 + sha256: c97defd418eef4ec88c0d1652cdce84b9f7b63dd7198e266d06ac1710d527067 + url: "https://pub.dev" + source: hosted + version: "5.0.8" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" + url: "https://pub.dev" + source: hosted + version: "1.0.3" sdks: dart: ">=3.1.0-185.0.dev <3.11.0" - flutter: ">=1.20.0" + flutter: ">=3.7.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 3559e707..a0a110bb 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -17,7 +17,7 @@ environment: dependencies: flutter: sdk: flutter - + path_provider: polyvox_filament: path: ../ diff --git a/ios/src/AssetManager.cpp b/ios/src/AssetManager.cpp index 845086df..72caebf2 100644 --- a/ios/src/AssetManager.cpp +++ b/ios/src/AssetManager.cpp @@ -21,13 +21,11 @@ #include "Log.hpp" #include "AssetManager.hpp" -#include "material/UnlitMaterialProvider.hpp" #include "material/FileMaterialProvider.hpp" -#include "gltfio/materials/uberarchive.h" +// #include "gltfio/materials/uberarchive.h" extern "C" { #include "material/image.h" -#include "material/unlit_opaque.h" } namespace polyvox { @@ -54,20 +52,18 @@ _scene(scene) { _gltfResourceLoader = new ResourceLoader({.engine = _engine, .normalizeSkinningWeights = true }); - auto uberdata = resourceLoaderWrapper->load("packages/polyvox_filament/assets/materials_ios_arm64.uberz"); + auto uberdata = resourceLoaderWrapper->load("packages/polyvox_filament/assets/default.uberz"); + + if (!uberdata.data) { + Log("Failed to load ubershader material. This is fatal."); + } _ubershaderProvider = gltfio::createUbershaderProvider( - _engine, uberdata.data, uberdata.size); - // _ubershaderProvider = gltfio::createUbershaderProvider( - // _engine, UBERARCHIVE_DEFAULT_DATA, UBERARCHIVE_DEFAULT_SIZE); - // _ubershaderProvider = gltfio::createJitShaderProvider(_engine, true); + _engine, uberdata.data, uberdata.size); + Log("Created ubershader provider."); + EntityManager &em = EntityManager::get(); - - //_unlitProvider = new UnlitMaterialProvider(_engine); - - // auto rb = _resourceLoaderWrapper->load("file:///mnt/hdd_2tb/home/hydroxide/projects/polyvox/flutter/polyvox_filament/materials/toon.filamat"); - // auto toonProvider = new FileMaterialProvider(_engine, rb.data, (size_t) rb.size); - + _assetLoader = AssetLoader::create({_engine, _ubershaderProvider, _ncm, &em }); _gltfResourceLoader->addTextureProvider("image/ktx2", _ktxDecoder); _gltfResourceLoader->addTextureProvider("image/png", _stbDecoder); @@ -77,7 +73,6 @@ _scene(scene) { AssetManager::~AssetManager() { _gltfResourceLoader->asyncCancelLoad(); _ubershaderProvider->destroyMaterials(); - //_unlitProvider->destroyMaterials(); destroyAll(); AssetLoader::destroy(&_assetLoader); diff --git a/ios/src/FilamentViewer.cpp b/ios/src/FilamentViewer.cpp index 53c1aa03..11553a65 100644 --- a/ios/src/FilamentViewer.cpp +++ b/ios/src/FilamentViewer.cpp @@ -21,6 +21,7 @@ */ #include #include +#include #include #include #include @@ -108,13 +109,13 @@ static constexpr float4 sFullScreenTriangleVertices[3] = { static const uint16_t sFullScreenTriangleIndices[3] = {0, 1, 2}; -FilamentViewer::FilamentViewer(const void* context, const ResourceLoaderWrapper* const resourceLoaderWrapper) +FilamentViewer::FilamentViewer(const void* sharedContext, const ResourceLoaderWrapper* const resourceLoaderWrapper) : _resourceLoaderWrapper(resourceLoaderWrapper) { #if TARGET_OS_IPHONE _engine = Engine::create(Engine::Backend::METAL); #else - _engine = Engine::create(Engine::Backend::OPENGL, nullptr, (void*)context, nullptr); + _engine = Engine::create(Engine::Backend::OPENGL, nullptr, (void*)sharedContext, nullptr); #endif _renderer = _engine->createRenderer(); @@ -136,10 +137,15 @@ FilamentViewer::FilamentViewer(const void* context, const ResourceLoaderWrapper* Log("Main camera created"); _view = _engine->createView(); + _view->setPostProcessingEnabled(false); + Log("View created"); setToneMapping(ToneMapping::ACES); + Log("Set tone mapping"); + setBloom(0.6f); + Log("Set bloom"); _view->setScene(_scene); _view->setCamera(_mainCamera); @@ -148,7 +154,7 @@ FilamentViewer::FilamentViewer(const void* context, const ResourceLoaderWrapper* _mainCamera->setLensProjection(_cameraFocalLength, 1.0f, kNearPlane, kFarPlane); // _mainCamera->setExposure(kAperture, kShutterSpeed, kSensitivity); - + Log("View created"); const float aperture = _mainCamera->getAperture(); const float shutterSpeed = _mainCamera->getShutterSpeed(); const float sens = _mainCamera->getSensitivity(); @@ -188,14 +194,18 @@ FilamentViewer::FilamentViewer(const void* context, const ResourceLoaderWrapper* .format(Texture::InternalFormat::RGB16F) .sampler(Texture::Sampler::SAMPLER_2D) .build(*_engine); - - _imageMaterial = - Material::Builder() - .package(IMAGE_PACKAGE, IMAGE_IMAGE_SIZE) - .build(*_engine); - _imageMaterial->setDefaultParameter("showImage",0); - _imageMaterial->setDefaultParameter("backgroundColor", RgbaType::sRGB, float4(0.5f, 0.5f, 0.5f, 1.0f)); - _imageMaterial->setDefaultParameter("image", _imageTexture, _imageSampler); + try { + _imageMaterial = + Material::Builder() + .package(IMAGE_IMAGE_DATA, IMAGE_IMAGE_SIZE) + .build(*_engine); + _imageMaterial->setDefaultParameter("showImage",0); + _imageMaterial->setDefaultParameter("backgroundColor", RgbaType::sRGB, float4(0.5f, 0.5f, 0.5f, 1.0f)); + _imageMaterial->setDefaultParameter("image", _imageTexture, _imageSampler); + } catch(...) { + Log("Failed to load background image material provider"); + std::rethrow_exception(std::current_exception()); + } _imageScale = mat4f { 1.0f , 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; _imageMaterial->setDefaultParameter("transform", _imageScale); @@ -401,16 +411,14 @@ void FilamentViewer::loadTextureFromPath(string path) { } else if(endsWith(path, pngExt)) { loadPngTexture(path, rb); } - _resourceLoaderWrapper->free(rb); - } void FilamentViewer::setBackgroundColor(const float r, const float g, const float b, const float a) { _imageMaterial->setDefaultParameter("showImage", 0); _imageMaterial->setDefaultParameter("backgroundColor", RgbaType::sRGB, float4(r, g, b, a)); const Viewport& vp = _view->getViewport(); - _imageMaterial->setDefaultParameter("transform", _imageScale); + _imageMaterial->setDefaultParameter("transform", _imageScale); } void FilamentViewer::clearBackgroundImage() { @@ -559,13 +567,25 @@ void FilamentViewer::createSwapChain(const void *window, uint32_t width, uint32_ #else if(window) { _swapChain = _engine->createSwapChain((void*)window, filament::backend::SWAP_CHAIN_CONFIG_TRANSPARENT | filament::backend::SWAP_CHAIN_CONFIG_READABLE); + Log("Created window swapchain."); } else { + Log("Created headless swapchain."); _swapChain = _engine->createSwapChain(width, height, filament::backend::SWAP_CHAIN_CONFIG_TRANSPARENT | filament::backend::SWAP_CHAIN_CONFIG_READABLE); } #endif - Log("Swapchain created."); + // filament::backend::OpenGLPlatform* platform = dynamic_cast(_engine->getPlatform()); + // if(!platform->isExtraContextSupported()) { + // Log("Extra context unsupported."); + // } else { + // Log("Creating additional context."); + + // platform->createContext(false); + // } + // platform->makeCurrent((filament::backend::Platform::SwapChain*)_swapChain, (filament::backend::Platform::SwapChain*)_swapChain); + // Log("Made current."); } + void FilamentViewer::createRenderTarget(intptr_t textureId, uint32_t width, uint32_t height) { // Create filament textures and render targets (note the color buffer has the import call) _rtColor = filament::Texture::Builder() @@ -811,7 +831,11 @@ void FilamentViewer::loadIbl(const char *const iblPath, float intensity) { double _elapsed = 0; int _frameCount = 0; -void FilamentViewer::render(uint64_t frameTimeInNanos) { +void FilamentViewer::render( + uint64_t frameTimeInNanos, + void* pixelBuffer, + void (*callback)(void *buf, size_t size, void *data), + void* data) { if (!_view || !_mainCamera || !_swapChain) { Log("Not ready for rendering"); @@ -831,12 +855,24 @@ void FilamentViewer::render(uint64_t frameTimeInNanos) { _elapsed += tmr.elapsed(); _frameCount++; - // Render the scene, unless the renderer wants to skip the frame. - if (_renderer->beginFrame(_swapChain, frameTimeInNanos)) { + if(pixelBuffer) { + auto pbd = Texture::PixelBufferDescriptor( + pixelBuffer, size_t(1024 * 768 * 4), + Texture::Format::RGBA, + Texture::Type::BYTE, nullptr, callback, data); + + _renderer->beginFrame(_swapChain, 0); _renderer->render(_view); + _renderer->readPixels(0,0,1024,768, std::move(pbd)); _renderer->endFrame(); } else { - // skipped frame + // Render the scene, unless the renderer wants to skip the frame. + if (_renderer->beginFrame(_swapChain, frameTimeInNanos)) { + _renderer->render(_view); + _renderer->endFrame(); + } else { + // skipped frame + } } } diff --git a/ios/src/PolyvoxFilamentApi.cpp b/ios/src/PolyvoxFilamentApi.cpp index fab3782d..79bead61 100644 --- a/ios/src/PolyvoxFilamentApi.cpp +++ b/ios/src/PolyvoxFilamentApi.cpp @@ -122,9 +122,11 @@ extern "C" { void render( const void* const viewer, - uint64_t frameTimeInNanos - ) { - ((FilamentViewer*)viewer)->render(frameTimeInNanos); + uint64_t frameTimeInNanos, + void* pixelBuffer, + void (*callback)(void *buf, size_t size, void *data), + void* data) { + ((FilamentViewer*)viewer)->render(frameTimeInNanos, pixelBuffer, callback, data); } void set_frame_interval( diff --git a/lib/filament_controller.dart b/lib/filament_controller.dart index ec0e6f08..7215e877 100644 --- a/lib/filament_controller.dart +++ b/lib/filament_controller.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'dart:ui' as ui; import 'package:flutter/services.dart'; import 'package:polyvox_filament/animations/bone_animation_data.dart'; @@ -37,11 +38,23 @@ class FilamentController { }); } + Timer? _renderTicker; + Future setRendering(bool render) async { if (_viewer == null || _resizing) { throw Exception("No viewer available, ignoring"); } - return _channel.invokeMethod("setRendering", render); + if(Platform.isWindows) { + _renderTicker?.cancel(); + if(render) { + _renderTicker = Timer.periodic(Duration(milliseconds: 1000 ~/ 60), (timer) { + _channel.invokeMethod("render"); + }); + } + } else { + return _channel.invokeMethod("setRendering", render); + } + } Future render() async { @@ -91,6 +104,8 @@ class FilamentController { throw Exception( "Do not call createViewer when a viewer has already been created without calling destroyViewer"); } + + print("Creating viewer with pixel ratio $_pixelRatio"); size = ui.Size(width * _pixelRatio, height * _pixelRatio); _textureId = @@ -99,13 +114,14 @@ class FilamentController { _viewer = await _channel .invokeMethod("createFilamentViewer", [size.width, size.height]); - // await _channel.invokeMethod("updateViewportAndCameraProjection", - // [size.width.toInt(), size.height.toInt(), 1.0]); - // _assetManager = await _channel.invokeMethod("getAssetManager"); + await _channel.invokeMethod("updateViewportAndCameraProjection", + [size.width.toInt(), size.height.toInt(), 1.0]); + _assetManager = await _channel.invokeMethod("getAssetManager"); _textureIdController.add(_textureId); _isReadyForScene.complete(true); + } bool _resizing = false; @@ -260,7 +276,7 @@ class FilamentController { throw Exception("No viewer available, ignoring"); } await _channel - .invokeMethod("grabBegin", [x * _pixelRatio, y * _pixelRatio, 1]); + .invokeMethod("grabBegin", [x * _pixelRatio, y * _pixelRatio, true]); } Future panUpdate(double x, double y) async { @@ -283,7 +299,7 @@ class FilamentController { throw Exception("No viewer available, ignoring"); } await _channel - .invokeMethod("grabBegin", [x * _pixelRatio, y * _pixelRatio, 0]); + .invokeMethod("grabBegin", [x * _pixelRatio, y * _pixelRatio, false]); } Future rotateUpdate(double x, double y) async { diff --git a/linux/filament_pb_texture.cc b/linux/filament_pb_texture.cc index 62a07d9a..2caf7102 100644 --- a/linux/filament_pb_texture.cc +++ b/linux/filament_pb_texture.cc @@ -12,7 +12,7 @@ #include #include - +// This was just an experiment for copying pixel buffers to Flutter. This won't actually render anything from Filament. G_DEFINE_TYPE(FilamentPBTexture, filament_pb_texture, fl_pixel_buffer_texture_get_type()) @@ -24,8 +24,8 @@ static gboolean video_texture_copy_pixels (FlPixelBufferTexture* texture, uint32_t* height, GError** error) { - auto buffer = new std::vector(400*200*4); - for (int i = 0; i < 400*200*4; i++) + auto buffer = new std::vector(width*height*4); + for (int i = 0; i < width*height*4; i++) { if(i%4 == 1 || i % 4 == 3) { buffer->at(i) = (uint8_t)255; @@ -33,10 +33,10 @@ static gboolean video_texture_copy_pixels (FlPixelBufferTexture* texture, buffer->at(i) = (uint8_t)0; } } - *width = 400; - *height = 200; + *width = width; + *height = height; *out_buffer = buffer->data(); - std::cout << "COPY" << std::endl; + std::cout << "COPYING PIXEL BUFFER" << std::endl; return TRUE; } diff --git a/macos/include/material/UnlitMaterialProvider.hpp b/macos/include/material/UnlitMaterialProvider.hpp deleted file mode 100644 index c2d7d4fe..00000000 --- a/macos/include/material/UnlitMaterialProvider.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef UNLIT_MATERIAL_PROVIDER -#define UNLIT_MATERIAL_PROVIDER - -#include "material/unlit_opaque.h" - -namespace polyvox { - class UnlitMaterialProvider : public MaterialProvider { - - const Material* _m; - const Material* _ms[1]; - - const Engine* _engine; - - public: - UnlitMaterialProvider(Engine* engine) { - _engine = engine; - _m = Material::Builder() - .package( UNLIT_OPAQUE_UNLIT_OPAQUE_DATA, UNLIT_OPAQUE_UNLIT_OPAQUE_SIZE) - .build(*engine); - _ms[0] = _m; - } - - filament::MaterialInstance* createMaterialInstance(MaterialKey* config, UvMap* uvmap, - const char* label = "material", const char* extras = nullptr) { - MaterialInstance* d = (MaterialInstance*)_m->getDefaultInstance(); - return d; - } - - /** - * Gets a weak reference to the array of cached materials. - */ - const filament::Material* const* getMaterials() const noexcept { - return _ms; - } - - /** - * Gets the number of cached materials. - */ - size_t getMaterialsCount() const noexcept { - return (size_t)1; - } - - void destroyMaterials() { - // TODO - do we need to do anything here? - } - - bool needsDummyData(filament::VertexAttribute attrib) const noexcept { - return false; - } - }; -} - -#endif \ No newline at end of file diff --git a/macos/src/AssetManager.cpp b/macos/src/AssetManager.cpp index e923aa73..8e192d82 100644 --- a/macos/src/AssetManager.cpp +++ b/macos/src/AssetManager.cpp @@ -51,8 +51,8 @@ _scene(scene) { _gltfResourceLoader = new ResourceLoader({.engine = _engine, .normalizeSkinningWeights = true }); - - auto uberdata = resourceLoaderWrapper->load("packages/polyvox_filament/assets/materials.uberz"); +sdfsdfds + auto uberdata = resourceLoaderWrapper->load("packages/polyvox_filament/assets/default.uberz"); _ubershaderProvider = gltfio::createUbershaderProvider( _engine, uberdata.data, uberdata.size); diff --git a/pubspec.yaml b/pubspec.yaml index 9ef1d228..64fbdc5a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,8 +31,7 @@ ffigen: flutter: assets: - - assets/materials.uberz - - assets/materials_ios_arm64.uberz + - assets/ plugin: platforms: android: