Your problem is that LightPosition isn't declared as a uniform. It should be declared like this:
uniform vec3 LightPosition;
Add this to the GLSL class:
void uniform3f(int location, float v0, float v1, float v2)
{
gl.glUniform3fARB(location, v0, v1, v2);
}
You will now need to actually initialize the LightPosition parameter. After startShader()
, but before you call glutSolid()
, do this:
glsl.uniform3f(glsl.getUniformLocation("LightPosition"), 10.0, 10.0, 20.0);
That should work (it worked for me).
It is very simple, really. All you need is to bind the sampler to some texture unit with glUniform1i
. So for your code sample, assuming the two uniform samplers:
uniform sampler2D DecalTex; // The texture (we'll bind to texture unit 0)
uniform sampler2D BumpTex; // The bump-map (we'll bind to texture unit 1)
In your initialization code:
// Get the uniform variables location. You've probably already done that before...
decalTexLocation = glGetUniformLocation(shader_program, "DecalTex");
bumpTexLocation = glGetUniformLocation(shader_program, "BumpTex");
// Then bind the uniform samplers to texture units:
glUseProgram(shader_program);
glUniform1i(decalTexLocation, 0);
glUniform1i(bumpTexLocation, 1);
OK, shader uniforms set, now we render. To do so, you will need the usual glBindTexture
plus glActiveTexture
:
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
glBindTexture(GL_TEXTURE_2D, decalTexHandle);
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
glBindTexture(GL_TEXTURE_2D, bumpHandle);
// Done! Now you render normally.
And in the shader, you will use the textures samplers just like you already do:
vec4 a = texture2D(DecalTex, tc);
vec4 b = texture2D(BumpTex, tc);
Note: For techniques like bump-mapping, you only need one set of texture coordinates, since the textures are the same, only containing different data. So you should probably pass texture coordinates as a vertex attribute.
Best Answer
One option is to pass information via uniform variables.
After
you can use
and for example
In your vertex or fragment shader, you need to add the following declaration:
That's it, in your shader you can now access (read-only) the value you passed earlier on via
glUniform1f
.Of course uniform variables can be any valid GLSL type including complex types such as arrays, structures or matrices. OpenGL provides a
glUniform
function with the usual suffixes, appropriate for each type. For example, to assign to a variable of typevec3
, one would useglUniform3f
orglUniform3fv
.Note: the value can't be modified during execution of the shader, i.e. in a
glBegin
/glEnd
block. It is read-only and the same for every fragment/vertex processed.There are also several tutorials using uniforms, you can find them by googling "glsl uniform variable".
I hope that helps.