2

所以我一直在https://open.gl/上学习 OpenGL 3.3 ,我对一些东西感到非常困惑。

  1. VAO-s。据我了解,它们用于存储glVertexAttribPointer呼叫。
  2. VBO-s。它们存储顶点。所以如果我用多个对象制作东西,我需要为每个对象一个 VBO 吗?
  3. 着色器程序 - 为什么我们需要多个着色器程序,它们到底是做什么的?
  4. 这条线到底做了什么:glBindFragDataLocation(shaderProgram, 0, "outColor");

最重要的是如何将所有这些融入到一个大项目中?VAO-s 究竟用于什么用途?大多数教程只涵盖了使用硬编码顶点绘制一个或 2 个立方体的内容,那么如何管理具有大量对象的场景呢?我已经阅读了这个线程,并对场景管理是如何发生的有了一些了解,但我仍然不知道如何将 OpenGL 的东西连接到这一切。

4

1 回答 1

8

1-是的。VAOs一般存储顶点数组绑定。当您看到您正在执行大量启用、禁用和更改 GPU 状态的调用时,您可以在程序的早期执行所有这些操作,然后使用 VAO 获取绑定和的“快照”什么不是,在那个时间点。稍后,在您的实际绘图调用期间,您需要做的就是VAO再次绑定它以将所有顶点状态设置为它们当时的状态。就像VBOs立即模式如何更快,因为它们一次发送所有顶点,VAOs通过一次更改许多顶点状态来更快地工作。

2-VBO 只是将 ..etc 坐标发送到 GPU 以在屏幕上呈现的另一种glPosition方式glColor。这个想法是,与立即模式不同,您通过gl*Attribute*调用一一发送您的顶点数据,是提前将所有顶点上传到 GPU 并检索它们的位置作为 ID。在渲染时,您只需将 GPU(将VBOid 绑定到类似的东西GL_ARRAY_BUFFER,并用于glVertexAttribPointer指定如何存储顶点数据的详细信息)指向该位置并发出渲染命令。这显然可以通过开销来节省大量时间,因此速度要快得多。

至于VBO每个对象应该有一个,甚至VBO所有对象都应该有一个,这取决于程序员和他们要渲染的对象的结构。毕竟,VBOs它们本身只是你存储在 GPU 中的一堆数据,你通过glVertexAttribPointer调用告诉计算机它们是如何排列的。

3-Shaders 用于定义一个管道 - 一个例程 - 顶点、颜色、法线等在被发送到 GPU 之后会发生什么,直到它们在屏幕上呈现为片段或像素。当您将顶点发送到 GPU 时,它们通常仍然是 3D 坐标,但屏幕是 2D 像素片。仍然存在根据 ProjectionModelView 矩阵(顶点着色器的工作)重新定位这些顶点的过程,然后将 3D 几何(几何着色器)“展平”或光栅化为 2D 平面。然后对展平的 2D 场景(片段着色器)进行着色,最后相应地照亮屏幕上的像素。在 OpenGL 版本 1.5 及以下版本中,您对这些阶段没有太多控制,因为它们都是固定的(因此术语fixed pipeline)。想想你在这些着色器阶段可以做什么,你会发现你可以用它们做很多很棒的事情。例如,在片段着色器中,就在您将片段颜色发送到 GPU 之前,取反颜色的符号并加 1 以使使用该着色器渲染的对象的颜色反转!

至于需要使用多少个着色器,再次由程序员决定是否使用多个着色器。他们可以将所需的所有功能合并到一个大型着色器(超级着色器)中,并使用布尔值打开和关闭这些功能uniforms(通常被认为是一种不好的做法),或者让每个着色器做某件事并根据他们需要什么。

这条线到底是做什么的: glBindFragDataLocation(shaderProgram, 0, "outColor");

这意味着out在片段着色器执行结束时存储在声明的变量“outColor”中的任何内容都将作为最终的主要片段颜色发送到 GPU。

最重要的是如何将所有这些融入到一个大项目中?VAO-s 究竟用于什么用途?大多数教程只涵盖了绘制一个或两个带有硬编码顶点的立方体,那么如何管理具有大量对象的场景呢?我已经阅读了这个线程,并对场景管理是如何发生的有了一些了解,但我仍然不知道如何将 OpenGL 的东西连接到这一切。

他们一起工作,在屏幕上画出漂亮的彩色形状。VBOs 是存储场景顶点的结构(全部以丑陋的方式对齐),VertexAttribPointer调用来告诉 GPU 中的数据VBO是如何排列的,VAOs 提前存储所有这些VertexAttribPointer指令并一次发送它们只需在主循环中的渲染过程中绑定一个,并在屏幕上绘制场景的过程中为您提供更多控制的着色器。

所有这一切一开始听起来会让人不知所措,但通过练习你会习惯的。

于 2015-11-15T15:35:43.200 回答