我正在使用 OpenGL ES 1.1 开发一款 iPhone 游戏。在这个游戏中,我有角色被射击时会发出的血液粒子,因此屏幕上可以同时出现 1000+ 血液粒子。问题是,当我要渲染的粒子超过 500 个时,游戏的帧速率会大幅下降。
目前,每个粒子都使用 glDrawArrays(..) 渲染自身,我知道这是速度减慢的原因。所有粒子共享相同的纹理图集。
那么减少绘制大量粒子造成的速度减慢的最佳选择是什么?以下是我找到的选项:
- 将所有血液粒子分组在一起,并使用单个 glDrawArrays(..) 调用来渲染它们 --如果我使用此方法,是否有办法为每个粒子有自己的旋转和阿尔法?或者使用此方法时所有这些都必须具有相同的旋转?如果我无法渲染具有独特旋转的粒子,那么我就无法使用此选项。
- 在 OpenGL ES 2.0 中使用点 Sprite 。我尚未使用 OpenGL ES 2.0,因为我需要在规定的期限内在 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 和缩放?
任何建设性的建议都会很有帮助,我们将不胜感激!
谢谢!
最佳答案
使用大约 1-10 个纹理,每个纹理由透明背景上的 200 个红血点组成,然后每个纹理绘制大约 3-10 次。然后你就有了数千个点。您以球形图案等方式绘制所有图像 - 分层爆炸。
游戏时你不可能总是与现实做到一一对应。仔细观察一些在旧 Xbox 或 iPad 等上运行的游戏 - 您需要执行一些快捷方式 - 并且完成后它们通常看起来很棒。
关于objective-c - 如何在 iPhone OpenGL ES 粒子系统中绘制 1000 多个粒子(具有独特的旋转、缩放和 Alpha)而不减慢游戏速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7435123/