glColor coloring all textures
Asked Answered
S

4

6

I'm fairly new to OpenGL so maybe the answer will be obvious. I am currently trying to make a blue circle using GL_TRIANGLE_FAN in C++. My problem is that when I set the color using glColor4f, it sets all my other textures to have a blue color over them such as shown below (this is supposed to be silvery metal).

I draw the textures using the method shown below.

glLoadIdentity();
glTranslatef(x,y,0);

glBindTexture(GL_TEXTURE_2D, this->texture); 

glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(0,0,0);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(width,0,0);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(width,height,0);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(0,height,0);   
glEnd();

I'm not sure whether I just have to clear a flag for it to work, but I've been stuck for a few days now.

Sport answered 21/1, 2012 at 21:13 Comment(0)
E
7

Unbind the texture and set the color back to white after you're done drawing:

glLoadIdentity();
glTranslatef(x,y,0);

glEnable( GL_TEXTURE_2D );
glBindTexture(GL_TEXTURE_2D, this->texture); 

glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(0,0,0);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(width,0,0);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(width,height,0);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(0,height,0);   
glEnd();

glColor4f(1, 1, 1, 1);
glBindTexture(GL_TEXTURE_2D, 0);

And if you aren't rendering textures on the next object, disable texturing:

glDisable( GL_TEXTURE_2D );
Ez answered 21/1, 2012 at 21:27 Comment(8)
It worked! The blue was removed from the other objects (unfortunately it seems as though the circle isn't drawing) but that's tangent to the thread's initial question. Thanks!Sport
sorry but "unbind a texture"? This is the 1st time that I hear such nonsenseHowerton
same here, unbinding isnt necessary. just use glDisable(GL_TEXTURE_2D)Miniature
@VJovic: Well, binding a texture object will surely unbind the texture object bound previously. Binding the default texture object (=0) which is no texture, will therefore unbind the texture. Texture unbinding is also a standard term talking about OpenGL code (for example you must unbind a texture before you can use it as a rendertarget FBO attachment, the term "unbind" is even used in FBO specification IIRC).Tarlatan
@Tarlatan have you meant to say "unbind a frame buffer object, when using FBO"? I see no reasons to unbind a textureHowerton
@VJovic: No I meant texture. In the case of having a texture being used as color attachment of a FBO, you can not use the FBO as rendertarget, as long as the texture is bound to a texturing unit. It must be unbound first. I hereby refer you to code example 3ff in the FBO specification, where unbinding is used (glBindTexture(..., 0)); opengl.org/registry/specs/ARB/framebuffer_object.txtTarlatan
@Tarlatan interesting. I wasn't awared of that. However that seems irrelevant to the question, as FBO was no mentionedHowerton
@VJovic: Unbinding a texture has nothing to do with FBOs. Effectively unbinding a texture has the same effect as disabling its texture target/unit. In fact, when it comes to shaders and OpenGL you no longer have texture targets but only bindings and uniforms (you no longer glEnable/glDisable(GL_TEXTURE_...) when using shaders!). So in that regard doing a unbind is the future proof method.Tarlatan
T
8

After drawing your blue circle, you should set the color back to white (default value) using glColor4f(1.f, 1.f, 1.f, 1.f);. Please note that by default the texture gets modulated by the currently set color (blue in your case) and that's the reason why your silver material gets a bluish tone (final color = blue color * texture color).

Tyranny answered 21/1, 2012 at 21:28 Comment(1)
Thanks for the answer! It worked. I would give you the check mark except Robert posted before you. I still gave you a +1 though!Sport
E
7

Unbind the texture and set the color back to white after you're done drawing:

glLoadIdentity();
glTranslatef(x,y,0);

glEnable( GL_TEXTURE_2D );
glBindTexture(GL_TEXTURE_2D, this->texture); 

glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(0,0,0);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(width,0,0);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(width,height,0);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(0,height,0);   
glEnd();

glColor4f(1, 1, 1, 1);
glBindTexture(GL_TEXTURE_2D, 0);

And if you aren't rendering textures on the next object, disable texturing:

glDisable( GL_TEXTURE_2D );
Ez answered 21/1, 2012 at 21:27 Comment(8)
It worked! The blue was removed from the other objects (unfortunately it seems as though the circle isn't drawing) but that's tangent to the thread's initial question. Thanks!Sport
sorry but "unbind a texture"? This is the 1st time that I hear such nonsenseHowerton
same here, unbinding isnt necessary. just use glDisable(GL_TEXTURE_2D)Miniature
@VJovic: Well, binding a texture object will surely unbind the texture object bound previously. Binding the default texture object (=0) which is no texture, will therefore unbind the texture. Texture unbinding is also a standard term talking about OpenGL code (for example you must unbind a texture before you can use it as a rendertarget FBO attachment, the term "unbind" is even used in FBO specification IIRC).Tarlatan
@Tarlatan have you meant to say "unbind a frame buffer object, when using FBO"? I see no reasons to unbind a textureHowerton
@VJovic: No I meant texture. In the case of having a texture being used as color attachment of a FBO, you can not use the FBO as rendertarget, as long as the texture is bound to a texturing unit. It must be unbound first. I hereby refer you to code example 3ff in the FBO specification, where unbinding is used (glBindTexture(..., 0)); opengl.org/registry/specs/ARB/framebuffer_object.txtTarlatan
@Tarlatan interesting. I wasn't awared of that. However that seems irrelevant to the question, as FBO was no mentionedHowerton
@VJovic: Unbinding a texture has nothing to do with FBOs. Effectively unbinding a texture has the same effect as disabling its texture target/unit. In fact, when it comes to shaders and OpenGL you no longer have texture targets but only bindings and uniforms (you no longer glEnable/glDisable(GL_TEXTURE_...) when using shaders!). So in that regard doing a unbind is the future proof method.Tarlatan
E
1

When You have enabled glEnable(GL_COLOR_MATERIAL) and changed a color by glColor, then all your textures will be affected by this color. This is because by default the texture is displayed in modulate mode (glColor multiplied by texture colors).

If you don't have lighting enabled, to restore the original texture color is simple - just set glColor to white: glColor4f(1.0, 1.0, 1.0, 1.0). The problem comes, when you have lighting enabled on your texture. Then, setting the color to white or changing texture mode to REPLACE doesn't help at all - your lighting effects will be removed! (which nobody seems to be noticing!) The reason for this is because with enabling GL_COLOR_MATERIAL by default you're getting behaviour, where glColor commands changes both Ambient and Diffuse colours at the same time - thus your ambient and diffuse material properties will be affected (lost). So all you have to do, to restore the material state (and thus lighting effects), which you had before applying glEnable(GL_COLOR_MATERIAL), is the following:

glDisable(GL_COLOR_MATERIAL); //disable color influence
GLfloat ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f }; //default material has this ambient color!
GLfloat diffuse[] = { 0.8f ,0.8f ,0.8f, 1.0f }; //default material has this diffuse color!
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); //restore default material ambient color
glMaterialfv(GL_FRONT, GL_AMBIENT, diffuse); //restore default material diffuse color

