顶点数组对象是上下文的一部分吗?

Posted

技术标签:

【中文标题】顶点数组对象是上下文的一部分吗?【英文标题】:Is Vertex Array Object a part of Context? 【发布时间】:2017-12-02 09:28:03 【问题描述】:

要在OpenGL 3.0中使用顶点数组对象,我们使用以下步骤创建顶点数组对象的名称,然后将其绑定到上下文。

glGenVertexArrays(1,&VAO) = 生成顶点数组的名称 glBindVertexArrays(&VAO) = 将名称与顶点数组绑定。

与创建和使用顶点缓冲区不同,我们生成名称、绑定它、分配内存然后将数据填充到缓冲区中。

glGenBuffers(1, &VBO) = 生成顶点缓冲区的名称 glBindBuffer( GL_ARRAY_BUFFER, VBO ) = 将名称绑定到 GL_ARRAY_BUFFER glBufferData(....) = 分配内存并填充数据

由于我们没有在这些行中为 Vertex Array Object 分配内存,这是否意味着 Vertex Array Object 的内存已作为一部分分配Context 并使用 glBindVertexArrays() 引用指向为顶点数组对象分配的内存的指针?

【问题讨论】:

【参考方案1】:

glBufferData(....) = 分配内存并填充数据

您确实在为缓冲区分配内存。但这与为缓冲区 object 分配内存不同

让我们用 C++ 术语来表达。缓冲区对象类似于vector<char>。做glGenBuffers/glBindBuffer 就像分配一个vector<char> 对象(让我们在堆上做):

auto buffer = new vector<char>;

buffer 指向一个真实的活动对象。 sizeof(*buffer) 将返回多个字节的内存,buffer 指向的对象需要多少内存。您可以请求buffer-&gt;size(),它会返回一个合法且定义明确的值。

glGetBufferParameteri64v(target, GL_BUFFER_SIZE) 相当于调用buffer-&gt;size()。您可以在创建对象后调用此函数,然后再调用glBufferData

buffer-&gt;size()GL_BUFFER_SIZE 这两种情况下,返回的大小都是0。因为您还没有向对象中放入任何东西。在这两种情况下,对象现在都存在,但它是空的

glBufferData 就像调用buffer-&gt;resize。您现在告诉您分配给 自身 的对象分配一定大小的存储空间并(可选地)用特定数据填充它。

顶点数组对象的不同之处仅在于其用途。缓冲区对象的目的是包含存储。顶点数组对象的目的是定义存储(存储在缓冲区中)和提供渲染操作的顶点数组之间的关联。

在我们的 C++ 类比中,VAO 更像是一个常规结构:

struct VAO

  int elementBuffer;
  VertexFormat vf[16];
  VertexBufferBinding vb[16];
;

这个VAO 结构不需要在sizeof(VAO) 之外分配存储空间。就像许多 C++ 对象不需要分配存储空间一样。因此,它没有 glBufferData 的等价物。

所以为了回答您的问题,所有 OpenGL 对象的内存归创建它们的 OpenGL 上下文所有。只是 一些 OpenGL 对象可以拥有超出其基本对象的额外存储空间。 vector&lt;char&gt; 有一个内部字节数组。并且缓冲区对象有一个内部字节数组。

VAO 在对象本身之外没有内部存储阵列。

【讨论】:

尼科尔,谢谢你的解释!顶点缓冲区存在于 GPU 内存 (VRAM) 和客户端/CPU 内存 (RAM) 上的顶点数组对象中是否正确?如果是这种情况,位于 RAM 上的 Vertex Array Object 如何将数据指向 VRAM? @user2259784:存储任何对象的实际数据的位置是一个实现细节。为缓冲区对象分配的存储空间位于 GPU 可访问的内存中。这是否意味着“VRAM”取决于驱动程序。

以上是关于顶点数组对象是上下文的一部分吗?的主要内容,如果未能解决你的问题,请参考以下文章

Swizzling 顶点数组、顶点缓冲区对象和着色器

为啥 EGL 上下文只与一个线程相关

为啥顶点数组对象会导致错误?

C#中的大数组算术

仅对 UIView 绘制的上下文的一部分进行动画处理?

核心数据对象无效