奇数访问违反读取错误/ gldrawarray使用

Odd access violation reading error / glDrawArrays usage

本文关键字:gldrawarray 使用 取错误 反读 访问      更新时间:2023-10-16

我不确定这是否属于这里或在图形编程.....我得到了一个非常烦人的访问违反读取错误,我不知道为什么。我想做的是重构一个关键帧函数(计算两个顶点位置之间的中间位置)。这个函数编译和工作正常

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();

这里函数计算位置并绘制它们。我想做的是事先计算所有位置,将它们存储在顶点数组中,然后绘制它们。如果我尝试删除它并用下面的

替换程序中完全相同部分的这个块
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++;
        }
    }

我得到访问违反错误"未处理的异常在0x01455626在Graphics_template_1.exe: 0xC0000005:访问违反读取位置0xed5243c0"指向第7行

Vec3f pos = v1->pos * (1 - frac) + v2->pos * frac;

,其中两个v在调试器中似乎没有值....直到这一点,函数的行为方式与上面的完全相同,我不明白为什么会这样?

编辑 ------------------------------------------------------------------------------------

感谢Werner发现问题是数组初始化!根据您的建议,我使用std:矢量容器重构了函数,并使用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()更有效率?

感谢您的时间和帮助!

好的,我们来做一个答案。猜测是:

当你不写索引时它会崩溃吗?你查过了吗不是写过索引的结束(覆盖您的其他数据结构)?

你的回复是,你创建了一个数组GLfloat索引[],因为你不知道数组的大小。

最好的(执行)解决方案是提前计算数组大小并适当地创建数组。

GLfloat *indices = new GLfloat[calculated_number_of_elements];
...use array...;
delete [] indices;

还可以创建std::vector:

std::vector<GLfloat> indices(calculated_number_of_elements);

vector还有一个优点是可以动态调整大小