Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concept behind OpenGL's 'Bind' functions

Tags:

opengl

I am learning OpenGL from this tutorial. My question is about the specification in general, not about a specific function or topic. When seeing code like the following:

glGenBuffers(1, &positionBufferObject); glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); 

I'm confused about the utility of calling the bind functions before and after setting the buffer data. It seems superfluous to me, due to my inexperience with OpenGL and Computer Graphics in general.

The man page says that:

glBindBuffer lets you create or use a named buffer object. Calling glBindBuffer with target set to GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER or GL_PIXEL_UNPACK_BUFFER and buffer set to the name of the new buffer object binds the buffer object name to the target. When a buffer object is bound to a target, the previous binding for that target is automatically broken.

What exactly is the concept/utility of 'binding' something to a 'target' ?

like image 610
manasij7479 Avatar asked Mar 18 '12 13:03

manasij7479


People also ask

What does it mean to bind in OpenGL?

A Binding Point specifies the behavior of the OpenGL object. Binding Points, also known as Targets, allows OpenGL objects to be used for different purposes. The most common binding points are: GL_ARRAy_BUFFER.

What does bind buffer do?

DNA Binding Buffer is designed for use in the DNA Clean & Concentrator family of products. This buffer facilities efficient binding and recovery of DNA from enzymatic reactions and impure DNA samples.

What is a VAO in OpenGL?

A Vertex Array Object (VAO) is an OpenGL Object that stores all of the state needed to supply vertex data (with one minor exception noted below). It stores the format of the vertex data as well as the Buffer Objects (see below) providing the vertex data arrays.

What is a binding point?

A bind point refers to a place in a video game where a character will be sent to after using a particular item. Depending on the video game, the bind point is a specific building, a boat, a particular landmark or a specific set of coordinates.


2 Answers

the commands in opengl don't exist in isolation. they assume the existence of a context. one way to think of this is that there is, hidden in the background, an opengl object, and the functions are methods on that object.

so when you call a function, what it does depends on the arguments, of course, but also on the internal state of opengl - on the context/object.

this is very clear with bind, which says "set this as the current X". then later functions modify the "current X" (where X might be buffer, for example). [update:] and as you say, the thing that is being set (the attribute in the object, or the "data member") is the first argument to bind. so GL_ARRAY_BUFFER names a particular thing that you are setting.

and to answer the second part of the question - setting it to 0 simply clears the value so you don't accidentally make unplanned changes elsewhere.

like image 112
andrew cooke Avatar answered Oct 21 '22 15:10

andrew cooke


The OpenGL technique can be incredibly opaque and confusing. I know! I've been writing 3D engines based upon OpenGL for years (off and on). In my case part of the problem is, I write the engine to hide the underlying 3D API (OpenGL), so once I get something working I never see the OpenGL code again.

But here is one technique that helps my brain comprehend the "OpenGL way". I think this way of thinking about it is true (but not the whole story).

Think about the hardware graphics/GPU cards. They have certain capabilities implemented in hardware. For example, the GPU may only be able to update (write) one texture at a time. Nonetheless, it is mandatory that the GPU contain many textures within the RAM inside the GPU, because transfer between CPU memory and GPU memory is very slow.

So what the OpenGL API does is to create the notion of an "active texture". Then when we call an OpenGL API function to copy an image into a texture, we must do it this way:

1:  generate a texture and assign its identifier to an unsigned integer variable. 2:  bind the texture to the GL_TEXTURE bind point (or some such bind point). 3:  specify the size and format of the texture bound to GL_TEXTURE target. 4:  copy some image we want on the texture to the GL_TEXTURE target. 

And if we want to draw an image on another texture, we must repeat that same process.

When we are finally ready to render something on the display, we need our code to make one or more of the textures we created and copied images upon to become accessible by our fragment shader.

As it turns out, the fragment shader can access more than one texture at a time by accessing multiple "texture units" (one texture per texture unit). So, our code must bind the textures we want to make available to the texture units our fragment shaders expect them bound to.

So we must do something like this:

glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, mytexture0);  glActiveTexture (GL_TEXTURE1); glBindTexture (GL_TEXTURE_2D, mytexture1);  glActiveTexture (GL_TEXTURE2); glBindTexture (GL_TEXTURE_2D, mytexture2);  glActiveTexture (GL_TEXTURE3); glBindTexture (GL_TEXTURE_2D, mytexture3); 

Now, I must say that I love OpenGL for many reasons, but this approach drive me CRAZY. That's because all the software I have written for years would look like this instead:

error = glSetTexture (GL_TEXTURE0, GL_TEXTURE_2D, mytexture0); error = glSetTexture (GL_TEXTURE1, GL_TEXTURE_2D, mytexture1); error = glSetTexture (GL_TEXTURE2, GL_TEXTURE_2D, mytexture2); error = glSetTexture (GL_TEXTURE3, GL_TEXTURE_2D, mytexture3); 

Bamo. No need for setting all this state over and over and over again. Just specify which texture-unit to attach the texture to, plus the texture-type to indicate how to access the texture, plus the ID of the texture I want to attach to the texture unit.

I also wouldn't need to bind a texture as the active texture to copy an image to it, I would just give the ID of the texture I wanted to copy to. Why should it need to be bound?

Well, there's the catch that forces OpenGL to be structured in the crazy way it is. Because the hardware does some things, and the software driver does other things, and because what is done where is a variable (depends on GPU card), they need some way to keep the complexity under control. Their solution is essentially to have only one bind point for each kind of entity/object, and to require we bind our entities to those bind points before we call functions that manipulate them. And as a second purpose, binding entities is what makes them available to the GPU, and our various shaders that execute in the GPU.


At least that's how I keep the "OpenGL way" straight in my head. Frankly, if someone really, really, REALLY understands all the reasons OpenGL is (and must be) structured the way it is, I'd love them to post their own reply. I believe this is an important question and topic, and the rationale is rarely if ever described at all, much less in a manner that my puny brain can comprehend.

like image 26
honestann Avatar answered Oct 21 '22 16:10

honestann