68

I am following some begginer OpenGL tutorials, and am a bit confused about this snippet of code:

glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); //Bind GL_ARRAY_BUFFER to our handle
glEnableVertexAttribArray(0); //?
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); //Information about the array, 3 points for each vertex, using the float type, don't normalize, no stepping, and an offset of 0. I don't know what the first parameter does however, and how does this function know which array to deal with (does it always assume we're talking about GL_ARRAY_BUFFER?

glDrawArrays(GL_POINTS, 0, 1); //Draw the vertices, once again how does this know which vertices to draw? (Does it always use the ones in GL_ARRAY_BUFFER)

glDisableVertexAttribArray(0); //?
glBindBuffer(GL_ARRAY_BUFFER, 0); //Unbind

I don't understand how glDrawArrays knows which vertices to draw, and what all the stuff to do with glEnableVertexAttribArray is. Could someone shed some light on the situation?

Devid Farinelli
  • 7,514
  • 9
  • 42
  • 73
w4etwetewtwet
  • 1,330
  • 2
  • 10
  • 20

3 Answers3

55

The call to glBindBuffer tells OpenGL to use vertexBufferObject whenever it needs the GL_ARRAY_BUFFER.

glEnableVertexAttribArray means that you want OpenGL to use vertex attribute arrays; without this call the data you supplied will be ignored.

glVertexAttribPointer, as you said, tells OpenGL what to do with the supplied array data, since OpenGL doesn't inherently know what format that data will be in.

glDrawArrays uses all of the above data to draw points.

Remember that OpenGL is a big state machine. Most calls to OpenGL functions modify a global state that you can't directly access. That's why the code ends with glDisableVertexAttribArray and glBindBuffer(..., 0): you have to put that global state back when you're done using it.

Steve Howard
  • 6,737
  • 1
  • 26
  • 37
  • 1
    Ok, one final thing that puzzels me. How does glDrawArrays know which vertex attribute to use. I am assuming I can have more than one, so I could enable index 1 as so: glEnableVertexAttribArray(1), then give that some attributes using glVertexAttribPointer(), however in my example how does glDrawArrays know to use the attributes at index 0 to interpret the format of the data. – w4etwetewtwet Sep 30 '13 at 19:46
  • 1
    @handuel: It uses *all* enabled vertex attributes. What each attribute means exactly defined through the programming of the vertex shader. – datenwolf Sep 30 '13 at 19:55
  • 1
    @datenwolf Ok, so I set vertex attributes, the shader program then uses those + the data in/(pointed to by?) GL_ARRAY_BUFFER to generate output, which glDrawArrays draws? Hopefully that is correct because in that case I finally understand it. – w4etwetewtwet Sep 30 '13 at 19:59
  • 1
    @handuel: Actually the vertex shader gets into action after glDrawArrays gets called. glDrawArrays simply passes the data for each active vertex attribute enabled using `glEnableVertexAttribArray` into the drawing queue. In the vertex shader there's a binding for each vertex attribute array, and the shader determines what becomes screen position, what color and so on. – datenwolf Sep 30 '13 at 20:06
  • 1
    @datenwolf OK, what data do shaders receive? Just what is in GL_ARRAY_BUFFER, or can they get data from other buffers? – w4etwetewtwet Sep 30 '13 at 20:13
  • 5
    @handuel: When `glVertexAttribPointer(attrib_index, …)` is called the buffer bound by `glBindBuffer(GL_ARRAY_BUFFER, …)` gets bound to the vertex attribute specified by the *first* parameter of `glVertexAttribPointer`. To bind another buffer to another attribute you do another `glBindBuffer(GL_ARRAY_BUFFER, …); glVertexAttribPointer(…);`. –– The call of `glEnableVertexAttribArray` is not required to make the binding between buffer and attribute. But enabling a vertex attribute array makes the `glDraw…` calls use the enabled attributes. – datenwolf Sep 30 '13 at 20:18
  • @datenwolf So does it mean, that I don't need to bind anything to GL_ARRAY_BUFFER before draw call? Is this code OK?: > glBindBuffer(GL_ARRAY_BUFFER, 0); > glDrawArrays(GL_TRIANGLES, 0, 3); – Jerry Lundegaard Jul 06 '20 at 07:24
  • 1
    @JerryLundegaard: Yes, `glDraw…` functions don't care about the buffer binding. The functions for setting up the vertex attribute buffer association do. – datenwolf Jul 06 '20 at 09:04
5

DrawArrays takes data from ARRAY_BUFFER.

Data are 'mapped' according to your setup in glVertexAttribPointer which tells what is the definition of your vertex.

In your example you have one vertex attrib (glEnableVertexAttribArray) at position 0 (you can normally have 16 vertex attribs, each 4 floats). Then you tell that each attrib will be obtained by reading 3 GL_FLOATS from the buffer starting from position 0.

Patapoom
  • 794
  • 1
  • 7
  • 16
fen
  • 9,835
  • 5
  • 34
  • 57
  • Thanks, that helps me to understand. What does glEnableVertexAttribArray do? – w4etwetewtwet Sep 30 '13 at 19:32
  • @handuel updated the answer, see the tutorial from arcsynthesis.org – fen Sep 30 '13 at 19:37
  • @fen But, if drawArrays takes data from ARRAY_BUFFER, does it mean that I cannot use data from multiple buffers in the shader? Because your cannot have multiple buffers bounded to ARRAY_BUFFER at the same time. BTW posted link doesn't work anymore. – Jerry Lundegaard Jul 06 '20 at 07:25
1

Complementary to the other answers, here some pointers to OpenGL documentation. According to Wikipedia [1], development of OpenGL has ceased in 2016 in favor of the successor API "Vulkan" [2,3]. The latest OpenGL specification is 4.6 of 2017, but it has only few additions over 3.2 [1].

The code snippet in the original question does not require the full OpenGL API, but only a subset that is codified as OpenGL ES (originally intended for embedded systems) [4]. For instance, the widely used GUI development platform Qt uses OpenGL ES 3.X [5].

The maintainer of OpenGL is the Khronos consortium [1,6]. The reference of the latest OpenGL release is at [7], but has some inconsistencies (4.6 linked to 4.5 pages). If in doubt, use the 3.2 reference at [8].

A collection of tutorials is at [9].

  1. https://en.wikipedia.org/wiki/OpenGL
  2. https://en.wikipedia.org/wiki/Vulkan
  3. https://vulkan.org
  4. https://en.wikipedia.org/wiki/OpenGL_ES
  5. see links in function references like https://doc.qt.io/qt-6/qopenglfunctions.html#glVertexAttribPointer
  6. https://registry.khronos.org
  7. https://www.khronos.org/opengl
  8. https://registry.khronos.org/OpenGL-Refpages/es3
  9. http://www.opengl-tutorial.org
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Joachim W
  • 7,290
  • 5
  • 31
  • 59