以下内容来自:
1、《OpenSceneGraph三维渲染引擎编程指南》肖鹏 刘更代 徐明亮 清华大学出版社
2、《OpenSceneGraph三维渲染引擎设计与实践》王锐 钱学雷 清华大学出版社
3、自己的总结
OSG中类的继承关系等见OSG学习:OSG组成(二)——场景树。
下载完整工程OSG_3_GeometryQuads
创建C++项目后,首先需要配置OSG环境,具体步骤看OSG学习:WIN10系统下OSG+VS2017编译及运行第六步:新建OSG项目测试。
绘制一个四边形
// stdafx.h
#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
//osgUtil工具类库,提供通用的共用类,用于操作场景图形及内容,如更新、裁剪、遍历、数据统计及场景图的一些优化。包括Delaunay三角面绘制功能、法线生成功能等。Optimizer优化器
#include <osgUtil/Optimizer>
//.cpp
/*绘制并渲染几何体的主要步骤:
1.创建各种向量数据,如顶点、纹理坐标、颜色、法线。顶点数据按照逆时针顺序添加,以确保背面剔除的正确
2.实例化几何对象osg::Geometry,设置顶点坐标数组、纹理坐标数组、颜色数组、法线数组、绑定方式和数据解析
3.加入叶节点绘制并渲染
*/
osg::ref_ptr<osg::Node> createQuad()
{
//创建一个叶节点对象
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
//创建一个几何体对象
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();
//创建顶点数组,注意顶点的添加顺序是逆时针的
osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array();
//添加数据
v->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
v->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
v->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
v->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
//设置顶点数据setVertexArray(Array *array)
geom->setVertexArray(v.get());
//创建纹理数组
osg::ref_ptr<osg::Vec2Array> vt = new osg::Vec2Array();
//添加数据
vt->push_back(osg::Vec2(0.0f, 0.0f));
vt->push_back(osg::Vec2(1.0f, 0.0f));
vt->push_back(osg::Vec2(1.0f, 1.0f));
vt->push_back(osg::Vec2(0.0f, 1.0f));
//设置纹理坐标数组setTexCoordArray(unsigned int unit, Array *)参数纹理单元/纹理坐标数组
geom->setTexCoordArray(0, vt.get());
//数据绑定:法线、颜色,绑定方式为:
//BIND_OFF不启动用绑定/BIND_OVERALL绑定全部顶点/BIND_PER_PRIMITIVE_SET单个绘图基元绑定/BIND_PER_PRIMITIVE单个独立的绘图基元绑定/BIND_PER_VERTIE单个顶点绑定
//采用BIND_PER_PRIMITIVE绑定方式,则OSG采用glBegin()/glEnd()函数进行渲染,因为该绑定方式为每个独立的几何图元设置一种绑定方式
//创建颜色数组
osg::ref_ptr<osg::Vec4Array> vc = new osg::Vec4Array();
//添加数据
vc->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
vc->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
vc->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
vc->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
//设置颜色数组setColorArray(Array *array)
geom->setColorArray(vc.get());
//设置颜色的绑定方式setColorBinding(AttributeBinding ab)为单个顶点
geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
//创建法线数组
osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array();
//添加法线
nc->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
//设置法线数组setNormalArray(Array *array)
geom->setNormalArray(nc.get());
//设置法线的绑定方式setNormalBinding(AttributeBinding ab)为全部顶点
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
//添加图元,绘制基元为四边形
//数据解析,即指定向量数据和绑定方式后,指定渲染几何体的方式,不同方式渲染出的图形不同,即时效果相同,可能面数或内部机制等也有区别,函数为:
//bool addPrimitiveSet(PrimitiveSet *primitiveset)参数说明:osg::PrimitiveSet是无法初始化的虚基类,因此主要调用它的子类指定数据渲染,最常用为osg::DrawArrays
//osg::DrawArrays(GLenum mode, GLint first, GLsizei count)参数为指定的绘图基元、绘制几何体的第一个顶点数在指定顶点的位置数、使用的顶点的总数
//PrimitiveSet类继承自osg::Object虚基类,但不具备一般一般场景中的特性,PrimitiveSet类主要封装了OpenGL的绘图基元,常见绘图基元如下
//POINTS点/LINES线/LINE_STRIP多线段/LINE_LOOP封闭线
//TRIANGLES一系列三角形(不共顶点)/TRIANGLE_STRIP一系列三角形(共用后面两个顶点)/TRIANGLE_FAN一系列三角形,顶点顺序与上一条语句绘制的三角形不同
//QUADS四边形/QUAD_STRIP一系列四边形/POLYGON多边形
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
//添加到叶节点
geode->addDrawable(geom.get());
return geode.get();
}
int main(int argc, char **argv)
{
//方法1:在智能指针中创建viewer,使用它的方法用"->"
//创建Viewer对象,场景浏览器
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
osg::ref_ptr<osg::Group> root = new osg::Group();
//添加到场景
root->addChild(createQuad());
//优化场景数据
osgUtil::Optimizer optimizer;
optimizer.optimize(root.get());
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
return 0;
//方法2:直接创建viewer,使用它的方法用"."
/*osg::ref_ptr<osg::Group> root = new osg::Group();
root->addChild(createQuad());
osgViewer::Viewer viewer;
viewer.setSceneData(root.get());
return viewer.run();*/
}
在上面的例子中,涉及的一系列向量数据的实现函数为:
void setVertexArray(Array *array) //设置顶点数组
void setVertexData(const ArrayData &arrayData) //设置顶点数组数据
void setVertexIndices(IndexArray *array) //设置顶点索引数组
void setNormalArray(Array *array) //设置法线数组
void setNormalData(const ArrayData &arrayData) //设置法线数组数据
void setNormalIndices(IndexArray *array) //设置法线索引数组
void setCorlorArray(Array *array) //设置颜色数组
void setCorlorData(const ArrayData &arrayData) //设置颜色数组数据
void setCorlorIndices(IndexArray *array) //设置颜色索引数组
void setTexCoordArray(unsigned int unit, Array *) //设置纹理坐标数组,参数纹理单元 / 纹理坐标数组
void setTexCoordData(unsigned int index, const ArrayData &arrayData) //设置纹理坐标数组数据,参数纹理单元 / 纹理坐标数组数据
void setTexCoordIndices(unsigned int unit, IndexArray *) //设置纹理坐标索引数组,参数纹理单元 / 纹理索引坐标数组
结果图:
