2010-12-03 43 views
5

我無法通過使用頂點緩衝區對象來渲染某些幾何圖形。我打算繪製一個點的平面,所以基本上我的空間中每個離散位置都有一個頂點。然而,我無法渲染那架飛機,因爲每次我調用glDrawElements(...)時,應用程序崩潰都會返回一個訪問衝突異常。我想,初始化時肯定會出現一些錯誤。OpenGL 3.x:使用頂點緩衝區對象和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; 
+0

請始終提及您要使用哪個版本的OpenGL - 3.x有點模糊。順便說一句,在任何`glVertexAttribPointer`或`glEnableVertexAttribArray`之前創建並綁定頂點數組對象是一種很好的做法。您可能正在使用OpenGL兼容性配置文件,因此您沒有收到錯誤。 – Kos 2010-12-03 20:49:56

+0

夠公平的。我猜3.x有點含糊。我認爲即使是小版本的GL也有很大的不同。所以,目前我正在使用OpenGL 3.3。 – Walter 2010-12-06 00:28:21

回答

0

看看這個頁面上的第二個例子,並將它與你做了什麼:http://www.opengl.org/wiki/VBO_-_just_examples

和你有一個錯字:GL_DTREAM_DRAW 。

+0

看來,我沒有看到樹木。我知道那個頁面,但出於某種原因,我監督了「glEnableClientState(...)」已被棄用的事實!這有點令人尷尬。對不起,打擾你。 – Walter 2010-12-03 09:17:42

+0

是唯一的問題嗎?你的代碼現在工作正常嗎? – Bojan 2010-12-03 09:23:57

0

不推薦使用glEnableClientState(...)方法!對不起,出於某種原因,我監督了這一事實。

6

當您使用緩衝區對象時,gl *指針中的最後一個參數和glDrawElements中的第4個參數不再是主內存中的地址(您仍然是!),而是偏移到緩衝區對象中。確保以字節計算這些偏移量! 「offsetof」宏在那裏非常有用。