合肥免费做网站,网站宝 西部数码网站管理助手,授权网站系统,企业网站改版的好处1、场景基本绘图类 在 OSG 中创建几何体的方法比较简单#xff0c;通常有 3 种处理几何体的手段#xff1a;
使用松散封装的OpenGL 绘图基元#xff1b;使用 OSG 中的基本几何体#xff1b;从文件中导入场景模型。 使用松散封装的OpenGL 绘图基元绘制几何体具有很强的灵活…1、场景基本绘图类 在 OSG 中创建几何体的方法比较简单通常有 3 种处理几何体的手段
使用松散封装的OpenGL 绘图基元使用 OSG 中的基本几何体从文件中导入场景模型。 使用松散封装的OpenGL 绘图基元绘制几何体具有很强的灵活性但工作量通常非常大当面对大型场景时绘制几何体将是一项非常艰巨而富有挑战的工作因此通常还是采用读入外部模型的方法。
1.1 向量与数组类 在 OSG 中定义了大量的类来保存数据数据通常是以向量的形式来表示的向量数据主要包括顶点坐标、纹理坐标、颜色和法线等。例如定义 osg::Vec2 来保存纹理坐标定义 osg::Vec3 来保存顶点坐标和法线坐标定义 osg::Vec4 保存颜色的 RGBA 值。osg::Vec2、osg::Vec3 和 osg::Vec4 是分别用来保存向量的二维数组、三维数组和四维数组这些类不仅能够保存各种数据还提供了向量的基本运算机制如加、减、乘、除四则元算、点积和单位化等相关的操作。 在 OSG 中还定义了模板数组用来保存对象例如可以用顶点索引对象osg::DrawElementsUInt来保存顶点索引用颜色索引osg::TemplateIndexeArray来保存颜色。但最常用的还是保存向量数据如 osg::Vec3Array 来保存众多顶点坐标、osg::Vec2Array 保存纹理坐标等这些模板数组都继承自 std::Vector因此它们具有向量的基本操作方法例如可以利用 push_back()添加一个元素可以利用pop_back()删除一个元素同样也可以使用 clear()删除所有的元素。
1.2 Drawable 类 Drawable 类是一个纯基类无法实例化。作为可绘制对象基类的 osg::Drawable 类它派生了很多类它的继承关系图如图 4-1 所示。 从图 4-1 可以看出由 osg::Drawable 派生的类有 9 个分别是 osg::DrawPixels、osg::Geometry、osg::ShapeDrawable、osgParticle::ParticleSystem、osgParticle::PrecipitationEffect::PrecipitationDrawable、osgShadow::OccluderGeometry、osgShadow::ShadowVolumeGeometry、osgSim::ImpostorSprite 和 osgText::TextBase其中从 OSG 核心库派生出了 3 个类分别是 osg::DrawPiexels 类主要封装了 OpenGL中 glDrawPixels()的功能、osg::Geometry 类绘制几何体的类应用比较灵活和 osg::ShapeDrawable类主要封装了一些已经定义好的几何体不需要设置坐标即可直接调用如长方体、正方体、球体 等。其他的类中有两个派生自粒子系统库有两个派生自阴影库还有两个分别派生自 osgSim 库和 osgText 文字库。
1.3 PrimitiveSet 类 osg::PrimitiveSet 类继承自 osg::Object 虚基类但它不具备一般场景中的特性。osg::PrimitiveSet 类的继承关系图如图 4-2 所示。 该类主要松散封装了 OpenGL 的绘图基元通过指定绘图基元来指定几何体顶点将采用哪一种或几种基元绘制。常用的绘图基元包括如下几种
POINTS GL_POINTS //绘制点
LINES GL_LINES //绘制线
LINE_STRIP GL_LINE_STRIP //绘制多段线
LINE_LOOP GL_LINE_LOOP //绘制封闭线
TRIANGLES GL_TRIANGLES //绘制一系列的三角形不共用顶点
TRIANGLE_STRIP GL_TRIANGLE_STRIP //绘制一系列三角形共用后面的两个顶点
TRIANGLE_FAN GL_TRIANGLE_FAN //绘制一系列三角形顶点顺序与上一条语句绘制的三角形不同
QUADS GL_QUADS //绘制四边形
QUAD_STRIP GL_QUAD_STRIP //绘制一系列四边形
POLYGON GL_POLYGON //绘制多边形从 osg::PrimitiveSet 类的继承关系图可以看出它的派生类主要有如下 3 个
osg::DrawArrays 类。继承自 osg::PrimitiveSet它封装了glDrawArrays()顶点数组绘图命令用于指定顶点和绘图基元。osg::DrawElements 类。它又派生出 3 个子类分别是 osg::DrawElementsUByte、osg::DrawElementsUShort和osg::DrawElementsUInt封装了 glDrawElements()的指令可以起索引的作用在后面的示例中会用到。osg::DrawArrayLengths 类。它的主要作用是多次绘制即多次调用glDrawArrays()且每次均使用不同的长度和索引范围在绘制过程中用得不是很多。
DrawArrays 的基本用法如下
osg::DrawArrays::DrawArrays( GLenum mode, GLint first,GLsizei count );
/*参数说明第一个参数是指定的绘图基元即前面所列举的常见绘图基元第二个参数是指绘制几何体的第一个
顶点数在指定顶点的位置数第三个参数是使用的顶点的总数*/还有一点值得注意的是虽然 osg::PrimitiveSet 类提供与 OpenGL 一样的顶点机制但是在内部渲染上还是有一定区别的。根据渲染环境的不同渲染的方式也是不一样的可能会采用顶点、顶点数组、显示列表或者 glBegin()/glEnd()来渲染几何体继承自 Drawable 类的对象如 Geometry在默认条件下将使用显示列表。其中osg::Drawable::setUseDisplayList(false)用于手动禁止使用显示列表。还有一种比较特殊的情况如果设置BIND_PER_PRIMITIVE 绑定方式那么OSG将采用glBegin()/glEnd()函数进行渲染。因为在设置使用绑定方式为 BIND_PER_PRIMITIVE 后它就为每个独立的几何图元设置一种绑定属性。
2、基本几何体的绘制 OSG 创建的场景和对象是由简单的图元我们把构成 3D 对象的构件称为图元按照一定的方式排列和组合而成的OSG 中的所有图元都是一维或二维对象包括单个的点、直线和复杂的多边形。
2.1 几何体类 osg::Geometry 它的主要作用是对指定绘制几何体的顶点数及对数据的解析主要提供了如下 3大类方法
1指定向量数据。就是以前所涉及的顶点数据、纹理坐标及颜色等一系列向量数据可以通过下面的几个函数来实现
void setVertexArray(Array*array) //设置顶点数组
void setVertexData(const ArrayDataarrayData) //设置顶点数组数据
void setVertexIndices(IndexArray*array) //设置顶点索引数组
void setNormalArray(Array*array) //设置法线数组
void setNormalData(const ArrayDataarrayData) //设置法线数组数据
void setNormalIndices(IndexArray*array) //设置法线索引数组
void setColorArray(Array*array) //设置颜色数组
void setColorData(const ArrayDataarrayData) //设置颜色数组数据
void setColorIndices(IndexArray*array) //设置颜色索引数组
void setTexCoordArray(unsigned int unit,Array*)
//设置纹理坐标数组第一个参数是纹理单元第二个是纹理坐标数组
void setTexCoordData(unsigned int index, const ArrayData arrayData)
//设置纹理坐标数组数据第一个参数是纹理单元第二个是纹理坐标数组数据
void setTexCoordIndices(unsigned int unit, IndexArray *)
//设置纹理坐标索引数组第一个参数是纹理单元第二个是纹理索引坐标数组2设置绑定方式。数据绑定主要有两项即法线及颜色可以通过下面的两个函数来实现
void setNormalBinding(AttributeBinding ab) //设置法线绑定方式
void setColorBinding(AttributeBinding ab) //设置颜色绑定方式绑定方式主要有下面几种
BIND_OFF //不启用绑定
BIND_OVERALL //绑定全部的顶点
BIND_PER_PRIMITIVE_SET //单个绘图基元绑定
BIND_PER_PRIMITIVE //单个独立的绘图基元绑定
BIND_PER_VERTEX //单个顶点绑定3数据解析。当在指定了各种向量数据和绑定方式之后采用何种方式来渲染几何体就是最为关键的。不同的方式下渲染出来的图形是不一样的即使效果一样可能面数或内部机制等也是有区别的。数据解析主要通过如下函数来指定
bool addPrimitiveSet(PrimitiveSet*primitiveset)
/*参数说明osg::PrimitiveSet 是无法初始化的虚基类因此这里主要是调用它的子类来指定数据渲染最常用的就是
前面介绍的 osg::DrawArrays用法比较简单初始化一个对象实例参数说明见前面 osg::DrawArrays 类*/通过前面的讲述可知绘制并渲染几何体主要有如下 3 大步骤 1创建各种向量数据如顶点、纹理坐标、颜色和法线等。需要注意的是添加顶点数据时主要按照逆时针顺序添加以确保背面剔除backface culling的正确后面还会有介绍。 2实例化一个几何体对象osg::Geometry设置顶点坐标数组、纹理坐标数组、颜色数组、法线数组、绑定方式及数据解析。 3加入叶节点绘制并渲染。
2.2 示例 2.3 示例源码
#include osgViewer/Viewer#include osg/Node
#include osg/Geode
#include osg/Group#include osgDB/ReadFile
#include osgDB/WriteFile#include osgUtil/Optimizer#include osgViewer/ViewerEventHandlers //事件监听
#include osgGA/StateSetManipulator //事件响应类对渲染状态进行控制#pragma comment(lib, OpenThreadsd.lib)
#pragma comment(lib, osgd.lib)
#pragma comment(lib, osgDBd.lib)
#pragma comment(lib, osgUtild.lib)
#pragma comment(lib, osgGAd.lib)
#pragma comment(lib, osgViewerd.lib)
#pragma comment(lib, osgTextd.lib)//创建一个四边形节点
osg::ref_ptrosg::Node createQuad()
{//创建一个叶节点对象osg::ref_ptrosg::Geode geode new osg::Geode();//创建一个几何体对象osg::ref_ptrosg::Geometry geom new osg::Geometry();//创建顶点数组osg::ref_ptrosg::Vec3Array aryVertex new osg::Vec3Array();//添加数据aryVertex-push_back(osg::Vec3(0.0f, 0.0f, 0.0f));aryVertex-push_back(osg::Vec3(1.0f, 0.0f, 0.0f));aryVertex-push_back(osg::Vec3(1.0f, 0.0f, 1.0f));aryVertex-push_back(osg::Vec3(0.0f, 0.0f, 1.0f));aryVertex-push_back(osg::Vec3(0.0f, -1.0f, 0.0f));//设置顶点数据geom-setVertexArray(aryVertex.get());//创建四边形顶点索引数组指定绘图基元为四边形注意添加顺序osg::ref_ptrosg::DrawElementsUInt quad new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);//添加数据quad-push_back(0);quad-push_back(1);quad-push_back(2);quad-push_back(3);//添加到几何体geom-addPrimitiveSet(quad.get());//创建三角形顶点索引数组指定绘图基元为三角形注意添加顺序osg::ref_ptrosg::DrawElementsUInt triangle new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);//添加数据triangle-push_back(4);triangle-push_back(0);triangle-push_back(3);//添加到几何体geom-addPrimitiveSet(triangle.get());//创建颜色数组osg::ref_ptrosg::Vec4Array vecColor new osg::Vec4Array();//添加数据vecColor-push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));vecColor-push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));vecColor-push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));vecColor-push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));vecColor-push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));//设置颜色数组geom-setColorArray(vecColor.get());//创建颜色索引数组//osg::TemplateIndexArrayunsigned int ,osg::Array::UIntArrayType,4,4* colorIndex new osg::TemplateIndexArrayunsigned int ,osg::Array::UIntArrayType,4,4();//添加数据注意添加数据顺序与顶点一一对应//colorIndex-push_back(0);//colorIndex-push_back(1);//colorIndex-push_back(2);//colorIndex-push_back(3);//colorIndex-push_back(2);//设置颜色索引数组//geom-setColorIndices(colorIndex);//设置颜色的绑定方式为单个顶点geom-setColorBinding(osg::Geometry::BIND_PER_VERTEX);//创建法线数组osg::ref_ptrosg::Vec3Array vecNormal new osg::Vec3Array();//添加法线vecNormal-push_back(osg::Vec3(0.0f, -1.0f, 0.0f));//设置法线数组geom-setNormalArray(vecNormal.get());//设置法线的绑定方式为全部顶点geom-setNormalBinding(osg::Geometry::BIND_OVERALL);//添加到叶节点geode-addDrawable(geom.get());return geode.get();
}int main()
{//创建Viewer对象场景浏览器osg::ref_ptrosgViewer::Viewer viewer new osgViewer::Viewer();osg::ref_ptrosg::Group root new osg::Group();//添加到场景root-addChild(createQuad());//优化场景数据osgUtil::Optimizer optimizer;optimizer.optimize(root.get());viewer-setSceneData(root.get());//切换网格模式方便比较viewer-addEventHandler(new osgGA::StateSetManipulator(viewer-getCamera()-getOrCreateStateSet()));viewer-addEventHandler(new osgViewer::StatsHandler());//实现状态信息统计viewer-addEventHandler(new osgViewer::WindowSizeHandler());viewer-setUpViewInWindow(400,400,1000,800);viewer-run();return 0;
}3、OSG预定义几何体
3.1 osg::Shape 类 osg::Shape 类直接继承自 osg::Object 基类继承关系图如图 4-6 所示。 osg::Shape 类是各种内嵌几何体的基类它不但可用于剔除和碰撞检测还可用于生成预定义的几何体对象。常用的内嵌几何体包括如下几种
osg::Box //正方体
osg::Capsule //太空舱
osg::Cone //椎体
osg::Cylinder //柱体
osg::HeightField //高度图
osg::InfinitePlane //无限平面
osg::Sphere //球体
osg::TriangleMesh //三角片3.2 osg::ShapeDrawable 类 在 OSG 中内嵌预定义的几何体如果渲染这些内嵌的几何体就必须将其与 osg::Drawable 关联。实际应用中可以使用 osg::Drawable 类的派生类 osg::ShapeDrawable来完成这个功能。osg::ShapeDrawable 类在前面已经讲到它派生自osg::Drawable 类。由于它继承自 osg::Drawable 类所以它的实例需要被添加到叶节点中才能被实例绘制。 在 osg::ShapeDrawable 类的构造函数中提供了关联 osg::Shape 的方法
ShapeDrawable(Shape*shape, TessellationHints *hints0)
//第一个参数为 shape第二个参数默认下不细化3.3 网格化类 网格化类osg::TessellationHints直接继承自 osg::Object 基类。osg::TessellationHints 类的主要作用是设置预定义几何体对象的精细程度精细程度越高表示其细分越详细但对于不同的预定义几何体对象它的作用是不一样的例如 Box四棱柱网格化类对于四棱柱没有意义。Capsule太空舱太空舱分 3 个部分上下半球部分和圆柱侧面部分默认圆柱侧面被细分。Cone圆锥直接细分。Cylinder柱体直接细分。Sphere球直接细分。目前osg::TessellationHints 类并不完整部分类成员函数还没有实现具体可以参看源码。在内嵌几何体对象中默认的情况下网格化类的精细度为 0表示预定义的几何体此时按照原顶点默认绘制不做任何细化处理。
3.4 示例 3.5 示例源码
#include windows.h#include osgViewer/Viewer
#include osg/Node
#include osg/Geode
#include osg/Geometry
#include osg/Group
#include osg/Switch
#include osg/Billboard
#include osg/Texture2D
#include osg/Image
#include osg/Vec3
#include osg/Vec2
#include osg/PositionAttitudeTransform
#include osg/MatrixTransform
#include osgDB/ReadFile
#include osgDB/WriteFile
#include osgUtil/Optimizer
#include osg/PagedLOD
#include osgSim/Impostor
#include osgViewer/ViewerEventHandlers //事件监听
#include osgGA/StateSetManipulator //事件响应类对渲染状态进行控制
#include osgUtil/Simplifier //简化几何体
#include osg/OccluderNode
#include osg/StateSet
#include osg/ConvexPlanarOccluder
#include osg/BoundingBox
#include osg/BoundingSphere
#include osgUtil/Optimizer
#include iostream
#include osg/ShapeDrawable#pragma comment(lib, OpenThreadsd.lib)
#pragma comment(lib, osgd.lib)
#pragma comment(lib, osgDBd.lib)
#pragma comment(lib, osgUtild.lib)
#pragma comment(lib, osgGAd.lib)
#pragma comment(lib, osgViewerd.lib)
#pragma comment(lib, osgTextd.lib)
#pragma comment(lib, osgSimd.lib)
#pragma comment(lib, osgFXd.lib)//绘制多个预定义的几何体
osg::ref_ptrosg::Geode createShape()
{//创建一个叶节点osg::ref_ptrosg::Geode geode new osg::Geode();//设置半径和高度float radius 0.8f;float height 1.0f;//创建精细度对象精细度越高细分就越多osg::ref_ptrosg::TessellationHints hints new osg::TessellationHints;//设置精细度为 0.5fhints-setDetailRatio(0.5f);//添加一个球体第一个参数是预定义几何体对象第二个是精细度默认为 0geode-addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f, 0.0f, 0.0f), radius), hints.get()));//添加一个正方体geode-addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(2.0f, 0.0f, 0.0f), 2 * radius), hints.get()));//添加一个圆锥geode-addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(4.0f, 0.0f, 0.0f), radius, height), hints.get()));//添加一个圆柱体geode-addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(6.0f, 0.0f, 0.0f), radius, height),hints.get()));//添加一个太空舱geode-addDrawable(new osg::ShapeDrawable(new osg::Capsule(osg::Vec3(8.0f, 0.0f, 0.0f), radius, height),hints.get()));return geode.get();
}int main()
{//创建Viewer对象场景浏览器osg::ref_ptrosgViewer::Viewer viewer new osgViewer::Viewer();osg::ref_ptrosg::Group root new osg::Group();//添加到场景root-addChild(createShape());//优化场景数据osgUtil::Optimizer optimizer;optimizer.optimize(root.get());viewer-setSceneData(root.get());//切换网格模式方便比较viewer-addEventHandler(new osgGA::StateSetManipulator(viewer-getCamera()-getOrCreateStateSet()));viewer-addEventHandler(new osgViewer::StatsHandler());//实现状态信息统计viewer-addEventHandler(new osgViewer::WindowSizeHandler());viewer-setUpViewInWindow(400,400,1000,800);viewer-run();return 0;
}4、多边形分格化
4.1 定义 如果读者对 OpenGL 有一定了解的话应该知道 OpenGL 为了快速渲染多边形只能直接显示简单的凸多边形。所谓简单的凸多边形就是多边形上任意两点的连线上的点依属于该多边形。对凹多边形或者自交叉多边形的渲染结果将不确定。下面列举一些需要分格化的多边形如图 4-10 所示。 为了正确显示凹多边形或者自交叉多边形就必须把它们分解为简单的凸多边形这种做法就称为多边形的分格化。OSG 是对底层 OpenGL API 的封装所以它同样只能直接显示简单的凸多边形对于凹多边形或者自交叉多边形渲染也是不确定的。 在 OSG 中提供了一个多边形分格化的类 osgUtil::Tessellator它继承自 osg::Referenced 类继承关系图如图 4-11 所示。 在 OSG 中进行多边形分格化渲染需要如下 3 个步骤 1创建多边形分格化对象。 2设置分格化对象的类型通常有下面 3 种类型
TESS_TYPE_GEOMETRY, //分格化几何体
TESS_TYPE_DRAWABLE, //分格化几何体中的 Drawable如多边形、三角形、四边形等
TESS_TYPE_POLYGONS //只分格化几何体中的多边形3根据计算的环绕数指定相应的环绕规则。
1环绕数 在《OpenGL 编程指南》第 5 版中曾指出“对于一条简单的轮廓线每个点的环绕数就是环绕这个点的所有轮廓线的代数和用一个有符号的整数表示求和规则是逆时针环绕的轮廓线为正顺时针环绕的轮廓线为负。这个过程把一个有符号的整数数值与平面上的每个顶点相关联。注意对于区域中的所有点它们的环绕数都是相同的”。图 4-12 为轮廓线与环绕数的计算方法读者可以通过此图理解环绕数及如何计算环绕数。
2环绕规则 如果一个区域的环绕数属于环绕规则所选择的类型那么它就是它的内部区域。通常环绕规则把具有奇数和非零环绕数的区域定义为内部区域。环绕规则主要是针对环绕数来确定的。 几种常用的环绕规则如下
TESS_WINDING_ODDGLU_TESS_WINDING_ODD //环绕数为奇数
TESS_WINDING_NONZEROGLU_TESS_WINDING_NONZERO //环绕数为非零数
TESS_WINDING_POSITIVEGLU_TESS_WINDING_POSITIVE //环绕数为正数
TESS_WINDING_NEGATIVEGLU_TESS_WINDING_NEGATIVE //环绕数为负数
TESS_WINDING_ABS_GEQ_TWOGLU_TESS_WINDING_ABS_GEQ_TWO //环绕数为绝对值大于或等于 24.2 示例 4.3 示例源码
#include windows.h#include osgViewer/Viewer
#include osg/Node
#include osg/Geode
#include osg/Geometry
#include osg/Group
#include osg/Switch
#include osg/Billboard
#include osg/Texture2D
#include osg/Image
#include osg/Vec3
#include osg/Vec2
#include osg/PositionAttitudeTransform
#include osg/MatrixTransform
#include osgDB/ReadFile
#include osgDB/WriteFile
#include osgUtil/Optimizer
#include osg/PagedLOD
#include osgSim/Impostor
#include osgViewer/ViewerEventHandlers //事件监听
#include osgGA/StateSetManipulator //事件响应类对渲染状态进行控制
#include osgUtil/Simplifier //简化几何体
#include osg/OccluderNode
#include osg/StateSet
#include osg/ConvexPlanarOccluder
#include osg/BoundingBox
#include osg/BoundingSphere
#include osgUtil/Optimizer
#include iostream
#include osg/ShapeDrawable
#include osgUtil/Tessellator#pragma comment(lib, OpenThreadsd.lib)
#pragma comment(lib, osgd.lib)
#pragma comment(lib, osgDBd.lib)
#pragma comment(lib, osgUtild.lib)
#pragma comment(lib, osgGAd.lib)
#pragma comment(lib, osgViewerd.lib)
#pragma comment(lib, osgTextd.lib)
#pragma comment(lib, osgSimd.lib)
#pragma comment(lib, osgFXd.lib)//使用分格化绘制凹多边形
osg::ref_ptrosg::Geode tesslatorGeometry()
{osg::ref_ptrosg::Geode geode new osg::Geode();osg::ref_ptrosg::Geometry geom new osg::Geometry();geode-addDrawable(geom.get());//以下是一些顶点数据//墙const float wall[5][3] { { 2200.0f, 0.0f, 1130.0f },{ 2600.0f, 0.0f, 1130.0f },{ 2600.0f, 0.0f, 1340.0f },{ 2400.0f, 0.0f, 1440.0f },{ 2200.0f, 0.0f, 1340.0f } };//门const float door[4][3] { { 2360.0f, 0.0f, 1130.0f },{ 2440.0f, 0.0f, 1130.0f },{ 2440.0f, 0.0f, 1230.0f },{ 2360.0f, 0.0f, 1230.0f } };//四扇窗户const float windows[16][3] { { 2240.0f, 0.0f, 1180.0f },{ 2330.0f, 0.0f,1180.0f },{ 2330.0f, 0.0f, 1220.0f },{ 2240.0f, 0.0f, 1220.0f },{ 2460.0f, 0.0f, 1180.0f },{ 2560.0f, 0.0f, 1180.0f },{ 2560.0f, 0.0f, 1220.0f },{ 2460.0f, 0.0f, 1220.0f },{ 2240.0f, 0.0f, 1280.0f },{ 2330.0f, 0.0f, 1280.0f },{ 2330.0f, 0.0f, 1320.0f },{ 2240.0f, 0.0f, 1320.0f },{ 2460.0f, 0.0f, 1280.0f },{ 2560.0f, 0.0f, 1280.0f },{ 2560.0f, 0.0f, 1320.0f },{ 2460.0f, 0.0f, 1320.0f } };//设置顶点数据osg::ref_ptrosg::Vec3Array coords new osg::Vec3Array();geom-setVertexArray(coords.get());//设置法线osg::ref_ptrosg::Vec3Array normal new osg::Vec3Array();normal-push_back(osg::Vec3(0.0f, -1.0f, 0.0f));geom-setNormalArray(normal.get());geom-setNormalBinding(osg::Geometry::BIND_OVERALL);//添加墙for (int i 0; i 5; i){coords-push_back(osg::Vec3(wall[i][0], wall[i][1], wall[i][2]));}geom-addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, 5));//添加门for (int i 0; i 4; i){coords-push_back(osg::Vec3(door[i][0], door[i][1], door[i][2]));}//添加窗for (int i 0; i 16; i){coords-push_back(osg::Vec3(windows[i][0], windows[i][1], windows[i][2]));}geom-addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 5, 20));//创建分格化对象osg::ref_ptrosgUtil::Tessellator tscx new osgUtil::Tessellator();//设置分格类型为几何体tscx-setTessellationType(osgUtil::Tessellator::TESS_TYPE_GEOMETRY);//设置只显示轮廓线为 false这里还需要填充tscx-setBoundaryOnly(false);//设置环绕规则tscx-setWindingType(osgUtil::Tessellator::TESS_WINDING_ODD);//使用分格化tscx-retessellatePolygons(*(geom.get()));return geode.get();
}int main()
{//创建Viewer对象场景浏览器osg::ref_ptrosgViewer::Viewer viewer new osgViewer::Viewer();osg::ref_ptrosg::Group root new osg::Group();//添加到场景root-addChild(tesslatorGeometry());//优化场景数据osgUtil::Optimizer optimizer;optimizer.optimize(root.get());viewer-setSceneData(root.get());//切换网格模式方便比较viewer-addEventHandler(new osgGA::StateSetManipulator(viewer-getCamera()-getOrCreateStateSet()));viewer-addEventHandler(new osgViewer::StatsHandler());//实现状态信息统计viewer-addEventHandler(new osgViewer::WindowSizeHandler());viewer-setUpViewInWindow(400,400,1000,800);viewer-run();return 0;
}