OpenGL中的VBO到底是什么?

OpenGL中的VBO到底是什么?,opengl,glsl,vbo,opengl-3,opengl-4,Opengl,Glsl,Vbo,Opengl 3,Opengl 4,我正在努力理解OpenGL背后的理论,目前我正在学习VBOs 这就是我到目前为止所理解的:当我们声明一系列顶点时,比如说形成三角形基本体的3个顶点,我们基本上不存储它们,它们只是在代码中声明的 但是,如果我们想将它们存储在某个地方,我们可以使用VBO来存储这些顶点的定义。并且,通过相同的VBO,我们将所有顶点信息发送到顶点着色器(这是一组代码)。现在,VBO位于GPU中,所以当我们调用VBO时,我们基本上将所有信息存储在GPU的内存中。然后作为管道渲染过程一部分的顶点着色器“进入”GPU内存,“

我正在努力理解OpenGL背后的理论,目前我正在学习VBOs

这就是我到目前为止所理解的:当我们声明一系列顶点时,比如说形成三角形基本体的3个顶点,我们基本上不存储它们,它们只是在代码中声明的

但是,如果我们想将它们存储在某个地方,我们可以使用VBO来存储这些顶点的定义。并且,通过相同的VBO,我们将所有顶点信息发送到顶点着色器(这是一组代码)。现在,VBO位于GPU中,所以当我们调用VBO时,我们基本上将所有信息存储在GPU的内存中。然后作为管道渲染过程一部分的顶点着色器“进入”GPU内存,“查看”VBO并检索所有信息。换句话说,VBO存储顶点数据(三角形顶点)并将其发送到顶点着色器

因此,VBO->将信息发送到->顶点着色器

这是正确的吗?我想确定这是否是正确的解释,因为我发现自己在屏幕上画三角形,有时是由许多三角形组成的字母,其中包含一系列代码和函数,我基本上是通过记忆学习的,但并不真正理解它们的作用

要分解它:

//我在这里声明VBO
无符号整数VBO;
//我们有1个VBO,所以我们为它生成一个ID,这个ID是:GL\u ARRAY\u BUFFER
glGenBuffers(1和VBO)
//GL_ARRAY_BUFFER是VBO的ID,我们将把它绑定到VBO本身
glBindBuffer(GL_数组_缓冲区,VBO)
//这里的一堆信息基本上是这样的:我想获取顶点数据(
//我声明为浮点的三角形)并将其发送到VBO的ID,即
//GL\u ARRAY\u BUFFER,然后我想指定顶点的大小
//数据、顶点数据本身和“静态绘制”内容
glBufferData(…)。
完成所有这些操作后,VBO现在包含其中的所有顶点数据。我们告诉VBO,现在把它发送到顶点着色器

这是管道的开始,jsut是开始


这是正确的吗?(我还没有读过VAOs做什么,在开始之前,我想知道我在脑海中解构VBOs的方式是否正确,否则我会感到困惑)

这一切归结为:当你在“正常”程序中工作时,你所拥有的只是CPU、缓存、寄存器、主内存等

但是,当您使用计算机图形(和其他领域)时,您希望使用GPU,因为它对于特定任务更快。GPU是一台独立的计算机,拥有自己的处理器、管道和主存储器

这意味着您的程序需要以某种方式将所有数据传输到另一台计算机,并告诉另一台计算机如何处理这些数据。这不是一件容易的事情,所以OpenGL为您简化了事情。因此,它们为您提供了一个抽象(VBO),表示GPU中顶点的缓冲区,以及其他任务的许多其他抽象。然后,它们为您提供函数来创建该资源(
glGenBuffers
),用数据填充它(
glBufferData
),“绑定它”以使用它(
glBindBuffer
),等等


记住,为了你的利益,这只是一种简化。事实上,关于如何在下面执行所有操作的细节要复杂得多。将VBO作为顶点或IBO作为索引这样的抽象可以更容易地使用它们。

我认为您混淆了许多不同的东西,并且存在一些混淆,因此我尝试按照您提出的顺序来处理其中的大部分:

当我们声明一系列顶点时,比如说形成三角形基本体的3个顶点,我们基本上不存储它们,它们只是在代码中声明的

没有。如果你“无处”存储数据,那么你就没有它。此外,您在这里混淆了变量的声明、定义和初始化。对于顶点数据(与所有其他形式的数据一样),有两种基本策略:

  • 您可以将数据存储在某个位置,通常存储在文件中。直接在源代码中指定它只意味着它存储在某个二进制文件中,可能是可执行文件本身(或它使用的某个共享库)

  • 您可以通过一些数学公式或更一般的算法程序性地生成数据

  • 方法1。2当然可以是混合的,通常,方法2需要一些参数(这些参数本身需要存储在某个地方,所以参数也只是情况1)

    并且,通过相同的VBO,我们将所有顶点信息发送到顶点着色器(这是一组代码)。现在,VBO位于GPU中,所以当我们调用VBO时,我们基本上将所有信息存储在GPU的内存中

    OpenGL实际上只是一个规范,它完全不知道GPU和VRAM的存在。因此,OpenGL使用缓冲区对象(BOs)的概念,作为某种大小的连续内存块,完全由GL实现管理。作为用户,您可以要求德国劳埃德船级社创建或销毁此类BO,指定其大小,并完全控制内容——如果您愿意,您可以将MP3文件放入BO中(这不是一个很好的用例)

    另一方面,GL实现控制实际分配内存的位置,以及GPU的GL实现 实际上有专用视频存储器的系统可以选择将BO直接存储在VRAM中。像
    GL\u STATIC\u DRAW
    这样的提示可以帮助GL实现决定在哪里放置这样的缓冲区是最好的(但是提示系统有点缺陷,现代GL中存在更好的替代方案,但我不在这里讨论)
    GL_STATIC_DRAW
    意味着您打算只指定一次内容,并使用may times作为绘图选项的源-因此数据不会经常更改(当然不会以每帧为基础或更频繁地更改),如果成功,最好将其存储在VRAM中
    // here I declare the VBO 
    unsigned int VBO;
    
    // we have 1 VBO, so we generate an ID for it, and that ID is: GL_ARRAY_BUFFER 
    glGenBuffers(1, &VBO) 
    
    // GL_ARRAY_BUFFER is the VBO's ID, which we are going to bind to the VBO itself 
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    
    // bunch of info in here that basically says: I want to take the vertex data (the 
    // triangle that I declared as a float) and send it to the VBO's ID, which is 
    // GL_ARRAY_BUFFER, then I want to specify the size of the vertex 
    // data, the vertex data itself and the 'static draw' thingy
    glBufferData(...).