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 16

Thread: Questions about and glVertexAttribPointer and the fixed function pipeline

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2018
    Posts
    8

    Questions about and glVertexAttribPointer and the fixed function pipeline

    Firstly, about the programmable pipeline:

    Using the OpenGL 3.3 Core specification, when I call glVertexAttribPointer with a pointer of 0 (or nullptr) and no VBO bound, I never get a GL_INVALID_OPERATION error. No errors, what?!

    The specification (https://www.khronos.org/registry/Ope...pec33.core.pdf) says on page 344: Calling VertexAttribPointer when no buffer object or no vertex array object is bound will generate an INVALID_OPERATION error, as will calling any array drawing command when no vertex array object is bound.

    Q1: Does this mean that the driver has this function implemented incorrectly? If not then what is the use of passing no VBO and 0 to glVertexAttribPointer?

    Code :
    glBindBuffer(GL_ARRAY_BUFFER, 0);
     
    glVertexAttribPointer(index, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (void *) 0);

    Secondly, about the fixed function pipeline:

    Q2: In OpenGL 3.1 or a compatibility context, how does glDrawArrays know whether to use immediate mode (glEnableClientState and glVertexPointer) vs modern glVertexAttribPointer calls? Is it if a shader is bound, it uses modern and if no shader is bound it uses immediate? What happens if I mix together immediate mode, then move to modern halfway through?
    Q3: Following up: is it possible to use any modern OpenGL with the old immediate mode together? For example, send vertex data via glVertex3f then process it through a programmable shader? (Guessing not, but wanted to ask)
    Q4: And finally: if the fixed function pipeline didn't have shaders, does this mean that many complex graphics effects just weren't possible before shaders or had to be done on the CPU? Was very old hardware specifically designed for fixed function only?

    Thanks, much appreciated if anyone can answer one or all questions! I'm not using immediate mode, but wanted to know how it worked.

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,828
    Quote Originally Posted by BingoBingo View Post
    Using the OpenGL 3.3 Core specification, when I call glVertexAttribPointer with a pointer of 0 (or nullptr) and no VBO bound, I never get a GL_INVALID_OPERATION error. No errors, what?!

    The specification (https://www.khronos.org/registry/Ope...pec33.core.pdf) says on page 344: Calling VertexAttribPointer when no buffer object or no vertex array object is bound will generate an INVALID_OPERATION error, as will calling any array drawing command when no vertex array object is bound.

    Q1: Does this mean that the driver has this function implemented incorrectly? If not then what is the use of passing no VBO and 0 to glVertexAttribPointer?
    The specification of glVertexAttribPointer() in 2.8 says
    An INVALID_OPERATION error is generated under any of the following conditions:
    ...
    * any of the *Pointer commands specifying the location and organization of vertex array data are called while zero is bound to the ARRAY_BUFFER buffer object binding point (see section 2.9.6), and the pointer argument is not NULL.
    AFAICT, the only point is to provide a way to reset the state to its initial value (where the buffer is zero and the pointer is null).

    Quote Originally Posted by BingoBingo View Post
    Secondly, about the fixed function pipeline:

    Q2: In OpenGL 3.1 or a compatibility context, how does glDrawArrays know whether to use immediate mode (glEnableClientState and glVertexPointer) vs modern glVertexAttribPointer calls? Is it if a shader is bound, it uses modern and if no shader is bound it uses immediate? What happens if I mix together immediate mode, then move to modern halfway through?
    "Immediate mode" means glBegin/glEnd.

    If you use glDraw*, then it uses all enabled arrays, both for fixed-function attributes (position, colour, normal, texture coordinates, fog coordinates) and generic attributes. Note that the position attribute (glVertexPointer, glVertex) is mapped to generic attribute zero (in particular, calling glVertexAttrib*(0,...) inside glBegin/glEnd emits a new vertex).

    Quote Originally Posted by BingoBingo View Post
    Q3: Following up: is it possible to use any modern OpenGL with the old immediate mode together? For example, send vertex data via glVertex3f then process it through a programmable shader? (Guessing not, but wanted to ask)
    Yes. Fixed-function attributes are available in the vertex shader via compatibility input variables (gl_Position, gl_Color, etc). Fixed-function state is available in any shader via compatibility uniform variables. These are documented in the GLSL specification.

    Quote Originally Posted by BingoBingo View Post
    Q4: And finally: if the fixed function pipeline didn't have shaders, does this mean that many complex graphics effects just weren't possible before shaders or had to be done on the CPU?
    Yes.
    Quote Originally Posted by BingoBingo View Post
    Was very old hardware specifically designed for fixed function only?
    Yes. The Geforce 3 (ca 2001) was the first GPU to support programmable shaders.

  3. #3
    Junior Member Newbie
    Join Date
    Jan 2018
    Posts
    8
    Thanks for all the answers! They really help.

    Quote Originally Posted by GClements View Post
    The specification of glVertexAttribPointer() in 2.8 says
    I understand this but that is more for old times when glVertexAttribPointer could be used with a regular pointer to main memory. I'm specifically wondering why what is written in the spec isn't what happens in reality:

    Client vertex and index arrays - all vertex array attribute and element array index pointers must refer to buffer objects. The default vertex array object (the name zero) is also deprecated. Calling VertexAttribPointer when no buffer object or no vertex array object is bound will generate an INVALID_OPERATION error, as will calling any array drawing command when no vertex array object is bound.
    This is written in the core specification and is not what happens in my code... which is why I'm confused. If they wrote that in the spec, surely it should be implemented similarly?

    To satisfy the full specification, surely the driver should have thrown an invalid operation with no buffer being bound..?

    Also, side note, isn't gl_Position the output and gl_Vertex the input?

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,828
    Quote Originally Posted by BingoBingo View Post
    This is written in the core specification and is not what happens in my code... which is why I'm confused. If they wrote that in the spec, surely it should be implemented similarly?
    There are two descriptions in the specification: one in 2.8 and one in E.2.2. The latter omits the "and the pointer argument is not NULL" part. The former is normative; the latter simply attempts to summarise the change.

    Quote Originally Posted by BingoBingo View Post
    To satisfy the full specification, surely the driver should have thrown an invalid operation with no buffer being bound..?
    No. The actual specification of glVertexAttribPointer() is explicit that it only raises GL_INVALID_OPERATION when no buffer is bound and the pointer argument is not NULL.

    Quote Originally Posted by BingoBingo View Post
    Also, side note, isn't gl_Position the output and gl_Vertex the input?
    That's correct. gl_Vertex is the compatibility attribute.

  5. #5
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,394
    Quote Originally Posted by GClements View Post
    No. The actual specification of glVertexAttribPointer() is explicit that it only raises GL_INVALID_OPERATION when no buffer is bound and the pointer argument is not NULL.
    Yes, and that's only going to be true if you're using an OpenGL Core profile, not an OpenGL Compatibility profile. So if you want that behavior, make sure you're creating a GL context in the Core profile.

  6. #6
    Junior Member Newbie
    Join Date
    Jan 2018
    Posts
    8
    Quote Originally Posted by Dark Photon View Post
    Yes, and that's only going to be true if you're using an OpenGL Core profile, not an OpenGL Compatibility profile. So if you want that behavior, make sure you're creating a GL context in the Core profile.
    When it says "are sourced from buffers if the array’s buffer binding is non-zero" (Compat 3.3 2.9.6, pg 62 here) does buffer binding refer to GL_ARRAY_BUFFER or to the currently bound VAO?

    I just created a Compatibility profile and:

    Compat (pointer = null):
    VAO: NOT BOUND & VBO: NOT BOUND RESULT: NO ERROR
    VAO: BOUND & VBO: NOT BOUND RESULT: NO ERROR
    VAO: NOT BOUND & VBO: BOUND RESULT: NO ERROR
    VAO: BOUND & VBO: BOUND RESULT: NO ERROR

    Compat (pointer = to a client mem address, not offset):
    VAO: NOT BOUND & VBO: NOT BOUND RESULT: NO ERROR
    VAO: BOUND & VBO: NOT BOUND RESULT: INVALID_OPERATION
    VAO: NOT BOUND & VBO: BOUND RESULT: NO ERROR
    VAO: BOUND & VBO: BOUND RESULT: NO ERROR

    Core (pointer = null):
    VAO: NOT BOUND & VBO: NOT BOUND RESULT: INVALID_OPERATION
    VAO: BOUND & VBO: NOT BOUND RESULT: NO ERROR
    VAO: NOT BOUND & VBO: BOUND RESULT: INVALID_OPERATION
    VAO: BOUND & VBO: BOUND RESULT: NO ERROR

    Core (pointer = to client mem address, not offset):
    VAO: NOT BOUND & VBO: NOT BOUND RESULT: INVALID_OPERATION
    VAO: BOUND & VBO: NOT BOUND RESULT: INVALID_OPERATION
    VAO: NOT BOUND & VBO: BOUND RESULT: INVALID_OPERATION
    VAO: BOUND & VBO: BOUND RESULT: NO ERROR
    For Core, this makes perfect sense. You need a VAO bound always, and you need a VBO bound if pointer is not null.
    For Compatibility, it allows everything that core allows, plus it also has no error when a VAO is not bound.

    When a VAO is not bound, am I correct in saying that the pointer argument is interpreted as a client memory address? I couldn't find this in the spec.

  7. #7
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    6,008
    Quote Originally Posted by BingoBingo View Post
    When a VAO is not bound, am I correct in saying that the pointer argument is interpreted as a client memory address?
    How do you think we used buffer objects before VAOs?

    In the compatibility profile, VAO 0 is merely the default vertex array object. It cannot be deleted, but in every other way, it acts like a proper VAO. In the core profile, VAO 0 is not a valid VAO, so attempting to modify it (by binding 0 and calling VAO-modifying functions) will result in an error.

  8. #8
    Junior Member Newbie
    Join Date
    Jan 2018
    Posts
    8
    Ah, I think that makes sense! Just got confused as it said VBOs were added in 1.5 and VAOs in 3.0 and I can't say I like how OpenGL reused the same functions for multiple purposes.

    From how I understand it now:

    1. The no array buffer was bound for the attribute (zero) then it sources from client memory (for compatibility), if it's not zero then it sources from the buffer as an offset (modern).
    2. VAOs are always bound regardless of compatibility or not, just a default VAO is created in compatibility for you (but a VAO must be bound initially in modern).
    3. Any attributes that are disabled but used in the shaders are sourced from the client's state and can be set (almost as a default/uniform value) by glVertexAttrib* commands.
    4. There are many ways to send attributes to shaders in compatibility e.g: glBegin, glVertex3f, glEnd or sourced from client memory or sourced from a server-side buffer object.

    Feel free to correct any of these if wrong but that's the gist that I've understood from all the replies.

    Need to play around with some compatibility stuff to really get a grip on it.

    Really appreciate all the replies, and my only other question is: what is the point of keeping VertexAttrib* functions around as opposed to just sending in Uniforms? They are both constants, non-changing per vertex.
    Last edited by BingoBingo; 01-25-2018 at 09:08 AM.

  9. #9
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,828
    Quote Originally Posted by BingoBingo View Post
    what is the point of keeping VertexAttrib* functions around as opposed to just sending in Uniforms? They are both constants, non-changing per vertex.
    Attributes can change per vertex. So if something is an attribute (vertex shader input variable), you can provide either a value for each vertex with glVertexAttribPointer() or a single value for all vertices with glVertexAttrib().

    Also, it makes it easier to retro-fit shaders to legacy code which uses glBegin/glEnd.

  10. #10
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    6,008
    I can't say I like how OpenGL reused the same functions for multiple purposes.
    Nobody's forcing you to use them.

    what is the point of keeping VertexAttrib* functions around as opposed to just sending in Uniforms?
    Stuff in OpenGL is like candy; it doesn't have to have a point.

    What is the state of a VS input linked to a disabled array? The answer to that will either be an error at draw time (yet one more), undefined behavior (we've got plenty of that too), or a default value. And by and large, OpenGL's design has preferred defaults to errors and UB (see default textures and so forth).

    So if implementations already have to allow some kind of default value anyway, allowing users to set those defaults does no real harm. Well, save the fact that, by having the feature around, it suggests that it would be a good idea to use it. And it isn't, but that's a bridge we already crossed when we allowed defaults in the first place.

Posting Permissions

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