2、《OpenSceneGraph三维渲染引擎设计与实践》王锐 钱学雷 清华大学出版社
3、自己的总结
创建C++项目后,首先需要配置OSG环境,具体步骤看OSG学习:WIN10系统下OSG+VS2017编译及运行第六步:新建OSG项目测试。
首先重新来看一下场景的构成:基本的绘图基元――场景:
基本的绘图基元――简单的几何体――复杂的几何体――复杂的场景。
对几何体进行适当地修改,可以提高渲染效率。这些操作都由osgUtil库提供,主要有简化osgUtil::Simplifier、生成法线osgUtil::SmoothingVisitor(OSG学习:几何对象的绘制(二)――简易房屋:创建人字顶部分)、生成Delaunay三角网osgUtil::DelaunayTriangulator、条带化osgUtil::TriStripVisitor等。
本篇文章解析生成Delaunay三角网的方法:
不规则三角网TIN是数字地形建模中表达地形表面的重要手段,它通过不规则离散分布的数据点生成的连续三角面来逼近地形表面,它能以不同层次的分辨率来描述地形表面,地形平坦的地方点稀疏三角网较大且稀疏,地形陡峭的地方三角网小且密集。
狄洛尼Delaunay三角网是所有可能的三角网中在地形拟合方面最出色的方法。生成Delaunay三角网的传统算法主要为Lawson算法和Bowyer-Watson算法。
步骤:
1)创建顶点数组;
2)创建osgUtil::DelaunayTriangulator类对象并初始化顶点数组,同时生成三角网;
3)创建一个几何体对象,把osgUtil::DelaunayTriangulator类对象生成的绘制图元加入到几何体中,在生成三角网时还可以添加限制条件:点、线、多边形。
根据代码来了解使用方法:
// stdafx.h #include <osg/Node> //节点类 #include <osg/Geode> //是个几何节点,可以说是一个几何Group节点,一般的可绘制几何体都是通过它来传向root进行渲染,是OSG几何绘制的最高管理节点 #include <osg/Group> //对节点起到组织作用,一般作为父节点或者根节点出现 #include <osg/Geometry> //基本绘制几何体类,用户绘制基本的几何体 #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osgViewer/Viewer> #include <osgViewer/ViewerEventHandlers> //事件监听 #include <osgGA/StateSetManipulator> //事件响应类,对渲染状态进行控制 #include <osgUtil/Optimizer> //优化器 #include <osgUtil/DelaunayTriangulator> //Delaunay三角网
//.cpp /* 创建顶点数组并添加数据 设置其他相关属性(可选) 创建osgUtil::DelaunayTriangulator类对象并生成三角网 创建几何体对象,把三角网类对象生成的绘制图元添加到几何体中 按w键显示网格化模型,可以看出网格密度不同 由于光照条件默认开启,旋转模型可以看出不同部位亮度显示不同 按l键显示关闭光照,旋转模型,可以看出亮度不变 */ osg::Drawable *createTriangulate() { //创建顶点数组 osg::ref_ptr<osg::Vec3Array> coords = new osg::Vec3Array(); //不同于前面例子中添加数组数据的方法,先获取顶点的值并设置为数组,然后将数组值添加到顶点数组 //设置顶点的值 float vertex[][3] = { -5.0f,-5.0f, 0.4f, 1.0f, -5.6f, 0.0f, 5.0f, -4.0f, -0.5f, -6.2f, 0.0f, 4.2f, -1.0f,-0.5f, 4.8f, 4.3f, 1.0f, 3.0f, -4.8f, 5.4f, 0.3f, 0.6f, 5.1f,-0.8f, 5.2f, 4.5f, 0.1f }; //计算顶点数组的大小 unsigned int n = sizeof(vertex) / sizeof(float[3]); //添加顶点数据 for (unsigned int i = 0; i < n; i++) { coords->push_back(osg::Vec3(vertex[i][0], vertex[i][1], vertex[i][2])); } //创建颜色数组 osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array(); //添加颜色数据 color->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); color->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); color->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); color->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); color->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); color->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); color->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); color->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); color->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); //创建Delaunay三角网对象 osg::ref_ptr<osgUtil::DelaunayTriangulator> dt = new osgUtil::DelaunayTriangulator(coords.get()); //生成三角网 dt->triangulate(); //创建几何体 osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry(); //设置顶点数组 geometry->setVertexArray(coords.get()); //设置颜色数组 geometry->setColorArray(color.get()); //设置颜色的绑定方式为单个顶点 geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); //添加到绘图基元 geometry->addPrimitiveSet(dt->getTriangles()); return geometry.release(); } int main() { //添加到叶节点 osg::ref_ptr<osg::Geode> geode = new osg::Geode(); geode->addDrawable(createTriangulate()); //添加到根节点 osg::ref_ptr<osg::Group> root = new osg::Group(); root->addChild(geode.get()); //优化场景数据 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(); }
查看效果:
按w键显示网格模型,可以看出格网密度不同,由于点很少,因此当按两次w键后显示的点看不出来;
由于光照条件默认开启,旋转模型可以看出不同部位亮度显示不同,按l键显示关闭光照,旋转模型,可以看出亮度不变,仔细观察显示点时的情况,可以看到一两个点。