查看: 1667|回复: 3

对“天空半球贴图接缝问题”的回复

[复制链接]

该用户从未签到

发表于 2011-6-13 22:37:21 | 显示全部楼层 |阅读模式
由于不会在回复里贴图,只好发个新话题了。
我对TexEnv的理解有限,经过各种模式的尝试,发现TexEnv影响到的是纹理的色泽等因素,而对于纹理贴图的方式没有改变,例如,用REPLACE模式依旧如下图:
未命名.JPG
可以看到有很明显的一条接缝。请问是纹理坐标的原因吗?
完整代码如下:class MoveEarthySkyWithEyePointTransform : public osg::Transform
{
public:
    /** Get the transformation matrix which moves from local coords to world coords.*/
    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.preMultTranslate(osg::Vec3(eyePointLocal.x(),eyePointLocal.y(),0.0f));
        }
        return true;
    }    /** Get the transformation matrix which moves from world coords to local coords.*/
    virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
    {
        std::cout<<"computing transform"<<std::endl;
   
        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
        if (cv)
        {
            osg::Vec3 eyePointLocal = cv->getEyeLocal();
            matrix.postMultTranslate(osg::Vec3(-eyePointLocal.x(),-eyePointLocal.y(),0.0f));
        }
        return true;
    }
};osg::ref_ptr<osg::Node> createSky()
{
int i, j;
    float lev[] = { -5, -1.0, 1.0, 15.0, 30.0, 60.0, 90.0  };
float x, y, z;
    float alpha, theta;
    float radius = 150.0f;
    int nlev = sizeof( lev )/sizeof(float); osg::ref_ptr<osg::Geode> geode = new osg::Geode();
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();
//设置顶点、纹理坐标
osg::Vec3Array& coords = *(new osg::Vec3Array(19*nlev));
osg::Vec2Array& tcoords = *(new osg::Vec2Array(19*nlev));
int ci = 0;
    for( i = 0; i < nlev; i++ )
    {
        for( j = 0; j <= 18; j++ )
        {
   //转换为角度
            alpha = osg:egreesToRadians(lev);
            theta = osg::DegreesToRadians((float)(j*20));
   //计算顶点的alpha,theta角
            x = radius * sinf( alpha ) * cosf( theta );
            y = radius * sinf( alpha ) * sinf( theta );
            z = radius * cosf( alpha );   
   //计算从原点到该顶点的矢量
            coords[ci][0] = x;
            coords[ci][1] = y;
            coords[ci][2] = z;
   //纹理坐标
            tcoords[ci][0] = (float)j/18.0;
            tcoords[ci][1] = (float)i/(float)(nlev-1);
   
            ci++;
        }
}
geom->setVertexArray( &coords );//设置顶点坐标
    geom->setTexCoordArray( 0, &tcoords );//设置纹理坐标
//添加图元
  for( i = 0; i < nlev-1; i++ )
    {
  osg::ref_ptr<osg::DrawElementsUShort> drawElements = new osg::DrawElementsUShort(osg:rimitiveSet::TRIANGLE_STRIP);
        drawElements->reserve(38);        for( j = 0; j <= 18; j++ )
        {
            drawElements->push_back((i+1)*19+j);
            drawElements->push_back((i+0)*19+j);
        }
  geom->addPrimitiveSet(drawElements.get());
    }
osg::ref_ptr<osg::TexEnv> te = new osg::TexEnv();
    te->setMode(osg::TexEnv::REPLACE);
   
//设置纹理贴图
  osg::ref_ptr<osg::Image> image = osgDB::readImageFile("sky1.jpg");
osg::ref_ptr<osg::Texture2D> tex = new osg::Texture2D;  
tex->setImage(image.get());
//设置渲染状态
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
stateset->setTextureAttributeAndModes(0,tex.get(),osg::StateAttribute::ON);
stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
    stateset->setMode( GL_CULL_FACE, osg::StateAttribute::ON );
stateset->setTextureAttributeAndModes(0, te.get(), osg::StateAttribute::ON);
//将深度设置为远平面
osg::ref_ptr<osg::Depth> depth = new osg::Depth;
    depth->setFunction(osg::Depth::ALWAYS);
    depth->setRange(1.0,1.0);   
    stateset->setAttributeAndModes(depth,osg::StateAttribute::ON );
//设置渲染顺序
stateset->setRenderBinDetails(-1,"RenderBin");
geom->setStateSet(stateset.get());
//绘制
geode->addDrawable(geom.get());
//设置变换
/*osg::ref_ptr<osg::Transform> transform = new MoveEarthySkyWithEyePointTransform;
transform->setCullingActive(false);
transform->addChild(geode.get());*/
return geode.get();
/*osg::ref_ptr<osg::ClearNode> clearNode = new osg::ClearNode;
clearNode->setRequiresClear(false);
clearNode->addChild(transform.get());*/
//return clearNode.get();
//return transform.get();
} int _tmain(int argc, _TCHAR* argv[])
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
osg::ref_ptr<osg::Group> root = new osg::Group(); osg::ref_ptr<osg::Node> node = createSky();
  root->addChild(node.get());
  osgUtil::Optimizer optimizer;
optimizer.optimize(root.get());
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
return 0;
}

该用户从未签到

发表于 2011-6-14 08:31:43 | 显示全部楼层
在我看起来似乎很明显是您的贴图文件本身制作的不合理,如果这个贴图本身就不能拼接起来的话,那么肯定会看到鲜明的界线,这个是理所当然的

该用户从未签到

 楼主| 发表于 2011-6-14 09:50:30 | 显示全部楼层
就是说不管是那种方式制作天空球,对图片都有要求……只能PS了吗

该用户从未签到

发表于 2011-6-14 13:25:10 | 显示全部楼层
那是必然的,图片边界本身就不合格的话,如何拼接
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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