gpt4 book ai didi

c++ - 2D 粒子系统 - 性能

转载 作者:搜寻专家 更新时间:2023-10-31 00:45:05 24 4
gpt4 key购买 nike

我已经根据 "Bulding an Advanced Particle System" (John van der Burg, Game Developer Magazine, March 2000) 中概述的想法和概念实现了 2D 粒子系统.

现在我想知道我应该从这个系统中获得什么样的性能。我目前正在我的简单(未完成)SDL/OpenGL 平台游戏的上下文中测试它,其中所有粒子每帧都会更新。绘制如下

// Bind Texture
glBindTexture(GL_TEXTURE_2D, *texture);
// for all particles
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex2f(x,y);
glTexCoord2d(1,0); glVertex2f(x+w,y);
glTexCoord2d(1,1); glVertex2f(x+w,y+h);
glTexCoord2d(0,1); glVertex2f(x,y+h);
glEnd();

其中一个纹理用于​​所有粒子。

它平稳地运行到大约 3000 个粒子。老实说,我期待的更多,特别是因为这意味着要在屏幕上与多个系统一起使用。我应该期望平滑显示多少个粒子?

PS:我对 C++ 和 OpenGL 也比较陌生,所以很可能是我在某个地方搞砸了!?

编辑 使用POINT_SPRITE

glEnable(GL_POINT_SPRITE);
glBindTexture(GL_TEXTURE_2D, *texture);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);

// for all particles
glBegin(GL_POINTS);
glPointSize(size);
glVertex2f(x,y);
glEnd();

glDisable( GL_POINT_SPRITE );

完全看不出使用 GL_QUADS 有任何性能差异!?

编辑 使用 VERTEX_ARRAY

// Setup
glEnable (GL_POINT_SPRITE);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
glPointSize(20);

// A big array to hold all the points
const int NumPoints = 2000;
Vector2 ArrayOfPoints[NumPoints];
for (int i = 0; i < NumPoints; i++) {
ArrayOfPoints[i].x = 350 + rand()%201;
ArrayOfPoints[i].y = 350 + rand()%201;
}

// Rendering
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex arrays
glVertexPointer(2, GL_FLOAT, 0, ArrayOfPoints); // Specify data
glDrawArrays(GL_POINTS, 0, NumPoints); // ddraw with points, starting from the 0'th point in my array and draw exactly NumPoints

使用 VA 对上述情况产生了性能差异。然后我尝试了 VBO,但真的没有看到那里的性能差异吗?

最佳答案

我不能说您对该解决方案有多少期望,但有一些方法可以改进它。

首先,通过使用 glBegin() 和 glEnd(),您正在使用即时模式,据我所知,这是最慢的处理方式。此外,它甚至不再出现在当前的 OpenGL 标准中。

对于 OpenGL 2.1

点 Sprite :

您可能想要使用点 Sprite 。我使用它们实现了一个粒子系统并获得了不错的性能(至少就我当时的知识而言)。使用点 Sprite ,您每帧执行的 OpenGL 调用更少,并且您发送到图形卡的数据更少(或者甚至将数据存储在图形卡中,对此不确定)。一个简短的谷歌搜索甚至应该给你一些实现来查看。

顶点数组:

如果使用点 Sprite 没有帮助,您应该考虑结合使用顶点数组和点 Sprite (以节省一点内存)。基本上,您必须将粒子的顶点数据存储在一个数组中。然后,您可以通过使用 GL_VERTEX_ARRAY 作为参数调用 glEnableClientState() 来启用顶点数组支持。之后,调用 glVertexPointer()(参数在 OpenGL 文档中有说明)并调用 glDrawArrays() 来绘制粒子。这会将您的 OpenGL 调用减少到只有少数,而不是每帧 3000 次调用。

适用于 OpenGL 3.3 及以上

实例化:

如果您针对 OpenGL 3.3 或更高版本进行编程,您甚至可以考虑使用实例化来绘制粒子,这应该会进一步加快速度。同样,简短的谷歌搜索会让您看到一些相关代码。

一般情况:

使用 SSE:

此外,更新顶点位置时可能会浪费一些时间。所以,如果你想加快速度,你可以看看使用 SSE 来更新它们。如果操作正确,您将获得很多性能(至少在大量粒子时)

数据布局:

最后,我最近找到了一个关于数组结构 (SoA) 和结构数组 (AoS) 的链接(divergentcoder.com/programming/aos-soa-explorations-part-1,感谢 Ben)。通过粒子系统示例比较了它们如何影响性能。

关于c++ - 2D 粒子系统 - 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7522511/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com