我不确定这是属于这里还是在graphichs编程.....我得到一个非常讨厌的访问违规读取错误,我无法弄清楚为什么。我想要做的是重构一个关键帧功能(计算两个顶点位置之间的中间位置)。这个函数编译并正常工作
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++;
}
}
我收到访问冲突错误“在Graphics_template_1.exe中0x01455626处未处理的异常:0xC0000005:访问冲突读取位置0xed5243c0”指向第7行
Vec3f pos = v1->pos * (1 - frac) + v2->pos * frac;
其中两个Vs似乎在调试器中没有值....直到这一点,函数的行为方式与上面的完全相同,我不明白为什么会发生这种情况?
EDIT ---------------------------------------------- --------------------------------------
感谢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(),对吗?
感谢您的时间和帮助!
答案 0 :(得分:1)
好的,让我们回答一下。猜测是:
当你不写索引时它会崩溃吗?你有没有检查过你 没有写过索引的结尾(覆盖你的其他数据 结构)?
您的回复是,您创建了一个数组GLfloat indices [],因为您事先并不知道数组大小。
最佳(执行)解决方案是提前计算数组大小并合适地创建数组。
GLfloat *indices = new GLfloat[calculated_number_of_elements];
...use array...;
delete [] indices;
更好的是你可以创建一个std :: vector:
std::vector<GLfloat> indices(calculated_number_of_elements);
该向量还具有可以动态调整大小的优势。