查看: 2295|回复: 5

求教圆柱体的法线问题

[复制链接]

该用户从未签到

发表于 2010-11-30 11:33:15 | 显示全部楼层 |阅读模式
本帖最后由 lurena 于 2010-11-30 11:36 编辑

file:///c://1.jpgfile:///c://2.jpg  右边的圆柱明显好很多,细分程度是一样的.是法线的问题吗?
1.jpg
2.jpg

该用户从未签到

 楼主| 发表于 2010-11-30 11:43:52 | 显示全部楼层
这是左边圆柱法线的计算过程
osg::ref_ptr<osg::Vec3Array> normal=new osg::Vec3Array();
        for(i = 0; i < gemesh.nNumFaces; i++)
        {
                //创建三角形定点索引数组,指定绘图基元为三角形,顺序为逆时针
                osg::ref_ptr<osg:rawElementsUInt> triangle =new osg::DrawElementsUInt(osg:rimitiveSet::TRIANGLES,0);
                int verIndex1=gemesh.faces[i].v1;triangle->push_back(verIndex1);
                int verIndex2=gemesh.faces[i].v2;triangle->push_back(verIndex2);
                int verIndex3=gemesh.faces[i].v3;triangle->push_back(verIndex3);       
                //添加几何体
                geometry->addPrimitiveSet(triangle.get());
                //计算法线
                Vec3 vertex1(gemesh.verts[verIndex1].x,gemesh.verts[verIndex1].y,gemesh.verts[verIndex1].z);
                Vec3 vertex2(gemesh.verts[verIndex2].x,gemesh.verts[verIndex2].y,gemesh.verts[verIndex2].z);
                Vec3 vertex3(gemesh.verts[verIndex3].x,gemesh.verts[verIndex3].y,gemesh.verts[verIndex3].z);
                Vec3 n = Vec3(vertex3 - vertex2) ^ Vec3(vertex1 - vertex2);
                n.normalize();
                normal->push_back(n);
        }
        geometry->setNormalArray(normal);
        geometry->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);

该用户从未签到

 楼主| 发表于 2010-11-30 11:46:50 | 显示全部楼层
这是右边圆柱(osg::cylinder)的绘制过程
void DrawShapeVisitor::drawCylinderBody(unsigned int numSegments, float radius, float height)
{
    const float angleDelta = 2.0f*osg:I/(float)numSegments;
    const float texCoordDelta = 1.0f/(float)numSegments;
   
    const float r = radius;
    const float h = height;
   
    float basez = -h*0.5f;
    float topz = h*0.5f;
   
    float angle = 0.0f;
    float texCoord = 0.0f;
   
    bool drawFrontFace = _hints ? _hints->getCreateFrontFace() : true;
    bool drawBackFace = _hints ? _hints->getCreateBackFace() : false;
   
    // The only difference between the font & back face loops is that the
    //  normals are inverted and the order of the vertex pairs is reversed.
    //  The code is mostly duplicated in order to hoist the back/front face
    //  test out of the loop for efficiency

    GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter();

    gl.Begin(GL_QUAD_STRIP);

    if (drawFrontFace) {

      for(unsigned int bodyi=0;
          bodyi<numSegments;
          ++bodyi,angle+=angleDelta,texCoord+=texCoordDelta)
      {
          float c = cosf(angle);
          float s = sinf(angle);
  
          gl.Normal3f(c,s,0.0f);
  
          gl.TexCoord2f(texCoord,1.0f);
          gl.Vertex3f(c*r,s*r,topz);
  
          gl.TexCoord2f(texCoord,0.0f);
          gl.Vertex3f(c*r,s*r,basez);
      }
  
      // do last point by hand to ensure no round off errors.
      gl.Normal3f(1.0f,0.0f,0.0f);
  
      gl.TexCoord2f(1.0f,1.0f);
      gl.Vertex3f(r,0.0f,topz);
  
      gl.TexCoord2f(1.0f,0.0f);
      gl.Vertex3f(r,0.0f,basez);
    }
   
    if (drawBackFace) {
      for(unsigned int bodyi=0;
          bodyi<numSegments;
          ++bodyi,angle+=angleDelta,texCoord+=texCoordDelta)
      {
          float c = cosf(angle);
          float s = sinf(angle);
  
          gl.Normal3f(-c,-s,0.0f);
  
          gl.TexCoord2f(texCoord,0.0f);
          gl.Vertex3f(c*r,s*r,basez);

          gl.TexCoord2f(texCoord,1.0f);
          gl.Vertex3f(c*r,s*r,topz);
      }
  
      // do last point by hand to ensure no round off errors.
      gl.Normal3f(-1.0f,0.0f,0.0f);
  
      gl.TexCoord2f(1.0f,0.0f);
      gl.Vertex3f(r,0.0f,basez);
  
      gl.TexCoord2f(1.0f,1.0f);
      gl.Vertex3f(r,0.0f,topz);
    }

    gl.End();
}

该用户从未签到

发表于 2010-12-2 09:50:09 | 显示全部楼层
主要的区别就在法线上,您可以使用SmoothingVisitor来自动生成法线

该用户从未签到

 楼主| 发表于 2010-12-13 15:18:27 | 显示全部楼层
谢谢指点,确实是法线的问题。将法线方向设成顶点棱线上,不应该设在面上。 2010-12-13_151703.png

该用户从未签到

发表于 2011-10-21 09:45:25 | 显示全部楼层
回复 5# lurena
您的意思是按照逐个顶点来设置法线。即采用osg::Geometry::BIND_PER_VERTEX的方式。?是吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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