OpenGL ES-如何使用不同的字母、旋转和比例批量渲染500多个粒子



我正在开发一款iOS游戏,一次需要渲染500-800个粒子。我了解到,在OpenGL ES中批量渲染多个精灵是一个好主意,而不是在游戏中的每个精灵上调用glDrawArrays(..),以便能够在帧速率大幅降低的情况下渲染更多的精灵。

我的问题是:如何批处理渲染500多个粒子,这些粒子都具有不同的字母、旋转和比例,但共享相同的纹理图谱?这个问题的重点是每个粒子的不同字母旋转尺度

我意识到这个问题与如何在iPhone OpenGL ES粒子系统中绘制1000多个粒子(具有唯一的旋转、缩放和alpha)而不减慢游戏速度非常相似?,然而,这个问题并没有涉及到批处理渲染。在利用顶点缓冲区对象之前,我想了解OpenGL ES中的批处理渲染,它具有唯一的字母、旋转和缩放(但具有相同的纹理)。因此,虽然我计划最终使用VBO,但我想首先采用这种方法。

代码示例将不胜感激,如果您像某些示例那样使用索引数组,请解释索引数组的结构和用途。

编辑我使用的是OpenGL ES 1.1。

EDIT下面是如何渲染场景中每个粒子的代码示例。假设它们共享相同的纹理,并且在执行此代码之前,该纹理已经绑定在OpenGL ES 1.1中。

- (void) render {
    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);
    // glBindTexture(GL_TEXTURE_2D, texture[0]);
    glVertexPointer(2, GL_FLOAT, 0, texturedQuad.vertices);
    glEnableClientState(GL_VERTEX_ARRAY);

    glTexCoordPointer(2, GL_FLOAT, 0, texturedQuad.textureCoords);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glPopMatrix();
}

如果能提供此方法的代码替代方案,我们将不胜感激!

一种可能性是将这些值包含在顶点属性数组中——我认为这是最好的选择。如果您使用的是OpenGL ES 1.1而不是2.0,那么您将无法使用此方法。顶点属性数组允许您在每个顶点存储值。在这种情况下,您可以将每个字母和旋转存储在各自的属性数组中,并将它们传递给具有glVertexAttribArray的着色器。然后着色器将使用alpha进行旋转变换和颜色处理。

另一种选择是在CPU上进行旋转变换,然后将具有类似alpha值的粒子批处理到几个绘制调用中。这个版本需要更多的工作,而且它不会是一个单独的绘制调用,但如果着色器不是一个选项,它仍然有助于优化。

注意:您链接的问题还建议使用阵列解决方案

编辑:如果您的代码是OpenGL ES 1.0,这里有一个使用glColorPointer:的解决方案

// allocate buffers to store an array of all particle data
verticesBuffer = ... 
texCoordBuffer = ...
colorBuffer = ...
for (particle in allParticles)
{
  // Create matrix from rotation
  rotMatrix = matrix(particle.rotation.x, particle.rotation.y, particle.rotation.z)
  // Transform particle by matrix
  verticesBuffer[i] = particle.vertices * rotMatrix
  // copy other data
  texCoordBuffer[i] = particle.texCoords;
  colorBuffer[i] = color(1.0, 1.0, 1.0, particle.alpha);
}
glVertexPointer(verticesBuffer, ...)
glTexCoordPointer(texCoodBuffer, ...)
glColorPointer(colorBuffer, ...)
glDrawArrays(particleCount * 4, ...);

该解决方案的一个好的优化是共享每个渲染的缓冲区,这样就不必在每帧重新分配它们。

相关内容

  • 没有找到相关文章

最新更新