Skip to content
  • 首页
  • 留言
  • 关于

Share the joys of programming and technology

Filament加载并渲染glTF模型

Filament加载并渲染glTF模型

2022年10月23日 liyanliang Comments 0 Comment

1.初始化Filament

 void initFilamentEngine(void* nativeWindow)
 {
     filament::Engine* m_engine = filament::Engine::create(filament::backend::Backend::METAL);
     filament::SwapChain* m_swapChain = m_engine->createSwapChain(nativeWindow);
     filament::View* m_view = m_engine->createView();
 }

2.初始化renderer

 void initFilaRenderer()
 {
     filament::View* filaView = getFilaView();
     filament::Engine* filaEngine = getFilaEngine();
     
     filament::Renderer* m_renderer = filaEngine->createRenderer();
     m_renderer->setClearOptions({.clearColor={0.0, 0.0, 0.0, 1.0}, .clear = true});
     filament::Scene* m_scene = filaEngine->createScene();
     filaView->setScene(m_scene);
     utils::Entity m_camera = utils::EntityManager::get().create();
     auto camComponent = filaEngine->createCamera(m_camera);
     filaView->setCamera(camComponent);
     filaView->setPostProcessingEnabled(true);
     filaView->setAntiAliasing(filament::AntiAliasing::NONE);
     filaView->setMultiSampleAntiAliasingOptions({true, 4, false});
     filaView->setAmbientOcclusionOptions({.enabled = false});
     
     filaEngine->getDebugRegistry().setProperty("d.shadowmap.lispsm", false);
 }

3.上传glTF数据

(1)声明变量

     filament::gltfio::MaterialProvider* _matProvider;
     filament::gltfio::AssetLoader* _assetLoader;
     filament::gltfio::FilamentAsset* _asset;
     filament::gltfio::ResourceLoader* _resourceLoader;
     filament::gltfio::TextureProvider* _textureProvider;
     filament::gltfio::Animator* _animator;
     std::vector<utils::Entity> _newCreatedEntites;
     std::vector<utils::Entity> _entites;
     std::vector<utils::Entity> _lightEntites;
     std::vector<filament::math::float2> _lightProperties;
     mbgl::TimePoint _anmStartTime;
     std::string _curAnmName;
     int8_t _curAnmIndex;
     bool   _curAnmLoop;
     float  _curAnmDuration;
     bool   _resourceHasLoaded;
     
     static constexpr int kNumAvailable = 128;
     utils::Entity _renderables[kNumAvailable];
     
     std::mutex _mutex;
     std::vector<utils::Entity> m_sceneEntites;

