c++ - 奇怪的访问冲突读取错误/glDrawArrays 使用

标签 c++ opengl rendering

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

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 数组中,然后绘制它们。 如果我尝试删除它并用以下内容替换程序中完全相同的部分中的这个 bloc

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;

这两个 V 在调试器中似乎没有任何值(value)....到目前为止,该函数的行为方式与上面的完全相同,我不明白为什么会这样?

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

感谢 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() 更有效,对吧?

感谢您的宝贵时间和帮助!

最佳答案

好的,让我们把它作为一个答案。猜测是:

Does it crash when you do not write to indices? Did you check that you are not writing past the end of indices (overwriting your other data structs)?

你的回答是,你创建了一个数组 GLfloat indices[],因为你事先不知道数组的大小。

最佳(性能)解决方案是提前计算数组大小并适本地创建数组。

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

更好的是你可以创建一个 std::vector:

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

vector 还具有可以动态调整大小的优点。

关于c++ - 奇怪的访问冲突读取错误/glDrawArrays 使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8242427/

相关文章:

c++ - 类数据成员不可访问

c++ - SQL Server 2005 和 2012 与 C++ 的兼容性

c++ - 计算着色器 OpenGL 写入纹理

c++ - 什么是适合 opengl 常量的类型名称?

javascript - 为什么我的组件在更改状态后没有重新呈现?

css - 在文本框下方显示跨度

c++复制构造函数中的用户定义成员

c++ - 在 C++ 中摆脱 CString 中的换行符

c++ - fatal error : GL/gl. h: 没有那个文件或目录

2D游戏中Java swing渲染现象