Can't get multitexturing to work

Member
Posts: 35
Joined: 2009.10
Post: #1
I have two textures I want to draw in a quad using a shader that will combine them, but I can't figure out how to do that.

This is what I'm doing so far:

Set up the VBO for the screen quad
Code:
static const GLdouble const VERTICES[] = { 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0 };
static const int NUM_VERTICES = 4;

GLuint *vbo = calloc(NUM_BUFFERS, sizeof(*vbo));
glGenBuffers(2, vbo); // Vertex and texture coordinates

// Copy vertex data
glBindBuffer(GL_ARRAY_BUFFER, vbo[VERTEX_DATA]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLdouble) * NUM_VERTICES * 2, VERTICES, GL_STATIC_DRAW);

// Copy texture data
glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXTURE_DATA]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLdouble) * NUM_VERTICES * 2, VERTICES, GL_STATIC_DRAW);

Try to draw the textures
Code:
// tex1 and tex2 are GLuints.

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex1);
glEnable(GL_TEXTURE_2D);
    
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tex2);
glEnable(GL_TEXTURE_2D);

glEnableClientState(GL_VERTEX_ARRAY);

// Vertices

glBindBuffer(GL_ARRAY_BUFFER, vbo[VERTEX_DATA]);
glVertexPointer(2, GL_DOUBLE, 0, 0);

// Textures

glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXTURE_DATA]);

glClientActiveTexture (GL_TEXTURE0);
glTexCoordPointer(2, GL_DOUBLE, 0, 0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glClientActiveTexture (GL_TEXTURE1);
glTexCoordPointer(2, GL_DOUBLE, 0, 0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

// Drawing

glDrawArrays(GL_QUADS, 0, NUM_VERTICES);

glDisableClientState(GL_VERTEX_ARRAY);
// How would I call glDisableClientState(GL_TEXTURE_COORD_ARRAY)?
// I ask because the use of glEnableClientState(GL_TEXTURE_COORD_ARRAY)
// seems to be different due to the multiple textures.

Vertex shader
Code:
void main()
{
    gl_Position = ftransform();
    gl_TexCoord[0] = gl_MultiTexCoord0;
}

Fragment shader
Code:
uniform sampler2D bottomTex, topTex;

void main()
{
    vec4 bottomColour = texture2D(bottomTex, gl_TexCoord[0].st);
    vec4 topColour = texture2D(topTex, gl_TexCoord[0].st);

    gl_FragColor = bottomColour + topColour;
}

The effect I'm getting is that the first texture seems to be drawn twice, where colours contributed by that texture are brightened. Nothing from the second texture is visible.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #2
I don't see you setting the uniform values for bottomTex, topTex.

All uniforms default to zero when you link the shaders. So both samplers are pointing at unit zero unless you change them.
Quote this message in a reply
Member
Posts: 35
Joined: 2009.10
Post: #3
I have to set the uniform values for textures? I don't think I saw that before. Blink

So...where and how do I do this? I just tried this:
Code:
glUniform1i(loc, tex1);
glUniform1i(loc, tex2);
...just after setting the shader and before drawing the quad. Now the first texture is gone and all I can see is the second texture. Blush
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #4
Texture uniforms refer to the texture unit the texture is bound to, not the texture ID (unfortunately).
Code:
glActiveTexture(GL_TEXTURE0);
glBindTexture(target1, tex1);
glUniform1i(tex1loc, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(target2, tex2);
glUniform1i(tex2loc, 1);

Make sure you keep track of which texture unit is active too Wink
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #5
Coyote Wrote:I have to set the uniform values for textures? I don't think I saw that before. Blink

It's spelled out very clearly in the documentation.

See section 2.15.3, Shader Variables > Samplers:
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. Setting a sampler’s value to i selects texture image unit number i. The values of i range from zero to the implementation- dependent maximum supported number of texture image units.

The type of the sampler identifies the target on the texture image unit. The texture object bound to that texture image unit’s target is then used for the texture lookup. For example, a variable of type sampler2D selects target TEXTURE 2D on its texture image unit. Binding of texture objects to targets is done as usual with BindTexture. Selecting the texture image unit to bind to is done as usual with ActiveTexture.
The location of a sampler needs to be queried with GetUniformLocation, just like any uniform variable. Sampler values need to be set by calling Uniform1i{v}.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Using glTexCoordPointer with multitexturing TomorrowPlusX 6 13,578 Dec 5, 2006 09:42 AM
Last Post: NYGhost
  Lighting and Multitexturing problem Scribendi 0 2,570 Sep 25, 2005 09:22 PM
Last Post: Scribendi
  OpenGL Multitexturing Details w/Alpha WakingJohn 22 10,699 Dec 4, 2004 10:52 AM
Last Post: WakingJohn
  Sparseness of Multitexturing documentatin in Red Book WhatMeWorry 2 3,163 Nov 10, 2004 01:54 PM
Last Post: arekkusu
  Decomposing multitexturing to multiple passes arekkusu 4 3,965 Dec 1, 2003 12:43 PM
Last Post: Sohta