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

Thread: Help: Telling one mesh from another in the vertex shader

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

    Help: Telling one mesh from another in the vertex shader

    Sorry if this is vague, but I don't really know what I'm looking for to solve this, and I don't really know what to ask. I have a couple different meshes that I am rendering with different vbos. What I want is to give each mesh a position vector (and possibly more info later on, such as a skeleton animation) that it will use to calculate the new position of the mesh in the vertex shader. Right now I am giving each vertex an attribute called meshID which then gets the mesh's position vector from a uniform vec3 array. I feel like there must be a better way of telling each mesh apart or even assigning attributes to each mesh, but I don't know what it would be.

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,184
    Quote Originally Posted by cookedbird View Post
    Right now I am giving each vertex an attribute called meshID which then gets the mesh's position vector from a uniform vec3 array. I feel like there must be a better way of telling each mesh apart or even assigning attributes to each mesh, but I don't know what it would be.
    The typical way to deal with this is to pass the constant per-vertex data you need for each vertex in via vertex attribute arrays (position, normal, bone/joint indices and weights, etc.). The card knows well in advance of your shader executing for a vertex what input data it needs to feed to the vertex shader, so that streams really well (sequential access, with prefetch; read: fast).

    And the data that might be "shared" by multiple vertices (e.g. skeletal animation joint/bone skinning transforms, etc.) is often provided via uniform data (textures and otherwise) and "looked up" by the shader as-needed. That's potentially random access though without prefetch where the GPU doesn't know that you need that until it tries to execute that line in your shader (but texture/uniform caches managed under-the-covers as well as workgroup suspension help with the latency).

    That said, you could instead make all of your per-vertex mesh input data available via uniforms (textures, etc.) and just look up into it via a vertex ID and some "mesh ID uniform or mesh buffer binding" (it sounds like this is what you're contemplating). However, here you're pitting potential random access against sequential access with prefetch for just looking up the basic constant per-vertex input data, which in the general case is more difficult to make fast.

    When in doubt, try it both ways and see! Experience really helps to lock it in.
    Last edited by Dark Photon; 12-18-2012 at 10:50 AM.

  3. #3
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    8
    so I want to do your "looked up" by the shader but I don't know how. what it sounds like you said is something like

    uniform mat4 skeleton[][];
    in int joint;

    void main(void)
    {
    mat4 mjoint = skeleton[meshID][joint];
    ....
    }

    Is that what you are talking about? If so how would I get the meshID, or am I just reading what you wrote wrong. I feel like I'm missing some key fact.
    Thanks for replying!
    Last edited by cookedbird; 12-18-2012 at 11:43 AM.

  4. #4
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    8
    Okay, I think I realized what my problem was. I didn't realize that you could change uniforms between draw calls, I thought everything was drawn once glFlush was called or something like that, so I thought it would be pointless to change the uniform. But if I understand right I can do something like this...

    glBindBuffer(GL_ARRAY_BUFFER, vbo_1);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_1);
    glUniform1fv(uniform_ skeleton, 10, skeleton_1);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));

    glBindBuffer(GL_ARRAY_BUFFER, vbo_2);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_2);
    glUniform1fv(uniform_ skeleton, 10, skeleton_2);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));

    glutSwapBuffers();

  5. #5
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,184
    Quote Originally Posted by cookedbird View Post
    Okay, I think I realized what my problem was. I didn't realize that you could change uniforms between draw calls, I thought everything was drawn once glFlush was called or something like that, so I thought it would be pointless to change the uniform. But if I understand right I can do something like this...

    Code cpp:
    glBindBuffer(GL_ARRAY_BUFFER, vbo_1);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_1);
    glUniform1fv(uniform_ skeleton, 10, skeleton_1);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
     
    glBindBuffer(GL_ARRAY_BUFFER, vbo_2);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_2);
    glUniform1fv(uniform_ skeleton, 10, skeleton_2);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
    Yup, you got it.

Posting Permissions

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