1

I'm now maintaining an lagacy code and found "strange" usage in OpenGL.

First, the OpenGL version is 3.2 compability profile.

Then, there is nothing refering to VAO in the code, however, in Dont need to have a VAO? what @Dietrich Epp said is below :

If you use a compatibility OpenGL context, you don't need a VAO. In a sense, there is a "default" VAO which is always bound.

And what confused me is how the data are fed to OpenGL . The pseudocode may explain clear:

// foo.cpp

void PrimitiveLoading()
{
  // load vertex position data
  glBindBuffer(GL_ARRAY_BUFFER, postionVBO);
  glBufferData(GL_ARRAY_BUFFER, /* postion data */);
  glBindBuffer(GL_ARRAY_BUFFER, 0);

  // load vertex position index data 
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, positionEBO);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, /* postion index data */);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

  // load UV data 
  glBindBuffer(GL_ARRAY_BUFFER, uvVBO, GL_STATIC_DRAW);
  glBufferData(GL_ARRAY_BUFFER, /* UV data */);
  glBindBuffer(GL_ARRAY_BUFFER, 0);

  /*
  The postion data are loaded before ELEMENT, while the UV data are behind. 
  This means ELEMENT is associated with the postion but not the UV, right?
  */
}

void PrimitiveRendering()
{
  // define the vertex postion format
  glBindBuffer(GL_ARRAY_BUFFER, postionVBO);
  glVertexAttribPointer(/*position attribute setting*/);

  // define the uv format
  glBindBuffer(GL_ARRAY_BUFFER, uvVBO);
  glVertexAttribPointer(/*UV attribute setting*/);
  glBindBuffer(GL_ARRAY_BUFFER, 0); // GL_ARRAY_BUFFER bind to 0

  // draw
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, positionEBO);
  glDrawElements(GL_TRIANGLES, positionEBO, GL_UNSIGNED_INT, 0);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

  /*
  before drawing, GL_ARRAY_BUFFER bind to 0(not bind to both postionVBO and uvVBO), but it works.

  And the data are fed to respectively postionVert and uvVert in foo.vert below as expected. how and why ? 

  Moreover, it seems the ELEMENT affects not not only postionVAO but also uvVAO.
  */
}

// foo.vert

version 150

in vec3 postionVert;
in vec2 uvVert;

...// other code

the questions are written as comments. Could anyone explain how this usage works?

foo
  • 368
  • 1
  • 15
  • 1
    "*Could anyone explain how this usage works?*" It works exactly like core OpenGL would, if you bind one VAO at the start of the program and don't ever change or unbind it. – Nicol Bolas May 11 '18 at 03:07

1 Answers1

4

The postion data are loaded before ELEMENT, while the UV data are behind. This means ELEMENT is associated with the postion but not the UV, right?

No. Index arrays are not "associated" with any attribute. When you do indexed rendering, the index used applies to all attributes. You cannot use different indices to fetch different attributes.

before drawing, GL_ARRAY_BUFFER bind to 0(not bind to both postionVBO and uvVBO), but it works.

Of course it works. What is bound to GL_ARRAY_BUFFER does not matter for rendering purposes. It only matters when you call glVertexAttrib*Pointer, which takes the buffer that is currently bound to that binding point and hooks the given attribute index to that buffer.

Think of GL_ARRAY_BUFFER as just being a weird way of passing an additional parameter to glVertexAttrib*Pointer. Since you didn't call that function, the extra parameter isn't passed to anyone.

When you're "not using a VAO" in compatibility contexts, you're still using a VAO. The VAO-modifying functions all work exactly the same as they do for core contexts. The only difference is that in compatibility, VAO object 0 is a real vertex array object, while in core contexts it is not a valid object. So in compatibility contexts, there's always some VAO that is currently bound.

Nicol Bolas
  • 378,677
  • 53
  • 635
  • 829