奇数访问冲突读取错误/ glDrawArrays用法

时间:2011-11-23 12:47:08

标签: c++ opengl rendering

我不确定这是属于这里还是在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(),对吗?

感谢您的时间和帮助!

1 个答案:

答案 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);

该向量还具有可以动态调整大小的优势。