1

Though I've understood the state design of OpenGL enough to work with it, I've still struggled visualizing the inner workings on the CPU/GPU. Currently I'm stuck wondering how VBO's are copied onto the GPU using GL_ARRAY_BUFFER.

I previously understood the VBO's to be a 'state' of GL_ARRAY_BUFFER, this led me to 3 different options as to how that might work, shown below.

The top answer of the following thread explains: "The GL_ARRAY_BUFFER target for buffer objects represents the intent to use that buffer object for vertex attribute data" What does the GL_ARRAY_BUFFER target mean in glBindBuffer?

which, as I understand it, means that GL_ARRAY_BUFFER is sort of a 'state' of a VBO. It could have a different state, but it does require to have a state to be able to be copied onto 'the' GPU buffer/ a smaller allocated buffer on the GPU? Or am I misunderstanding it? does 'binding' mean something different from setting a state? (this 4th option is not visualized below).

Are any of these 4 ideas accurate? or is it something completely different? Apologies for the horrendous diagram. I hope it's clear enough though.

Any confirmation / correction would be greatly appreciated!

VBO path to GPU

I also looked though this post What exactly is a VBO in OpenGL? which states

"Since you use GL_ARRAY_BUFFER here as the target parameter, this operation (glBufferData(...)) will affect the BO which is currently bound as GL_ARRAY_BUFFER.

After doing all that, the VBO now contains all the vertex data within.

Basically, yes."

this implies the VBO memory on the GPU is set through the GL_ARRAY_BUFFER, which is what I understood at first.

options 3 & 4 seem most logical to me. Could it be that VBO and GL_ARRAY_BUFFER are both states of eachother simultaneously, depending on the context?: which VBO is active / which target is active for the VBO

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • All of the OpenGL commands have little to do with what the GPU does. The GPU most likely receives one big command, when you call glDrawArrays, telling it all of the vertex formats and vertex locations all at once. – user253751 Jan 04 '23 at 19:10

2 Answers2

3

Frankly, it's not any of the options you listed. GL_ARRAY_BUFFER is a client-side binding point that's used to name the active buffer that you operate on with other commands. It's used purely in communications with the driver. Furthermore, by means of DSA (direct state access, OpenGL 4.5+) you can fully set up a VBO without ever binding it to anything.

This is probably a better diagram to describe the situation:

diagram

Note the GL_ARRAY_BUFFER binding point can be tracked either by the driver or the user-process libGL. It's really not essential.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • Thank you for the quick response! It's much clearer now, especially with your handy diagram. I'm still new to OpenGL and haven't heard of DSA yet. I'm only familiar with the 'state' system described in the book LearnOpenGL by Joey de Vries. I have 1 follow-up question if you don't mind. Would you say most of the 'state' objects, e.g. the variables declared in glad.h (in my case): ... #define GL_ARRAY_BUFFER 0x8892 #define GL_ELEMENT_ARRAY_BUFFER 0x8893 #define GL_ARRAY_BUFFER_BINDING 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 ... are all also client-side? – HolyCowOfDoom Jan 04 '23 at 19:06
  • 1
    @HolyCowOfDoom the numbers themselves serve only their purpose to communicate between you and the driver. But some of them do correspond to actual GPU state more closely. For example `GL_ELEMENT_ARRAY_BUFFER` is part of a VAO state; this state will be sent in some form to the GPU when you issue a draw command so the GPU would know where to read the indices from. – Yakov Galka Jan 04 '23 at 19:20
1

glBufferData creates the buffer object and the data store of the buffer and optionally initializes the data. As long as glBufferData is not called there is no object and no reserved (GPU) data store. The buffer's size is immutable. glGenBuffers creates only the "name" of the buffer (the buffer ID).
Actually a buffer has no type. However, a buffer can be used for different things and to each target (like GL_ARRAY_BUFFER) a different buffer can be bound. GL_ARRAY_BUFFER is only used to identify the buffer in various API functions.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174