OpenGL ES - 如何批量渲染具有不同alpha,旋转和比例的500多个粒子? [英] OpenGL ES - How to Batch Render 500+ particles w/ different alphas, rotations, and scales?

查看:190
本文介绍了OpenGL ES - 如何批量渲染具有不同alpha,旋转和比例的500多个粒子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am developing an iOS game that will need to render 500-800 particles at a time. I have learned that it is a good idea to batch render many sprites in OpenGL ES instead of calling glDrawArrays(..) on every sprite in the game in order to be able to render more sprites w/out a drastic reduction in frame rate.

我的问题是:我如何批量渲染500多个粒子,这些粒子都具有不同的alpha,旋转和鳞片,但共享相同的纹理图集?此问题的重点在于每个粒子的不同 alphas 旋转比例

My question is: how do I batch render 500+ particles that all have different alphas, rotations, and scales, but share the same texture atlas? The emphasis of this question is on the different alphas, rotations, and scales for each particle.

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

I realize this question is very similar to How do I draw 1000+ particles (w/ unique rotation, scale, and alpha) in iPhone OpenGL ES particle system without slowing down the game?, however, that question does not address batch rendering. Before I take advantage of vertex buffer objects, I want to understand batch rendering in OpenGL ES w/ unique alphas, rotations, and scales (but with the same texture). Therefore, while I plan on using VBOs eventually, I want to take this approach first.

代码示例将非常受欢迎,如果您使用索引数组作为示例请解释一下索引数组的结构和目的。

Code examples would greatly be appreciated, and if you use an indices array as some examples do, please explain the structure and purpose of the indices array.

编辑我正在使用OpenGL ES 1.1。

EDIT I am using OpenGL ES 1.1.

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

EDIT Below is a code example of how I render each particle in the scene. Assume that they share the same texture and that texture is already bound in OpenGL ES 1.1 before this code executes.

- (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();
}

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

A code alternative to this method would be greatly appreciated!

推荐答案

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

One possibility would be to include those values in a vertex attrib array - I think this is the best option. If you're using OpenGL ES 1.1 instead of 2.0 you're screwed out of this method. Vertex attrib arrays allow you to store values at each vertex in this case you could store the alphas and rotations each in their own attrib array and pass them to the shader with glVertexAttribArray. The shader would then do the rotation transformation and color processing with the alpha.

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

The other option would be to do rotation transformation on the CPU, and then batch particles with a similar alpha values into several draw calls. This version would require a little bit more work and it would not be a single draw call but it would still help to optimize if the shader is not an option.

注意:您链接的问题也推荐阵列解决方案

编辑:鉴于此处您的代码是OpenGL ES 1.0 ,这是使用 glColorPointer 的解决方案:

Given your code here is an OpenGL ES 1.0, here's a solution using 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, ...);

这个解决方案的一个很好的优化是分享每个渲染的缓冲区,这样你就没有了每帧重新分配它们。

A good optimization for this solution would be to share the buffers for each render so you don't have to reallocate them every frame.

这篇关于OpenGL ES - 如何批量渲染具有不同alpha,旋转和比例的500多个粒子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