查看: 6532|回复: 10

请教!关于osg中增加多个光源的问题!!!!

[复制链接]

该用户从未签到

发表于 2011-3-23 10:44:56 | 显示全部楼层 |阅读模式
本帖最后由 luyang0222 于 2011-3-23 10:46 编辑

我在教程上面看到关于增加2个光源的方法是这样的:
      osg::StateSet* stateset;
      stateset=group->getOrCreateStateSet();
      stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
      stateset->setMode(GL_LIGHT0, osg::StateAttribute::ON);
      stateset->setMode(GL_LIGHT1, osg::StateAttribute::ON);
然后是不是创建2个光源:
      osg:: lightSource* lightsource1 = new osg:: lightSource;
      osg:: lightSource* lightsource2 = new osg:: lightSource;
再分别设置好参数后,添加到group节点上去就是了?

可是我按上面做了之能显示出一个光源啊,(我用的是聚光灯,在每个lightsource和group之间分别增加了osg:: positionAttitudeTransform节点pat1,和pat2,以改变聚光灯的初始位置和照射方向)奇怪的是,在将pat添加到组节点的代码中:group->addChild(pat1);group->addChild(pat2);pat1和pat2哪个放在后面写,就显示哪个光源。

在下语言表达能力欠缺,不知道说的是否清楚。若各位需要我哪里再补充的,尽管提出

该用户从未签到

发表于 2011-3-23 11:55:55 | 显示全部楼层
我很晕反正

该用户从未签到

 楼主| 发表于 2011-3-23 12:30:38 | 显示全部楼层
回复 2# tianxiao888


    请别晕啊,说白了就是如何使用2个光源,但是教程上没有说那么仔细,弄了好久也没弄出来,请给予指导

该用户从未签到

发表于 2011-3-23 12:47:46 | 显示全部楼层
请给出您的主要实现代码,并保证其长度在50行以内

该用户从未签到

 楼主| 发表于 2011-3-23 13:31:04 | 显示全部楼层
本帖最后由 luyang0222 于 2011-3-23 14:14 编辑

