顶点数组对象是上下文的一部分吗?
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->size()
,它会返回一个合法且定义明确的值。
glGetBufferParameteri64v(target, GL_BUFFER_SIZE)
相当于调用buffer->size()
。您可以在创建对象后调用此函数,然后再调用glBufferData
。
在buffer->size()
和GL_BUFFER_SIZE
这两种情况下,返回的大小都是0。因为您还没有向对象中放入任何东西。在这两种情况下,对象现在都存在,但它是空的。
glBufferData
就像调用buffer->resize
。您现在告诉您分配给 自身 的对象分配一定大小的存储空间并(可选地)用特定数据填充它。
顶点数组对象的不同之处仅在于其用途。缓冲区对象的目的是包含存储。顶点数组对象的目的是定义存储(存储在缓冲区中)和提供渲染操作的顶点数组之间的关联。
在我们的 C++ 类比中,VAO 更像是一个常规结构:
struct VAO
int elementBuffer;
VertexFormat vf[16];
VertexBufferBinding vb[16];
;
这个VAO
结构不需要在sizeof(VAO)
之外分配存储空间。就像许多 C++ 对象不需要分配存储空间一样。因此,它没有 glBufferData
的等价物。
所以为了回答您的问题,所有 OpenGL 对象的内存归创建它们的 OpenGL 上下文所有。只是 一些 OpenGL 对象可以拥有超出其基本对象的额外存储空间。 vector<char>
有一个内部字节数组。并且缓冲区对象有一个内部字节数组。
VAO 在对象本身之外没有内部存储阵列。
【讨论】:
尼科尔,谢谢你的解释!顶点缓冲区存在于 GPU 内存 (VRAM) 和客户端/CPU 内存 (RAM) 上的顶点数组对象中是否正确?如果是这种情况,位于 RAM 上的 Vertex Array Object 如何将数据指向 VRAM? @user2259784:存储任何对象的实际数据的位置是一个实现细节。为缓冲区对象分配的存储空间位于 GPU 可访问的内存中。这是否意味着“VRAM”取决于驱动程序。以上是关于顶点数组对象是上下文的一部分吗?的主要内容,如果未能解决你的问题,请参考以下文章