2012-01-05 182 views
2

我有我的OpenGL代碼工作,但我試圖提高它的性能有點(想在舊設備上提高一點幀率)。我正在嘗試使用頂點緩衝區對象來做到這一點。OpenGL ES 1.1中的頂點緩衝區對象不工作

我所做的所有代碼都是繪製一系列360個GL_TRIANGLES,並將紋理應用到它們。我將座標和紋理座標交織成一個數據結構。

typedef struct { 
    GLfloat vertex[2]; 
    GLfloat texture[2]; 
    GLfloat padding[4]; 
} TextureVertex2D; 

typedef struct { 
    TextureVertex2D textureVertex[3]; 
} TextureTriangle2D; 

這裏是我的初始化

textureTriangles = (TextureTriangle2D*)malloc(360 * sizeof(TextureTriangle2D)); 

glGenTextures(1, &texture[0]); 
glBindTexture(GL_TEXTURE_2D, texture[0]); 

// This section is the only new code introduced for the VBOs. 
glGenBuffers(1, &buffer[0]); 
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); 
glBufferData(GL_ARRAY_BUFFER, sizeof(TextureTriangle2D)*360, textureTriangles[0].textureVertex[0].vertex, GL_DYNAMIC_DRAW); 
// end new code  

glVertexPointer(2, GL_FLOAT, sizeof(TextureVertex2D), textureTriangles[0].textureVertex[0].vertex); 
glTexCoordPointer(2, GL_FLOAT, sizeof(TextureVertex2D), textureTriangles[0].textureVertex[0].texture); 

/* 
textureTriangles is filled and the texture image is loaded in 
*/ 

相關的部分爲儲蓄實際VBO,我已經嘗試了兩種方法(兩者有相同的結果)

// Option 1 
GLvoid* vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); 
memcpy(vbo_buffer, textureTriangles[0].textureVertex[0].vertex, 360 * sizeof(TextureTriangle2D)); 
glUnmapBufferOES(GL_ARRAY_BUFFER); 

// Option 2 
glBufferSubData(GL_ARRAY_BUFFER, sizeof(TextureVertex2D), 360 * sizeof(TextureTriangle2D), textureTriangles[0].textureVertex[0].vertex); 

然後我結合緩衝

glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); 

最後進行描繪

glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

glDrawArrays(GL_TRIANGLES, 0, 3*360); 

glDisableClientState(GL_VERTEX_ARRAY); 
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

沒有維也納各組織,繪圖工作正常。在我添加上面的VBO代碼後,繪圖不再位於正確的位置(偏移了幾個像素),它鎖定了我的整個應用程序。有任何想法嗎?

+0

在你的'glBufferSubData'第二個參數應是'0'而不是'sizeof(TextureVertex2D)'。但是,無論如何,在更新整個緩衝區時,您應該使用'glBufferData'。 – 2012-01-06 13:37:05

回答

1

當使用VBOs時,gl...Pointer的最後一個參數不是指向包含頂點數據的某個數組的指針,而是指向當前綁定的GL_ARRAY_BUFFER的字節偏移量。所以,你不specifiy你的CPU的頂點數據,你已經複製到緩衝區的地址,但其中的屬性都存儲在這個緩衝區中的數據偏移:

glVertexPointer(2, GL_FLOAT, sizeof(TextureVertex2D), 
    offsetof(TextureVertex2D,vertex)); 
glTexCoordPointer(2, GL_FLOAT, sizeof(TextureVertex2D), 
    offsetof(TextureVertex2D,texture)); 
+0

修復了它。謝謝您的幫助! – 2012-01-06 18:42:31

+0

@RossKimes Upvoting總是讚賞。 – 2012-01-06 18:47:25

0

在這一行:

glBufferData(GL_ARRAY_BUFFER, sizeof(TextureTriangle2D)*360, textureTriangles[0].textureVertex[0].vertex, GL_DYNAMIC_DRAW); 

我想,因爲每個三角形應指定sizeof(TextureTriangle2D)*360*3(在拉伸陣列請求使用GL_TRIANGLES)要求3個頂點座標。

我沒有關於通過3D多的信息座標只使用2座標(我猜的,具有Z固定爲零?),但聲明本身應受在您身邊

我本來期望審查:

typedef struct { 
    GLfloat vertex[3]; 
    GLfloat texture[2]; 
    GLfloat padding[3]; 
} TextureVertex2D; 

但是,這取決於你的引擎。

+0

只使用2個座標就好了,z只會是0(不使用時w是1)。如果你使用3個座標,那麼當然填充只應該是3而不是4(如果需要的話)。我會糾正這一點。 – 2012-01-06 13:33:15

+0

當然,這個尺寸錯誤也需要在他的更新例程中進行更改。 – 2012-01-06 13:38:01

+0

@ChristianRau我不認爲這是問題。就像你說的,z總是等於0(這是我想要的,我只畫2D對象)。 – 2012-01-06 17:05:47