与基本逻辑代码相比,OpenGL glDrawElements() 调用的繁重程度如何?
我打算对我的 OpenGL 程序做一些优化(它不需要优化,但我这样做是为了它).出于好奇,与基本逻辑代码相比,OpenGL 绘图函数的成本有多高?目前,我正在开始一个游戏,其中屏幕上布满了正方形,以表示 2D 块状景观.这意味着正方形(两个三角形)的绘制调用被多次调用.目前,我打算添加一些代码来查看当前帧中块的位置,并将它们组合在一起.例如,如果有一列高 7 个块,而不是执行 7 个单独的 drawBlock() 函数(其中包含 glDrawElements() 调用),我可以调用一个函数,绘制一个 1 x 7 的矩形,等等打开,整个屏幕.
I'm planning to do some optimization on my OpenGL program (it doesn't need optimizing, but I'm doing it for the sake of it). Out of curiosity, how expensive are OpenGL drawing functions compared to basic logic code? At the moment, I'm making the start of a game where the screen is filled with squares, to represent a 2D blocky landscape. This means that the draw call for a square(two triangles) is called many times. At the moment, I'm planning to add in some code that looks at the positioning of blocks in the current frame, and groups them together. For example, if there is a column that is 7 blocks high, instead of doing 7 separate drawBlock() functions (which contain the glDrawElements() calls) I could call one function, that draws a rectangle that is 1 x 7, and so on, throughout the screen.
如果计算绘制内容的代码实际上比单独绘制块占用的 CPU 多,我不会费心这样做.
I won't bother doing this if the code that calculates what to draw, actually uses up more of the CPU than just drawing the blocks individually would.
推荐答案
glDrawElements
(或任何其他OpenGL 渲染命令) 无法真正估计.这是因为它的成本在很大程度上取决于您在绘制调用之间更改的 OpenGL 状态.调用 OpenGL 状态更改函数(基本上,不是某种形式的 glGet 或某种形式的 glDraw 的任何 OpenGL 函数)的成本将相对较快.但它会使下一次绘制调用变慢.
The cost of glDrawElements
(or any other OpenGL rendering command) cannot really be estimated. This is because its cost depends a great deal on what OpenGL state you changed between draw calls. The cost of calling an OpenGL state changing function (basically, any OpenGL function that isn't a glGet of some form or a glDraw of some form) will be relatively quick. But it will make the next draw call slower.
有关 OpenGL 性能的此视频 显示了绘制时哪些状态更改的成本更高相对于其它的.真正精彩的部分在大约 31 分钟后开始.
This video on OpenGL performance shows which state changes are more costly at draw time than others. The really good part starts around 31 minutes in.
如果您在绘制调用之间没有更改任何 OpenGL 状态,则绘制调用相对较快.不同的状态对绘制调用有不同的影响.从最快到最慢(根据上面 NVIDIA 的介绍,请谨慎对待):
Draw calls are relatively fast if you haven't changed any OpenGL state between draw calls. Different pieces of state have different effects on draw calls. From fastest to slowest (according to NVIDIA's presentation above, so take it with a grain of salt):
- 非 UBO 制服更新
- 顶点缓冲区绑定(不改变格式)
- UBO 绑定
- 顶点格式变化
- 纹理绑定
- 片段后处理状态变化
- 着色器程序更改
- 渲染目标开关
- Non-UBO uniform updates
- Vertex buffer bindings (without changing formats)
- UBO binding
- Vertex format changes
- Texture bindings
- Fragment post-processing state changes
- Shader program changes
- Render target switches
现在,绘制调用将比基本逻辑"更昂贵.它们并不便宜,即使它们之间没有状态变化.如果效率对您的代码很重要,那么将您的方块分组是个好主意.
Now, a draw call will be more expensive than "basic logic". They're not cheap, even without state changes between them. If efficiency is important to your code, then grouping your squares is a good idea.
相关文章