multitexturing and glsl

Hi all,

I know how to use multitextures in glsl. However I couldn’t manage to write JOGL code to load multitextures to texture units. I only need the java code that sends textures to shaders. Here is what I do:


    ...

    int vertexShader = loadShader(gl, GL.GL_VERTEX_SHADER, shader + ".vert");
    int fragmentShader = loadShader(gl, GL.GL_FRAGMENT_SHADER, shader + ".frag");
    
    program = createProgram(gl, vertexShader, fragmentShader);
    
    colorMap = gl.glGetUniformLocation(program, "colorMap");
    normalMap = gl.glGetUniformLocation(program, "normalMap");

    try
    {
      Texture texture;
      
      gl.glActiveTexture(GL.GL_TEXTURE0);
      texture = TextureIO.newTexture(getFile("color_map.jpg"), false);
      gl.glBindTexture(GL.GL_TEXTURE_2D, texture.getTextureObject());
      
      gl.glActiveTexture(GL.GL_TEXTURE1);
      texture = TextureIO.newTexture(getFile("normal_map.jpg"), false);
      gl.glBindTexture(GL.GL_TEXTURE_2D, texture.getTextureObject());
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }

    ...

    gl.glUseProgram(program);
    gl.glUniform1i(colorMap, 0);
    gl.glUniform1i(normalMap, 1);

    gl.glBegin(GL.GL_QUADS);
    gl.glMultiTexCoord2f(GL.GL_TEXTURE0, 0, 0);
    gl.glMultiTexCoord2f(GL.GL_TEXTURE1, 0, 0);
    gl.glVertex2f(0, 0);
    gl.glMultiTexCoord2f(GL.GL_TEXTURE0, 1, 0);
    gl.glMultiTexCoord2f(GL.GL_TEXTURE1, 1, 0);
    gl.glVertex2f(1, 0);
    gl.glMultiTexCoord2f(GL.GL_TEXTURE0, 1, 1);
    gl.glMultiTexCoord2f(GL.GL_TEXTURE1, 1, 1);
    gl.glVertex2f(1, 1);
    gl.glMultiTexCoord2f(GL.GL_TEXTURE0, 0, 1);
    gl.glMultiTexCoord2f(GL.GL_TEXTURE1, 0, 1);
    gl.glVertex2f(0, 1);
    gl.glEnd();

vertex shader


void main()
{
  gl_TexCoord[0] = gl_MultiTexCoord0;
  gl_TexCoord[1] = gl_MultiTexCoord1;
  gl_Position = ftransform();
} 

fragement shader


uniform sampler2D colorMap;
uniform sampler2D normalMap;

void main()
{
  vec3 normal = normalize(texture2D(normalMap, gl_TexCoord[1].st).xyz);
  
  vec3 lightVector = vec3(0, 0, 1);
  
  float intensity = max(dot(normal, lightVector), 0);
  
  gl_FragColor = intensity * texture2D(colorMap, gl_TexCoord[0].st);
}

any help?

thanks in advance,
Ozgur

i think you shouldnt put 0 and 1 in your glUniform call, but rather the ids of your textures

confusing isn’t it. this 0 and 1 are the ids of texture units that are activated with gl.glActiveTexture(GL.GL_TEXTURE_0);

hi,

you should rather use glUniform1i(…) for texture ids instead of the float version of the method. On the other side in the GLSL shader use uniform sampler[1,2,3…]D colorMap etc to store the ids.

[edit]
btw setting uniforms is slow on some hardware, try to set those on init rather on render if possible…

still doesn’t work

move it below useProgram()…

I tried that too

ok, i give up for now :wink: continuing when i am at home

well, i still think that you shouldnt use 0 and 1 but rather the ids of the texture objects.

you didn’t look reply#1 and reply#2…

well, i did look at those replies, but maybe i am not getting things here…

only thing i can say is, that in my shaders i use glUniform with the id of the texture objects and it works perfectly like this:

glUniform1i( location, texture.getId() );

Hope this clarifies things (although I’m not sure how yours worked emzic?):

[quote]Samplers are special uniforms used in the OpenGL Shading Language to identify
the texture object used for each texture lookup. The value of a sampler indicates
the texture image unit being accessed.
… Sampler values need to be set by calling Uniform1i
[/quote]
My only suggestion is to call glEnable(GL.GL_TEXTURE_2D) for each texture unit. The spec said the sampler used the currently bound texture for it’s unit, but maybe it has to be enabled too?

Thanks for all the answers. I figured out what are prone to problems:

1 - uniform setting must be after useProgram, at least for the first time.
2 - textures don’t need to be enabled or disabled, binding to texture unit is enough.
3 - multi texture coordinates are not a must, when textures are mapped identically.