我不确定这个问题应该放在这里还是图形编程中......我遇到了一个非常烦人的访问冲突读取错误,而且我无法找出原因。我正在尝试重构一个关键帧函数(计算两个顶点位置之间的中间位置)。这个函数可以编译并正常工作。
glBegin(GL_TRIANGLES);
for(int i = 0; i < numTriangles; i++) {
MD2Triangle* triangle = triangles + i;
for(int j = 0; j < 3; j++) {
MD2Vertex* v1 = frame1->vertices + triangle->vertices[j];
MD2Vertex* v2 = frame2->vertices + triangle->vertices[j];
Vec3f pos = v1->pos * (1 - frac) + v2->pos * frac;
Vec3f normal = v1->normal * (1 - frac) + v2->normal * frac;
if (normal[0] == 0 && normal[1] == 0 && normal[2] == 0) {
normal = Vec3f(0, 0, 1);
}
glNormal3f(normal[0], normal[1], normal[2]);
MD2TexCoord* texCoord = texCoords + triangle->texCoords[j];
glTexCoord2f(texCoord->texCoordX, texCoord->texCoordY);
glVertex3f(pos[0], pos[1], pos[2]);
}
}
glEnd();
这里的函数计算位置并进行绘制。我想要做的是预先计算所有位置,将它们存储在Vertex数组中,然后绘制它们。 如果我尝试删除它,并在程序完全相同的部分用以下代码块替换它:
int vCount = 0;
for(int i = 0; i < numTriangles; i++) {
MD2Triangle* triangle = triangles + i;
for(int j = 0; j < 3; j++) {
MD2Vertex* v1 = frame1->vertices + triangle->vertices[j];
MD2Vertex* v2 = frame2->vertices + triangle->vertices[j];
Vec3f pos = v1->pos * (1 - frac) + v2->pos * frac;
Vec3f normal = v1->normal * (1 - frac) + v2->normal * frac;
if (normal[0] == 0 && normal[1] == 0 && normal[2] == 0) {
normal = Vec3f(0, 0, 1);
}
indices[vCount] = normal[0];
vCount++;
indices[vCount] = normal[1];
vCount++;
indices[vCount] = normal[2];
vCount++;
MD2TexCoord* texCoord = texCoords + triangle->texCoords[j];
indices[vCount] = texCoord->texCoordX;
vCount++;
indices[vCount] = texCoord->texCoordY;
vCount++;
indices[vCount] = pos[0];
vCount++;
indices[vCount] = pos[1];
vCount++;
indices[vCount] = pos[2];
vCount++;
}
}
我在第7行遇到了访问冲突错误,错误信息为“Unhandled exception at 0x01455626 in Graphics_template_1.exe: 0xC0000005: Access violation reading location 0xed5243c0”。
Vec3f pos = v1->pos * (1 - frac) + v2->pos * frac;
在调试器中,两个 V 似乎没有任何值... 直到这一点,该函数的行为与上面的函数完全相同,我不明白为什么会出现这种情况?
编辑------------------------------------------------------------------------------------
感谢 Werner 发现问题是数组初始化!根据您的建议,我使用 std:vector 容器重构了函数,并使用 glDrawArrays 而不是立即模式进行绘图... 但是,性能并没有得到改善,帧率比以前低很多!我是否正确/有效地使用了此函数?这是重构后的绘制函数:
for(int i = 0; i < numTriangles; i++) {
MD2Triangle* triangle = triangles + i;
for(int j = 0; j < 3; j++) {
MD2Vertex* v1 = frame1->vertices + triangle->vertices[j];
MD2Vertex* v2 = frame2->vertices + triangle->vertices[j];
Vec3f pos = v1->pos * (1 - frac) + v2->pos * frac;
Vec3f normal = v1->normal * (1 - frac) + v2->normal * frac;
if (normal[0] == 0 && normal[1] == 0 && normal[2] == 0) {
normal = Vec3f(0, 0, 1);
}
normals.push_back(normal[0]);
normals.push_back(normal[1]);
normals.push_back(normal[2]);
MD2TexCoord* texCoord = texCoords + triangle->texCoords[j];
textCoords.push_back(texCoord->texCoordX);
textCoords.push_back(texCoord->texCoordY);
vertices.push_back(pos[0]);
vertices.push_back(pos[1]);
vertices.push_back(pos[2]);
}
}
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glNormalPointer(GL_FLOAT, 0, &normals[0]);
glTexCoordPointer(2, GL_FLOAT, 0, &textCoords[0]);
glVertexPointer(3, GL_FLOAT, 0, &vertices[0]);
glDrawArrays(GL_TRIANGLES, 0, vertices.size()/3);
glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
vertices.clear();
textCoords.clear();
normals.clear();
我这里做了额外的操作吗?因为这个方法应该比glBegin()/End()更高效,是这样吗?
谢谢你的时间和帮助!
MD2Vertex* v1 = frame1->vertices + triangle->vertices[j];
可能(或v2)导致错误指针。由于我们看不到这行中使用的值是如何产生的,所以我们无法猜测太多,只能说可能有些未初始化。 - PlasmaHHg++ -Wall -g
),并且使用调试器(在Linux上,可以使用gdb
调试器,或者可能还有ddd
作为其前端)来调试你的程序? - Basile StarynkevitchendFrame
和startFrame
中有哪些值? - BЈовић