1

I've got a Vertex Buffer Object (VBO) that I typically use (with an appropriate VAO) to draw points with lines between them via two calls to glDrawArrays (one with GL_POINTS and one with GL_LINE_STRIP).

Now I'm interested in ditching the GL_LINE_STRIP and drawing lines between specific indices in the VBO by defining an Index Buffer Object (IBO) and using glDrawElements.

However, when I create the one VBO and then create and fill the IBO, my call to glDrawArrays(GL_POINTS,...) does nothing! If I simply comment out the line that calls glBufferData(GL_ELEMENT_ARRAY_BUFFER,...), the glDrawArrays call works again. I assumed that adding an IBO would simply be ignored by the glDrawArrays call, but apparently it's not.

So, is it possible to use one VBO to render using a glDrawArrays and (via an IBO) glDrawElements?

One bit of confusion for me is how the IBO is linked to the VBO and/or the VAO and therefore to the current draw command. For example, is it possible to use one VBO and then bind to two different IBOs for different glDrawElements calls? (e.g., what if I want to draw triangles with indices 0, 1, 2 and 1, 2, 3; but I then want to draw lines between indices 0, 1 and 1, 3).

The steps I'm taking in code to connect the IBO with my VAO are as follows:

  1. Create the buffer IDs for both the VBO and IBO
  2. Bind and fill the VBO
  3. Create the ID for the VAO
  4. Bind the VAO (glBindVertexArray) and setup my attribute(s) (using glEnableVertexAttribArray, glVertexAttribFormat, glVertexAttribBinding and glBindVertexBuffer)
  5. Bind and fill the IBO
  6. Un-bind the VAO (glBindVertexArray(0))

Is there something else I need to use (or a different order of actions) to associate the IBO with the VAO?

Thanks.


EDIT - I Found my coding error:

When I generated my buffers, I generated 4 at once to a single array (for use with this and other OpenGL buffers in the code). However, when I assigned the IDs to specific variable names, I used index 0 (zero) for both the VBO and the IBO (then using indices 2 and 3 for other buffers). Basically, I accidentally skipped index 1 and therefore overwrote my VBO when I filled my IBO. As noted in a comment below, this exercise at least helped solidify my understanding of how IBOs are used in the context of VBOs. Thanks.

FTLPhysicsGuy
  • 1,035
  • 1
  • 11
  • 23
  • *"I assumed that adding an IBO would simply be ignored by the glDrawArrays call [...]"* - Yes it is. There's a bug in your code somewhere, but it's hard to tell without seeing the code. – Rabbid76 Dec 05 '21 at 07:58
  • *"... is it possible to use one VBO and then bind to two different IBOs for different `glDrawElements` calls?"* - No. The IBO is stores in the Vertex Array Object. You can only associate one IBO the the VAO. However, you can create multiple VAOs. See [Vertex Specification - Index buffers](https://www.khronos.org/opengl/wiki/Vertex_Specification#Index_buffers). – Rabbid76 Dec 05 '21 at 08:00
  • @Rabbid76 Thanks for the comments. At least I know it's supposed to work and It's a bug in my code. I'll see if I can work it out or if I need to get down to a code-level question. As to the IBO/VAO connection, I'll add to my question to indicate how I'm trying to do it in code to ensure I'm associating the IBO with my VBO. – FTLPhysicsGuy Dec 05 '21 at 13:20
  • The IBO (reference) is stored in the VAO. So you need to bind the VAO before the IBO. – Rabbid76 Dec 05 '21 at 13:41

1 Answers1

1

The Index Buffer (ELEMENT_ARRAY_BUFFER) binding is stored within the Vertex Array Object. When glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO) is called the element buffer object ID is stored in the currently bound Vertex Array Object. Therefore the VAO must be bound before the element buffer with glBindVertexArray(VAO).

In compared to the Index Buffer, the Vertex Buffer binding (ARRAY_BUFFER) is a global state.
Each attribute which is stated in the VAOs state vector may refer to a different ARRAY_BUFFER. When glVertexAttribPointer is called the buffer which is currently bound to the target ARRAY_BUFFER, is associated to the specified attribute index and the ID of the object is stored in the state vector of the currently bound VAO.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thanks for the reply. Note that I no longer use glVertexAttribPointer but instead I define the attributes in my VAO outside of there render loop using `glEnableVertexAttribArray`, `glVertexAttribFormat`, `glVertexAttribBinding`, and `glBindVertexBuffer`. In the render loop, I just bind to the VAO (via another `glBindVertexArray` call) and call the gl draw routine(s). I assume that when I'm establishing my VAO (outside the render loop) and bind/fill the IBO after the original `glBindVertexArray`, that OpenGL is associating the IBO with the VAO (note the event order in my edited question). – FTLPhysicsGuy Dec 05 '21 at 19:00
  • FOUND THE ERROR! I found the silly error in my code. I'll add the info to my original question. However, this discussion had helped me solidify my understanding of how IBOs are used in the context of VAOs. Thanks again. – FTLPhysicsGuy Dec 05 '21 at 19:14