您可以在单个 VBO 中使用多个目标吗? [英] Can you use multiple targets with a single VBO?

查看:63
本文介绍了您可以在单个 VBO 中使用多个目标吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

示例代码:

1. glGenBuffers(1, &VboId);
2. glBindBuffer(GL_ARRAY_BUFFER, VboId);
3. glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
4. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

所以我们生成一个通用的 VBO 句柄,然后我们使用GL_ARRAY_BUFFER"绑定它.绑定它似乎有两个目的:

So we generate a generic VBO handle, and then we bind it using "GL_ARRAY_BUFFER". Binding it seems to have 2 purposes:

  1. 我们必须先绑定缓冲区,然后才能通过 glBufferData
  2. 将数据复制到 GPU
  3. 我们必须先绑定缓冲区,然后才能通过 glVertexAttribPointer
  4. 为其添加属性
  1. We must bind the buffer before we can copy data to the GPU via glBufferData
  2. We must bind the buffer before we can add attributes to it via glVertexAttribPointer

而且我认为这是绑定 VBO 所需的唯一 2 次.我的问题是,在任何情况下,第 2 行和第 3 行的目标(GL_ARRAY_BUFFER、GL_ELEMENT_ARRAY_BUFFER、GL_PIXEL_PACK_BUFFER 或 GL_PIXEL_UNPACK_BUFFER)是否不同?或者我们想在第 4 行之前将其重新绑定到不同的目标?

And I think those are the only 2 times you need to bind the VBO. My question is, is there any scenario in which target (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER, or GL_PIXEL_UNPACK_BUFFER) would be different on lines 2 and 3? Or we would want to rebind it to a different target before line 4?

我们可以将多个缓冲区目标绑定到单个 VBO 吗?

Can we bind multiple buffer targets to a single VBO?

推荐答案

您没有将目标绑定到缓冲区对象.目标是 OpenGL 上下文中可以绑定事物(如缓冲区对象)的位置.因此,您将缓冲区对象绑定到 目标,而不是相反.

You do not bind targets to a buffer object. Targets are locations in the OpenGL context that you can bind things (like buffer objects) to. So you bind buffer objects to targets, not the other way around.

缓冲对象(没有像 VBO 这样的东西.只有缓冲对象)只是一个未格式化的, OpenGL 驱动程序拥有的线性内存数组.您可以将其用作顶点数组数据的源,方法是将缓冲区绑定到 GL_ARRAY_BUFFER 并调用 gl*Pointer 函数之一.这些函数使用当前绑定到GL_ARRAY_BUFFER的缓冲区.通过将它们绑定到 GL_ELEMENT_ARRAY_BUFFER 并调用 glDrawElements 函数之一,您可以将它们用作索引数据的来源.

A buffer object (there is no such thing as a VBO. There are simply buffer objects) is just a unformatted, linear array of memory owned by the OpenGL driver. You can use it as source for vertex array data, by binding the buffer to GL_ARRAY_BUFFER and calling one of the gl*Pointer functions. These function only work with the buffer currently bound to GL_ARRAY_BUFFER. You can use them as the source for index data by binding them to GL_ELEMENT_ARRAY_BUFFER and calling one of the glDrawElements functions.

用于修改缓冲区对象内容的函数(glBufferDataglMapBufferglBufferSubData 等)都专门为其操作指定一个目标工作.所以 glBufferData(GL_ARRAY_BUFFER, ...) 对当前绑定到 GL_ARRAY_BUFFER 的任何缓冲区进行处理.

The functions used to modify a buffer objects contents (glBufferData, glMapBuffer, glBufferSubData, etc) all specifically take a target for their operations to work on. So glBufferData(GL_ARRAY_BUFFER, ...) does its stuff to whatever buffer is currently bound to GL_ARRAY_BUFFER.

因此有两种函数会影响缓冲区对象:修改其内容的函数,以及在操作中使用它们的函数.后者特定于某个来源;glVertexAttribPointer 总是 使用当前绑定到 GL_ARRAY_BUFFER 的缓冲区.你不能让它使用不同的目标.同样,glReadPixels 总是使用绑定到 GL_PIXEL_PACK_BUFFER 的缓冲区.等等.如果一个函数处理缓冲区对象但没有将目标作为参数,那么它的文档会告诉你它从哪个目标查找缓冲区.

So there are two kinds of functions that affect buffer objects: those that modify their contents, and those that use them in operations. The latter are specific to a source; glVertexAttribPointer always uses the buffer currently bound to GL_ARRAY_BUFFER. You can't make it use a different target. Similarly, glReadPixels always uses the buffer bound to GL_PIXEL_PACK_BUFFER. And so forth. If a function does stuff with buffer objects but doesn't take a target as a parameter, then its documentation will tell you which target it looks for its buffer from.

注意:顶点数组有点奇怪.顶点属性和缓冲区对象之间的关联是通过调用glVertexAttribPointer 来实现的.该函数的作用是使用当前绑定到 GL_ARRAY_BUFFER 的缓冲区对象为该属性设置适当的数据.当前绑定"是指在调用此函数时绑定.所以在调用这个函数之后,你可以立即调用 glBindBuffer(GL_ARRAY_BUFFER, 0),它不会改变你去渲染时发生的什么.它会呈现得很好.

Note: Vertex arrays are kinda weird. The association between a vertex attribute and a buffer object is made by calling glVertexAttribPointer. What this function does is set the appropriate data for that attribute, using the buffer object that is currently bound to GL_ARRAY_BUFFER. By "currently bound", I mean bound at the time this function is called. So immediately after calling this function, you can call glBindBuffer(GL_ARRAY_BUFFER, 0), and it will change nothing about what happens when you go to render. It will render just fine.

通过这种方式,您可以为不同的属性使用不同的缓冲区对象.该信息将一直保留,直到您通过另一个 glVertexAttribPointer 调用对该特定属性进行更改.

In this way, you can use different buffer objects for different attributes. The information will be retained until you change it with another glVertexAttribPointer call for that particular attribute.

这篇关于您可以在单个 VBO 中使用多个目标吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