c++ - 计算顶点法线时出现问题(在 C++ 中,用于 openGL 项目)

标签 c++ opengl vector

我有一个项目,我必须在其中读取 OBJ 文件并使用 GLUT 显示模型。我可以很好地阅读和展示模型,但我无法让法线正常工作。我已将所有面保存在 Faces[] 数组中,该数组包含 3 个 vtx[](= 点)数组,其中 x、y、z 和法线也具有 x、y、z 坐标。我计算对应于每个面的 3 个顶点中的每一个的 2 个 vector ,我得到它们的叉积,我对其进行归一化并将其 x、y、z 坐标添加到法线参数(这样如果有多个对于每个顶点的法线,我们将它们添加到一个类似于所有法 vector 的平均值的东西)然后我再次归一化。当我打印出一些法线坐标以查看发生了什么时,它打印出 0,0,(有些奇怪)作为 x,y,z。无论如何,这是代码。

     for (int i = 0 ; i<triangle_index; i++)
    {
        float ux,uy,uz,vx,vy,vz,nn,nx,ny,nz;

    //get vectors from first vertex of face
        ux= Faces[triangle_index].vtx[1].x - Faces[triangle_index].vtx[0].x ;
        uy= Faces[triangle_index].vtx[1].y - Faces[triangle_index].vtx[0].y ;
        uz= Faces[triangle_index].vtx[1].z - Faces[triangle_index].vtx[0].z ;

        vx= Faces[triangle_index].vtx[2].x - Faces[triangle_index].vtx[0].x ;
        vy= Faces[triangle_index].vtx[2].y - Faces[triangle_index].vtx[0].y ;
        vz= Faces[triangle_index].vtx[2].z - Faces[triangle_index].vtx[0].z ;
   //CrossProduct 
        nx = (uy*vz) - (vy*uz);
        ny = (vx*uz) - (ux*vz);
        nz = (ux*vy) - (uy*vx);
   //Length         
        nn = sqrt((nx*nx)+(ny*ny)+(nz*nz));
   //Normalize                  
        nx = nx/nn;
        ny = ny/nn;
        nz = nz/nn;
    //Save to Vertex.Normal (plus any previous data)
    Faces[triangle_index].vtx[0].norm.x =(Faces[triangle_index].vtx[0].norm.x + nx);
    Faces[triangle_index].vtx[0].norm.y =(Faces[triangle_index].vtx[0].norm.y + ny);
    Faces[triangle_index].vtx[0].norm.z =(Faces[triangle_index].vtx[0].norm.z + nz);

  //get length again 

  nn =  sqrt((Faces[triangle_index].vtx[0].norm.x*Faces[triangle_index].vtx[0].norm.x)+(Faces[triangle_index].vtx[0].norm.y*Faces[triangle_index].vtx[0].norm.y)+(Faces[triangle_index].vtx[0].norm.z*Faces[triangle_index].vtx[0].norm.z));

    //Normalize again

        Faces[triangle_index].vtx[0].norm.x =(Faces[triangle_index].vtx[0].norm.x)/nn;
        Faces[triangle_index].vtx[0].norm.y =(Faces[triangle_index].vtx[0].norm.y)/nn;
        Faces[triangle_index].vtx[0].norm.z =(Faces[triangle_index].vtx[0].norm.z)/nn;

   //---------------Same For Second Vertex of the Same Face---------------------------/

        ux= Faces[triangle_index].vtx[2].x - Faces[triangle_index].vtx[1].x ;
        uy= Faces[triangle_index].vtx[2].y - Faces[triangle_index].vtx[1].y ;
        uz= Faces[triangle_index].vtx[2].z - Faces[triangle_index].vtx[1].z ;

        vx= Faces[triangle_index].vtx[0].x - Faces[triangle_index].vtx[1].x ;
        vy= Faces[triangle_index].vtx[0].y - Faces[triangle_index].vtx[1].y ;
        vz= Faces[triangle_index].vtx[0].z - Faces[triangle_index].vtx[1].z ;

        nx = (uy*vz) - (vy*uz);
        ny = (vx*uz) - (ux*vz);
        nz = (ux*vy) - (uy*vx);

        nn = sqrt((nx*nx)+(ny*ny)+(nz*nz));

        nx = nx/nn;
        ny = ny/nn;
        nz = nz/nn;

        Faces[triangle_index].vtx[1].norm.x =(Faces[triangle_index].vtx[1].norm.x + nx);
        Faces[triangle_index].vtx[1].norm.y =(Faces[triangle_index].vtx[1].norm.y + ny);
        Faces[triangle_index].vtx[1].norm.z =(Faces[triangle_index].vtx[1].norm.z + nz);

    nn =sqrt((Faces[triangle_index].vtx[1].norm.x*Faces[triangle_index].vtx[1].norm.x)+(Faces[triangle_index].vtx[1].norm.y*Faces[triangle_index].vtx[1].norm.y)+(Faces[triangle_index].vtx[1].norm.z*Faces[triangle_index].vtx[1].norm.z));

        Faces[triangle_index].vtx[1].norm.x =(Faces[triangle_index].vtx[1].norm.x)/nn;
        Faces[triangle_index].vtx[1].norm.y =(Faces[triangle_index].vtx[1].norm.y)/nn;
        Faces[triangle_index].vtx[1].norm.z =(Faces[triangle_index].vtx[1].norm.z)/nn;
    //------------------Again for number three--------------------------------
    ux= Faces[triangle_index].vtx[0].x - Faces[triangle_index].vtx[2].x ;
    uy= Faces[triangle_index].vtx[0].y - Faces[triangle_index].vtx[2].y ;
    uz= Faces[triangle_index].vtx[0].z - Faces[triangle_index].vtx[2].z ;

    vx= Faces[triangle_index].vtx[1].x - Faces[triangle_index].vtx[2].x ;
    vy= Faces[triangle_index].vtx[1].y - Faces[triangle_index].vtx[2].y ;
    vz= Faces[triangle_index].vtx[1].z - Faces[triangle_index].vtx[2].z ;

    nx = (uy*vz) - (vy*uz);
    ny = (vx*uz) - (ux*vz);
    nz = (ux*vy) - (uy*vx);

    nn = sqrt((nx*nx)+(ny*ny)+(nz*nz));

    nx = nx/nn;
    ny = ny/nn;
    nz = nz/nn;

    Faces[triangle_index].vtx[2].norm.x =(Faces[triangle_index].vtx[2].norm.x + nx);
    Faces[triangle_index].vtx[2].norm.y =(Faces[triangle_index].vtx[2].norm.y + ny);
    Faces[triangle_index].vtx[2].norm.z =(Faces[triangle_index].vtx[2].norm.z + nz);

    nn =  sqrt((Faces[triangle_index].vtx[2].norm.x*Faces[triangle_index].vtx[2].norm.x)+(Faces[triangle_index].vtx[2].norm.y*Faces[triangle_index].vtx[2].norm.y)+(Faces[triangle_index].vtx[2].norm.z*Faces[triangle_index].vtx[2].norm.z));

    Faces[triangle_index].vtx[2].norm.x =(Faces[triangle_index].vtx[2].norm.x)/nn;
    Faces[triangle_index].vtx[2].norm.y =(Faces[triangle_index].vtx[2].norm.y)/nn;
    Faces[triangle_index].vtx[2].norm.z =(Faces[triangle_index].vtx[2].norm.z)/nn;

   } 

