VAO and element array buffer state

杀马特。学长 韩版系。学妹 提交于 2019-11-30 00:09:37

After some time, I found out this was actually kind of my bad. The laptop with the mobile NVIDIA Quadro 4200 graphics card was set so that all the apps would run on the Intel graphics by default, even when the laptop was in the performance mode. I don't understand why would someone want to do that, as then there was no way for any application to use the more powerful GPU from OpenGL (it was still possible to use it for OpenCL as there is explicit device selection, also maybe for DirectX - that would explain why some games ran smoothly).

Nevertheless, the described errorneous behavior is just a bug in Intel drivers, that's all there's to it. Intel drivers do not save ELEMENT_ARRAY_BUFFER_BINDING. There.

I'm sincerely sorry for asking the question, as there was no way to give a good answer without knowing the above.

I actually believe that ARB VAO is missing the element array buffer binding (or any other buffer binding) state.

Belief is not required; the spec tells the facts.

From the ARB_vertex_array_object specification:

The command

void GenVertexArrays(sizei n, uint *arrays);

returns previous unused vertex array object names in . These names are marked as used, for the purposes of GenVertexArrays only, and are initialized with the state listed in tables 6.6 (except for the CLIENT_ACTIVE_TEXTURE selector state), 6.7 and 6.8 (except for the ARRAY_BUFFER_BINDING state).

So there we have it: the entire state encompassed by VAOs are the contents of those three tables, with the noted exceptions.

The extension is written against The OpenGL Graphics Specification version 2.1 (PDF). Therefore, any page numbers, section labels, or table numbers are referenced relative to that spec.

I'm not about to copy those three tables here. But if you look on page 273 (by the spec's page count)/page 287 (by the number of physical pages), you will find table 6.8. And on that table is the following:

  • ELEMENT_ARRAY_BUFFER_BINDING

There is no ambiguity here. The information may not be plainly stated. But it is there, unquestionably. The ELEMENT_ARRAY_BUFFER_BINDING is part of VAO state.

Therefore, your problem can come from one of two sources:

  1. Driver bug. As I stated in a comment, a driver bug seems unlikely. Not impossible, just unlikely. NVIDIA's drivers are pretty self-similar for different hardware, and VAOs are hardly mirrored in hardware. Unless you are using different versions of the drivers, there's little reason to expect an error to be due to a driver bug.

  2. User error. I know you claim that your code works, and therefore it's fine. Everyone makes that claim about some code. And there have been plenty of times when I would swear up and down that some code was working just fine. Yet it was broken; it just so happened to get by. It happens. If you post your code, then at least we would be able to discount this possibility. Otherwise, we have nothing more than your word. And considering how often human beings are wrong about that, that isn't worth much.

A likely cause for this is that your Intel adapter cannot provide an OpenGL 3.3 context, but instead defaults to 2.1 or the like. As others have pointed out, in earlier versions of OpenGL the element array buffer state was not part of a VAO.

Ruud van Gaal

I can imagine the ELEMENT buffer not being cached; if you do:

glBindBuffer(GL_ARRAY_BUFFER, n_vertex_buffer_object);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), p_OffsetInVBO(0));

It is like saying:

gBoundBuffer_GL_ARRAY_BUFFER=n_vertex_buffer_object;
currentVAO->enable|=(1<<0);
currentVAO->vertexBuffer=IndexToPointer(gBoundBuffer_GL_ARRAY_BUFFER);

In other words, glBindBuffer() doesn't do anything but set the value of GL_ARRAY_BUFFER. It is at glVertexAttribPointer() where you modify the VAO.

So when you do:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, p_index_buffer_object_list[0]);
glBindVertexArray(0);

You really do:

gBoundBuffer_GL_ELEMENT_ARRAY_BUFFER=p_index_buffer_object_list[0];
currentVAO=0;

Where it makes sense that the GL_ELEMENT_ARRAY_BUFFER binding is not doing anything. I'm not sure if there is a glVertexAttribPointer()-like variant for elements though (like glElementPointer()), which would actually act on the VAO.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!