2012-03-17 187 views
4

我想在我的Open GL ES 1.1遊戲中使用頂點緩衝對象(VBOs)來改進我的複雜模型渲染。在閱讀了SO和這篇(http://playcontrol.net/ewing/jibberjabber/opengl_vertex_buffer_object.html)教程的幾篇文章之後,我仍然無法理解VBO以及如何在我的Cheetah 3D導出模型格式下實現它們。有人能給我舉一個實現VBO的例子,並用它來繪製給定數據結構的頂點並解釋語法嗎?我非常感謝任何幫助!iPhone Cheetah 3D OpenGL ES頂點緩衝區對象(VBO)示例

#define body_vertexcount 434 
#define body_polygoncount 780 

// The vertex data is saved in the following format: 
// u0,v0,normalx0,normaly0,normalz0,x0,y0,z0 
float body_vertex[body_vertexcount][8]={ 
{0.03333, 0.00000, -0.68652, -0.51763, 0.51063, 0.40972, -0.25028, -1.31418}, 
{...}, 
{...} 
} 

GLushort body_index[body_polygoncount][3]={ 
{0, 1, 2}, 
{2, 3, 0} 
} 

我在Pro OpenGL ES(Appress)的第9章的幫助下編寫了下面的代碼。我得到EXE_BAD_ACCESS與DrawElements命令,我不知道爲什麼。有人可以擺脫一些光線嗎?謝謝 -

// First thing we do is create/setup the index buffer 
glGenBuffers(1, &bodyIBO); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bodyIBO); 

// For constrast, instead of glBufferSubData and glMapBuffer, 
// we can directly supply the data in one-shot 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, body_polygoncount*sizeof(GLubyte), body_index, GL_STATIC_DRAW); 

// Define our data structure 
int numXYZElements = 3; 
int numNormalElements = 3; 
int numTextureCoordElements = 2; 
long totalXYZBytes; 
long totalNormalBytes; 
long totalTexCoordinateBytes; 
int numBytesPerVertex; 

// Allocate a new buffer 
glGenBuffers(1, &bodyVBO); 

// Bind the buffer object to use 
glBindBuffer(GL_ARRAY_BUFFER, bodyVBO); 

// Tally up the size of the data components 
numBytesPerVertex = numXYZElements; 
numBytesPerVertex += numNormalElements; 
numBytesPerVertex += numTextureCoordElements; 
numBytesPerVertex *= sizeof(GLfloat); 

// Actually allocate memory on the GPU (Data is static here) 
glBufferData(GL_ARRAY_BUFFER, numBytesPerVertex * body_vertexcount, 0, GL_STATIC_DRAW); 

// Upload data to the cache (memory mapping) 
GLubyte *vboBuffer = (GLubyte *)glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); 

// Caclulate the total number of bytes for each data type 
totalXYZBytes = numXYZElements * body_vertexcount * sizeof(GLfloat); 
totalNormalBytes = numNormalElements * body_vertexcount * sizeof(GLfloat); 
totalTexCoordinateBytes = numTextureCoordElements * body_vertexcount * sizeof(GLfloat); 

// Set the total bytes property for the body 
self.bodyTotalBytes = totalXYZBytes + totalNormalBytes + totalTexCoordinateBytes; 

// Setup the copy of the buffer(s) using memcpy() 
memcpy(vboBuffer, body_vertex, self.bodyTotalBytes); 

// Perform the actual copy 
glUnmapBufferOES(GL_ARRAY_BUFFER); 

這裏是哪裏,我發現了異常的繪圖命令:

// Activate the VBOs to draw 
    glBindBuffer(GL_ARRAY_BUFFER, bodyVBO); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bodyIBO); 

    // Setup drawing 
    glMatrixMode(GL_MODELVIEW); 
    glEnable(GL_TEXTURE_2D); 
    glClientActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D,lightGreyInt); 

    // Setup pointers 
    glVertexPointer(3, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 0); 
    glTexCoordPointer(2, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 12); 
    glNormalPointer(GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 24); 

    // Now draw the body 
    glDrawElements(GL_TRIANGLES, body_polygoncount,GL_UNSIGNED_SHORT, (GLvoid*)((char*)NULL)); 
    //glDrawElements(GL_TRIANGLES, body_polygoncount, GL_UNSIGNED_SHORT, nil); 
    //glDrawElements(GL_TRIANGLES,body_polygoncount*3,GL_UNSIGNED_SHORT,body_index); 
+0

我不能相信這是說明這個問題非常好給你,假設你已經知道如何頂點數組和OpenGL的其餘產品(其中你的** **你的OpenGL ES 1.1的遊戲建議提被發現沒有學習資源)。你也可以看[這裏](http://www.songho.ca/opengl/gl_vbo.html),但是從你的問題鏈接的教程看起來是合理的(我只瀏覽了它,雖然)。 – 2012-03-18 15:24:36

+0

你有什麼麻煩?我們不只是爲你編寫代碼。數據結構和語法怎麼樣,你不明白嗎?只要儘可能明確,我們就可以制定出合理的答案。 – user1118321 2012-03-18 15:52:02

+0

我貼我的代碼,我特別有麻煩呈現交織的數據與glDrawElements調用。我得到EXC_BAD_ACCESS,我會很感激一些幫助 - – PhilBot 2012-03-18 19:09:24

回答

3

嗯,首先你的所有索引緩衝區太小,你不只是有body_polygoncount指數,但body_polygoncount * 3。您也搞砸了的類型,因爲他們是短褲,你需要GLushort而不是GLubyte,所以應該是

glBufferData(GL_ELEMENT_ARRAY_BUFFER, body_polygoncount*3*sizeof(GLushort), 
      body_index, GL_STATIC_DRAW); 

然後,你搞砸了你的屬性的偏移量,因爲您的數據第一個包含紋理COORDS,那麼正常的,然後每個頂點的位置,應該是

glVertexPointer(3, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 20); //3rd, after 5*4 byte 
glTexCoordPointer(2, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 0); //1st 
glNormalPointer(GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 8);  //2nd, after 2*4 bytes 

最後,在glDrawElements叫你不給三角形的數量,但件(指數)的數量,所以它應該是

glDrawElements(GL_TRIANGLES, body_polygoncount*3, 
       GL_UNSIGNED_SHORT, (GLvoid*)((char*)NULL)); 

否則你的代碼看起來很合理(當然映射是沒有意義的,你可能只是再次使用glBufferData,但我想你是爲了學習而做的),如果你理解它所做的一切,那就沒有什麼更多了。

但我不知道所有這些錯誤也會發生,如果你剛剛使用客戶端頂點數組沒有VBO,我認爲OpenGL ES 1.1沒有立即模式glBegin/glEnd。所以我想知道爲什麼你的遊戲之前沒有使用VBOs工作,如果你不知道這些錯誤。

+0

謝謝你 - 我看到我的錯誤..現在它的意義。我以前繪製如下:/ /繪製槍 - 渲染和紋理處理槍X // glBindTexture(GL_TEXTURE_2D,lightGreyInt); glVertexPointer(3,GL_FLOAT,sizeof(vertexStruct),&interpolatedVerticesGun [0] [5]); glTexCoordPointer(2,GL_FLOAT,sizeof(vertexStruct),&interpolatedVerticesGun [0] [0]); glNormalPointer(GL_FLOAT,sizeof(vertexStruct),&interpolatedVerticesGun [0] [2]); glDrawElements(GL_TRIANGLES,gun2_polygoncount * 3,GL_UNSIGNED_SHORT,gun2_index); – PhilBot 2012-03-19 03:15:06