- 我需要为每个对象创建一个VAO和一个VBO吗?
- 或者我应该为每个对象的VBO(顶点、纹理数据等)创建一个VAO?
顶点数组对象(VAO)在概念上只是薄状态包装。
顶点缓冲对象(VBO)存储实际数据。
另一种思考这个问题的方法是,VAOs描述存储在一个或多个VBO中的数据。
将VBOs(和缓冲区对象一般)视为存储在服务器(GPU)内存中的非结构化数据数组。如果您想要,可以将顶点数据布局在多个数组中,或者将它们压缩到单个数组中。在任何情况下,缓冲区对象都会转化为存储数据的位置。
顶点数组对象跟踪绘制命令所需的指向VBO内存的实际指针。
然而,与C语言中的指针相比,它们略微复杂一些。顶点指针跟踪了绑定时指定的缓冲对象、其地址空间中的偏移量、顶点属性之间的步幅以及如何解释底层数据(例如,将整数值保持不变还是将其转换为浮点型[0.0,1.0],通过将其归一化到数据类型的范围)。
例如,整数数据通常会被转换为浮点型,但是您用于指定顶点指针的命令(glVertexAttribPointer (...)
与glVertexAttribIPointer (...)
)决定了此行为。
顶点数组对象还跟踪当前绑定到GL_ELEMENT_ARRAY_BUFFER
的缓冲对象。
GL_ELEMENT_ARRAY_BUFFER
是 glDrawElements (...)
命令从中获取其索引列表的地方(假设绑定非零),并且 没有 glElementArrayPointer (...)
命令。 glDrawElements (...)
将指针和绘制命令组合成单个操作,并将使用存储在活动顶点数组对象中的绑定来完成此操作。
有了这个前提,除非您的对象共享顶点数据,否则通常需要为每个对象使用唯一的VBO集。
如果您愿意,可以为整个软件使用单个VAO,或者您可以利用改变绑定VAO会改变几乎所有必要状态以绘制不同对象的事实。
因此,绘制您的地形和立方体可能只需更改绑定的VAO即可。如果您需要为它们应用不同的纹理,则可能需要执行更多操作,但是VAO会处理所有与顶点数据相关的设置。
;)
如果我的回答给您带来了不同的理解,请接受我的道歉。 - glampert