我要发帖 回复

管理员

735

主题

2万

积分

30

专家分

忠于职守杰出贡献鼓励

兴趣点(最多三项):

建模技术

私信
发表时间 : 2007-11-23 13:02:46 | 浏览 : 2477    评论 : 1
译者:竹林小舍

原文出处:http://www.nps.navy.mil/cs/sullivan/osgtutorials/osgShape.htm







目标:

用osg::Shape实例构建场景。使用osg::StateSet控制shape的渲染。



使用Shape类:

Shape
类是所有形状类别的基类。Shape既可用于剪裁和碰撞检测也可用于定义程序性地产生几何体的那些基本形状。下面的类继承自Shape类:




TriangleMesh




Sphere




InfinitePlane




HeightField




Cylinder




Cone




CompositeShape




Box




为了使这些形状可以被渲染,我们需要把他们和Drawable类的实例关联起来。ShapeDrawable类提供了这样的功能。这个类继承自Drawable并允许我们把Shape实例附加到可以被渲染的东西上。既然ShapeDrawable类继承自Drawable,ShapDrawable实例就可以被加到Geode类实例上。下面的步骤演示了将一个单位立方体加到空场景中时是如何做到这些的。



// Declare a group to act as root node of a scene:



osg::Group* root = new osg::Group();







// Declare a box class (derived from shape class) instance



// This constructor takes an osg::Vec3 to define the center



// and a float to define the height, width and depth.



// (an overloaded constructor allows you to specify unique



// height, width and height values.)



osg::Box* unitCube = new osg::Box( osg::Vec3(0,0,0), 1.0f);







// Declare an instance of the shape drawable class and initialize



// it with the unitCube shape we created above.



// This class is derived from 'drawable' so instances of this



// class can be added to Geode instances.



osg::ShapeDrawable* unitCubeDrawable = new osg::ShapeDrawable(unitCube);







// Declare a instance of the geode class:



osg::Geode* basicShapesGeode = new osg::Geode();







// Add the unit cube drawable to the geode:



basicShapesGeode->addDrawable(unitCubeDrawable);







// Add the goede to the scene:



root->addChild(basicShapesGeode);




产生一个球体和上面的代码基本相似。没有太多的注释的代码看起来是这个样子:



// Create a sphere centered at the origin, unit radius:



osg::Sphere* unitSphere = new osg::Sphere( osg::Vec3(0,0,0), 1.0);



osg::ShapeDrawable* unitSphereDrawable



= new osg::ShapeDrawable(unitSphere);




现在,我们可以使用transform节点将这个球体加到场景中,以便让它离开原点。unitSphereDrawable不能直接添加到场景中(因为它不是继承自node类),所以我们需要一个新的geode以便添加它。



osg::PositionAttitudeTransform* sphereXForm =




new osg::PositionAttitudeTransform();



sphereXForm->setPosition(osg::Vec3(2.5,0,0));







osg::Geode* unitSphereGeode = new osg::Geode();



root->addChild(sphereXForm);







sphereXForm->addChild(unitSphereGeode);



unitSphereGeode->addDrawable(unitSphereDrawable);



设置状态

前面的教程讲解了如何生成纹理,将其指定为从文件加载的图像,生成一个带纹理的StateSet。下面的代码建立了两个状态集合——一个是BLEND纹理模式,另一个是DECAL纹理模式。BLEND模式:



// Declare a state set for 'BLEND' texture mode



osg::StateSet* blendStateSet = new osg::StateSet();







// Declare a TexEnv instance, set the mode to 'BLEND'



osg::TexEnv* blendTexEnv = new osg::TexEnv;



blendTexEnv->setMode(osg::TexEnv::BLEND);







// Turn the attribute of texture 0 - the texture we loaded above - 'ON'



blendStateSet->setTextureAttributeAndModes




(0,KLN89FaceTexture,osg::StateAttribute::ON);







// Set the texture texture environment for texture 0 to the



// texture envirnoment we declared above:



blendStateSet->setTextureAttribute(0,blendTexEnv);




重复这些步骤,产生DECAL纹理模式的状态集合。



osg::StateSet* decalStateSet = new osg::StateSet();







osg::TexEnv* decalTexEnv = new osg::TexEnv();



decalTexEnv->setMode(osg::TexEnv::DECAL);







decalStateSet->setTextureAttributeAndModes




(0,KLN89FaceTexture,osg::StateAttribute::ON);



decalStateSet->setTextureAttribute(0,decalTexEnv);




产生了状态集合后我们就可以把它们应用在场景中的节点上。在scene graph的绘制遍历(root->leaf)中状态是积累的。除非这个节点有一个它自己的状态,否则它会继承其父节点的状态。(如果一个节点有一个以上的父节点,它会使用一个以上的状态渲染。)



root->setStateSet(blendStateSet);



unitSphereGeode->setStateSet(decalStateSet);




最后一步是进入仿真循环。



viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);



viewer.setSceneData( root );



viewer.realize();







while( !viewer.done() )



{




viewer.sync();




viewer.update();




viewer.frame();



}



return 0;





[ 本帖最后由 obuil 于 2007-11-23 01:25 PM 编辑 ]

最近VR访客

qianlima888 评论于2008-5-5 18:56:41
谢谢!

手机版|VR开发网 统计 津ICP备18009691号
网安备12019202000257

GMT+8, 2021-10-29 01:11 AM

返回顶部