在现代 opengl 中绘制基本形状,哪种方法更好?

Drawing basic shapes in mordern opengl, which approach is better?

  1. 在 GPU 中预分配一个顶点缓冲区,然后填充顶点数据,然后绘制它们以复制传统的 opengl 函数,如 glVertex2fglNormal2f 等,并用它们绘制形状.

  2. 在程序开始时将所有原始形状的顶点数据一次发送到GPU,然后在绘制形状时在顶点着色器中绘制适当的部分。

这些是我能想到的所有方法,但我不确定这两种方法中的哪一种方法是最佳的。 游戏和游戏引擎是否使用类似的方法?或者有更好的方法吗?

你的两种方法比你假装的更相似。它们都“在 GPU 上预分配一个缓冲区”,都“用数据填充它”,并且都有一个顶点着色器,该着色器将使用统一提供的 MVP 矩阵转换数据。

到目前为止,你的两种方法之间的唯一区别似乎是第一种方法每帧上传你的顶点,而第二种方法只上传一次。

如果您的模型确实是静态的——那么请务必采用第二种方法。如果您有某种无法在顶点着色器中完成的动画(例如,您正在绘制一个随着 window 尺寸变化而回流的 GUI),那么第二种方法根本不适用。

@CheeseMan69: How would your shapes move if the buffer isn't dynamic?

@YakovGalka I'll transform them with a matrix in the vertex shader

我猜你想象在你的缓冲区中有一个基元,然后每帧多次调用 glUniformglDrawArrays?那确实会很慢。您实际上将为每个基元提交不同的 MVP 矩阵。根据经验,您希望通过一次 OpenGL 调用绘制许多图元。为此,您需要将矩阵移动到 UBO、SSBO 或实例化顶点属性。然而,与首先提交每个基元的正确顶点相比,MVP 矩阵将占用更多的带宽和计算。