前言

  对于一些较大的图形,会出现显示卡顿和渲染缓慢的问题,这时候就要使用到osgUtil::Simplifier简化器,来对其进行简化。

 

Demo

  

  

  

 

osgUtil

  osgUtil库是osg的四大核心库之一,OSG 核心库提供了用于场景图形操作的核心场景图形功能、类和方法;开发3D图形程序所需的某些特定功能函数和编程接口,以及2D和3D文件I/O的OSG 插件入口。
  
  osgUtil(OSG Utilities)模块提供了场景更新、裁剪、绘制、数据统计等公用工具。

 

osgUtil::Simplifier:简化几何体类

  

  OsgUtil::Simplifier 是 OpenSceneGraph (OSG) 库中的一个工具类,用于简化几何图形。OpenSceneGraph 是一个高性能的场景图渲染引擎,用于图形应用程序的开发,比如可视化、模拟、虚拟现实和游戏等。OsgUtil::Simplifier 类提供了一种方法来减少场景中的多边形数量,这在需要优化渲染性能或减小场景文件大小时非常有用。

功能概述

  OsgUtil::Simplifier 的主要功能是简化几何体,比如网格(mesh)。它通过移除一些不太重要的顶点或边来实现这一点,从而减少多边形的数量。简化的程度可以通过参数设置来控制,以达到在保持视觉质量的同时减少渲染负载的目的。

使用场景

  • 性能优化:在需要渲染大量几何体时,通过简化几何体可以减少GPU的负担,提高渲染速度。
  • 文件大小优化:简化后的几何体可以生成较小的场景文件,这对于网络传输或资源存储都是有益的。
  • 实时应用:在实时渲染应用中,如虚拟现实或增强现实,简化可以帮助保持帧率稳定,提供流畅的用户体验。

基本用法

  使用 OsgUtil::Simplifier 通常涉及以下几个步骤:

  • 创建简化器实例:创建一个 OsgUtil::Simplifier 的实例。
  • 设置简化参数:通过配置简化器的参数(如目标多边形数量、误差容限等)来控制简化的程度。
  • 应用简化:将需要简化的几何体(如 osg::Geometry 或 osg::Node)传递给简化器进行处理。
  • 获取结果:简化器处理后会返回简化后的几何体,可以将其用于渲染。
      注意事项
  • 视觉质量:虽然简化可以提高性能,但过度简化可能会导致视觉质量的显著下降。因此,需要仔细调整简化参数以找到性能和质量的平衡点。
  • 数据完整性:简化过程中可能会修改原始数据,因此在使用前最好保留原始数据的备份。
  • 资源消耗:简化操作可能需要一定的计算资源,特别是在处理复杂的几何体时。因此,在实时应用中需要谨慎使用,以避免引入额外的延迟。
      OsgUtil::Simplifier 是 OpenSceneGraph 提供的一个强大工具,可以帮助开发者在不影响视觉体验的前提下,优化渲染性能和资源使用。
 

osgUtil::Simplifier使用步骤

步骤一:引入头文件

   

#include <osgUtil/Simplifier>

步骤二:创建实例,同步设置简化参数

  

// 步骤二:创建实例
double sampleRatio = 0.5f;
double maximumError = 4.0f;
double maximumLength = 0.0f;
osgUtil::Simplifier simplifier = osgUtil::Simplifier(sampleRatio, maximumError, maximumLength);

步骤三:应用简化到几何体

  

// 步骤三:设置简化参数
osg::ref_ptr<osg::Node> pNode2 = (osg::Node*)pNode->clone(osg::CopyOp::DEEP_COPY_ALL);
// 接收报错:terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc
// 模型太大,简化类型时出现内存分配错误
pNode2->accept(simplifier);

步骤四:使用简化后的几何体

  

// 移动下,方便对比
osg::ref_ptr<osg::MatrixTransform> pMatrixTransform = new osg::MatrixTransform();
pMatrixTransform->addChild(pNode2);
osg::Matrix matrix = pMatrixTransform->getMatrix();
matrix = matrix * osg::Matrix::translate(0, 3.5, 0);
pMatrixTransform->setMatrix(matrix);
pGroup->addChild(pMatrixTransform);
 

Demo源码

