3

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

我的问题是:如何批量渲染 500 多个具有不同 alpha、旋转和比例但共享相同纹理图集的粒子?这个问题的重点是每个粒子的不同 alphasrotationsscales

我意识到这个问题与How do I draw 1000+particles (w/unique rotation, scale, and alpha) in iPhone OpenGL ESparticle system without slowing the game非常相似?,但是,该问题并未涉及批量渲染。在我利用顶点缓冲区对象之前,我想了解 OpenGL ES 中的批处理渲染,带有唯一的 alpha、旋转和缩放(但具有相同的纹理)。因此,虽然我最终计划使用 VBO,但我想首先采用这种方法。

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

编辑我正在使用 OpenGL ES 1.1。

编辑下面是我如何渲染场景中每个粒子的代码示例。假设它们共享相同的纹理,并且在此代码执行之前,纹理已经绑定在 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();
}

非常感谢此方法的替代代码!

4

1 回答 1

7

一种可能性是将这些值包含在顶点属性数组中——我认为这是最好的选择。如果您使用的是 OpenGL ES 1.1 而不是 2.0,那么您将无法使用这种方法。顶点属性数组允许您在每个顶点存储值,在这种情况下,您可以将 alpha 和旋转分别存储在它们自己的属性数组中,并使用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, ...);

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

于 2012-08-03T00:52:06.810 回答