OpenGL 3.x:使用顶点缓冲区对象和glDrawElements(...)时的访问冲突

时间:2010-12-03 06:11:13

标签: opengl opengl-3 vertex-buffer

使用顶点缓冲区对象渲染某些几何体时遇到问题。我打算绘制一个点平面,所以基本上是我空间中每个离散位置的一个顶点。但是,我无法渲染该平面,因为每次调用glDrawElements(...)时,应用程序崩溃都会返回访问冲突异常。我想,初始化时肯定会有一些错误。

这是我到目前为止所做的:


#define SPACE_X 512
#define SPACE_Z 512

typedef struct{
    GLfloat x, y, z; // position
    GLfloat nx, ny, nz; // normals
    GLfloat r, g, b, a; // colors
} Vertex;

typedef struct{
    GLuint i; // index
} Index;

// create vertex buffer
GLuint vertexBufferObject;
glGenBuffers(1, &vertexBufferObject);

// create index buffer
GLuint indexBufferObject;
glGenBuffers(1, &indexBufferObject);

// determine number of vertices / primitives
const int numberOfVertices = SPACE_X * SPACE_Z;
const int numberOfPrimitives = numberOfVertices; // As I'm going to render GL_POINTS, number of primitives is the same as number of vertices

// create vertex array
Vertex* vertexArray = new Vertex[numberOfVertices];

// create index array
Index* indexArray = new Index[numberOfPrimitives];

// create planes (vertex array)
// color of the vertices is red for now
int index = -1;
for(GLfloat x = -SPACE_X / 2; x < SPACE_X / 2; x++) {
    for(GLfloat z = -SPACE_Z / 2; z < SPACE_Z / 2; z++) {
        index++;
        vertexArray[index].x = x;
        vertexArray[index].y = 0.0f;
        vertexArray[index].z = z;
        vertexArray[index].nx = 0.0f;
        vertexArray[index].ny = 0.0f;
        vertexArray[index].nz = 1.0f;
        vertexArray[index].r = 1.0;
        vertexArray[index].g = 0.0;
        vertexArray[index].b = 0.0;
        vertexArray[index].a = 1.0;
    }
}

// bind vertex buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);

// buffer vertex array
glBufferData(GL_ARRAY_BUFFER, numberOfVertices * sizeof(Vertex), vertexArray, GL_DTREAM_DRAW);

// bind vertex buffer again
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);

// enable attrib index 0 (positions)
glEnableVertexAttribArray(0);

// pass positions in
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), vertexArray);

// enable attribute index 1 (normals)
glEnableVertexAttribArray(1);

// pass normals in
glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertexArray[0].nx);

// enable attribute index 2 (colors)
glEnableVertexAttribArray(2);

// pass colors in
glVertexAttribPointer((GLuint)2, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertexArray[0].r);

// create index array
for(GLunit i = 0; i < numberOfPrimitives; i++) {
    indexArray[i].i = i;
}

// bind buffer
glBindBuffer(GL_ELEMENET_ARRAY_BUFFER, indexBufferObject);

// buffer indices
glBufferData(GL_ELEMENET_ARRAY_BUFFER, numberOfPrimitives * sizeof(Index), indexArray, GL_STREAM_DRAW);

// bind buffer again
glBindBuffer(GL_ELEMENET_ARRAY_BUFFER, indexBufferObject);

// AND HERE IT CRASHES!
// draw plane of GL_POINTS
glDrawElements(GL_POINTS, numberOfPrimitives, GL_UNSIGNED_INT, indexArray);

// bind default buffers
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

// delete vertex / index buffers
glDeleteBuffers(1, &vertexBufferObject);
glDeleteBuffers(1, &indexBufferObject);

delete[] vertexArray;
vertexArray = NULL;

delete[] indexArray;
indexArray = NULL;

3 个答案:

答案 0 :(得分:6)

当您使用缓冲区对象时,gl * Pointer中的最后一个参数和glDrawElements中的第4个参数不再是主存储器中的地址(您的仍然是!),但是偏移到缓冲区对象中。确保以字节为单位计算这些偏移量! “offsetof”宏在那里非常有用。

答案 1 :(得分:0)

查看此页面上的第二个示例,并将其与您的行为进行比较:http://www.opengl.org/wiki/VBO_-_just_examples

你有一个拼写错误:GL_DTREAM_DRAW。

答案 2 :(得分:0)

不推荐使用方法glEnableClientState(...)!对不起,出于某种原因我监督了这个事实。