osg::ref_ptr<osg::Node> OsgWidget::getSimplifierNode()
{
// 其他demo的控件
updateControlVisible(false); osg::ref_ptr<osg::Group> pGroup = new osg::Group(); // 加载支持stl格式插件
// osgDB::Registry::instance()->addFileExtensionAlias(".stl", "stl"); // 加载模型
{
osg::ref_ptr<osg::Node> pNode;
QString filePath = "T:/CVN76.STL"; // QString filePath = "cow.osg";
pNode = osgDB::readNodeFile(filePath.toStdString());
if(!pNode.get())
{
LOG << "Failed to openFile:" << filePath;
} pGroup->addChild(pNode); #if 1
// 对模型进行简化
// 步骤一:添加头文件
// #include <osgUtil/Simplifier>
// 步骤二:创建实例
// double sampleRatio = 0.5f;
// double sampleRatio = 0.3f;
double sampleRatio = 0.1f;
double maximumError = 4.0f;
double maximumLength = 0.0f;
osgUtil::Simplifier simplifier = osgUtil::Simplifier(sampleRatio, maximumError, maximumLength);
// 步骤三:设置简化参数
osg::ref_ptr<osg::Node> pNode2 = (osg::Node*)pNode->clone(osg::CopyOp::DEEP_COPY_ALL);
// 接收报错:terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc
// 模型太大,简化类型时出现内存分配错误
pNode2->accept(simplifier); // 移动下,方便对比
osg::ref_ptr<osg::MatrixTransform> pMatrixTransform = new osg::MatrixTransform();
pMatrixTransform->addChild(pNode2);
osg::Matrix matrix = pMatrixTransform->getMatrix();
matrix = matrix * osg::Matrix::translate(0, 3.5, 0);
pMatrixTransform->setMatrix(matrix); pGroup->addChild(pMatrixTransform);
#endif
} return pGroup.get();
}
 

工程模板v1.37.0

  

 

入坑

入坑一:应用简化器的时候崩溃

问题

  应用简化器的时候崩溃
  

原因

  是模型太大,简化失败, 因为测试了其他图形是可以的:
  

  崩溃时的cpu、内存和gpu占用率:
  

  看到其保存的文件达到300MB:
  

解决

  可尝试加大内存,因为笔者是mingw32版本的,没有进行研究了,具体参照文章《关于 Qt运行加载内存较大崩溃添加扩大运行内存 的解决方法》

OSG开发笔记(三十四): OsgUtil::Simplifier:简化几何体,提升显示性能和渲染效率的更多相关文章

  1. 树莓派开发笔记(十四):入手研华ADVANTECH工控树莓派UNO-220套件(三):使用研发自带系统测试rtc、gpio、232和485套件接口

    前言   上一篇说明了必须要使用研华自带的8G卡的系统,通过沟通拿到了相关的系统,购买的时候会带8GB的卡,请自行备份一份镜像.本篇对uno-220套件的相关研华配套的额外接口做测试,篇幅较长,重点讲 ...

  2. Java开发笔记(十四)几种运算符的优先级顺序

    到目前为止,我们已经学习了Java语言的好几种运算符,包括算术运算符.赋值运算符.逻辑运算符.关系运算符等基础运算符,并且在书写赋值语句时都没添加圆括号,显然是默认了先完成算术.逻辑.关系等运算,最后 ...

  3. Android笔记三十四.Service综合实例二

    综合实例2:client訪问远程Service服务 实现:通过一个button来获取远程Service的状态,并显示在两个文本框中. 思路:如果A应用须要与B应用进行通信,调用B应用中的getName ...

  4. .Net开发笔记(十四) 基于“泵”的UDP通信(接上篇)

    上一篇中说到了“泵”在编程中的作用以及一些具体用处,但没有实际demo,可能不好理解,这篇文章我分享一个UDP通信的demo,大概实现了类似“飞鸽传书”在局域网中文本消息和文件传输的功能.功能不全也不 ...

  5. BizTalk开发系列(三十四) Xpath

    XPath 是在 XML 文档中查找信息的语言,在BizTalk的开发中应用非常广泛,当然你可以不必先学Xpath再去学BizTalk.但是如果对Xpath有一定了解的 话,在很多应用下会使你的开发更 ...

  6. Android UI开发第三十四篇——SlidingPaneLayout

    SlidingPaneLayout也是系统支持的高级控件,是Android团对在2013 google IO大会期间更新的Support库(Version 13)中新加入的重要的功能.它支持左右滑动菜 ...

  7. 网站开发进阶(三十四)编码中的setCharacterEncoding 理解

    编码中的setCharacterEncoding 理解 1.pageEncoding="UTF-8"的作用是设置JSP编译成Servlet时使用的编码. 2.contentType ...

  8. tensorflow学习笔记(三十四):Saver(保存与加载模型)

    Savertensorflow 中的 Saver 对象是用于 参数保存和恢复的.如何使用呢? 这里介绍了一些基本的用法. 官网中给出了这么一个例子: v1 = tf.Variable(..., nam ...

  9. Java开发学习(三十四)----Maven私服(二)本地仓库访问私服配置与私服资源上传下载

    一.本地仓库访问私服配置 我们通过IDEA将开发的模块上传到私服,中间是要经过本地Maven的 本地Maven需要知道私服的访问地址以及私服访问的用户名和密码 私服中的仓库很多,Maven最终要把资源 ...

  10. PHP学习笔记三十四【记录日志】

    <?php function my_error2($errno,$errmes) { echo "错误号:".$errno; //默认时区是格林威治相差八个时区 //设置 1 ...

随机推荐

  1. LLM论文研读: MindSearch

    1. 背景 近日中科大与上海人工智能实验室联合推出的MindSearch思索,引起了不小的关注,github上的星标,短短几周时间,已经飙到了4.2K.看来确实有些内容,因此本qiang~研读了论文及 ...

  2. 【工具分享】红队重点资产指纹识别 -- P1finger -0.02(最新版本)

    工具介绍: P1finger 红队行动下的重点资产指纹识别工具.P1finger 是一个重点资产指纹识别的工具,旨在通过HTTP请求特征来识别目标系统.其主要特点包括: 语言和实现: 语言:使用Go语 ...

  3. LCD屏幕显示PNG图像

    正点原子LCD屏幕显示PNG图像 本文概要 这段时间在学习正点原子的IMX6ULL开发板,在应用编程中有一个代码练习是需要在LCD屏幕上显示PNG图像,但由于我的屏幕参数和教程中的有些出入,于是经过自 ...

  4. keras各种问题

    还是不熟悉造成的,keras的各种包使用起来真是有点小麻烦.导入方式不同就容易引起错误,也不提示你导入的库不存在,但是就是调用的时候报错. 比如近期写文章想画模型图,plot_model模块导入出问题 ...

  5. vue中如何使用JSX?

    JSX是什么? JSX 是一种 Javascript 的语法扩展,JSX = Javascript + XML,即在 Javascript 里面写 XML,因为 JSX 的这个特性,所以他即具备了 J ...

  6. QT硬件异构计算

    QT硬件异构计算 使用AI技术辅助生成 1 QT硬件异构计算概述 1.1 硬件异构计算概念 1.1.1 硬件异构计算概念 硬件异构计算概念 <QT硬件异构计算>正文 硬件异构计算概念 在进 ...

  7. Kubernetes集群证书过期解决办法

    问题现象 K8S集群证书过期后,会导无法创建Pod,通过kubectl get nodes也无法获取信息,甚至dashboard也无法访问. 一.确认K8S证书过期时间 查看k8s某一证书过期时间: ...

  8. 《Vue.js 设计与实现》读书笔记 - 第12章、组件的实现原理

    第12章.组件的实现原理 12.1 渲染组件 在渲染器内部的实现看,一个组件是一个特殊类型的虚拟 DOM 节点.之前在 patch 我们判断了 VNode 的 type 值来处理,现在来处理类型为对象 ...

  9. 如何解决使用 router.push 跳转路由第二次之后页面就不会刷新了

    router.push({ name:"monitor", query:{ deviceid:"1676156672197922816", // 设备 ID i ...

  10. 工作使用:Exchange命令集(超级重要)

    工作使用:Exchange命令集(超级重要) 命令1:导出某个用户的邮件                  New-MailboxExportRequest   -mailbox  dusonglin ...