使用OpenGL ES 1.1中的顶点缓冲区对象绘制不起作用

时间:2012-01-05 23:32:40

标签: iphone opengl-es vbo vertex-buffer

我的OpenGL代码正在运行,但我正在努力提高其性能(希望在旧设备上略微提高帧速率)。我正在尝试使用顶点缓冲区对象。

我的所有代码都是绘制一系列应用了纹理的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,绘图工作正常。在我添加上面的VBO代码后,绘图不再位于正确的位置(偏移几个像素),它锁定了我的整个应用程序。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

使用VBO时,gl...Pointer的最后一个参数不是指向包含顶点数据的某个数组的指针,而是指向当前绑定GL_ARRAY_BUFFER的字节偏移量。因此,您没有指定已经复制到缓冲区中的CPU顶点数据的地址,而是指定存储属性的缓冲区数据中的偏移量:

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

答案 1 :(得分:0)

在这一行:

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

我认为你应该指定sizeof(TextureTriangle2D)*360*3,因为每个三角形(在绘图数组请求中使用GL_TRIANGLES)需要3个顶点坐标。

我没有太多关于使用2个坐标传递3D坐标的信息(我猜Z的固定为零?)但是声明本身应该在你身边进行审查

我原以为:

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

但这很大程度上取决于你的发动机。