以下内容来自:
1、《OpenSceneGraph三维渲染引擎编程指南》肖鹏 刘更代 徐明亮 清华大学出版社
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键显示关闭光照,旋转模型,可以看出亮度不变,仔细观察显示点时的情况,可以看到一两个点。