5、osg绘制正方形和四方块以及内置的几何图形

1、首先要定义一个几何图形,用来创建正方形的一个对象,这个对象根据坐标,颜色来进行绘制,如下代码创建一个几何对象:

osg::ref_ptr<osg::Geometry> geom=new osg::Geometry();//定义一个几何体
2、创建一个坐标集合对象,并且向对象中存入4个3维坐标点,如下代码所示:

//首先定义四个点
osg::ref_ptr<osg::Vec3Array> v=new osg::Vec3Array();//定义一个几何体坐标集合
v->push_back(osg::Vec3(-1.0,0.0,-1.0));//左下角坐标点
v->push_back(osg::Vec3(1.0,0.0,-1.0));//右下角坐标点
v->push_back(osg::Vec3(1.0,0.0,1.0));//右上角坐标点
v->push_back(osg::Vec3(-1.0,0.0,1.0));//左上角坐标点
geom->setVertexArray(v.get());//将坐标设置到几何体节点中

以下是坐标解释,在osg中,左右是x轴(左负,右正),上下为z轴(上正,下负),里外是y轴(里正,外负),如下图所示:


那么根据坐标可在图中画出图形,如下图所示:



3、创建一个颜色集合数组,分别向该集合存入四个颜色,每个颜色代表一个顶点,一共四种颜色,并且通过setColorArray与原来的几何体进行关联,并设置颜色绑定方式为逐点绑定,如下代码所示:

//定义颜色数组
osg::ref_ptr<osg::Vec4Array> c=new osg::Vec4Array();//定义一个颜色数组颜色
c->push_back(osg::Vec4(1.0,0.0,0.0,1.0));//数组的四个参数分别为RGBA,其中A表示透明度
c->push_back(osg::Vec4(0.0,1.0,0.0,1.0));
c->push_back(osg::Vec4(0.0,0.0,1.0,1.0));
c->push_back(osg::Vec4(1.0,1.0,1.0,1.0));
geom->setColorArray(c.get());//与几何体中进行关联
geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);//设置绑定方式为逐点绑定。
4、定义图形的法线,就是我们从哪个方向去看图形,先定义一个坐标集合,然后向集合中添加一个法线坐标,然后通过setNormalArray设置法线,并通过setNormalBinding来绑定法线,并设置顶点关联方式,如下代码所示:

//定义法线
osg::ref_ptr<osg::Vec3Array> n=new osg::Vec3Array();//定义了一个法线绑定到该四方体中
n->push_back(osg::Vec3(0.0,-1.0,0.0));//法线为指向Y轴负半轴
geom->setNormalArray(n.get());//添加法线到几何体中
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);//将法线进行绑定
//设置顶点的关联方式,这里是Quad方式,总共有这么些方式: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));
5、定义一个几何组,并把刚创建好的geom集合体添加到组中,如下代码所示:

//定义一个几何组结点,并把几何体结点加入到几何组结点当中
osg::ref_ptr<osg::Geode> geode=new osg::Geode();
geode->addDrawable(geom.get());
如下所有代码所示:

#include "stdafx.h"
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/Geode>//Geode是专门管理可绘制几何体的总闸
#include <osg/Geometry>
osg::ref_ptr<osg::Node> createQuade();
int _tmain(int argc, _TCHAR* argv[])
{
	osgViewer::Viewer viewer;
	osg::ref_ptr<osg::Group> root=new osg::Group();
	root->addChild(createQuade().get());
	viewer.setSceneData(root.get());
	viewer.realize();
	return viewer.run();
}
osg::ref_ptr<osg::Node> createQuade()
{
	osg::ref_ptr<osg::Geometry> geom=new osg::Geometry();//定义一个几何体
	//首先定义四个点
	osg::ref_ptr<osg::Vec3Array> v=new osg::Vec3Array();//定义一个几何体坐标集合
	v->push_back(osg::Vec3(-1.0,0.0,-1.0));//左下角坐标点
	v->push_back(osg::Vec3(1.0,0.0,-1.0));//右下角坐标点
	v->push_back(osg::Vec3(1.0,0.0,1.0));//右上角坐标点
	v->push_back(osg::Vec3(-1.0,0.0,1.0));//左上角坐标点
	geom->setVertexArray(v.get());//将坐标设置到几何体节点中
	//定义颜色数组
	osg::ref_ptr<osg::Vec4Array> c=new osg::Vec4Array();//定义一个颜色数组颜色
	c->push_back(osg::Vec4(1.0,0.0,0.0,1.0));//数组的四个参数分别为RGBA,其中A表示透明度
	c->push_back(osg::Vec4(0.0,1.0,0.0,1.0));
	c->push_back(osg::Vec4(0.0,0.0,1.0,1.0));
	c->push_back(osg::Vec4(1.0,1.0,1.0,1.0));
	geom->setColorArray(c.get());//与几何体中进行关联
	geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);//设置绑定方式为逐点绑定。
	//定义法线
	osg::ref_ptr<osg::Vec3Array> n=new osg::Vec3Array();//定义了一个法线绑定到该四方体中
	n->push_back(osg::Vec3(0.0,-1.0,0.0));//法线为指向Y轴负半轴
	geom->setNormalArray(n.get());//添加法线到几何体中
	geom->setNormalBinding(osg::Geometry::BIND_OVERALL);//将法线进行绑定
	//设置顶点的关联方式,这里是Quad方式,总共有这么些方式: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));
	
	//定义一个几何组结点,并把几何体结点加入到几何组结点当中
	osg::ref_ptr<osg::Geode> geode=new osg::Geode();
	geode->addDrawable(geom.get());
	return geode.get();
}
其运行效果如下图所示:

正面


反面
6、如果要绘制四方块,则只需要更改一个参数即可,将geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));中的QUADS更改为LINE_LOOP即可,参数可以为:POINTS[点],LINES[线],LINE_STRIP[线带],LINE_LOOP[闭合线段],TRIANGLES[三角形],TRIANGLE_STRIP[三角带],TRIANGLE_FAN[三角扇],QUADS[四方块],QUAD_STRIP[四方块带],POLYGON[多边形],更改之后的效果如下所示:

7、设置线框的宽度,需要添加一个LineWidth对象,如下代码所示:
osg::ref_ptr<osg::LineWidth> lineSize=new osg::LineWidth();
lineSize->setWidth(10.0);//设置线的宽度
geom->getOrCreateStateSet()->setAttributeAndModes(lineSize.get(),osg::StateAttribute::ON);
8、整个代码如下所示:
#include "stdafx.h"
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/Geode>//Geode是专门管理可绘制几何体的总闸
#include <osg/Geometry>
#include <osg/LineWidth>
osg::ref_ptr<osg::Node> createQuade();
int _tmain(int argc, _TCHAR* argv[])
{
	osgViewer::Viewer viewer;
	osg::ref_ptr<osg::Group> root=new osg::Group();
	root->addChild(createQuade().get());
	viewer.setSceneData(root.get());
	viewer.realize();
	return viewer.run();
}
osg::ref_ptr<osg::Node> createQuade()
{
	osg::ref_ptr<osg::Geometry> geom=new osg::Geometry();//定义一个几何体
	osg::ref_ptr<osg::LineWidth> lineSize=new osg::LineWidth();
	lineSize->setWidth(10.0);//设置线的宽度
	geom->getOrCreateStateSet()->setAttributeAndModes(lineSize.get(),osg::StateAttribute::ON);
	//首先定义四个点
	osg::ref_ptr<osg::Vec3Array> v=new osg::Vec3Array();//定义一个几何体坐标集合
	v->push_back(osg::Vec3(-1.0,0.0,-1.0));//左下角坐标点
	v->push_back(osg::Vec3(1.0,0.0,-1.0));//右下角坐标点
	v->push_back(osg::Vec3(1.0,0.0,1.0));//右上角坐标点
	v->push_back(osg::Vec3(-1.0,0.0,1.0));//左上角坐标点
	geom->setVertexArray(v.get());//将坐标设置到几何体节点中
	//定义颜色数组
	osg::ref_ptr<osg::Vec4Array> c=new osg::Vec4Array();//定义一个颜色数组颜色
	c->push_back(osg::Vec4(1.0,0.0,0.0,1.0));//数组的四个参数分别为RGBA,其中A表示透明度
	c->push_back(osg::Vec4(0.0,1.0,0.0,1.0));
	c->push_back(osg::Vec4(0.0,0.0,1.0,1.0));
	c->push_back(osg::Vec4(1.0,1.0,1.0,1.0));
	geom->setColorArray(c.get());//与几何体中进行关联
	geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);//设置绑定方式为逐点绑定。
	//定义法线
	osg::ref_ptr<osg::Vec3Array> n=new osg::Vec3Array();//定义了一个法线绑定到该四方体中
	n->push_back(osg::Vec3(0.0,-1.0,0.0));//法线为指向Y轴负半轴
	geom->setNormalArray(n.get());//添加法线到几何体中
	geom->setNormalBinding(osg::Geometry::BIND_OVERALL);//将法线进行绑定
	//设置顶点的关联方式,这里是Quad方式,总共有这么些方式:POINTS,LINES,LINE_STRIP,LINE_LOOP,TRIANGLES,TRIANGLE_STRIP,TRIANGLE_FAN,QUADS,QUAD_STRIP,POLYGON
	//此关联方式来决定绘制什么样的图形,比如Quad表示四方块,POINTS[点],LINES[线],LINE_STRIP[线带],LINE_LOOP[闭合线段],TRIANGLES[三角形],TRIANGLE_STRIP[三角带],TRIANGLE_FAN[三角扇],QUADS[四方块],QUAD_STRIP[四方块带],POLYGON[多边形]
	geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,4));
	
	//定义一个几何组结点,并把几何体结点加入到几何组结点当中
	osg::ref_ptr<osg::Geode> geode=new osg::Geode();
	geode->addDrawable(geom.get());
	return geode.get();
}
运行效果如下所示:
8、在osg中的几何类型都包含在osg::Shape类中,然后将这些在添加到geode中,最后将geode添加到root中进行渲染,其形状可以分为:osg::Box[盒子],osg::Capsule[胶囊形],osg::CompositeShape[组合型],osg::Cone[圆锥形],osg::Cylinder[圆柱形],osg::HeightField[高程形],osg::InfinitePlane[有限面],osg::Sphere[球形],osg::TriangleMesh[三角蒙皮]。
如以下代码:
#include "stdafx.h"
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/Geode>//Geode是专门管理可绘制几何体的总闸
#include <osg/Geometry>
#include <osg/ShapeDrawable>
#include <osg/Shape>
osg::ref_ptr<osg::Node> createShape();
int _tmain(int argc, _TCHAR* argv[])
{
	osgViewer::Viewer viewer;
	osg::ref_ptr<osg::Group> root=new osg::Group();
	root->addChild(createShape().get());
	viewer.setSceneData(root.get());
	viewer.realize();
	return viewer.run();
}
osg::ref_ptr<osg::Node> createShape()
{
	osg::ref_ptr<osg::Geode> geode=new osg::Geode();
	float radius=0.08;//(以米为单位)
	float height=0.1;
	osg::TessellationHints *hints=new osg::TessellationHints();
	hints->setDetailRatio(0.5);//表示模型的粗细度。值越大精细度就越大。打个比方,当精细度小时,一个球可能只有几条线组成,很不圆。但是当精细度大时就十分像个球了。
	//绘制一个球型,以(0,0,0)为圆心,以0.08为半径,精细度为hints绘制一个球体
	geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0,0.0,0.0),radius),hints));
	//以(0.2,0,0)为坐标,以0.16为盒心,以长0.16米为长,绘制一个立方体
	geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.2,0.0,0.0),2*radius),hints));
	//以底面圆心(0.2,0,0)为坐标,半径为0.08米为圆心,以0.1米为高度,绘制一个圆锥
	geode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(0.4,0.0,0.0),radius,height),hints));
	//以底面圆心(0.6,0,0)为坐标,半径为0.08米为圆心,以0.1米为高度,绘制一个圆柱体
	geode->addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(0.6,0.0,0.0),radius,height),hints));
	//以圆心(0.8,0,0)为坐标,半径为0.08米为圆心,以0.1米为高度,绘制一个胶囊体
	geode->addDrawable(new osg::ShapeDrawable(new osg::Capsule(osg::Vec3(0.8,0.0,0.0),radius,height),hints));
	return geode.get();
}
运行效果如下:


  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值