本文介绍了OpenGL 3.x:使用顶点缓冲区对象和glDrawElements(...)时访问冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法通过使用顶点缓冲区对象来渲染某些几何图形.我打算绘制一个点平面,因此基本上是在我空间中每个离散位置上都有一个顶点.但是,我无法渲染该平面,因为每次调用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. 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;

推荐答案

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

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. Make sure to compute these offsets in bytes! The "offsetof" macro is very helpful there.

这篇关于OpenGL 3.x:使用顶点缓冲区对象和glDrawElements(...)时访问冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 13:10