2D游戏和现代OpenGL


10

前概念

好的,到目前为止,我收集的是:

  • 不要使用固定的管道(已弃用或将要弃用)
  • vbos存储“对象模型”(主要是n个顶点数据)
  • vaos描述了如何放置数据,以便绘图调用知道每个vbo的哪一部分是关于哪种顶点信息的(一个vao可以引用多个vbo,相反则有点困难)
  • 每个绘制调用还将顶点数据发送到着色器

我如何看待3D(可选)

有了这些信息,我可以看到使用现代OpenGL绘制3D复杂对象的效果如何。您基本上是将一堆对象模型(可能来自Blender或其他类似软件)加载到具有局部坐标的VBO中,然后只需为对象的每个实例提供不同的着色器参数(偏移量)即可绘制到世界空间。

问题/问题

但是,在2D中,问题和优先级完全不同。您不需要绘制很多复杂的对象,也不需要复杂的投影矩阵,并且着色器和着色器要简单得多。

用现代OpenGL频繁(实际上经常,基本上每帧)绘制变化的几何形状的最佳方法是什么?

在下面的段落中,您可以看到一些问题的想法(圆形和矩形问题),可以更好地识别我感兴趣的更改类型。

我的尝试(可选)

因此,我开始考虑如何处理在屏幕上绘制基本的2D几何:

  • 正方形:[(1, 0), (1, 1), (0, 1), (0, 0)]在局部空间中为正方形的几何图形加载VBO,然后为着色器提供正方形的实际宽度以及世界坐标和颜色信息

冷却,看起来很容易。让我们转到一个圆圈:

  • 一个圆圈:三角形风扇。精度(顶点数)多少?对于小圆圈,精度必须较低,对于错误环,精度必须较高。显然,加载1个VBO可能无法满足所有情况。如果由于圆的大小被调整为更大而需要增加精度怎么办?

不太酷。让我们移动到稍微容易一点的矩形:

  • 矩形:嗯。没有“常规矩形几何体”。您只需要一个宽度/高度比例即可,但是,如果尺寸改变,每个矩形可能会有所不同。

如您所见,事情从那里走下坡路。特别是对于复杂的多边形等等。

无代码政策:P

我只需要一个大概的想法,不需要任何代码,尤其是C或C ++代码。就像这样说:“使用此顶点数据创建一个VBO,然后将其绑定,...”。


我想我理解您的要求,但是您可能想给这个问题更多的指导。现在还不清楚要问什么,这实际上是一个直接原因。
莱索尔(Lysol)2014年

@AidanMueller我不确定您的意思,但是如果您有需要,可以随时提供更多指导。
Shoe

当前最重要的答案是说“您的主要问题似乎是”。这表明不清楚您要问什么。也许您应该在问题末尾总结一下您不知道的内容。毕竟,这是一个问答,不是讨论。
Lysol 2014年

@AidanMueller,我相信不是在这种情况下。它说:“您的主要问题似乎是……”,然后他(她)引用了我发布的问题。实际上表明它足够清晰,可以被引用。同样,该短语也并非表示我的问题不清楚,而是有一个主要问题和另一个次要问题(即:我提出的具体案例的解决方案是什么)。我确实没有看到我当前问题的问题,而且显然答案者也没有这样做,因为我发现两个答案都非常有用而且很明确。
Shoe

您可以使用片段着色器绘制精确的圆。
user253751 '16

Answers:


5

您的主要问题似乎是:

用现代OpenGL频繁(实际上经常,基本上每帧)绘制变化的几何形状的最佳方法是什么?

在大多数情况下,2d和3d OpenGL之间没有太大区别。图形管道具有一个额外的坐标Z,在2d中不会使用太多坐标,仅此而已。