回复 4# array


    王教授来了我就安心了,问题肯定能解决的。(虽然您老是谦虚说不是教授,但在我们这些学OSG的新人面前,您和我们的导师是一样的地位)
     我的主要思路是:先建立一个生成聚光灯的函数osg::Node* createSpotLightNode();并在主程序中连续2次调用该函数实现的,2次调用时分别加入到两个osg:: PositionAttitudeTransform节点pat1和pat2中以区分不同。
   具体的主要执行代码如下:
    /*创建聚光灯状态属性*/
    osg::StateSet* createSpotLightDecoratorState(unsigned int textureUnit)
{
     //允许光照并为根节点的StateSet允许两个光源
     osg::StateSet* stateset;
     stateset=group->getOrCreateStateSet();       //group是全局变量,为组节点
     stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
     stateset->setMode(GL_LIGHT0, osg::StateAttribute::ON);
     stateset->setMode(GL_LIGHT1, osg::StateAttribute::ON);
    /*后面有一堆属性设置,全是和中心环境颜色,纹理之类的设置,我觉得没什么相干,就省略了*/
      ……
      renturn stateset;
   
}
    /*聚光灯生成函数*/
  osg::Node* createSpotLightNode(const osg::Vec3& position, const osg::Vec3& direction, float angle, unsigned int lightNum, unsigned int textureUnit)
{
       //创建光源组节点
     osg::Group* lightgroup = new osg::Group;
     osg:: LightSource* lightsource = new osg:: LightSource;
       //设置光源的属性
     osg:: Light* light = new osg:: Light();
      light->setLightNum(lightNum);
      light->setPosition(osg::Vec4(position,1.0f));
       light->setDirection(direction);
      light->setAmbient(osg::Vec4(1.00f,1.00f,1.00f,1.0f));
      light->setDiffuse(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
      lightsource->setLight(light);
    lightgroup->addChild(lightsource);
    /*以下的代码是我从肖鹏那本教程中借用的,应该没什么问题,主要是形成聚光灯效果的*/
    osg::Vec3 up(0.0f,0.0f,1.0f);        //计算法向量
    up = (direction ^ up) ^ direction;
    up.normalize();
     osg::TexGenNode* texgenNode = new osg::TexGenNode;  //创建自动生成纹理坐标节点

  texgenNode->setTextureUnit(textureUnit);   //关联纹理单元

osg::TexGen* texgen = texgenNode->getTexGen(); //设置纹理坐标生成器

texgen->setMode(osg::TexGen::EYE_LINEAR); //设置模式为视觉线性

texgen->setPlanesFromMatrix(osg::Matrixd::lookAt(position,position+direction,up)*osg::Matrixd::perspective(angle,1.0,0.1
,100.0));   //从视图中指定参考平面

lightgroup ->addChild(texgenNode);
return lightgroup ;
}

主函数里
  group->setStateSet(createSpotLightDecoratorState(1));
然后在添加了两个osg:: PositionAttitudeTransform节点pat1和pat2,分别设置了不同的位置,然后分别调用上述的函数
  pat1->addChild(createSpotLightNode(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(0.0f,1.f,-1.0f), 90.0f, 0, 1));
  pat2->addChild(createSpotLightNode(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(0.0f,1.f,-1.0f), 90.0f, 1, 1));

   最后再把pat1和pat2加到组节点上
group->addChild(pat1);
group->addChild(pat2);

最后显示。结果只能显示出最后一个加到group上的pat2上的聚光灯,我若换了顺序:
group->addChild(pat2);
group->addChild(pat1);
则显示的是pat1上的聚光灯。
=========================================================
不知我这样说您是否清楚,我数了下代码30多行没超过50.如还有什么需要补充的尽管提

该用户从未签到

发表于 2011-3-23 14:52:39 | 显示全部楼层
我没有从您的程序中看出什么显著的问题,也许您省略的部分里有一些错误存在?下面是我在《OpenSceneGraph Beginners Guide》一书中实现的固定管线灯光效果,没有您那么复杂,也使用到了两个OpenGL灯光和用于变换的Transform节点:
  1. osg::Node* createLightSource( unsigned int num, const osg::Vec3& trans, const osg::Vec4& color )
  2. {
  3.     osg::ref_ptr<osg::Light> light = new osg::Light;
  4.     light->setLightNum( num );
  5.     light->setDiffuse( color );
  6.     light->setPosition( osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f) );
  7.    
  8.     osg::ref_ptr<osg::LightSource> lightSource = new osg::LightSource;
  9.     lightSource->setLight( light );

  10.     osg::ref_ptr<osg::MatrixTransform> sourceTrans = new osg::MatrixTransform;
  11.     sourceTrans->setMatrix( osg::Matrix::translate(trans) );
  12.     sourceTrans->addChild( lightSource.get() );
  13.     return sourceTrans.release();
  14. }

  15. int main( int argc, char** argv )
  16. {
  17.     osg::ref_ptr<osg::Node> model = osgDB::readNodeFile( "cessna.osg" );
  18.    
  19.     osg::ref_ptr<osg::Group> root = new osg::Group;
  20.     root->addChild( model.get() );
  21.    
  22.     osg::Node* light0 = createLightSource( 0, osg::Vec3(-20.0f, 0.0f, 0.0f), osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f) );
  23.     osg::Node* light1 = createLightSource( 1, osg::Vec3(0.0f, -20.0f, 0.0f), osg::Vec4(0.0f, 1.0f, 1.0f, 1.0f) );
  24.    
  25.     root->getOrCreateStateSet()->setMode( GL_LIGHT0, osg::StateAttribute::ON );
  26.     root->getOrCreateStateSet()->setMode( GL_LIGHT1, osg::StateAttribute::ON );
  27.     root->addChild( light0 );
  28.     root->addChild( light1 );
  29.    
  30.     osgViewer::Viewer viewer;
  31.     viewer.setSceneData( root.get() );
  32.     return viewer.run();
  33. }
复制代码

该用户从未签到

 楼主| 发表于 2011-3-23 15:35:20 | 显示全部楼层
回复 6# array


    真是非常感谢您孜孜不倦的教导,还附送了您程序中的一段代码让我参考。我运行了您的代码,果然没有任何问题。我想我的问题可能是出在的聚光灯设置上。至于聚光灯我一直都是参考肖鹏大师那本编程指南中的例子,我想您可能也看过。实现起来挺繁琐的,我想请问王教授,在聚光灯的实现上有什么更好的建议或是方法吗?
    下面这张图是我帮导师做的一个项目中的截图,但是老板说要把单头的聚光灯,换成2个小的双头灯,光为了这个我又从昨天忙到现在也没弄出来。
4535.jpg

该用户从未签到

发表于 2011-3-24 08:28:09 | 显示全部楼层
没有什么特殊的建议,熟悉一下OpenGL的固定管线对您会很有好处

该用户从未签到

发表于 2012-4-16 09:41:51 | 显示全部楼层
luyang0222 发表于 2011-3-23 15:35
回复 6# array

请问,您的这个地铁站或者铁路站的场景是如何渲染出来了。使用了其它的工具吗?

该用户从未签到

发表于 2012-4-16 20:47:01 | 显示全部楼层
luyang0222 发表于 2011-3-23 15:35
回复 6# array

您好,打扰您了,我想请问一下您的那个黑夜的效果是怎么做出来的。。

我也想做您的那种效果,漆黑的夜中 有汽车有2个灯~~~


还望您能指教下~~在此拜谢~~

该用户从未签到

发表于 2014-3-5 14:15:34 | 显示全部楼层
我也是这个问题, 只能加一个光源, 不知道为什么
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表