查看: 3207|回复: 12

OSG包围球的问题

[复制链接]

该用户从未签到

发表于 2011-5-30 11:49:37 | 显示全部楼层 |阅读模式
由于OSG的包围盒的6幅图片拼接不是很好做,于是决定采用包围球的办法。在osghangglide例子里的sky.cpp文件有一个包围球的做法。有些不太明白。
tcoords[ci][0] = (float)j/18.0; tcoords[ci][1] = (float)i/(float)(nlev-1);这两句应该是创建纹理坐标的,可是不知道原理是什么。
还有就是不想使用它所设定的颜色,想用一张图片来设置纹理,把所有设置颜色的语句注释掉,关联一张天空的图片,可是运行出来球面是白色的,希望高手指点一下。

该用户从未签到

发表于 2011-5-30 14:37:17 | 显示全部楼层
简单来说就是绘制一个球然后设置它的纹理坐标和渐变颜色数组,您可以在此基础上进行修改

该用户从未签到

 楼主| 发表于 2011-5-30 15:30:41 | 显示全部楼层
对啊,可是我看到OPENGL中球面纹理的坐标是:U = (tan-1(X/Z)2*pi)+1/2;V=(arcsin(Y)/pi)+1/2,跟这里的不一样。
另外,只把
Texture2D *tex = new Texture2D;
tex->setImage(osgDB::readImageFile("Images/white.rgb"));中图片改了,生成的颜色数组删除了,为什么纹理不是贴的图片?

该用户从未签到

 楼主| 发表于 2011-5-30 15:39:47 | 显示全部楼层
再问一下,该使用哪种纹理映射方式?

该用户从未签到

发表于 2011-5-30 16:38:21 | 显示全部楼层
我想您还是给出完整的信息比较好,不要一段一段地提供线索,让别人好像RPG解谜一样……既然您打算直接计算球面的纹理坐标,那么自然Texture2D就可以了

该用户从未签到

 楼主| 发表于 2011-5-30 18:42:53 | 显示全部楼层
我弄懂了例子里纹理坐标的算法了。
下面是部分代码,前面省略顶点坐标的计算和纹理坐标的计算,从绑定坐标开始。
    geom->setVertexArray( &coords );//设置顶点坐标
    geom->setTexCoordArray( 0, &tcoords );//设置纹理坐标
    osg::ref_ptr<osg::Image> image = new osg::Image;
      image->setFileName("sky1.jpg");
      osg::ref_ptr<osg::Texture2D> tex = new Texture2D;
     tex->setImage(image.get());

    osg::ref_ptr<osg::StateSet> dstate = new StateSet;
    dstate->setTextureAttributeAndModes(0, tex);
    dstate->setTextureAttribute(0, new TexEnv );
    dstate->setMode( GL_LIGHTING, StateAttribute::OFF );
    dstate->setMode( GL_CULL_FACE, StateAttribute::ON );   

    // clear the depth to the far plane.
    osg::ref_ptr<osg:epth> depth = new osg::Depth;
    depth->setFunction(osg::Depth::ALWAYS);
    depth->setRange(1.0,1.0);   
    dstate->setAttributeAndModes(depth,StateAttribute::ON );

    dstate->setRenderBinDetails(-2,"RenderBin");

    geom->setStateSet( dstate );

    Geode *geode = new Geode;
    geode->addDrawable( geom );

    geode->setName( "Sky" );
这段是对设置纹理有用的代码吧

该用户从未签到

发表于 2011-5-31 08:28:41 | 显示全部楼层
这段代码没什么特别的地方,我不知道您要做什么

该用户从未签到

 楼主| 发表于 2011-5-31 19:05:40 | 显示全部楼层
把sky1.jpg的图片当成纹理贴在半球上,但是效果是没有这个贴图,不知道问题出在哪了

该用户从未签到

发表于 2011-6-1 08:29:53 | 显示全部楼层
通常可能就是您的纹理坐标设置有误

该用户从未签到

 楼主| 发表于 2011-6-1 09:51:37 | 显示全部楼层
源程序获取坐标的程序我没有改动。
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 = 20.0f;
    int nlev = sizeof( lev )/sizeof(float);
   osg::ref_ptr<osg::Geometry> geom = new Geometry;

    Vec3Array& coords = *(new Vec3Array(19*nlev));   //顶点数组
   Vec2Array& tcoords = *(new Vec2Array(19*nlev));  //纹理坐标数组      
    int ci = 0;
    for( i = 0; i < nlev; i++ )
    {
        for( j = 0; j <= 18; j++ )
        {
                        //转换为角度
            alpha = osg:egreesToRadians(lev[i]);
            theta = osg::DegreesToRadians((float)(j*20));
                        //计算顶点的alpha,theta角
            x = radius * cosf( alpha ) * cosf( theta );
            y = radius * cosf( alpha ) * -sinf( theta );
            z = radius * sinf( 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++;
        }
    }

另外问一句,下面这段程序是做什么的,没看懂
for( i = 0; i < nlev-1; i++ )
    {
        DrawElementsUShort* drawElements = new DrawElementsUShort(PrimitiveSet::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);
    }

该用户从未签到

发表于 2012-7-11 15:12:54 | 显示全部楼层
可能和你天空贴图的路径有关,没有影射上系统文件路径,把“sky1.jpg”改为完整图片路径再试试。

该用户从未签到

发表于 2012-7-11 23:29:43 | 显示全部楼层
猜测,jpg文件没有读入……

该用户从未签到

发表于 2012-7-12 09:48:23 | 显示全部楼层
估计你图片没有复制在目录下!用绝对路径试试
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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