我正在使用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;
在 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 类。 SceneObjects是游戏中可渲染的对象。它们引用TexturedQuad实例并包含有关旋转,平移和缩放的信息。
这是SceneObject中的render方法:
- (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();
}
我强烈感觉我的indices数组结构不正确或者glDrawElements(..)函数调用不正确。
要回答这个问题,请:
非常感谢!
答案 0 :(得分:1)
我对OpenGL和OpenGL ES之间的差异没有经验,但我在代码中没有看到glEnableVertexAttribArray()的任何调用。
OpenGL ES 1.1 docs中的功能可疑不存在,但位于2.0,并且正在Apple's OpenGL ES VBO article中使用(感谢JSPerfUnkn0wn)。
以下是Vertex Buffer Objects和Index Buffer Objects上的其他一些优秀(非ES)教程。
答案 1 :(得分:0)
除非我遗漏了什么,否则你在哪里加载纹理?你正在设置纹理坐标,但我没有看到glBindTexture。我还假设alpha
是有效值。
请参阅清单9-1中的Apple OpenGL ES VBO article,和此OpenGL ES VBO tutorial。