Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 9 of 9

Thread: Order of function calls

  1. #1
    Junior Member Newbie
    Join Date
    Oct 2012
    Posts
    12

    Order of function calls

    I have a question about the order of these function calls:

    glBindBuffer(GL_ARRAY_BUFFER, buf1);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    Is it really necessary to bind a buffer before calling glVertexAttribPointer? glVertexAttribPointer sets the size, type, stride, normalization, and pointer (essentially an offset) into a buffer. It seems to me that these state values could be set without binding a buffer. Is this the case?

  2. #2
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    Is it really necessary to bind a buffer before calling glVertexAttribPointer?
    Yes, it really is. Or, if you don't want to read that:

    Quote Originally Posted by The Wiki
    Think of it like this. glBindBuffer​ sets a global variable, then glVertexAttribPointer​ reads that global variable and stores it in the VAO. Changing that global variable after it's been read doesn't affect the VAO. You can think of it that way because that's exactly how it works.

  3. #3
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,215
    Or from the classic documentation: http://www.opengl.org/sdk/docs/man/x...ribPointer.xml

    If a non-zero named buffer object is bound to the GL_ARRAY_BUFFER target (see glBindBuffer) while a generic vertex attribute array is specified, pointer is treated as a byte offset into the buffer object's data store.
    GL4.3 or the GL_ARB_vertex_attrib_binding extension will remove the dependency on the currently bound buffer when specifying vertex formats and layouts.

  4. #4
    Junior Member Newbie
    Join Date
    Oct 2012
    Posts
    12
    Thanks for the replies. I did some experimenting last night on my mac. If I place the calls to glVertexAttribPointer before binding my buffers, I get garbage on the screen. No errors, just garbage. This doesn't happen if the binding occurs before the calls to glVertexAttribPointer.

    Let me see if I understand the implications. glBindBuffer does not affect the VAO. However, glVertexAttribPointer does affect the VAO. In addition to storing the size, type, stride, and normalization state information, does glVertexAttribPointer also store the address of the buffer in the VAO? In the example that I gave, buf1 is associated with the target GL_ARRAY_BUFFER. I'll represent this conceptually as GL_ARRAY_BUFFER = ADDRESS(buf1). The pointer parameter to glVertexAttribPointer is an offset. So, I am thinking that glVertexAttribPointer is storing GL_ARRAY_BUFFER + pointer in the VAO which is the address of buf1 plus the offset passed to the function.

  5. #5
    Junior Member Newbie
    Join Date
    Oct 2012
    Posts
    12
    Another quick question about this topic. Let's say I make multiple calls to bind three different buffers to the same target (GL_ARRAY_BUFFER). glVertexAttribPointer is called for each and in each case the index parameter (the first parameter) to glVertexAttribPointer is different:

    glBindBuffer(GL_ARRAY_BUFFER, buf1);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ARRAY_BUFFER, buf2);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ARRAY_BUFFER, buf3);
    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);


    Will the state information for all three be stored in the VAO? Or will the latest calls to glBindBuffer/glVertexAttribPointer overwrite what was previously saved in the VAO? I assume that all three are stored because the index parameter differs for each even though the target (GL_ARRAY_BUFFER) is the same in each case.

  6. #6
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    456
    Yes, all 3 are stored since you used different attribute indices.

  7. #7
    Junior Member Newbie
    Join Date
    Oct 2012
    Posts
    12
    Thanks Dan!

  8. #8
    Advanced Member Frequent Contributor arekkusu's Avatar
    Join Date
    Nov 2003
    Posts
    783
    Search for "ARRAY_BUFFER_BINDING" in the specification and you'll see this explained in the "Vertex Arrays in Buffer Objects" section.

    And in the "Vertex Array Object State" table, showing exactly what state is tracked where.

  9. #9
    Junior Member Newbie
    Join Date
    Oct 2012
    Posts
    12
    arekkusu, thanks for the tip.

    I found ARRAY_BUFFER_BINDING in section 2.9.6 of the 3.2core spec. The spec isn't very clear. ARRAY_BUFFER_BINDING is mentioned only once: "For example, the VertexAttribPoint command copies the value of ARRAY_BUFFER_BINDING (the queriable name of the buffer binding corresponding to the target ARRAY_BUFFER) to the client state variable VERTEX_ATTRIB_ARRAY_BUFFER_BINDING for the specified index."

    This is the only place that I could find ARRAY_BUFFER_BINDING mentioned in the text of the spec. It has a value which apparently corresponds to the "queriable name of the buffer binding corresponding to the target ARRAY_BUFFER."

    I know what a buffer is. But what is a buffer binding? It is first mentioned on the top of page 44 but the term is not defined. I searched Google but also came up short for a definition. Whatever it is, it is an integer and apparently has a name.

    Table 6.6 does include ARRAY_BUFFER_BINDING and says that it is a positive integer, has an initial value of 0, and is described as the "current buffer binding."

    Section 2.9.1 describes creating and binding buffer objects. I am guessing that a call to BindBuffer creates a buffer binding. However, the spec doesn't explicitly say if this is the case. Table 6.6 provides some hints. The caption of table 6.6 says, "Vertex Array Data (not in Vertex Array objects)." There are four rows in the table. As already mentioned, one of the four rows contains ARRAY_BUFFER_BINDING. So, it appears that ARRAY_BUFFER_BINDING is the name of a state variable that is not stored in a VAO. Its value is the name of the current buffer binding. Now, GenBuffers reserves and returns buffer object names. Let's see if we can put this all together.

    A call to GenBuffers returns one or more buffer object names. At the time GenBuffers is called, a buffer object name is reserved but no buffer has been bound. To bind a buffer we need to call BindBuffer and pass a target (in this case the value ARRAY_BUFFER) and a buffer object name. At this point a buffer has been created, associated with a name, and bound to the target.

    A side effect of calling BindBuffer is the setting of state variable(s). One state variable is referred to as ARRAY_BUFFER_BINDING. Its value is set to the name of the buffer object that was passed to BindBuffer. The state variable appears to have global scope because it is not stored in any VAO according to table 6.6.

    It seems that this scenario could be represented as follows:

    // The function BindBuffer
    BindBuffer(target, name)
    {
    ...
    IF (target == ARRAY_BUFFER)
    GlobalState[ARRAY_BUFFER_BINDING] = name;
    ...
    }

    // get a bunch of buffer object names
    GenBuffers(n, buffers);

    // get one of the buffer object names
    name = buffers[i];

    // bind the buffer object name to the target ARRAY_BUFFER
    BindBuffer(ARRAY_BUFFER, name);

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •