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.

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.

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!

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();

[QUOTE=cookedbird;1245965]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));

[/QUOTE]

Yup, you got it.