2012-01-05 154 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