查看: 2941|回复: 16

法线的问题

[复制链接]

该用户从未签到

发表于 2009-12-2 10:48:52 | 显示全部楼层 |阅读模式
老大 请问要画这样一个几何体 需要几个法线
法线都如何指向???

难死了~~~
无标题.jpg

该用户从未签到

 楼主| 发表于 2009-12-2 10:50:45 | 显示全部楼层
还有 如果我知道 一块地形的 高

x y 可以计算 这要很多三角面片 这么多面片 要怎么设置法线 不会都指向Z轴吧~

该用户从未签到

 楼主| 发表于 2009-12-2 11:00:01 | 显示全部楼层
顺便说一下 法线需要指向内部!

该用户从未签到

发表于 2009-12-2 11:03:50 | 显示全部楼层
可以考虑用osgUtil::SmoothingVisitor自动计算法线。如果需要指向内部的话,不妨在计算完之后把法线数组里的每一个元素都反向一下~~

该用户从未签到

发表于 2009-12-2 20:53:54 | 显示全部楼层
osg源码里面有关于地形法线计算的代码

该用户从未签到

 楼主| 发表于 2009-12-2 22:50:48 | 显示全部楼层
恩 应该去看看 源码~

该用户从未签到

 楼主| 发表于 2009-12-3 10:48:56 | 显示全部楼层
本帖最后由 cooloboy 于 2009-12-3 10:58 编辑

我 看到 湖面之舟 发表的一篇 关于 从文件生成模型的方法 很感兴趣
http://bbs.osgchina.org/viewthre ... &highlight=readdata

但是 我按照他的方法 读入了一个 dem 文件
数据都读入了 没有显示出模型 不知 是否 法线问题~~

代码:
osg::ref_ptr<osg::Geode> ReadData()
{
       osg::ref_ptr<osg::Geode> geode=new osg::Geode;
    // 三维坐标
    osg::ref_ptr<osg::Vec3Array> v=new osg::Vec3Array;

    std::ifstream infile;
    infile.open("data/E312588N100496.dat");

    if(!infile)
    {
        std::cout << "Unable to open datafile";
        exit(1);
    }

    char buffer[32];
    while( infile >> buffer )
    {   
        int i = strlen(buffer);
        if ( i == 5)
        {
            double z = atof(buffer);
            v->push_back(osg::Vec3(x, y, (float)z / 10));
            y = y + terrainFace -> t() / 1024;
            if ( y <= terrainFace -> t() / 1024 ) x = terrainFace -> s() / 512;
        }
        else
        {
            y = 0;
            std::cout << buffer << std::endl;
        }
        memset(buffer, '\0', 32);
    }

    infile.close();


    // 总体面片
   osg::ref_ptr<osg::Geometry> geom3=new osg::Geometry;
    geom3->setVertexArray(v.get());
    // 设置面片类型


    geom3->addPrimitiveSet(new osg:rawElementsUShort());
    // 设置法线
    osgUtil::SmoothingVisitor::smooth(*geom3);
    // 设置颜色
    osg::ref_ptr<osg::Vec4Array> c = new osg::Vec4Array;
      c->push_back( osg::Vec4( 1.f, 1.f, 1.f, 1.f ) );
      geom3->setColorArray( c.get() );
      geom3->setColorBinding( osg::Geometry::BIND_OVERALL );

      geode->addDrawable(geom3.get());
      return geode.get();
}

该用户从未签到

 楼主| 发表于 2009-12-3 11:35:07 | 显示全部楼层
问题 可能出在 geom3->addPrimitiveSet() 了

该用户从未签到

 楼主| 发表于 2009-12-3 12:14:17 | 显示全部楼层
老大 解释 一下  谢谢了

该用户从未签到

发表于 2009-12-3 12:23:17 | 显示全部楼层
抱歉我不太想去解释个人的代码,您大可自己实践一下找出原因~~此外粗略看一下就知道这段代码不全,因为它没有录入任何的图元信息

该用户从未签到

 楼主| 发表于 2009-12-3 22:28:48 | 显示全部楼层
呵呵 可以了 没有加索引

但是 全黑  已经加入了
  // 设置法线
  osgUtil::SmoothingVisitor::smooth(*geom3);

还有 无法贴图

  // 设置纹理坐标
  osg::Vec2Array* texcoords = new osg::Vec2Array(4);
  (*texcoords)[0].set(1.00f,0.0f); // tex coord for vertex 0
  (*texcoords)[1].set(1.00f,1.0f); // tex coord for vertex 1
  (*texcoords)[2].set(0.00f,0.0f); // ""
  (*texcoords)[3].set(0.00f,1.0f); // ""
geom3->setTexCoordArray( 0,texcoords ); 加入就出错
无标题.jpg

该用户从未签到

发表于 2009-12-3 23:08:39 | 显示全部楼层
全黑的话,试着检查一下计算得到的法线,看看是不是都向内;自己写个循环把所有的法线数据都反向一下就可以了。

纹理坐标设置出错的原因,您自己一看便知:您认为这么多顶点坐标只对应四个纹理坐标吗?显然不是吧。一个顶点坐标·必须·对应一个纹理坐标,这是OpenGL和DirectX亘古不变的道理

该用户从未签到

发表于 2009-12-4 10:22:18 | 显示全部楼层
得到法线是空的,可能是设置了顶点索引的原因。我看到SmoothingVisitor对待顶点索引好像有问题。可以跟进去看一看...

该用户从未签到

 楼主| 发表于 2009-12-7 10:56:02 | 显示全部楼层
加入 了 纹理 坐标,但是怎么成了 斑马线???
11.JPG
我得纹理坐标设置是这样的:
for (k =0;k< 511 ; k++){
  for ( j=0; j<1024; j++){
   textcoords->push_back(osg::Vec2(double(k)/511,double(j)/1024));
  }
}

还有 在控制台输出中 最后那句什么意思??
12.JPG

该用户从未签到

发表于 2009-12-7 11:59:35 | 显示全部楼层
OpenGL的输入图像尺寸必须是2的幂次方,例如512x512,1024x1024,2048x2048等;如果不是的话,需要将其转换——这个工作OSG已经为我们完成了。不过对于大场景的构建来说,这个转换过程会损耗不少效率,因此建模师往往需要严格按照规范来进行建模和贴图。

至于您的纹理坐标,我不知道您最后要实现什么功能,也不知道您的顶点是如何排列的,因此不可能判断错误会在哪里~~请您自行排查

该用户从未签到

 楼主| 发表于 2009-12-7 13:25:24 | 显示全部楼层
好啦 哈哈 谢谢

只要将511改为 512 就可以了

该用户从未签到

发表于 2011-6-21 16:56:41 | 显示全部楼层
收获不少
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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