我要发帖 回复

高级会员

109

主题

1589

积分

0

专家分

OSG-VR-GIS

忠于职守杰出贡献

:

私信
发表时间 : 2007-12-21 14:18:06 | 浏览 : 1998    评论 : 1
Navy15 - 向场景中添加告示牌(Billboard)节点 (2)
下一步,我们编写场景设置和仿真循环的执行代码。代码中包括我们刚刚编写的向告示牌添加四边形实例的函数(Billboard类继承自Geode类,因此可以向其添加Drawable实例),以及旋转轴和告示牌朝向方向的设置。

int main( int argc, char **argv )
{
   osgViewer::Viewer viewer;

   osg::Group* rootNode = new osg::Group();
   osg::Node* tankNode = NULL;
   osg::Node* terrainNode = NULL;
   osg::PositionAttitudeTransform* tankXform =
      new osg::PositionAttitudeTransform();

   osgDB::FilePathList pathList = osgDB::getDataFilePathList();
   pathList.push_back("C:\\Projects\\OpenSceneGraph\\OpenSceneGraph-Data\\NPSData\\Models\\T72-Tank\\");
   pathList.push_back("C:\\Projects\\OpenSceneGraph\\OpenSceneGraph-Data\\NPSData\\Models\\JoeDirt\\");
   pathList.push_back("C:\\Projects\\OpenSceneGraph\\OpenSceneGraph-Data\\NPSData\\Textures\\");
   osgDB::setDataFilePathList(pathList);

   tankNode = osgDB::readNodeFile("T72-tank_des.flt");
   terrainNode = osgDB::readNodeFile("JoeDirt.flt");
   if (! (tankNode && terrainNode))
   {
      std::cout << "Couldn't load models, quitting." << std::endl;
      return -1;
   }
   rootNode->addChild(terrainNode);
   rootNode->addChild(tankXform);
   tankXform->addChild(tankNode);

   tankXform->setPosition( osg::Vec3(10,10,8) );
   tankXform->setAttitude(
      osg::Quat(osg::DegreesToRadians(-45.0), osg::Vec3(0,0,1) ) );

   viewer.setCameraManipulator(new osgGA::TrackballManipulator());
   viewer.setSceneData(rootNode);
   viewer.realize();

创建告示牌并设置其参数。我们希望告示牌可以环绕轴(0,0,1)旋转,并始终朝向视口。为了保证它始终面向视口,我们需要定义告示牌的法线方向为(0,-1,0)。

   osg::Billboard* shrubBillBoard = new osg::Billboard();
   rootNode->addChild(shrubBillBoard);

   shrubBillBoard->setMode(osg::Billboard::AXIAL_ROT);
   shrubBillBoard->setAxis(osg::Vec3(0.0f,0.0f,1.0f));
   shrubBillBoard->setNormal(osg::Vec3(0.0f,-1.0f,0.0f));

下面的代码将设置四边形几何体的渲染状态。我们将使用Alpha融合算法,使四边形看起来像是一个复杂的树木的几何形状。

osg::Texture2D *ocotilloTexture = new osg::Texture2D;
ocotilloTexture->setImage(osgDB::readImageFile("images\\ocotillo.png"));

osg::AlphaFunc* alphaFunc = new osg::AlphaFunc;
alphaFunc->setFunction(osg::AlphaFunc::GEQUAL,0.05f);

osg::StateSet* billBoardStateSet = new osg::StateSet;

billBoardStateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
billBoardStateSet->setTextureAttributeAndModes
      (0, ocotilloTexture, osg::StateAttribute::ON );
billBoardStateSet->setAttributeAndModes
      (new osg::BlendFunc, osg::StateAttribute::ON );
osg::AlphaFunc* alphaFunction = new osg::AlphaFunc;
alphaFunction->setFunction(osg::AlphaFunc::GEQUAL,0.05f);
billBoardStateSet->setAttributeAndModes( alphaFunc, osg::StateAttribute::ON );

下面,我们需要创建一些Drawable几何体并将其添加给告示牌节点实例。我们将使用上面定义的函数来创建几何体;并使用Billboard类重载的addDrawable方法来添加并放置这些四边形。

// 创建不同放缩系数的几何体,并赋予它们已定义好的渲染状态。
osg::Drawable* shrub1Drawable = createShrub( 1.0f, billBoardStateSet);
osg::Drawable* shrub2Drawable = createShrub( 2.0f, billBoardStateSet);
osg::Drawable* shrub3Drawable = createShrub( 1.2f, billBoardStateSet);

// 将这些几何体添加到告示牌节点,并设置其不同位置。
shrubBillBoard->addDrawable( shrub1Drawable , osg::Vec3(12,3,8) );
shrubBillBoard->addDrawable( shrub2Drawable , osg::Vec3(10,18,8));
shrubBillBoard->addDrawable( shrub3Drawable , osg::Vec3(6,10,8) )

这之后的代码就很寻常了。

   while( !viewer.done() )
   {
      viewer.frame();
   }
   return 0;
}

祝你好运!

最近VR访客


OSG中国官方网站:http://www.osgChina.org
OSG中国官方讨论区:http://bbs.osgChina.org

OSG专业群-OSG地形研究者 49668412
      OSG地形专业研究 45763709
obuil 评论于2007-12-21 14:38:22
用这个是不是就可以制作 太阳光晕了吧

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

GMT+8, 2021-4-18 10:49 PM

返回顶部