尝试渲染三角形网格(c++)时崩溃



我正在尝试使用GLSL渲染带有Phong着色的三角形网格,这是我指定法线的方法。

void renderWireframe(Mesh *mesh) 
{
    glDepthMask(GL_TRUE);
    glBegin(GL_TRIANGLES);
    for(int i=0; i<mesh->nt; i++) { //nv is the mesh's number of triangles
    int i0 = mesh->triangles[i].vInds[0];
    int i1 = mesh->triangles[i].vInds[1];
    int i2 = mesh->triangles[i].vInds[2];
    //Calculate normals for each vertex
    Vector fv0 = getvertexnormal(mesh, i0);
    Vector fv1 = getvertexnormal(mesh, i1);
    Vector fv2 = getvertexnormal(mesh, i2);
    glNormal3dv((double *)&fv0);
    glVertex3dv((double *)&mesh->vertices[i0]);
    glNormal3dv((double *)&fv1);
    glVertex3dv((double *)&mesh->vertices[i1]);
    glNormal3dv((double *)&fv2);
    glVertex3dv((double *)&mesh->vertices[i2]);
    }
glEnd();
}

getvertexnormal代码如下所示:

Vector getvertexnormal(Mesh *mesh, int vertex){
    int i = mesh->nt; //nt is the mesh's number of triangles
    int *adjface;
    adjface = new int[i]; //array to store adjacent faces
    //Store each triangle which has an intersection with the vertex'th vertex
    int nadjface = 0; 
    Triangle *t = mesh->triangles;
    for (int ix = 0; ix < mesh->nt; ix++){
        if(t[ix].vInds[0] == vertex){
            adjface[nadjface++] = ix;
        }
        else
            if (t[ix].vInds[1] == vertex)
                adjface[nadjface++] = ix;
            else
                if (t[ix].vInds[2] == vertex)
                    adjface[nadjface++] = ix;
    }
    // Average all adjacent triangles normals to get the vertex normal
    Vector norm = {0.0, 0.0, 0.0};
    for (int jx = 0; jx < nadjface; jx++){
        int ixFace = adjface[jx];
        norm.x += mesh->triangles[ixFace].vInds[0];
        norm.y += mesh->triangles[ixFace].vInds[1];
        norm.z += mesh->triangles[ixFace].vInds[2];
    }
    norm.x /= nadjface;
    norm.y /= nadjface;
    norm.z /= nadjface;
    return Normalize(norm);
}

每次我运行这个程序时,它看起来都像是开始渲染,然后在一秒钟后崩溃,并给我一个异常:

"glutglsl.exe中0x7562B727处的未处理异常:内存位置0x0028F1C8处的Microsoft C++异常:std::bad_alloc。"

如果我注释掉getvertexnomral()部分,改为

glNormal3dv((double *)&fv0);
glVertex3dv((double *)&mesh->vertices[i0]);
glNormal3dv((double *)&fv1);
glVertex3dv((double *)&mesh->vertices[i1]);
glNormal3dv((double *)&fv2);
glVertex3dv((double *)&mesh->vertices[i2]);

我写

glNormal3dv((double *)&Normalize(mesh->vertices[i0]));
glVertex3dv((double *)&mesh->vertices[i2]);
glNormal3dv((double *)&Normalize(mesh->vertices[i1]));
glVertex3dv((double *)&mesh->vertices[i1]);
glNormal3dv((double *)&Normalize(mesh->vertices[i2]));
glVertex3dv((double *)&mesh->vertices[i2]); 

但是它看起来不对(https://i.stack.imgur.com/eJthY.jpg)

所以我认为getvertexnormal()有问题。

顺便说一句,我在这方面完全是个新手。我的碎片着色器(GLSL)中有我所有的phong计算。要在大三角形网格上实现phong着色,这是正确的方法吗?

您的问题是内存泄漏。

您正在分配内存

adjface = new int[i];

但你永远不会删除它。new返回的值存储在一个局部变量中,不会复制到任何地方,也不会从函数中返回。因此,内存泄漏会导致内存耗尽和分配错误,因此new会抛出std::bad_alloc

这是C++。不要使用数组;请改用std::vector。或者delete[]


但我认为你并不真的需要一个数组:

Vector getvertexnormal(Mesh *mesh, int vertex) {
    int nadjface = 0; 
    Triangle *t = mesh->triangles;
    Triangle *last = t + (mesh->nt - 1);
    Vector norm = {0.0, 0.0, 0.0};
    for (; t <= last; t++) {
        for (int i = 0; i < 3; i++) {
            if (t->vInds[i] == vertex) {
                nadjface++;
                norm.x += t->vInds[0];
                norm.y += t->vInds[1];
                norm.z += t->vInds[2];
                break;
            }
        }
    }
    return Normalize(norm / nadjface);
}

如果我没有错的话,你可以简单地做

norm += t->vInds;

或者像那样的家庭。它可以使代码更短、更可读,甚至可能更快。

相关内容

  • 没有找到相关文章

最新更新