2
4

2 回答 2

0

If you have an AMD or NV GPU you can always use the EXT_direct_state_access extension to manipulate a buffer object without binding it (this is purely a driver feature and does not require any special class of hardware). Sadly, Intel, Mesa and Apple have not bothered to implement this extension despite its 5 year existence -- lazy slackers.


Have a look at the following functions, they will make what you are describing a lot easier:

  • glNamedBufferDataEXT (...)
  • glNamedBufferSubDataEXT (...)
  • glMapNamedBufferEXT (...)
  • glUnmapNamedBufferEXT (...)

Now, since adoption of DSA is sparse, you will probably have to write some fallback code for systems that do not support it. You can reproduce the functionality of DSA by writing functions with identical function signatures that use a dummy VAO to bind VBOs and IBOs for data manipulation on systems that do not support the extension. You will have to keep track of what VAO was bound before you use it, and restore it before said function returns to eliminate side-effects.

In a good engine you should shadow the VAO binding state rather than having to query it from GL. That is, instead of using glBindVertexArray (...) directly you implement a system that wraps that call and therefore always knows what VAO is bound to a particular context. In the end, this makes emulating DSA functionality where driver support does not exist a lot more efficient. If you attempt something like this, you need to be aware that glDelete (...) functions implicitly unbind (by binding 0) the object being deleted if it is bound in the current context.

于 2013-12-05T18:20:28.270 回答
0

GL_ELEMENT_ARRAY_BUFFER但是,如果在没有绑定 VAO 时仅将缓冲区绑定到是禁止的,则唯一的选择是表示索引缓冲区的类在创建/更新/等时绑定虚拟 VAO。

对旧问题的新答复,但在不需要 VAO(或干扰当前绑定的 VAO)的情况下使用索引缓冲区的一种简单方法是将缓冲区绑定到GL_ELEMENT_ARRAY_BUFFER.

例如,而不是这个:

glBindVertexArray(vaoID);                               // ...Do I even have a VAO yet?
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);   // <- Alters VAO state!
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, ...);

-- 可以改为这样写:

glBindBuffer(GL_COPY_WRITE_BUFFER, indexBufferID);
glBufferSubData(GL_COPY_WRITE_BUFFER, ...);

(这里我随意使用GL_COPY_WRITE_BUFFER了 ,它的存在是为了提供一个临时目标,使缓冲区之间的复制更容易,但大多数其他目标也可以。)

于 2021-06-03T19:50:04.960 回答