简体   繁体   English

使用顶点数组对象和顶点缓冲区对象

[英]Use of Vertex Array Objects and Vertex Buffer Objects

I am trying to understand these two, how to use them and how they are related. 我试图理解这两个,如何使用它们以及它们是如何相关的。 Let's say I want to create a simple terrain and a textured cube. 假设我想创建一个简单的地形和一个纹理立方体。 For both objects I have the array of triangles vertices and for the cube I have an array containing the texture's data. 对于这两个对象,我有三角形顶点的数组,对于立方体,我有一个包含纹理数据的数组。 My question is: how do I use VAOs and VBOs to create and render these two? 我的问题是: 如何使用VAO和VBO来创建和渲染这两个?

  1. Would I have to create a VAO and VBO for each object? 我是否必须为每个对象创建一个VAO和VBO?
  2. or should create a VAO for each object's VBO (vertices, texture data, etc.)? 或者应该为每个对象的VBO(顶点,纹理数据等)创建一个VAO?

There are many tutorials and books but I still don't get the very idea of how these concepts must be understood and used. 有许多教程和书籍,但我仍然不知道如何理解和使用这些概念。

Fundamentally, you need to understand two things: 从根本上说,你需要了解两件事:

  1. Vertex Array Objects (VAOs) are conceptually nothing but thin state wrappers. 顶点数组对象(VAO)在概念上只是瘦状态包装器。

  2. Vertex Buffer Objects (VBOs) store actual data. 顶点缓冲区对象(VBO)存储实际数据。

Another way of thinking about this is that VAOs describe the data stored in one or more VBOs. 另一种思考方式是VAO描述存储在一个或多个VBO中的数据。

Think of VBOs (and buffer objects in general) as unstructured arrays of data stored in server (GPU) memory. 将VBO(以及一般的缓冲区对象)视为存储在服务器(GPU)内存中的非结构化数据阵列。 You can layout your vertex data in multiple arrays if you want, or you can pack them into a single array. 如果需要,可以在多个数组中布置顶点数据,也可以将它们打包到单个数组中。 In either case, buffer objects boil down to locations where you will store data. 在任何一种情况下,缓冲区对象都会归结为存储数据的位置。

Vertex Array Objects track the actual pointers to VBO memory needed for draw commands. 顶点数组对象跟踪绘制命令所需的VBO内存的实际指针

They are a little bit more sophisticated than pointers as you would know them in a language like C, however. 然而,它们比指针更复杂,就像用C语言那样知道它们。 Vertex pointers keep track of the buffer object that was bound when they were specified, the offset into its address space, stride between vertex attributes and how to interpret the underlying data ( eg whether to keep integer values or to convert them to floating-point [ 0.0 , 1.0 ] by normalizing to the data type's range). 顶点指针跟踪指定时绑定的缓冲区对象,其地址空间的偏移量,顶点属性之间的跨距以及如何解释底层数据( 例如,是保留整数值还是将它们转换为浮点数[ 0.0,通过归一化到数据类型的范围1.0])。

For example, integer data is usually converted to floating-point, but it is the command you use to specify the vertex pointer ( glVertexAttribPointer (...) vs. glVertexAttribIPointer (...) ) that determines this behavior. 例如,整数数据通常转换为浮点数,但它是用于指定确定此行为的顶点指针( glVertexAttribPointer (...)glVertexAttribIPointer (...) )的命令。

Vertex Array Objects also track the buffer object currently bound to GL_ELEMENT_ARRAY_BUFFER . 顶点数组对象还跟踪当前绑定到GL_ELEMENT_ARRAY_BUFFER的缓冲区对象。

GL_ELEMENT_ARRAY_BUFFER is where the command: glDrawElements (...) sources its list of indices from (assuming a non-zero binding) and there is no glElementArrayPointer (...) command. GL_ELEMENT_ARRAY_BUFFER是命令: glDrawElements (...)获取索引列表(假设非零绑定)并且没有 glElementArrayPointer (...)命令。 glDrawElements (...) combines the pointer and draw command into a single operation, and will use the binding stored in the active Vertex Array Object to accomplish this. glDrawElements (...)将指针和绘图命令组合到一个操作中,并将使用存储在活动顶点数组对象中的绑定来完成此操作。


With that out of the way, unless your objects share vertex data you are generally going to need a unique set of VBOs for each. 除此之外,除非您的对象共享顶点数据,否则通常需要为每个对象提供一组唯一的VBO。

You can use a single VAO for your entire software if you want, or you can take advantage of the fact that changing the bound VAO changes nearly the entire set of states necessary to draw different objects. 如果需要,可以将单个VAO用于整个软件,或者可以利用更改绑定的VAO几乎改变绘制不同对象所需的整个状态集的事实。

Thus, drawing your terrain and cube could be as simple as changing the bound VAO. 因此,绘制地形和立方体可能就像更改绑定的VAO一样简单。 You may have to do more than that if you need to apply different textures to each of them, but the VAO takes care of all vertex data related setup. 如果您需要为每个纹理应用不同的纹理,则可能需要做更多的工作,但VAO会处理所有与顶点数据相关的设置。

Your question is not easily answerable here, but rather in a tutorial. 你的问题在这里不容易回答,而是在教程中。 You probably already know these two websites, but if not, I'm leaving the references. 您可能已经知道这两个网站,但如果没有,我将离开参考。

OGLDEV OGLDEV

OpenGL-Tutorial.org OpenGL-Tutorial.org

Now trying to elucidate your questions, a Vertex Array Object is an OpenGL object designed with the goal of reducing API overhead for draw calls. 现在试图阐明你的问题,Vertex数组对象是一个OpenGL对象,其目的是减少绘制调用的API开销。 You can think of it as a container for a Vertex Buffer and its associated states. 您可以将其视为顶点缓冲区及其关联状态的容器。 Something similar perhaps to the old display-lists. 类似于旧显示列表的东西。 Normally, there is a 1 to 1 relationship between a VAO and a VBO; 通常,VAO和VBO之间存在1比1的关系; that is, each VAO contains a unique VBO. 也就是说,每个VAO都包含一个唯一的VBO。 But this is not strictly necessary. 但这并非绝对必要。 You could have several VAOs referencing the same VBO. 您可以让几个VAO引用相同的VBO。

The simplest way to model this in code, I think, would be for you to have a VAO class/type and a method to attach a VBO to it. 我认为,在代码中对此进行建模的最简单方法是使用VAO类/类型以及将VBO附加到其中的方法。 Then give an instance of VAO to each mesh. 然后为每个网格提供一个VAO实例。 The mesh in turn can have a reference to a VBO type that may be its own or a shared one. 反过来,网格可以引用VBO类型,该类型可以是它自己的或共享的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM