我正在使用 OpenGL ES 1.1 为 iPhone 开发游戏。在这个游戏中,我有角色在被射击时会发出的血颗粒,因此屏幕上随时可以有1000多个血颗粒。问题是当我要渲染超过 500 个粒子时,游戏的帧速率会急剧下降。
目前,每个粒子都使用glDrawArrays(..)渲染自己,我知道这是速度变慢的原因。所有粒子共享相同的纹理图集。
那么减少绘制许多粒子的速度的最佳选择是什么?以下是我找到的选项:
- 将所有血液粒子组合在一起,并使用一个glDrawArrays(..)调用来渲染它们——如果我使用这种方法,有没有办法让每个粒子都有自己的旋转和 alpha?或者当使用这种方法时,它们是否都必须具有相同的旋转?如果我不能用独特的旋转来渲染粒子,那么我就不能使用这个选项。
- 在 OpenGL ES 2.0 中使用点精灵。 我还没有使用 OpenGL ES 2.0,b/c 我需要在我设定的截止日期之前在 App Store 上发布我的游戏。使用 OpenGL ES 需要初步研究,遗憾的是我没有时间进行。我将在以后的版本中升级到 OpenGL ES 2.0,但首先,我只想使用 1.1。
这是每个粒子本身的渲染。这是我最初的粒子渲染方法,它导致游戏在渲染 500 多个粒子后帧速率显着下降。
// original method: each particle renders itself.
// slow when many particles must be rendered
[[AtlasLibrary sharedAtlasLibrary] ensureContainingTextureAtlasIsBoundInOpenGLES:self.containingAtlasKey];
glPushMatrix();
// translate
glTranslatef(translation.x, translation.y, translation.z);
// rotate
glRotatef(rotation.x, 1, 0, 0);
glRotatef(rotation.y, 0, 1, 0);
glRotatef(rotation.z, 0, 0, 1);
// scale
glScalef(scale.x, scale.y, scale.z);
// alpha
glColor4f(1.0, 1.0, 1.0, alpha);
// load vertices
glVertexPointer(2, GL_FLOAT, 0, texturedQuad.vertices);
glEnableClientState(GL_VERTEX_ARRAY);
// load uv coordinates for texture
glTexCoordPointer(2, GL_FLOAT, 0, texturedQuad.textureCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// render
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
然后我使用了方法 1,但粒子不能使用这种方法(我知道)具有唯一的旋转、缩放或 alpha。
// this is method 1: group all particles and call glDrawArrays(..) once
// declare vertex and uv-coordinate arrays
int numParticles = 2000;
CGFloat *vertices = (CGFloat *) malloc(2 * 6 * numParticles * sizeof(CGFloat));
CGFloat *uvCoordinates = (CGFloat *) malloc (2 * 6 * numParticles * sizeof(CGFloat));
...build vertex arrays based on particle vertices and uv-coordinates.
...this part works fine.
// get ready to render the particles
glPushMatrix();
glLoadIdentity();
// if the particles' texture atlas is not already bound in OpenGL ES, then bind it
[[AtlasLibrary sharedAtlasLibrary] ensureContainingTextureAtlasIsBoundInOpenGLES:((Particle *)[particles objectAtIndex:0]).containingAtlasKey];
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, uvCoordinates);
// render
glDrawArrays(GL_TRIANGLES, 0, vertexIndex);
glPopMatrix();
我将重申我的问题:
如何渲染 1000 多个粒子而不会大幅降低帧速率,并且每个粒子仍然可以具有唯一的旋转、alpha 和缩放?
任何建设性的建议都会非常有帮助,我们将不胜感激!
谢谢!