我试图理解这两个,如何使用它们以及它们是如何相关的。让我们说我想创建一个简单的地形和一个纹理立方体。对于这两个对象,我有三角形顶点的数组,对于立方体,我有一个包含纹理数据的数组。我的问题是:如何使用VAO和VBO来创建和渲染这两个?
有许多教程和书籍,但我仍然不知道如何理解和使用这些概念。
答案 0 :(得分:51)
顶点数组对象(VAO)在概念上只是薄状态包装器。
顶点缓冲区对象(VBO)存储实际数据。
另一种思考方式是VAO描述存储在一个或多个VBO中的数据。
将VBO(以及一般的缓冲区对象)视为存储在服务器(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会处理所有与顶点数据相关的设置。
答案 1 :(得分:8)
你的问题在这里不容易回答,而是在教程中。您可能已经知道这两个网站,但如果没有,我将离开参考文献。
现在试图阐明您的问题,Vertex数组对象是一个OpenGL对象,其目的是减少绘制调用的API开销。您可以将其视为顶点缓冲区及其关联状态的容器。类似于旧显示列表的东西。 通常,VAO和VBO之间存在1比1的关系;也就是说,每个VAO都包含一个唯一的VBO。但这并非绝对必要。您可以让几个VAO引用相同的VBO。
我认为,在代码中对此进行建模的最简单方法是使用VAO类/类型以及将VBO附加到其中的方法。然后为每个网格提供一个VAO实例。反过来,网格可以引用VBO类型,可以是它自己的或共享的。