GLSL shader problem

Somewhat old thread here, but I was working on something involving GLSL today and was running into some problems along the lines described here. After staring at the C++ code for (quite) a while, I now believe that this is not actually a bug.

Starting with the sample shader code from above:

vshader = """
void main() {
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
"""

fshader = """
void main() {
    gl_FragColor = vec4(1.0, 0.5, 1.0, 1.0);
}
"""

Variable naming is very important here, and to my eye the C++ code is somewhat inconsistent in its handling of binding. For uniform variables either “gl_” or “p3d_” is acceptable, but for attributes only “p3d_” will be bound. So as a first pass, the code above needs to be changed to:

vshader = """
attribute vec4 p3d_Vertex;
void main() {
    gl_Position = gl_ModelViewProjectionMatrix * p3d_Vertex;
}
"""

That’ll get at least a pink blob rendered. To get it textured, it needs to look like this:

vshader = """
attribute vec4 p3d_Vertex;
attribute vec4 p3d_MultiTexCoord0;
void main() {
    gl_Position = gl_ModelViewProjectionMatrix * p3d_Vertex;
    gl_TexCoord[0] = p3d_MultiTexCoord0;
}
"""

fshader = """
uniform sampler2D p3d_Texture0;
void main() {
    gl_FragColor = texture2D(p3d_Texture0, gl_TexCoord[0].st);
}
"""

Note that:

  • “p3d_ModelViewProjectionMatrix” will work, and is probably a better choice than the “gl_” name used in the code above (I have a sneaking suspicion that the “gl_” version just works by accident).

  • “gl_MultiTexCoord0” won’t work, because attributes have to start with the “p3d_” prefix.

  • “gl_Texture0” doesn’t seem to work, in spite of it being a uniform, and unfortunately it doesn’t cause an error to be logged (I believe this is because anything beginning “gl_” is special to GLSL, so it isn’t even reported back to Panda’s C++ code).

  • “p3d_Texture[0…X]” is the only type of name that works for a sampler here (i.e. p3d_Tex0, etc. is no good), unless you explicitly declare a texture with the same name in your Panda code (using set_shader_input()). If you go that route, though, don’t name your variable “p3d_*” (i.e. use “Tex0”, not “p3d_Tex0”) or you’ll get an “Unrecognized uniform name” error. (For 90% of use cases, p3d_Texture[0…X] is your best bet.)

I’d recommend, then, that the original example should best be implemented as:

vshader = """
uniform mat4 p3d_ModelViewProjectionMatrix;
attribute vec4 p3d_Vertex;
attribute vec4 p3d_MultiTexCoord0;
void main() {
    gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
    gl_TexCoord[0] = p3d_MultiTexCoord0;
}
"""

fshader = """
uniform sampler2D p3d_Texture0;
void main() {
    gl_FragColor = texture2D(p3d_Texture0, gl_TexCoord[0].st);
}
"""

With this implementation I successfully got a textured smiley rendered in my window (caveat: I build my own Panda from the latest CVS sources, so there’s a chance there’s some other issue with recent public builds).

Given all of the above, I’m pretty sure that the bug mentioned previously in this thread (#912674) isn’t actually a problem, as the example code provided there is using “gl_” instead of “p3d_” throughout.

Hope all of this is of some help to the original posters, even at this late date. I’m going to be working in this general area of functionality for the next few days, so if anyone has additional problems/questions feel free to shout 'em out and I’ll see if I can help further.

–jonah