|
这是我运行的场景图,我做的是个天空盒子,但是不知道说什么会有一条一条的条带呢?下面是相关代码:
osg::Node* createSkyBox(osg::BoundingSphere bs)
{
osg::StateSet* stateset = new osg::StateSet();
//设置纹理映射方式,指定为替代方式,即纹理中的颜色代替原来的颜色
osg::TexEnv* te = new osg::TexEnv;
te->setMode(osg::TexEnv::REPLACE);
stateset->setTextureAttributeAndModes(0, te, osg::StateAttribute::ON);
//自动生成纹理坐标,反射方式(REFLECTION_MAP)
/*
NORMAL_MAP 标准模式-立方图纹理
REFLECTION_MAP 反射模式-球体纹理
SPHERE_MAP 球体模型-球体纹理
*/
osg::TexGen *tg = new osg::TexGen;
tg->setMode(osg::TexGen::NORMAL_MAP);
stateset->setTextureAttributeAndModes(0, tg, osg::StateAttribute::ON);
// //设置纹理矩阵
osg::TexMat *tm = new osg::TexMat;
stateset->setTextureAttribute(0, tm);
//设置立方图纹理
osg::TextureCubeMap* skymap = readCubeMap();
stateset->setTextureAttributeAndModes(0, skymap, osg::StateAttribute::ON);
stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
stateset->setMode( GL_CULL_FACE, osg::StateAttribute::OFF );
//将深度设置为远平面
osg:epth* depth = new osg::Depth;
depth->setFunction(osg::Depth::ALWAYS);
depth->setRange(1.0,1.0);//远平面
stateset->setAttributeAndModes(depth, osg::StateAttribute::ON);
//设置渲染顺序为-1,先渲染
stateset->setRenderBinDetails(-1,"RenderBin");
// osg::Drawable* drawable = new osg::ShapeDrawable(new osg::Box(bb.center(),bb.width()));
osg::Drawable* drawable = new osg::ShapeDrawable(new osg::Sphere(bs.center(),bs.radius()));
//把球体加入到叶节点
osg::Geode* geode = new osg::Geode;
geode->setCullingActive(false);
geode->setStateSet( stateset );
geode->addDrawable(drawable);
//设置变换
// osg::Transform* transform = new MoveEarthySkyWithEyePointTransform();
// transform->setCullingActive(false);
// transform->addChild(geode);
osg::ClearNode* clearNode = new osg::ClearNode;
clearNode->setRequiresClear(true);
clearNode->setCullCallback(new TexMatCallback(*tm));
// clearNode->addChild(transform);
clearNode->addChild(geode);
return clearNode;
// return transform;
}
其中
struct TexMatCallback:public osg::NodeCallback
{
TexMatCallback(osg::TexMat& tm):_texMat(tm)
{
}
virtual void operator()(osg::Node* node,osg::NodeVisitor* nv)
{
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
if(cv)
{
//得到模型视图矩阵并设置旋转角度
const osg::Matrix& MV = *(cv->getModelViewMatrix());
const osg::Matrix R = osg::Matrix::rotate( osg::DegreesToRadians(112.0f), 0.0f,0.0f,1.0f)*osg::Matrix::rotate( osg::DegreesToRadians(90.0f), 1.0f,0.0f,0.0f);
osg:uat q = MV.getRotate();
const osg::Matrix C = osg::Matrix::rotate( q.inverse() );
//设置纹理矩阵
// _texMat.setMatrix(C);
_texMat.setMatrix( C*R );
}
traverse(node,nv);
}
//纹理矩阵
osg::TexMat& _texMat;
};
//一个变换类,使天空盒绕视点旋转
class MoveEarthySkyWithEyePointTransform : public osg::Transform
{
public:
//局部矩阵计算成世界矩阵
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
{
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
if (cv)
{
osg::Vec3 eyePointLocal = cv->getEyeLocal();
matrix.preMult(osg::Matrix::translate(eyePointLocal));
}
return true;
}
//世界矩阵计算为局部矩阵
virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
{
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
if (cv)
{
osg::Vec3 eyePointLocal = cv->getEyeLocal();
matrix.postMult(osg::Matrix::translate(-eyePointLocal));
}
return true;
}
}; |
-
|