有几种方法可以更改每次绘制的几何形状。

  • 您可以每帧推送CPU提供的新顶点。(有关重复使用缓冲区的一些说明,请参阅/programming/14155615/opengl-updating-vertex-buffer-with-glbufferdata。)

  • 您可以使用绘制现有缓冲区的不同部分glDrawArrays(mode, first, count)。如果动画循环播放,也许您可​​以将具有不同顶点列表的预计算帧放在一个大缓冲区中,并在每帧中绘制缓冲区的适当部分。

  • 您可以将顶点列表与其他数据(例如统一数组或纹理)一起使用。在您的顶点着色器中,读取此数据并适当地应用它。这些只是将数据呈现给GPU的其他惯用法,而且性能可能不会有太大差异。

  • 如果您有许多相同几何的实例(可能受属性影响),则glDrawElementsInstanced()可能会有用

  • 您可以通过算法在顶点,几何或细分曲面着色器中影响顶点列表。如果可以用数学方式描述动画,则可以保持相同的顶点列表,并且每帧仅更改一些着色器制服。

也许您的动画可以表示为纯纹理,所有动画均由cpu逐像素完成,或从磁盘预先渲染。

总的来说,我会说:“计算机速度快,使它工作起来最简单,这可能是通过在每一帧设置新的CPU制造的顶点。然后,看看是否足够。配置电池/ CPU的使用情况首先是内存占用,其次。”

另一个问题解释为:“绘制圆形和矩形的好方法是什么?”

界。

  • 使用镶嵌细分着色器(或几何着色器),可以使几何动态化。

  • 您可以绘制正方形,并且在片段着色器中,半径内仅不透明(alpha = 1.0),半径外仅透明(alpha = 0.0)。然后每次都是像素完美。(使您的正方形顶点-1到+1,在片段着色器中类似,outColor.a = dot(coord.xy, coord.xy) < 1.0 ? 1.0 : 0.0;。也可以稍微平滑边缘,在那里看起来不错...)

  • 例如,您总是可以使用120三角形的风扇。可能足够好。

矩形。

  • 我想您回答了您自己的问题。您的建议会很好!

片段着色器/半径非常整洁,谢谢。关于我回答自己的问题,我认为我不明白你的意思。
Shoe

哦,就像正方形一样,您提到要控制宽度(我认为是均匀的),然后写道:“您只是有一个宽度/高度比例,仅此而已,但是如果尺寸改变,每个矩形可能会有所不同” 。因此,对于矩形,请执行与正方形相同的操作,但是您将需要4个值(x,y,w,h)而不是3个值(x,y,w)。或传入(xlow,xhigh,ylow,yhigh)为四套制服。使用(0,0)至(1,1)输入,足以使顶点着色器执行所需的操作。
大卫范布林克2014年

哦,我知道了,这很有意义。
擦鞋

固定功能管道中的GL_TRIANGLE_FAN等现代GL是否有自动风扇?
约翰·P

5

我不能说是这个领域的专家,在我的游戏项目中,我更多地专注于3D方面,因此通常使用3D方面的东西,我的2D方面非常简单。显然,我的观点是在游戏方面,所以我的2D图形更多的是关于使精灵发条而不是几何。从这个角度来看,

1)正方形和矩形很容易。我在VBO中只有一个1x1盒子,可以用来涂抹所有东西。我使用此“单位框”将MVP矩阵传递给着色器,并且将其与其他缩放比例结合使用以将框缩放到正确的尺寸-如您所知,您可以使用不同的x和y缩放比例。

出于我的目的,我一直在考虑从使用“单位框”过渡到某种粒子引擎再使用blit 2D精灵,但这是另一回事了。

2)我对圆没有太多的工作,我只使用具有特定顶点数的固定VBO。但是我可以想象,我可以进行一些大的调整来影响为该圆绘制的顶点数量。

将VBO数据连接到着色器属性时,我使用glVertexAttribPointer。它具有跨步参数,意在用于交错数据(我使用)。但是也许可以这样使用它:

glVertexAttribPointer(..., n * sizeof(VERTEX_DATA), ...);

...从缓冲区中选择第n个顶点,从而影响为该圆绘制的顶点数量。我可以创建几个具有相同VBO的VAO,并且步幅不同,这会影响绘制圆的顶点数量。我没有尝试过,想。

总的来说,是的,使用VBO等使CPU端的调整变得更加复杂,为什么我一直在研究不同的东西以在GPU端(着色器)进行调整。尽管如此,根据本文,即使您需要大量的CPU方面的“干预”,使用VBO在现代硬件上也更加有效:

http://www.quelsolaar.com/opengl_performance.txt

希望这对您设计和确定方向有帮助。


2
“大步调整,以影响为该圆绘制的顶点数”超级酷!
大卫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.