Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: glVertexAttribPointer

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

    glVertexAttribPointer

    According to the specification: http://www.opengl.org/sdk/docs/man3/...ribPointer.xml
    You can call this function when nothing is bound to GL_ARRAY_BUFFER, as long as your "pointer" or offset parameter is NULL. What does this do then? I thought whenever you called glVertexAttribPointer, whether you are using them in conjunction with a Vertex Array Object or not, there needs to be a vertex buffer object bound to GL_ARRAY_BUFFER, so that this generic vertex attribute "belongs" to a certain VBO.

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Apr 2010
    Location
    Germany
    Posts
    1,128
    First, you're mixing up the concepts of a VAO and a VBO. A VBO is merely a data store for some arbitrary vertex data. The VAO is used to not only store data, but to associate data and state. Therefore, when a vertex array object is currently bound and you call glVertexAttribPointer() the state you set with the call, if it is valid, will be stored as the specific state for the active VAO. This is NOT the case if you bind only a VBO. ATM I'm not quite sure if this also applies to the enabled/disabled state of generic vertex arrays (glEnabelVertexAttribArray() etc.).

    Second, the spec says that a non-zero VBO needs to be bound to GL_ARRAY_BUFFER if pointer is not NULL. Think about it. Since pointer is interpreted as a byte offset into a specific memory range, e.g. the space allocated for a specific buffer object, it would be rather undefined what such a pointer would mean if no buffer was bound. On the other hand, you can safely assume that an offset of NULL will have the attrib pointer point to the first element in the buffer. If you maintain different buffer objects for vertices, normals, tex coords and so on, this is not a problem. If, however, you want a single buffer with packed or interleaved data, you'll need a valid offset and possibly a stride to point to the correct sequence of elements in the buffer's memory.

    Questions?
    Last edited by thokra; 05-06-2012 at 03:18 AM. Reason: slight changes, typos

  3. #3
    Super Moderator OpenGL Guru
    Join Date
    Feb 2000
    Location
    Montreal, Canada
    Posts
    4,264
    If pointer is not NULL, a non-zero named buffer object must be bound to the
    GL_ARRAY_BUFFER target (see glBindBuffer),
    otherwise an error is generated
    According to them, if pointer is not NULL, you need to have a VBO bound?
    It seems to be suggesting that you can't source a RAM location.
    In GL 3 core, you can't use a RAM location?
    ------------------------------
    Sig: http://glhlib.sourceforge.net
    an open source GLU replacement library. Much more modern than GLU.
    float matrix[16], inverse_matrix[16];
    glhLoadIdentityf2(matrix);
    glhTranslatef2(matrix, 0.0, 0.0, 5.0);
    glhRotateAboutXf2(matrix, angleInRadians);
    glhScalef2(matrix, 1.0, 1.0, -1.0);
    glhQuickInvertMatrixf2(matrix, inverse_matrix);
    glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
    glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

  4. #4
    Senior Member OpenGL Pro
    Join Date
    Apr 2010
    Location
    Germany
    Posts
    1,128
    You can, but as I said before: What's the use of accessing some arbitrary location via a byte offset, if you have no idea if the corresponding address will be in the allocated space of the buffer object? It would be typical "undefined behavior".

  5. #5
    Junior Member Newbie
    Join Date
    May 2012
    Posts
    12
    Thanks for the responses, I really appreciate it.

    I don't think I'm mixing up VAO's and VBO's, but I may have not been clear in my original post. Here is what I mean. Let's say you have interleaved data in a VBO. You create a VAO, bind it, then calls to glVertexAttribPointer will both specify the format of the data (how many attributes, the type/size/number/stride/offset/etc. of each attribute), but also where that specific data is, the VBO currently bound to GL_ARRAY_BUFFER. You may unbind the VAO at this point.

    Now, when you want to render the model contained in that VBO, you bind the VAO to get the correct attributes, and do your draw call (glDrawArrays or whatever), then you can unbind the VAO or just go ahead and bind a new VAO to render a different model. No need to bind any VBOs at this point, because the correct VBO is stored as part of the VAO. This is what I mean by VAO's "belonging" to a certain VBO (edit: or set of VBO's, if you use separate VBO's for different attributes).

    So, that means, I can't do something like use one VAO to render many VBO's with similar attribute properties, right? Because each VAO is only associated with one (or one set) of VBO's.

    With that said, I'm guessing using glVertexAttribPointer without VAO's is similar. Each vertex attribute "belongs" to a certain VBO. If that is the case, how is it possible to call glVertexAttribPointer is nothing is bound to GL_ARRAY_BUFFER?

    Sorry if I'm fundamentally misunderstanding something.
    Last edited by redphi; 05-06-2012 at 03:06 PM.

  6. #6
    Super Moderator OpenGL Guru
    Join Date
    Feb 2000
    Location
    Montreal, Canada
    Posts
    4,264
    Yes, a VAO object tracks the pointers and also the VBO and IBO bound.
    You just bind the VAO and call glDraw_whatever.
    That's what I demonstrated in this tutorial.
    http://www.opengl.org/wiki/Tutorial1..._/_freeGLUT%29

    The case of VBO only, the states should be tracked as well.

    However, it sounds like you are coding for GL 3 and above, so you should always use VAO.
    Starting with GL 3.2 core, you no longer have a choice. You must use VAOs.
    ------------------------------
    Sig: http://glhlib.sourceforge.net
    an open source GLU replacement library. Much more modern than GLU.
    float matrix[16], inverse_matrix[16];
    glhLoadIdentityf2(matrix);
    glhTranslatef2(matrix, 0.0, 0.0, 5.0);
    glhRotateAboutXf2(matrix, angleInRadians);
    glhScalef2(matrix, 1.0, 1.0, -1.0);
    glhQuickInvertMatrixf2(matrix, inverse_matrix);
    glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
    glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

  7. #7
    Junior Member Newbie
    Join Date
    May 2012
    Posts
    12
    OK will do. VAO's are more convenient anyway. What's an IBO? Edit: "Index Buffer Object", got it
    Last edited by redphi; 05-06-2012 at 09:58 PM.

  8. #8
    Senior Member OpenGL Pro
    Join Date
    Apr 2010
    Location
    Germany
    Posts
    1,128
    Quote Originally Posted by redphi
    If that is the case, how is it possible to call glVertexAttribPointer is nothing is bound to GL_ARRAY_BUFFER?
    Because in that case the state of the attrib pointer is simply used for every subsequently bound VBO. The obvious drawback is that every buffer needs to be layed out to exactly match the pointer attributes. At least that's the way I understand this whole thing. To get around that, do what V-Man suggested (and is sound advice since VAO can significantly reduce API calls). However, be careful not to bind your VAOs to often and try to not use one VAO for one object if your object count is high (meaning more than a hundred or so) since VAO changes are supposedly expensive - at least time measurements if done using NVIDIA's Parallel Nsight suggest that.

  9. #9
    Junior Member Newbie
    Join Date
    May 2012
    Posts
    12
    Quote Originally Posted by thokra
    try to not use one VAO for one object if your object count is high
    Since a VAO tracks the pointers of certain, specific VBO's and IBO's as V-man said, how do you render two VBO's with one VAO? Or are you saying use the same VBO/VAO for multiple copies of the same object (though with possibly different positions, orientations, etc.)

  10. #10
    Senior Member OpenGL Pro
    Join Date
    Apr 2010
    Location
    Germany
    Posts
    1,128
    You don't. You still have one VBO, one VAO and one IBO. The difference is that the buffers store information of multiple objects. Then you can use http://www.opengl.org/sdk/docs/man3/...BaseVertex.xml or http://www.opengl.org/sdk/docs/man3/...BaseVertex.xml to render multiple objects with very few API calls. During all this you bind the VAO only a single time as long as you render objects from that buffer. One thing to be aware of is that you should only accumulate objects for a single draw call if they share the same shader which will further reduce API calls.

    Be aware however: This adds complexity to your code and it's usually not worth it when you object count is low enough. If you get to a few hundred or thousand it will most likely be worth the trouble. It can dramatically reduce API calls if done right. What's the worst case scenario you need to be able to handle?

Posting Permissions

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