我正在尝试使用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处的未处理异常:Microsoft C ++异常:内存位置0x0028F1C8处的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]);
但是看起来不正确(http://imgur.com/lxSUMAq)
所以我认为getvertexnormal()存在问题。
顺便说一下,我是这个东西的完全新手。我在片段着色器(GLSL)中进行了所有的phong计算。要在大三角形网格上实现phong着色,这是正确的方法吗?
答案 0 :(得分:0)
您的问题是内存泄漏。
您正在分配内存
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;
或类似的东西。它可以使您的代码更短,更易读,甚至可能更快。