Clearing glVertexAttribPointer

I just want to make sure that I understand correctly (I would ask about SO Chat, but it's dead there!):

We have a Vertex Array, which we make "current", binding it / we have a buffer that we bind to the target. then we fill this target with glBufferData which essentially fills everything related to this goal, that is, our buffer and then we call glVertexAttribPointer , which describes how the data is laid out - the data is what is connected with GL_ARRAY_BUFFER and this descriptor is stored in our initial array of vertices

(1) Do I understand correctly?
The documentation is a bit sparse about how everything correlates.

(2) Is there some type of vertex array by default? Because I forgot / skipped glGenVertexArrays and glBindVertexArray , and my program worked fine without it.




Edit: I skipped the step ... glEnableVertexAttribArray .

(3) The binding of the vertex attribute to the vertex array is glVertexAttribPointer at time glVertexAttribPointer , and then we can enable / disable the attribute via glEnableVertexAttribArray at any time, regardless of the moment at which the vertex array is bound?

Or (3b) Is the vertex attribute attached to the vertex array at time glEnableVertexAttribArray , and so we can add the same vertex attribute to multiple vertex arrays by calling glEnableVertexAttribArray at different times when different vertices of the Arrays are connected?

+84
opengl
Jan 02 2018-12-12T00:
source share
2 answers

Some terminology is a bit off:

  • A Vertex Array is just an array (usually a float[] ) that contains vertex data. This does not have to be associated with anything. Not to be confused with Vertex Array Object or VAO, which I will move on later.
  • A Buffer Object , commonly called a Vertex Buffer Object when storing vertices, or shorting to VBO, is what you call only Buffer .
  • Nothing goes back to the vertex array, glVertexAttribPointer works just like glVertexPointer or glTexCoordPointer , just instead of the named attributes you get a number that indicates your own attribute. You pass this value as index . All your calls to glVertexAttribPointer are queued the next time you call glDrawArrays or glDrawElements . If you have a VAO binding, VAO will save the settings for all your attributes.

The main problem here is that you are mixing vertex attributes with VAO. Vertex attributes are just a new way of defining vertices, tekscodes, normals, etc. For drawing. VAO store status. First, I will explain how a drawing with vertex attributes works, and then explain how you can reduce the number of method calls using VAO:

  • You must enable the attribute before you can use it in the shader. For example, if you want to send vertices to the shader, you will most likely send it as the first attribute of 0. So, before rendering, you need to enable it with glEnableVertexAttribArray(0); .
  • Now that the attribute is enabled, you need to determine the data that it will use. To do this, you need to bind your VBO - glBindBuffer(GL_ARRAY_BUFFER, myBuffer); .
  • And now we can define the attribute - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); . In the order of the parameter: 0 - the attribute that you define, 3 - the size of each vertex, GL_FLOAT - type, GL_FALSE means not normalize each vertex, the last 2 zeros mean that there is no step or offset on the vertices.
  • Draw something with it - glDrawArrays(GL_TRIANGLES, 0, 6);
  • The next thing you draw may not use the attribute 0 (it really will be, but this is an example), so we can disable it - glDisableVertexAttribArray(0);

Wrap this in glUseProgram() calls, and you have a rendering system that works with shaders properly. But suppose you have 5 different attributes, vertices, techcodes, normals, colors, and lightmap coordinates. First of all, you have to make one glVertexAttribPointer call for each of these attributes, and you will need to include all the attributes in advance. Let's say you define attributes 0-4 as I list them. You would include them all like this:

 for (int i = 0; i < 5; i++) glEnableVertexAttribArray(i); 

And then you have to bind different VBOs for each attribute (if you do not save them all in one VBO and do not use offsets / steps), then you need to make 5 different calls to glVertexAttribPointer , from glVertexAttribPointer(0,...); up to glVertexAttribPointer(4,...); for vertices in lightmap coordinates respectively.

Hope this system makes sense. Now I will move on to VAO to explain how to use them to reduce the number of method calls when performing this type of rendering. Please note that the use of VAO is not required.

A Vertex Array Object or VAO is used to store the state of all calls to glVertexAttribPointer and VBOs that were targeted when all calls to glVertexAttribPointer were made.

You create one with a call to glGenVertexArrays . To save everything you need to VAO, bind it with glBindVertexArray , then make a full draw call . All draw binding calls are intercepted and saved by the VAO. You can untie the VAO with glBindVertexArray(0);

Now that you want to draw an object, you don’t need to rewrite all VBO bindings or glVertexAttribPointer calls, you just need to bind VAO to glBindVertexArray , then call glDrawArrays or glDrawElements , and you will draw the same thing as all these method calls. You probably want to untie the VAO again.

Once you untie the VAO, the whole state will return to what it was before you linked the VAO. I'm not sure that any changes you make during VAO are saved, but this is easy to understand with a test program. I think you can come up with glBindVertexArray(0); as binding to VAO by default ...




Update: Someone drew my attention to the need to call a call. As it turned out, in fact, you do not need to do a FULL draw call when setting up VAO, just all the necessary things. I don’t know why I thought it was necessary before, but now it’s fixed.

+193
Jan 02 2018-12-12T00:
source share

The terminology and sequence of APIs that need to be called is really confusing. Even more confusing is how the various aspects are related β€” the buffer, the general vertex attribute, and the shader attribute attribute. See OpenGL-Terminology for a pretty good explanation.

In addition, the OpenGL-VBO link , shader, VAO shows a simple example with the necessary API calls. This is especially good for those who are switching from direct mode to a programmable pipeline.

Hope this helps.

Edit: As you can see from the comments below, people can make assumptions and draw conclusions. The reality is that it is rather confusing for beginners.

+2
Jan 01 '15 at 8:33
source share



All Articles