OpenGL ES 1.1顶点缓冲对象不工作



我正在使用OpenGL ES 1.1开发一款iPhone游戏,需要使用顶点缓冲对象来渲染500多个粒子而不会降低性能。

我的游戏能够使用非vbo方法成功地绘制,但现在我已经尝试合并vbo,什么也画不出来了。

请帮我找出我做错了什么,并提供一个正确的例子。

我有一个名为TexturedQuad的类,它由以下内容组成:

// TexturedQuad.h
enum {
    ATTRIB_POSITION,
    ATTRIB_TEXTURE_COORD
 };
@interface TexturedQuad : NSObject {
    GLfloat *textureCoords; // 8 elements for 4 points (u and v)
    GLfloat *vertices;      // 8 elements for 4 points (x and y)
    GLubyte *indices;       // how many elements does this need?
    // vertex buffer array IDs generated using glGenBuffers(..)
    GLuint vertexBufferID;
    GLuint textureCoordBufferID;
    GLuint indexBufferID;
    // ...other ivars
}
// @synthesize in .m file for each property
@property (nonatomic, readwrite) GLfloat *textureCoords;
@property (nonatomic, readwrite) GLfloat *vertices;
@property (nonatomic, readwrite) GLubyte *indices;
@property (nonatomic, readwrite) GLuint vertexBufferID;
@property (nonatomic, readwrite) GLuint textureCoordBufferID;
@property (nonatomic, readwrite) GLuint indexBufferID;
// vertex buffer object methods
- (void) createVertexBuffers;
- (void) createTextureCoordBuffers;
- (void) createIndexBuffer;
在<<p> strong> TexturedQuad。m,创建顶点缓冲区:
- (void) createVertexBuffers {
    glGenBuffers(1, &vertexBufferID);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
}
- (void) createTextureCoordBuffers {
    glGenBuffers(1, &textureCoordBufferID);
    glBindBuffer(GL_ARRAY_BUFFER, textureCoordBufferID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(textureCoords), textureCoords, GL_STATIC_DRAW);
}
- (void) createIndexBuffer {
    glGenBuffers(1, &indexBufferID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * 16, indices, GL_STATIC_DRAW);
}

上面的VBO创建方法由自定义的AtlasLibrary类调用,该类初始化每个TexturedQuad实例。

首先,顶点按以下格式排列:
// bottom left
quad.vertices[0] = xMin;
quad.vertices[1] = yMin;
// bottom right
quad.vertices[2] = xMax;
quad.vertices[3] = yMin;
// top left
quad.vertices[4] = xMin;
quad.vertices[5] = yMax;
// top right
quad.vertices[6] = xMax;
quad.vertices[7] = yMax;
其次,纹理坐标以以下格式排列(翻转以说明OpenGL ES的镜像倾向):
// top left (of texture)
quad.textureCoords[0] = uMin;
quad.textureCoords[1] = vMax;
// top right
quad.textureCoords[2] = uMax;
quad.textureCoords[3] = vMax;
// bottom left
quad.textureCoords[4] = uMin;
quad.textureCoords[5] = vMin;
// bottom right
quad.textureCoords[6] = uMax;
quad.textureCoords[7] = vMin;

…接下来,调用vbo创建方法(在AtlasLibrary中)

[quad createVertexBuffers];
[quad createTextureCoordBuffers];
[quad createIndexBuffer];
现在是肉和土豆。SceneObject类。场景对象是游戏中可渲染的对象。它们引用一个TexturedQuad实例,并包含关于旋转、平移和缩放的信息。

下面是SceneObject中的渲染方法:

- (void) render {
    // binds texture in OpenGL ES if not already bound
    [[AtlasLibrary sharedAtlasLibrary] ensureContainingTextureAtlasIsBoundInOpenGLES:self.containingAtlasKey];
    glPushMatrix();
    glTranslatef(translation.x, translation.y, translation.z);
    glRotatef(rotation.x, 1, 0, 0);
    glRotatef(rotation.y, 0, 1, 0);
    glRotatef(rotation.z, 0, 0, 1);
    glScalef(scale.x, scale.y, scale.z);
    // change alpha
    glColor4f(1.0, 1.0, 1.0, alpha);
    // vertices
    glBindBuffer(GL_ARRAY_BUFFER, texturedQuad.vertexBufferID);
    glVertexAttribPointer(ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT), &texturedQuad.vertices[0]);

    // texture coords
    glBindBuffer(GL_ARRAY_BUFFER, texturedQuad.textureCoordBufferID);
    glVertexAttribPointer(ATTRIB_TEXTURE_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT), &texturedQuad.textureCoords[0]);
    // bind index buffer array
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, texturedQuad.indexBufferID);
    // draw
    glDrawElements(GL_TRIANGLE_STRIP, sizeof(texturedQuad.indices) / sizeof(texturedQuad.indices[0]), GL_UNSIGNED_BYTE, texturedQuad.indices);
    glPopMatrix();
}

我有一种强烈的感觉,要么是我的索引数组结构不正确,要么是glDrawElements(..)函数调用不正确。

要回答这个问题,请:

  • 确定我做错了什么,这会导致OpenGL ES不绘制我的SceneObjects。
  • 提供正确的方法来做我想做的(根据我的框架,请)
  • 提供任何可能有帮助的建议或链接(可选)

非常感谢!

我没有经验的OpenGL和OpenGL ES之间的差异,但我没有看到任何调用glEnableVertexAttribArray()在你的代码。

该函数在OpenGL ES 1.1文档中可疑地缺席,但在2.0中,并且正在Apple的OpenGL ES VBO文章中使用(感谢JSPerfUnkn0wn)。

这里有一些关于顶点缓冲对象和索引缓冲对象的其他好的(虽然,非es)教程。

除非我错过了什么,你在哪里加载纹理?你在设置纹理坐标,但我没有看到glBindTexture。我也假设alpha是一个有效值。

参见Apple OpenGL ES VBO文章,即来自清单9-1,以及本OpenGL ES VBO教程。

最新更新