天天看點

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學習:幾何對象的繪制(一)——四邊形繪制一個四邊形