(2)上传数据

 void upload()
 {
     std::lock_guard<std::mutex> lock(_mutex);
     
     filament::Engine* engine = getFilaEngine();
         
     if (!_matProvider)
     {
         _matProvider = filament::gltfio::createUbershaderProvider(engine, UBERARCHIVE_DEFAULT_DATA, UBERARCHIVE_DEFAULT_SIZE);
     }
     
     if (!_assetLoader)
     {
         _assetLoader = filament::gltfio::AssetLoader::create({getFilaEngine(), _matProvider});
     }
     
     if (_bDirty && _asset && _assetLoader)
     {
         _assetLoader->destroyAsset(_asset);
         _asset = nullptr;
         
         _entites.clear();
         _lightEntites.clear();
         _lightProperties.clear();
     }
     
     if (!_asset)
     {
         if (_modelType == ModelType::GLTF) {
             _asset = _assetLoader->createAssetFromJson(_data, _dataLen); // glb模型数据和长度
         } else {
             _asset = _assetLoader->createAssetFromBinary(_data, _dataLen); // glb模型数据和长度
         }
         
         if (!_asset)
         {
             assert(false);
             Log::Info(mbgl::Event::General, "model parse() LoadModel model == null");
             return;
         }
         
         if (!_textureProvider)
         {
             _textureProvider = filament::gltfio::createStbProvider(backend.getFilaEngine());
         }
         
         if (!_resourceLoader)
         {
             filament::gltfio::ResourceConfiguration configuration = {engine, nullptr, false, false, true};
             _resourceLoader = new filament::gltfio::ResourceLoader(configuration);
             _resourceLoader->addTextureProvider("image/PNG", _textureProvider);
             _resourceLoader->addTextureProvider("image/png", _textureProvider);
             _resourceLoader->addTextureProvider("image/jpeg", _textureProvider);
             _resourceLoader->addTextureProvider("image/JPG", _textureProvider);
             _resourceLoader->addTextureProvider("image/ktx2", _textureProvider);
         }
 ​
         _resourceHasLoaded = false;
         _resourceLoader->asyncBeginLoad(_asset);;
         _animator = _asset->getAnimator();
         
         size_t lightCount = _asset->getLightEntityCount();
         _lightEntites.resize(lightCount);
         memcpy(&_lightEntites[0], _asset->getLightEntities(), sizeof(utils::Entity) * lightCount);
 ​
         auto& lcm = getFilaEngine()->getLightManager();
         for (auto& entity : _lightEntites)
         {
             _lightProperties.emplace_back(lcm.getIntensity(lcm.getInstance(entity)), lcm.getFalloff(lcm.getInstance(entity)));
         }
         
         _bDirty = false;
     }
     
     if (_newCreatedEntites.size() + _entites.size() != _asset->getRenderableEntityCount())
     {
         _resourceLoader->asyncUpdateLoad();
         if (!_resourceLoader->asyncUploadTangents())
         {
             return;
         }
         
         if (!_resourceHasLoaded)
         {
             _asset->releaseSourceData();
             
             if (_data)
             {
                 free(_data);
                 _data = nullptr;
             }
             
             _resourceHasLoaded = true;
         }
         
         while (size_t numWritten = _asset->popRenderables(_renderables, kNumAvailable))
         {
             auto orgCount = _newCreatedEntites.size();
             _newCreatedEntites.resize(orgCount + numWritten);
             memcpy(&_newCreatedEntites[orgCount], _renderables, sizeof(utils::Entity) * numWritten);
         }
     }
     else if (_textureProvider)
     {
         delete _resourceLoader;
         _resourceLoader = nullptr;
         
         delete _textureProvider;
         _textureProvider = nullptr;
     }
     
     bool bHasAnm = _curAnmName.empty();
     if (!bHasAnm && _curAnmIndex == -1)
     {
         const size_t numAnimations = _animator->getAnimationCount();
         for (size_t i = 0; i < numAnimations; i++) {
             if (_curAnmName == _animator->getAnimationName(i))
             {
                 _curAnmIndex = i;
                 _anmStartTime = mbgl::Clock::now();
                 _curAnmDuration = _animator->getAnimationDuration(i);
                 break;
             }
         }
     }
     else if (bHasAnm)
     {
         _curAnmIndex = -1;
     }
     
     if (_curAnmIndex != -1)
     {
         TimePoint nowTime =  mbgl::Clock::now();
         double elapseTime = std::chrono::duration_cast<std::chrono::milliseconds>(nowTime - _anmStartTime).count() / 1000.0;
         if (!_curAnmLoop && elapseTime >= _curAnmDuration)
         {
             elapseTime = _curAnmDuration;
             _curAnmName = "";
         }
         
         _animator->applyAnimation(_curAnmIndex, elapseTime);
     }
     
     _animator->updateBoneMatrices();
 }

4.添加Entity

 void render()
 {
     if (_entites.empty() && _newCreatedEntites.empty() && _lightEntites.empty())
     {
         return;
     }
     
 ​
     if (_bTransformDirty)
     {
         _bTransformDirty = false;
     
         filament::math::mat4 mat =  getModelMatrix(modelMat);
         auto& tcm =getFilaEngine()->getTransformManager();
         tcm.setTransform(tcm.getInstance(_asset->getRoot()), mat);
         
         size_t lightIndex = 0;
         auto& lcm = getFilaEngine()->getLightManager();
         for (auto& entity : _lightEntites)
         {
             auto& prot = _lightProperties[lightIndex++];
 ​
             lcm.setFalloff(lcm.getInstance(entity), prot.y);
             lcm.setIntensityCandela(lcm.getInstance(entity), prot.x);
         }
     }
     
     bool bMatDirty = false;
     auto depthMat = matrixDepthFor3D(bMatDirty);
     
     if (!_newCreatedEntites.empty())
     {
         if (!bMatDirty)
         {
             for (auto& entity : _newCreatedEntites)
             {
                 auto& rcm = parameters.backend.getFilaEngine()->getRenderableManager();
                 auto reInstance = rcm.getInstance(entity);
                 size_t inCount = rcm.getPrimitiveCount(reInstance);
                 for (size_t i = 0; i != inCount; ++i)
                 {
                     auto pMat = rcm.getMaterialInstanceAt(reInstance, i);
                     pMat->setParameter("cstransform", depthMat);
                 }
             }
         }
         
         _entites.insert(_entites.end(), _newCreatedEntites.begin(), _newCreatedEntites.end());
         _newCreatedEntites.clear();
     }
     
     if (bMatDirty)
     {
         for (auto& entity : _entites)
         {
             auto& rcm = parameters.backend.getFilaEngine()->getRenderableManager();
             auto reInstance = rcm.getInstance(entity);
             size_t inCount = rcm.getPrimitiveCount(reInstance);
             for (size_t i = 0; i != inCount; ++i)
             {
                 auto pMat = rcm.getMaterialInstanceAt(reInstance, i);
                 pMat->setParameter("cstransform", depthMat);
             }
         }
     }
     
     m_sceneEntites.insert(m_sceneEntites.end(), _lightEntites.begin(), _lightEntites.end());
     m_sceneEntites.insert(m_sceneEntites.end(), _entites.begin(), _entites.end());
 }
 const filament::math::mat4f& matrixDepthFor3D(bool& bDirty)
 {
     static float s_depthRange = 0.0;
     static filament::math::mat4f depth3dMat;
     
     bDirty = false;
     if (!IsEqual(depthRangeSize, s_depthRange))
     {
         s_depthRange = depthRangeSize;
         depth3dMat = matrixForDepthRange(0.0, s_depthRange);
         bDirty = true;
     }
 ​
     return depth3dMat;
 }
 ​
 filament::math::mat4f matrixForDepthRange(float minVal, float maxVal)
 {
     float b = minVal;
     float a = maxVal - b;
     
     return filament::math::mat4f(
         1, 0, 0, 0,
         0, 1, 0, 0,
         0, 0, a, 0,
         0, 0, b, 1
     );
 }
 ​

5.将view传递给渲染器

     if (m_renderer->beginFrame(getFilaSwapChain()))
     {
         m_renderer->render(getFilaView());
         m_renderer->endFrame();
     }

相关文章

  • 从DLL中动态加载一个函数:LoadLibrary和GetProcAddress的使用从DLL中动态加载一个函数:LoadLibrary和GetProcAddress的使用
  • 判断一个点是否在闭合区域内判断一个点是否在闭合区域内
  • #pragma message 编译时提示信息#pragma message 编译时提示信息
  • OpenGL-法线贴图(Normal Mapping)OpenGL-法线贴图(Normal Mapping)
  • WinDbg检查内存泄漏WinDbg检查内存泄漏
  • Midas W-满堂支架快速建模助手开发Midas W-满堂支架快速建模助手开发

Filament
filament

Post navigation

PREVIOUS
在mapbox中实现3dtiles的加载和绘制(移动端)
NEXT
IBL计算总结

发表回复 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

