我正在尝试在 opengl 中为我的 2d 游戏绘制大量的 2d 圆圈。它们的大小相同,质地相同。许多精灵重叠。最快的方法是什么?
我正在制作的效果示例 http://img805.imageshack.us/img805/6379/circles.png
(需要注意的是,黑边只是由于圆圈的扩大爆炸造成的。截屏后不久就被填充了。
目前我正在使用一对带纹理的三角形来制作每个圆圈。我在纹理边缘周围有透明度,以使其看起来像一个圆圈。事实证明,为此使用混合非常慢(并且 z 剔除是不可能的,因为它们被渲染为深度缓冲区的正方形)。相反,我没有使用混合,而是让我的片段着色器丢弃任何 alpha 为 0 的片段。这有效,但这意味着早期 z 是不可能的(因为片段被丢弃)。
速度受到大量透支和 gpu 填充率的限制。绘制圆圈的顺序并不重要(前提是它不会在创建闪烁的帧之间发生变化),所以我一直在努力确保屏幕上的每个像素只能写入一次。
我通过使用深度缓冲区尝试了这一点。在每一帧开始时,它被清除为 1.0f。然后,当绘制一个圆圈时,它会将深度缓冲区的那部分更改为 0.0f。当通常在那里绘制另一个圆时,它不是因为新圆的 az 也为 0.0f。这不小于深度缓冲区中当前存在的 0.0f,因此它不会被绘制。这有效,并且应该减少必须绘制的像素数量。然而; 奇怪的是它并没有更快。我已经问过一个关于这种行为的问题(当点具有相同的深度时,opengl 深度缓冲区很慢)并且建议是使用相等的 z 值时 z 剔除没有被加速。
相反,我必须给我所有的圈子从 0 向上分开假 z 值。然后,当我使用 glDrawArrays 和默认值 GL_LESS 进行渲染时,由于 z 剔除,我们正确地获得了速度提升(尽管早期 z 是不可能的,因为碎片被丢弃以使圆圈成为可能)。然而,这并不理想,因为我不得不为 2d 游戏添加大量与 z 相关的代码,而这根本不需要它(如果可能的话,不传递 z 值会更快)。然而,这是我目前找到的最快的方式。
最后我尝试使用模板缓冲区,这里我使用
glStencilFunc(GL_EQUAL, 0, 1);
glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
模板缓冲区每帧重置为 0。这个想法是在一个像素被绘制到第一次之后。然后在模板缓冲区中将其更改为非零。然后不应再次绘制该像素,从而减少透支量。然而,事实证明,这并不比仅在没有模板缓冲区或深度缓冲区的情况下绘制所有内容快。
人们发现写我正在尝试的最快方法是什么?