|
你们好,我在自己的小程序上想添加一个聚光灯,下面是根据编程指南来做的。但是结果发现聚光灯无法显示,同时我的运动模型也是暗的。。请问是我的参数设置问题,还是其他问题?另外,关于聚光灯的设置一般遵循什么思想。。谢谢!
osg::ref_ptr<osg::Image>createSpotLightImage(const osg::Vec4 & centerColour,const osg::Vec4& backgroundColour,unsigned int size ,float power)
{
//创建image对象
osg::ref_ptr<osg::Image >image=new osg::Image ;
//动态分配一个size*size大小的image;
image->allocateImage (size,size,1,GL_RGBA,GL_UNSIGNED_BYTE);
//填充image
float mid=(float(size)-1)*0.5f;
float div=2.0f/float(size);
for(unsigned int r=0;r<size;r++)
{
unsigned char*ptr=image->data (0,r,0);
unsigned int c=0;
for(;c<size;++c);
{
float dx=(float(c)-mid)*div;
float dy=(float(r)-mid)*div;
float r=powf(1.0f-sqrtf(dx*dx+dy*dy),power);
if(r<0.0f)r=0.0f;
osg::Vec4 color=centerColour*r+backgroundColour*(1.0f-r);
*ptr++=(unsigned char)((color[0])*255.0f);
*ptr++=(unsigned char)((color[1])*255.0f);
*ptr++=(unsigned char)((color[2])*255.0f);
*ptr++=(unsigned char)((color[3])*255.0f);
}
}
return image.get ();
}
//创建聚光灯状态属性
osg::ref_ptr<osg::StateSet>createSpotLightDecoratorState(unsigned int lightNum,unsigned int textureUnit)
{
osg::ref_ptr<osg::StateSet>stateset=new osg::StateSet;
stateset->setMode (GL_LIGHT0+lightNum,osg::StateAttribute::ON );
osg::Vec4 centerColour(1.0f,0.0f,1.0f,0.0f);
osg::Vec4 ambientColour(0.05f,0.05f,0.05f,1.0f);
osg::ref_ptr<osg::Texture2D>texture=new osg::Texture2D();
texture->setImage(createSpotLightImage(centerColour,ambientColour,64,1.0));
texture->setBorderColor(osg::Vec4(ambientColour));
texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_BORDER);
texture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_BORDER);
texture->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_BORDER);
stateset->setTextureAttributeAndModes(textureUnit,texture.get(),osg::StateAttribute::ON );
stateset->setTextureMode(textureUnit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
stateset->setTextureMode(textureUnit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
stateset->setTextureMode(textureUnit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
stateset->setTextureMode(textureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
return stateset.get ();
}
//创建聚光灯节点
osg::ref_ptr<osg::Node >creatSpotlightNode(const osg::Vec3&position,const osg::Vec3&direction,float angle,unsigned int lightNum,unsigned int textureUnit)
{
osg::ref_ptr<osg::Group>group=new osg::Group;
//创建光源
osg::ref_ptr<osg:ightSource>lightsoure=new osg::LightSource;
osg::ref_ptr<osg::Light>light=lightsoure->getLight ();
light->setLightNum (lightNum);
light->setPosition (osg::Vec4(position,1.0f));
light->setAmbient(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
light->setDiffuse(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
light->setSpotCutoff(20.0f);
light->setSpotExponent(50.0f);
light->setDirection(osg::Vec3(1.0f,1.0f,-1.0f));
group->addChild(lightsoure);
//计算法向量
osg::Vec3 up(0.0f,0.0f,1.0f);
up=(direction^up)^direction;
up.normalize();
osg::ref_ptr<osg::TexGenNode>texgenNode=new osg::TexGenNode;
texgenNode->setTextureUnit(textureUnit);
osg::ref_ptr<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.0,100));
group->addChild(texgenNode.get());
return group.get();
}
void main()
{
osgViewer::Viewer viewer;
osg::Vec3 center(0.0f,0.0f,0.0f);
float radius=50.0f;
osg::ref_ptr<osg::Group >root=new osg::Group ();
osg::ref_ptr<osg::Node >glider=osgDB::readNodeFile("glider.osg");
if(glider.get())
{
const osg::BoundingSphere& bs=glider->getBound ();
float size=radius/bs.radius()*0.3f;
}
root->addChild(glider.get());
root->setStateSet (createSpotLightDecoratorState(0,1));
root->addChild (creatSpotlightNode(osg::Vec3(0.0f,0.0f,0.0f),osg::Vec3(0.0f,1.0f,1.0f),60.0f,0,1));
osgUtil::Optimizer optimizer;
optimizer.optimize (root.get() );
viewer.setSceneData(root.get());
viewer.setCameraManipulator(new TrainCamera());
viewer.run();
}
上面的TrainCamera设置的是一个运动的视点。。 |
|