近期文章

  • IBL计算总结
  • Filament加载并渲染glTF模型
  • 在mapbox中实现3dtiles的加载和绘制(移动端)
  • 视锥体与AABB和OBB包围盒相交判断
  • 倾斜摄影在mapbox中的坐标转换
  • 解析3dTiles数据和提取b3dm模型文件
  • C++实现一个简单的语言解释器
  • OpenGL-法线贴图(Normal Mapping)
  • OpenGL-卡通着色(Cartoon)
  • OpenGL几何着色器实现贝塞尔曲线
  • WinDbg检查内存泄漏
  • OpenGL雾化效果实现-每像素雾化
  • OpenGL实现billboard效果(CPU)
  • 算法:寻找异常数字
  • OpenGL 几何着色器的应用
  • Midas XD-构件详图开发
  • Midas XD-选筋助手开发
  • Civil Designer开发-检测规范自动生成控制截面
  • Civil Designer开发-公路桥梁承载能力检算评定
  • Midas W-满堂支架快速建模助手开发

全站热点

  • C++编写的情人节小程序 (1,503)
  • Modern OpenGL绘制圆柱体 (703)
  • 提取最小封闭区域 (634)
  • 判断一个点是否在闭合区域内 (536)
  • 截面特性计算程序-附源码 (524)
  • OpenGL开发环境搭建-GLFW与GLAD配置 超详细 (487)
  • OpenGL绘制旋转立方体 (435)
  • Midas XD [错误] 右侧挡土墙的最下端深度必须小于地基的最下端深度 (411)
  • WordPress分页插件 – WP-PageNavi的使用(替换现有脚本) (375)
  • 使用ODA数据库出现 “ODA_ASSUME”: 找不到标识符的错误 (350)
  • 解析3dTiles数据和提取b3dm模型文件 (345)
  • 土木想往土木软件开发方向发展,应该如何准备 (330)
  • #pragma message 编译时提示信息 (322)
  • midas XD2020的开发 (317)
  • 从DLL中动态加载一个函数:LoadLibrary和GetProcAddress的使用 (308)
  • 两跨连续梁影响线绘制-附源码 (300)
  • Midas W-满堂支架快速建模助手开发 (290)
  • 算法:寻找异常数字 (249)
  • OpenGL几何着色器实现贝塞尔曲线 (174)
  • 通过Spy++抓取窗口以查询对话框id (173)

分类

  • C# (3)
  • C++ (17)
  • Filament (1)
  • GIS (3)
  • MFC (3)
  • ObjectARX (2)
  • OpenGL (12)
  • Revit开发 (1)
  • 岩土 (2)
  • 算法 (1)
  • 结构设计 (7)
  • 职场生涯 (1)
  • 计算几何 (3)

归档

  • 2022年10月 (3)
  • 2022年7月 (2)
  • 2022年4月 (1)
  • 2022年3月 (1)
  • 2022年2月 (1)
  • 2022年1月 (5)
  • 2021年11月 (7)
  • 2021年6月 (3)
  • 2021年5月 (2)
  • 2021年3月 (2)
  • 2021年2月 (8)
  • 2021年1月 (18)

标签

3dtiles b3dm Bezier Curves BillBoard C++ CDN CivilDesigner DLL EasyX filament fog GIS glTF json mapbox MFC Midas W Midas XD NormalMapping ObjectARX ODA OpenGL OpenXML Open XML PBR revit WinDbg 基坑设计 影响线 截面特性 桥梁 桥梁检测 桥梁设计 算法 计算几何 设计模式

书签

  • 李燕良的CSDN
  • 崔济东的博客
  • C++爱好者博客
  • 陈学伟的博客
  • 贾苏的博客
  • 陈睦锋的博客
  • 孙勇的博客

统计

  • 0
  • 43
  • 8
  • 57
  • 23
  • 69,989
  • 21,750

实时访问地域

© 2023   liyanliang.net Copyright. All Rights Reserved.