|
楼主 |
发表于 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.如还有什么需要补充的尽管提 |
|