如果我添加这个循环只是为了看看在计算法线之后会发生什么

for (int i =0 ; i<100;i++)
cout << "n "<<  Faces[i].vtx[0].norm.x<< " "<< Faces[i].vtx[0].norm.x <<" "<<  Faces[i].vtx[0].norm.x <<"\n";

我得到 norm.x,y,z 的所有零。 任何人都可以看到代码有什么问题吗?

最佳答案

你正在使用 triangle_index 为你的数组索引无处不在:

    ux= Faces[triangle_index].vtx[1].x - Faces[triangle_index].vtx[0].x ;
    uy= Faces[triangle_index].vtx[1].y - Faces[triangle_index].vtx[0].y ;
    uz= Faces[triangle_index].vtx[1].z - Faces[triangle_index].vtx[0].z ;

我认为您想改用循环索引:

    ux= Faces[i].vtx[1].x - Faces[i].vtx[0].x ;
    uy= Faces[i].vtx[1].y - Faces[i].vtx[0].y ;
    uz= Faces[i].vtx[1].z - Faces[i].vtx[0].z ;

您需要在整个循环中解决这个问题。

另外,为了正确地平均顶点处的法线,您应该只在这个循环中累积它们,并在新的第二个循环中重新归一化它们。即,将这两个步骤分两次进行:

    Faces[i].vtx[0].norm.x += nx;
    Faces[i].vtx[0].norm.y += ny;
    Faces[i].vtx[0].norm.z += nz;

    nn = sqrt( (Faces[i].vtx[0].norm.x*Faces[i].vtx[0].norm.x)
             + (Faces[i].vtx[0].norm.y*Faces[i].vtx[0].norm.y)
             + (Faces[i].vtx[0].norm.z*Faces[i].vtx[0].norm.z) );

    Faces[i].vtx[0].norm.x /= nn;
    Faces[i].vtx[0].norm.y /= nn;
    Faces[i].vtx[0].norm.z /= nn;

这样,与该顶点重合的每个三角形都具有相同的权重。

关于c++ - 计算顶点法线时出现问题(在 C++ 中,用于 openGL 项目),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20485527/

相关文章:

尝试获取点积的 C# 错误

c++ - 错误 C2355 : 'this' : can only be referenced inside non-static member functions or non-static data member initializers

c++ - MySQL C++ 连接器 : undefined reference to `get_driver_instance'

c++ - Windows CE 设备的唯一机器 ID

c++ - 纹理未应用于二维几何体

c++ - 设置 vector of int 指针,指向 int vector 的元素

C++ 程序崩溃

algorithm - 行进立方体算法中的等值

c++ - 如何防止 opengl 绘图拉伸(stretch)到窗口大小?

c++ - 有没有办法使用数组填充 vector ?