改进粒子系统OpenGL

时间:2011-07-25 09:40:46

标签: opengl opengl-es

我正在寻找一种提高粒子系统性能的方法,因为它在FPS方面非常昂贵。 这是因为我打电话:

glDrawElements(GL_TRIANGLE_STRIP, mNumberOfIndices,
          GL_UNSIGNED_SHORT, 0);

我为我的应用程序中的每个粒子调用此方法(可能在1000到5000个粒子之间)。请注意,当增加到超过1000个粒子时,我的应用程序开始在FPS中下降。我正在使用VBO:s,但调用此方法时的性能太高。

如何让粒子系统更有效率?

编辑:这是我的粒子系统绘制的东西:

glBindTexture(GL_TEXTURE_2D, textureObject);
glBindBuffer(GL_ARRAY_BUFFER, vboVertexBuffer[0]);
glVertexPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, vboTextureBuffer[0]);
glTexCoordPointer(2, GL_FLOAT, 0, 0); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndexBuffer[0]);

Vector3f partPos;

for (int i = 0; i < m_numParticles; i++) {
    partPos = m_particleList[i].m_pos;          
    glTranslatef(partPos.x, partPos.y, partPos.z);
    glDrawElements(GL_TRIANGLE_STRIP, mNumberOfIndices, 
        GL_UNSIGNED_SHORT, 0);
    gl.glTranslatef(-partPos.x, -partPos.y, -partPos.z);
}

2 个答案:

答案 0 :(得分:6)

你描述它的方式,听起来你每个粒子都有一个自己的VBO。这不是应该怎么做的。将所有粒子放入单个VBO中,并使用单个glDrawElementsglDrawArrays调用一次性绘制所有粒子。或者甚至更好,如果可用:使用实例化。

答案 1 :(得分:1)

在datenwolf所说的内容上稍微扩展一下,只需将所有粒子索引打包到一个索引缓冲区中,并通过单个glDrawElements调用绘制所有粒子。这意味着你不能再使用三角形条带,而是三角形套装,但这不应该是一个太大的问题。

否则,如果您的硬件支持实例化渲染(或更好的实例化数组),您可以通过使用从每个粒子的相应数组中获取的位置和texCoord数据渲染单个粒子n次来实现。然后,您仍然需要在顶点着色器中计算四个角的位置和texCoord数据(假设您为每个粒子绘制一个四边形),就像实例化数组一样,每个实例(粒子)只能获得一个属性。

你也可以使用几何着色器来创建粒子的四边形并只渲染一个单点集,但我认为这可能比实例更慢,考虑到SM4 / GL3硬件也很可能支持实例化。