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 6 of 6

Thread: VAO and attrib pointers to multiple shader progs

  1. #1
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    8

    VAO and attrib pointers to multiple shader progs

    Hello, I was wondering, is a VAO supposed to be able to keep track of shader attribute pointers to multiple programs?
    I.e. consider the following code:
    Code :
    glGenBuffers(1, &model.vertices);
    glBindBuffer(GL_ARRAY_BUFFER, model.vertices);
    glBufferData(GL_ARRAY_BUFFER, model.n_vertices*4*sizeof(float), shape.vertices, GL_STATIC_DRAW);
    glUseProgram(drawprog.program);
    glVertexAttribPointer(drawprog.vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(drawprog.vertexLocation);
    glUseProgram(shadowprog.program);
    glVertexAttribPointer(shadowprog.vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(shadowprog.vertexLocation);
     
    glGenBuffers(1, &model.normals);
    glBindBuffer(GL_ARRAY_BUFFER, model.normals);
    glBufferData(GL_ARRAY_BUFFER, model.n_vertices*3*sizeof(float), shape.normals, GL_STATIC_DRAW);
    glUseProgram(drawprog.program);
    glVertexAttribPointer(drawprog.normalLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(drawprog.normalLocation);
     
    glGenBuffers(1, &model.indices);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.indices);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, model.n_indices*sizeof(unsigned), shape.indices, GL_STATIC_DRAW);
     
    glBindVertexArray(0);

    This code renders correctly with nVidia proprietary drivers, but fails with ATI proprietary drivers as well as intel mesa drivers. Specifically, the shadowprog only draws the last of a list of primitives aka. models, while the drawprog draws correctly. If I comment out the block setting the normal attribute pointer for the drawprog, the shadowprog draws correctly on all GPUs (the drawprog obviously not).
    Can anyone clarify?
    Thanks!
    smani

  2. #2
    Member Regular Contributor
    Join Date
    Mar 2007
    Location
    CA
    Posts
    418

    Re: VAO and attrib pointers to multiple shader progs

    glUseProgram is not a part of the VAO/VBO state and hence nothing about it is stored in the VAO. So depending on the actual values of drawprog.vertexLocation, drawprog.normalLocation, and shadowprog.vertexLocation you are probably overwriting one of the attribute's "enabled" state. Does the following code work for you?

    Code :
    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
     
    glGenBuffers(1, &model.vertices);
    glBindBuffer(GL_ARRAY_BUFFER, model.vertices);
    glBufferData(GL_ARRAY_BUFFER, model.n_vertices*4*sizeof(float), shape.vertices, GL_STATIC_DRAW);
     
    glGenBuffers(1, &model.normals);
    glBindBuffer(GL_ARRAY_BUFFER, model.normals);
    glBufferData(GL_ARRAY_BUFFER, model.n_vertices*3*sizeof(float), shape.normals, GL_STATIC_DRAW);
     
    glGenBuffers(1, &model.indices);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.indices);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, model.n_indices*sizeof(unsigned), shape.indices, GL_STATIC_DRAW);
     
    glBindVertexArray(0);
    ... then when it comes to use the VAO with different Shader Programs
    Code :
    glBindVertexArray(vao);
     
    glUseProgram(drawprog.program);
    glBindBuffer(GL_ARRAY_BUFFER, model.vertices);
    glVertexAttribPointer(drawprog.vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(drawprog.vertexLocation);
    glBindBuffer(GL_ARRAY_BUFFER, model.normals);
    glVertexAttribPointer(drawprog.normalLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(drawprog.normalLocation);
    draw(...);
    glDisableVertexAttribArray(drawprog.vertexLocation);
    glDisableVertexAttribArray(drawprog.normalLocation);
     
    glUseProgram(shadowprog.program);
    glBindBuffer(GL_ARRAY_BUFFER, model.vertices);
    glVertexAttribPointer(shadowprog.vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(shadowprog.vertexLocation);
    draw(...);
    glDisableVertexAttribArray(shadowprog.vertexLocation);

  3. #3
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    8

    Re: VAO and attrib pointers to multiple shader progs

    Thanks for your reply. Yes, enabling all attributes separately works fine. I tried now manually generating the location identifiers and setting them with glBindAttribLocation, before linking the program. Again, this generally works fine on a nvidia card, though of the two example programs I am playing with, one does not render correctly with an ati card.
    If all manually provided location identifiers are unique and respect the fact that for instace for a 4x4 matrix, 4 identifiers are necessary, shouldn't it work? Thanks!

  4. #4
    Advanced Member Frequent Contributor
    Join Date
    Oct 2009
    Posts
    595

    Re: VAO and attrib pointers to multiple shader progs

    I am a follower of Dark Photon's advice, who advises us not to use VAO.

    Why? VAO does reduce state switches, but the GL will usually still switch between VBO's, which is supposedly expensive.

    If you VBO cache, VAO is irrelevant, since you don't know the pointers to attributes in advance.

  5. #5
    Member Regular Contributor
    Join Date
    Mar 2007
    Location
    CA
    Posts
    418

    Re: VAO and attrib pointers to multiple shader progs

    If all manually provided location identifiers are unique and respect the fact that for instace for a 4x4 matrix, 4 identifiers are necessary, shouldn't it work?
    I haven't tried that before so I cannot answer yes or no.

  6. #6
    Junior Member Newbie
    Join Date
    Dec 2010
    Posts
    8

    Re: VAO and attrib pointers to multiple shader progs

    Ok thanks

Posting Permissions

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