2、《OpenSceneGraph三维渲染引擎设计与实践》王锐 钱学雷 清华大学出版社
3、自己的总结
创建C++项目后,首先需要配置OSG环境,具体步骤看OSG学习:WIN10系统下OSG+VS2017编译及运行第六步:新建OSG项目测试。
首先重新来看一下场景的构成:基本的绘图基元――场景:
基本的绘图基元――简单的几何体――复杂的几何体――复杂的场景。
对几何体进行适当地修改,可以提高渲染效率。这些操作都由osgUtil库提供,主要有简化osgUtil::Simplifier、生成法线osgUtil::SmoothingVisitor、生成Delaunay三角网osgUtil::DelaunayTriangulator、条带化osgUtil::TriStripVisitor等。
本篇文章解析简化几何体的方法:
osgUtil::Simplifier类继承自osg::NodeVisitor类,以访问器的方式遍历几何体并对其进行简化处理。
这个简化方法使用边塌陷算法,该算法我没有详细了解,可以看一看这篇文章:实现边塌陷的网格简化方法。
根据代码来了解使用方法:
// stdafx.h #include <osg/Node> //节点类 #include <osg/Geode> //是个几何节点,可以说是一个几何Group节点,一般的可绘制几何体都是通过它来传向root进行渲染,是OSG几何绘制的最高管理节点 #include <osg/Group> //对节点起到组织作用,一般作为父节点或者根节点出现 #include <osg/PositionAttitudeTransform> //位置变换节点类,提供模型的位置变换、大小缩放、原点位置的设置、坐标系的变换 #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osgViewer/Viewer> #include <osgViewer/ViewerEventHandlers> //事件监听 #include <osgGA/StateSetManipulator> //事件响应类,对渲染状态进行控制 #include <osgUtil/Optimizer> //优化器 #include <osgUtil/Simplifier> //简化几何体
//.cpp /* 加载一个模型 深拷贝该模型到其他地方 对深拷贝的模型进行简化 将两个模型添加到叶节点 对场景进行优化 显示模型 按w键显示网格化模型,可以看出网格密度不同 按t键显示去表皮模型,可以看出模型相同 */ //读取模型 osg::Node *readModel() { osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg"); return node.release(); } //深拷贝并简化新模型 osg::Node *deepCopy(osg::Node *node) { /* 创建简化对象 simplifier(sampleRatio, maxError) 参数:样本比率、点的误差或边的长度 样本比率<1 设置点的误差 样本比率>1 设置边的长度限制 比率越大,简化越少 使用的是边塌陷算法 */ float sampleRatio = 0.3f; float maxError = 4.0f; osgUtil::Simplifier simplifier(sampleRatio, maxError); //深拷贝 osg::ref_ptr<osg::Node> deepnode = (osg::Node *)(node->clone(osg::CopyOp::DEEP_COPY_ALL)); //创建一个位置变换节点,将之设置为新位置,将深拷贝的模型移到新位置 osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform(); pat->setPosition(osg::Vec3(10.0f, 0.0f, 0.0f)); pat->addChild(deepnode); pat->accept(simplifier); return pat.release(); } int main() { //创建一个叶节点对象并添加节点 osg::ref_ptr<osg::Group> root = new osg::Group; osg::ref_ptr<osg::Node> node1 = readModel(); osg::ref_ptr<osg::Node> node2 = deepCopy(node1); root->addChild(node1); root->addChild(node2); //优化场景数据 osgUtil::Optimizer optimizer; optimizer.optimize(root.get()); //显示模型 osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer(); //切换网格模式,方便比较 viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet())); viewer->setSceneData(root.get()); viewer->realize(); return viewer->run(); }
结果: