使用“告示板”

osg中有一种结点叫做告示板结点,其从osg::Geode类派生,它与其他的osg::Geode类相似,但它有一个特点就是能够让自己的一面朝向观察屏幕。这样就可以有很多的应用,比如说,可以用多个这种结点做成一片森林。

osg::Billboard类有两种朝向方式,一种是平行于观察平面,一种是垂直与观察点。

#include <osg/Image>
#include <osg/Geometry>
#include <osg/Billboard>
#include <osg/StateSet>
#include <osg/Group>
#include <osg/Texture2D>
#include <osg/PositionAttitudeTransform>
#include <osgDB/readfile>
#include <osgViewer/Viewer>
#include <iostream>

#ifdef _DEBUG
#pragma comment(lib,"osgd.lib")
#pragma comment(lib,"osgDBd.lib")
#pragma comment(lib,"osgViewerd.lib")
#else
#pragma comment(lib,"osg.lib")
#pragma comment(lib,"osgDB.lib")
#pragma comment(lib,"osgViewer.lib")
#endif
//生成一个矩形
osg::ref_ptr<osg::Geometry> createTree()
{
	//绘制四边形
	osg::ref_ptr<osg::Geometry> rect = new osg::Geometry;

	//顶点坐标
	osg::ref_ptr<osg::Vec3Array> vectexArray = new osg::Vec3Array;
	vectexArray->push_back(osg::Vec3(-0.5f,0.0f,-0.5f));
	vectexArray->push_back(osg::Vec3(0.5f,0.0f,-0.5f));
	vectexArray->push_back(osg::Vec3(0.5f,0.0f,0.5f));
	vectexArray->push_back(osg::Vec3(-0.5f,0.0f,0.5f));

	rect->setVertexArray(vectexArray.get());

	//法向
	osg::ref_ptr<osg::Vec3Array> normalArray = new osg::Vec3Array;
	normalArray->push_back(osg::Vec3(1.0f,0.0f,0.0f)^osg::Vec3(0.0f,0.0f,1.0f));
	
	rect->setNormalArray(normalArray.get());
	rect->setNormalBinding(osg::Geometry::BIND_OVERALL);

	//纹理映射
	osg::ref_ptr<osg::Vec2Array> coordArray = new osg::Vec2Array;
	coordArray->push_back(osg::Vec2(0.0f,0.0f));
	coordArray->push_back(osg::Vec2(1.0f,0.0f));
	coordArray->push_back(osg::Vec2(1.0f,1.0f));
	coordArray->push_back(osg::Vec2(0.0f,1.0f));
	rect->setTexCoordArray(0,coordArray.get());

	
	rect->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
	
	return rect;
	




}

int main(int args,char** argv)
{
	osg::ref_ptr<osg::Group> root = new osg::Group;
	osg::ref_ptr<osg::Image> treeImage = osgDB::readImageFile("Images/tree0.rgba");
	//定义三种不同的告示板结点
	osg::ref_ptr<osg::Billboard> treeBillboard_rot_world = new osg::Billboard;
	treeBillboard_rot_world->setMode(osg::Billboard::POINT_ROT_WORLD);
	treeBillboard_rot_world->addDrawable(createTree().get());

	osg::ref_ptr<osg::Billboard> treeBillboard_rot_eye = new osg::Billboard;
	treeBillboard_rot_eye->setMode(osg::Billboard::POINT_ROT_EYE);
	treeBillboard_rot_eye->addDrawable(createTree().get());

	osg::ref_ptr<osg::Billboard> treeBillboard_rot_axial = new osg::Billboard;
	treeBillboard_rot_axial->setMode(osg::Billboard::AXIAL_ROT);
	treeBillboard_rot_axial->addDrawable(createTree().get());
	//普通结点
	osg::ref_ptr<osg::Geode> tree = new osg::Geode;
	tree->addDrawable(createTree().get());
	//分别贴上大树纹理
	if (treeImage.get())
	{
		osg::ref_ptr<osg::Texture2D> treeTexture = new osg::Texture2D;
		treeTexture->setDataVariance(osg::Object::DYNAMIC);
		treeTexture->setImage(treeImage.get());

		osg::ref_ptr<osg::StateSet> treeStateSet = new osg::StateSet;
		treeStateSet->setTextureAttributeAndModes(0,treeTexture.get());
		treeStateSet->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
		treeStateSet->setMode(GL_BLEND,osg::StateAttribute::ON);

		treeBillboard_rot_world->setStateSet(treeStateSet.get());
		treeBillboard_rot_eye->setStateSet(treeStateSet.get());
		treeBillboard_rot_axial->setStateSet(treeStateSet.get());
		tree->setStateSet(treeStateSet.get());
	}
	
	

	treeBillboard_rot_eye->setPosition(0,osg::Vec3(10.0f,5.0f,5.0f));
	treeBillboard_rot_world->setPosition(0,osg::Vec3(5.0f,5.0f,5.0f));
	treeBillboard_rot_axial->setPosition(0,osg::Vec3(15.0f,0.0f,0.0f));
	
	osg::ref_ptr<osg::PositionAttitudeTransform> treePos = new osg::PositionAttitudeTransform;
	treePos->setPosition(osg::Vec3(0.0f,0.0f,0.0f));
	treePos->addChild(tree.get());

	root->addChild(treeBillboard_rot_axial.get());
	root->addChild(treeBillboard_rot_world.get());
	root->addChild(treeBillboard_rot_eye.get());
	root->addChild(treePos.get());

	osgViewer::Viewer myViewer;
	myViewer.setSceneData(root.get());
	myViewer.realize();
	myViewer.run();
	return 0;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值