2

I am drawing one object using multi-texturing. That comes fine but when I draw other objects after that using only diffuse texture, that diffuse texture gets bound with previous texture. I know I have to deactivate texture units other than default and I have to make active texture unit at GL_TEXTURE0 but it's not working.

Here is my code

glClientActiveTexture(GL_TEXTURE0); // first texture
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, stride, texCoordOffset);
glClientActiveTexture(GL_TEXTURE1); // second texture
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, stride, texCoordLightOffset);

// Enable 2D texturing for the first texture.
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);

// Enable 2D texturing for the second texture.
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);

// We are trying for the multi-textured lighting effect from the OpenGL
// ES 2.0 book, page  223, Figure 10-3. The relevant shader equation is
// basecolor * (lightcolor + 0.25), so we set the constant as a base colour
glColor4f(0.25f, 0.25f, 0.25f, 1.0f);


// Set the light map has the current texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,m_new_tex);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,5.0f);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

// add the light map to the constant 0.25
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);

// Now set the background map (bricks) and modulate (multiply)
glActiveTexture(GL_TEXTURE1);
// we'll keep this code here as _texSelection will never be our lightmap
glBindTexture(GL_TEXTURE_2D, m_sky);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 5.0f);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

/* Set the texture environment mode for this texture to combine */
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

/* Set the method we're going to combine the two textures by. */
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);

/* Use the previous combine texture as source 0*/
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);

/* Use the current texture as source 1 */
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);

/*
 Set what we will operate on, in this case we are going to use
 just the texture colours.
 */
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);


glBindBuffer(GL_ARRAY_BUFFER, drawable.VertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawable.IndexBuffer);

glDrawElements(GL_TRIANGLES, drawable.IndexCount, GL_UNSIGNED_SHORT, 0);

glDisable(GL_TEXTURE_2D);

For simple diffuse texture what are the commands I have to write before binding texture?

Any other example code will be helpfull.

Christian Rau
  • 45,360
  • 10
  • 108
  • 185
rocksvick
  • 187
  • 2
  • 7
  • So multi-texturing seems to work? By the way, the state changed by `glTexParameter` is per-texture state and not per-unit state, so you don't need to change it every frame, but only after creating the texture. – Christian Rau Nov 08 '11 at 14:51

1 Answers1

1

First of all you have to disable texturing (glDisable(GL_TEXTURE_2D)) for each unused texture unit, which you are doing already. And of course you also have to disable the texture coordinate array for the unused texture units, so call glDisableClientState(GL_TEXTURE_COORD_ARRAY) when the second texture unit is active (after calling glClientActiveTexture(GL_TEXTURE1)).

And when you're finished with multi-texturing, you of course have to call glActiveTexture(GL_TEXTURE0) and glClientActiveTexture(GL_TEXTURE0). Othwerise all folowing texture operations apply to texture unit 1 instead of 0.

But all these things have already been stated in my answer to your other question. Have you even read that?

EDIT: And by the way, the state changed by glTexParameter is stored per-texture object and not per-unit. So you don't need to call these each frame, once after creating the texture is enough.

Christian Rau
  • 45,360
  • 10
  • 108
  • 185
  • @rocksvick If the answer was the solution to your problem, accepting would be appreciated. Or did I misunderstand your comment and you have solved it yourself (though I doubt the solution would be substantially different from mine)? – Christian Rau Nov 09 '11 at 17:33
  • thanks for the answer and yes problem was solved before your answer came...thanks by the way. – rocksvick Nov 10 '11 at 08:08
  • other objects are being rendered perfectly but when i try to render an object in the end that uses blending(objects are trees which are transparent), they dont remain transparent ,instead texture of texture unit0 is coming on those objects.. can u suggest some solution ? – rocksvick Nov 12 '11 at 17:31
  • @rocksvick Hard to answer. But as a general rule always set every state you need before rendering and restore it after rendering. OpenGL is a state machine, where every state keeps its value until **you** change it again. And it also doesn't know what a render frame is and keeps its state across frames, of course. – Christian Rau Nov 12 '11 at 18:15
  • thanks for the reply. i have one doubt. i have used glTexEnv during multitexturing .when i am done with multitexturing , after disabling texture unit 1 and activating texture unit 0 , do we need to reset glTexEnv ? if yes how to do that ? – rocksvick Nov 12 '11 at 20:32
  • @rocksvick The texture environment is per-unit state, so when activating unit 0, it has the same values you set last time you called `glTenEnv` when texture unit 0 was active. – Christian Rau Nov 12 '11 at 20:46