简体   繁体   English

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

[英]OpenGL 3.x: Access violation when using vertex buffer object and glDrawElements(…)

I have trouble rendering some geometry by using a vertex buffer object. 我无法通过使用顶点缓冲区对象来渲染某些几何图形。 I intend to draw a plane of points, so basically one vertex at every discrete position in my space. 我打算绘制一个点平面,因此基本上是在空间中每个离散位置上都有一个顶点。 However, I cannot render that plane, as every time I call glDrawElements(...), application crashes returning an access violation exception. 但是,我无法渲染该平面,因为每次调用glDrawElements(...)时,应用程序都会崩溃,并返回访问冲突异常。 There must be some mistake while initialization, I guess. 我猜初始化时一定有一些错误。

This is what I have so far: 这是我到目前为止的内容:


#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;

When you are using buffer objects, the last parameters in the gl*Pointer and 4th parameter in glDrawElements are no longer addresses in main memory (yours still are!), but offsets into the buffer objects. 使用缓冲区对象时,gl * Pointer中的最后一个参数和glDrawElements中的第4个参数不再是主内存中的地址(您仍然是!),而是偏移到缓冲区对象中。 Make sure to compute these offsets in bytes! 确保以字节为单位计算这些偏移量! The "offsetof" macro is very helpful there. 那里的“ offsetof”宏非常有用。

Look at the second example on this page and compare it to what you did: http://www.opengl.org/wiki/VBO_-_just_examples 查看此页面上的第二个示例,并将其与您所做的操作进行比较: http : //www.opengl.org/wiki/VBO_-_just_examples

And you have one typo: GL_DTREAM_DRAW. 您有一个错字:GL_DTREAM_DRAW。

The method glEnableClientState(...) is deprecated! 不推荐使用方法glEnableClientState(...)! Sorry, for some reason I had overseen that fact. 抱歉,出于某种原因,我监督了这个事实。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM