0
votes

I am having some trouble with rendering textures using opengl. First I render my texture, then I render a square. To set the color off my square I use glColor3f(1.0f,0.0f,0.0f); This makes the square red. But then when my textures is being rendered again it is rendered with red color too.

What is the problem here?

3

3 Answers

4
votes

When you call glColor, you are setting the constant color for all future draw calls. If you want it to go back to what it was when you started, you have to explicitly set it back after drawing your square.

Typically (depending on texture environment) the vertex color and constant color are combined during vertex shading, then interpolated, and later multiplied against the texel color in fragment shading.

If you use a glColor3f(1,0,0), you'll end up multiplying the texture's red channel by 1.0, and the green and blue channels by 0.0 -- so you'll get only the texture's red channel.

You'll need to reset your constant color to 1,1,1 to see the regular texture color.

Generally speaking you'll want to set all your common gl state ahead of time, and then "return" to that state after you draw anything that needs an uncommon change. This is sometimes called the "zero state". You'll note also that a lot of performance-tuning literature suggests batching things together that have similar uncommon non-zero-state needs -- this may or may not have an effect depending on graphics drivers, hardware, etc.

1
votes

The "problem" here is that (a) by default, opengl uses the GL_MODULATE texenv mode, so the color of the fragment is multiplied by the color of the texture to produce the final color and (b) that openGL is a state machine, so the color red stays as long as you set some other color.

Note that when using lighting, GL_MODULATE is very useful to combine the result of the lighting calculation with the texture colors.

If you want just the texture as is, you could either specify a white color before drawing the textured object, our use another texture enivronment mode like GL_REPLACE:

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

Have a look at the manpage of glTexEnv for an explanation of that function and the available modes and options.

0
votes

If you want just only draw the texture (even lighthing), it is not necesary a white color before draw the texture if you only want draw the texture. You only just specify the coordenates before the vertex in draw function, like this example:

void dibujarTexturaIluminacionPlana(GLuint texName){

        glShadeModel(GL_FLAT); //Flat model ilumination 

        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, texName);

        glBegin(GL_TRIANGLES);
        for(int i=0; i<caras.size(); i++){
            glNormal3f(normales[i].x, normales[i].y, normales[i].z);
            glTexCoord2f(cTs[caras[i]._0].x, cTs[caras[i]._0].y);
            glVertex3f(vertices[caras[i]._0].x, vertices[caras[i]._0].y ,vertices[caras[i]._0].z);
            glTexCoord2f(cTs[caras[i]._1].x, cTs[caras[i]._1].y);
            glVertex3f(vertices[caras[i]._1].x, vertices[caras[i]._1].y ,vertices[caras[i]._1].z);
            glTexCoord2f(cTs[caras[i]._2].x, cTs[caras[i]._2].y);
            glVertex3f(vertices[caras[i]._2].x, vertices[caras[i]._2].y ,vertices[caras[i]._2].z);
        }
        glEnd();

        glFlush();
        glDisable(GL_TEXTURE_2D);
    }

Wherein caras is "faces", normales is "normal" and vertices is "vertex".

So, if you want draw the texture, only you call the function.

glEnable(GL_LIGHTING); figuraPerfilCompleto.dibujarTexturaIluminacionPlana2(texturas[0]); glDisable(GL_LIGHTING);

Is not necesary call to glTexEnv...