天天看点

OSG学习:几何对象的绘制(一)——四边形绘制一个四边形

以下内容来自: 

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 *) //设置纹理坐标索引数组,参数纹理单元 / 纹理索引坐标数组
           

结果图:

OSG学习:几何对象的绘制(一)——四边形绘制一个四边形