OpenGL ES 渲染性能

发布于 2024-12-12 02:53:49 字数 865 浏览 0 评论 0原文

我有一个关于 OpenGL ES 下渲染性能的简单问题。

假设我正在 iPhone 或 Samsung Galaxy S 等移动设备上渲染一个简单的 2D 粒子系统,假设有 1000 个粒子。

所有粒子都从相同的纹理渲染。 粒子在其生命周期中会缩放和旋转。 我们这里讨论的是 OpenGL ES。

更实用的方法是什么:

1)设置一批顶点并将每个粒子变换到其中(使用CPU进行所需的变换),然后对glDrawArrays进行1次调用以一次绘制所有粒子。

2)使用(伪!)代码绘制每个粒子,如下所示:

glPushMatrix();         
glColor4f(_act_color.r, _act_color.g, _act_color.b, _act_color.a);  
glTranslatef(_pos.x, _pos.y, 0.0f);
glRotatef(_rot, 0, 0, 1);
glVertexPointer(2, GL_FLOAT, sizeof(vertexVT), &verBuf[0].v[0]);
glTexCoordPointer(2, GL_FLOAT, sizeof(vertexVT), &verBuf[0].t[0]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glPopMatrix();  

哪种方式更好。选择第一种方式时,它需要更多的 CPU 能力,但它在所有设备上的行为应该相同。第一种方法的一个缺点是我会得到一些顶点开销,因为我必须在每个粒子之间使用“退化”顶点。

第二种方式是在硬件中进行转换,但是所有 Open GL 突击队在不同平台上的行为方式是否相同?

您对每项实施有何看法?我想展示每种方式的优点和缺点。

I have a simple question concerning the render performance under OpenGL ES.

Lets assume i am rendering a simple 2D particle system, with lets say 1000 particles, on a mobile device like an iPhone or Samsung Galaxy S.

All particles are rendered from the same textures.
Particles get scaled and rotated during their lifecycle.
We are talking about OpenGL ES here.

What is the more practicable way:

1) Setup a batch of vertices and transform each particle into it ( using the CPU to do the required transformation) then do 1 single call to glDrawArrays to draw all particles at once.

2) Draw each single particle using (pseudo!) code like this:

glPushMatrix();         
glColor4f(_act_color.r, _act_color.g, _act_color.b, _act_color.a);  
glTranslatef(_pos.x, _pos.y, 0.0f);
glRotatef(_rot, 0, 0, 1);
glVertexPointer(2, GL_FLOAT, sizeof(vertexVT), &verBuf[0].v[0]);
glTexCoordPointer(2, GL_FLOAT, sizeof(vertexVT), &verBuf[0].t[0]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glPopMatrix();  

Which way is better. When choosing the first way, it requires more CPU power, but it should behave the same on all devices. One withdraw of the first way will be that I get some vertex overhead because I have to use "degenerated" vertices between every particle.

Second way does transformation in HW but will all the Open GL commandos behave the same way on different platforms?

What is your opinion to each implementation? I would like to show up the pros and contras of each way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月下凄凉 2024-12-19 02:53:49

哪种方式更好。

两者都不。 OpenGL 矩阵操作也发生在 CPU 上。每个矩阵-矩阵乘法(即 glRotate、glTranslate、glScale 所做的)都需要 64 次乘法和 16 次加法,同样会消耗 CPU 周期。

您实际上应该做的是实例化。有关详细说明,请参阅本文:http://nukecode .blogspot.com/2011/07/geometry-instancig-for-iphone-wip.html

Which way is better.

Neither. OpenGL matrix manipulation happens on the CPU as well. Every matrix-matrix multiplication -- that is what glRotate, glTranslate, glScale do -- require 64 multiplications and 16 additions, eating away CPU cycles just the same.

What you actually should do is instancing. See this article for a detailed explanation: http://nukecode.blogspot.com/2011/07/geometry-instancig-for-iphone-wip.html

独守阴晴ぅ圆缺 2024-12-19 02:53:49

实际上,第一种方法会更快,因为为每个单独的四边形进行单独的绘制调用非常昂贵。这也意味着您不必为每个四边形发送新矩阵到 GPU,从而节省时间。组合平移和旋转矩阵不需要完整的 4x4 矩阵乘法,您可以采取一些捷径。

如果您打算这样做,只需创建一个 VBO(使用 GL_DYNAMIC_DRAW 因为数据每帧都会更改),您可以将计算出的顶点数据复制到其中。如果你可以在没有旋转的情况下生活,你可以研究点精灵来处理粒子。

Actually, the first way will be faster, since doing a separate draw call for every individual quad is very expensive. It also means that you don't have to send a new matrix to the GPU for every quad, which saves time. And combining a translation and rotation matrix doesn't require a full 4x4 matrix multiplication, you can take some shortcuts there.

If you're going to do it this way, just create a single VBO (using GL_DYNAMIC_DRAW because the data will change every frame), into which you can copy the computed vertex data. And if you can live without the rotation, you could look into point sprites for doing the particles.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文