Please note, what are the default ambient and diffuse colors for default material! There is no pure white there!

This way, all the textures, that you use from this point will be drawn as intended (with the correct color and lighting effects). Took me some time to find this stuff, so I suppose it's nice to mention it here.

Extensometer answered 23/10, 2014 at 10:32 Comment(1)
Hi! I am still confused. So the above code should be inserted before draw_object function or after? Thank you!Rees
M
0

Before binding a texture, you need to enable it. And normally, you should disabled it when you are done with it. Something like this :

glEnable( GL_TEXTURE_2D );
glBindTexture(GL_TEXTURE_2D, this->texture); 

glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(0,0,0);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(width,0,0);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(width,height,0);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(0,height,0);   
glEnd();

glDisable( GL_TEXTURE_2D );
Marxist answered 21/1, 2012 at 21:16 Comment(3)
I added the Enables/Disables but it didn't seem to fix the problem.Sport
@Sport In that case, the problem seams to be elsewhere(and not in the code you posted). How do you create textures?Howerton
I will post code about how I load textures if I need to(I do it through SDL). I have one quick statement before I do though. If I remove the method for drawing the blue circle (or even just removing the glColor4f) from my code I don't have any issues with textures being blue. I feel like this behavior wouldn't indicate textures being loaded incorrectly but I could be wrong.Sport

© 2022 - 2024 — McMap. All rights reserved.