Textures and glColor

After rendering a texture (a bitmap image) to a quad, I display Help text if the F1 key is pressed. The text is a list of bitmaps as per NeHe Tutorial 13.
Before displaying the text, it’s colour is set with glColor3f.
If this is white, no problem.
If any colours are missing (as with yellow where blue is missing) then blue will be missing from the entire image.
After calling the print font routine, you have to set current color back to white for the rendered texture to be correctly displayed.
None of this is obvious from the ‘Blue Book’ or the Internet.
Does anyone know where there is a list of commands that are affected by glColor ?

OpenGL is a state machine. glColor changes the current color.

By default, textures are modulated with the current fragment’s color (which is why you can change the color of your text with glColor).

If you want your image to be unaffected by the current color, you must change the texture environment parameter to decal or replace mode (depending on the behavior you want wrt alpha channel).

Your rendering loop could be

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
draw texture
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor3ub(255, 255, 0);
draw text

Thanks for that.

I am still at a loss to explain why my programme does work if I do the following :-

  1. Declare: GLuint texture[3]; // Even though only two textures are ever allocated !

  2. glColor3f(1.0f, 0.0f, 0.0f); // Red Help Text

glBindTexture(GL_TEXTURE_2D, texture[2]); // Why do we have to bind to a non-existant texture ?

if (bDisplayHelp ) {ShowHelpInfo();}	// Display Help screen

glColor3f(1.0f, 1.0f, 1.0f); // back to white

We are binding to a non-existant texture !

If texture is dimensioned as texture[2] the lettering is black.
If we omit glBindTexture the lettering is again black.

Hmmm, im going to need a little more code( as in much more) to be able to help you. Can you post your bmp loading sequence?

OK, the bitmap loading code is the usual mods to the NeHe tutorial using the glaux library :frowning:

As this is a stereo programme, I render to back-left and back-right buffers.
With my shutters glasses I view the image page-flipped at full resolution.
The left image is not bound to a (non-existant) texture and is coloured black.
The right image is bound to the texture and is correctly displayed in red.
texture[] is dimensioned as texture[3], texture[2] has never been defined or mentioned anywhere else apart from just before displaying the text.
Strange ?

// -------------------------------------------------------------------------------------------------------
// Attempt to load bitmap from file and return pointer to RGBImageRec structure. Otherwise return NULL.
// This uses the glaux library which is not recommended for ‘real’ programmes.
// -------------------------------------------------------------------------------------------------------

AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image into a AUX_RGBImageRec structure

{
FILE *File=NULL; // Handle to a File Structure
if (!Filename) // Make Sure A Filename Was Given
{
return NULL; // If Not Return NULL
}

File=fopen(Filename,“r”); // Check To See If The File Exists

if (File) // Does The File Exist?
{

fclose(File); // Yes, Close The Handle and
return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer
}

MessageBox(NULL,“Cannot Open Texture File”,“ERROR”,MB_OK|MB_ICONEXCLAMATION);

return NULL; // If Load Failed Return NULL
}

// ------------------------------------------------------------------------------------------------------------------
// Load bitmaps from file and convert to a texture

int LoadGLTextures() // Load Bitmaps And Convert To Textures

{
int Status=FALSE; // Status Indicator is TRUE if conversion to texture succeeded

// _chdir(“d:\myfiles\my wallpaper”); // Change working directory

memset(TextureImage,0,sizeof(void *)*1); // Clear the image

if (TextureImage[0]=LoadBMP("Left.bmp"))  // Try to load first image,returns pointer to a AUX_RGBImageRec

{

	if (TextureImage[1]=LoadBMP("Right.bmp"))     // Try to load second texture for right image

	{

Status=TRUE;							// Set The Status To TRUE if successful

glGenTextures(2, &texture[0]);			// Create  texture names and save in texture[]

// Load First Texture

		CreateCleanBitmap(1024,1024);									//  m_pBitmap points to blank bitmap
		glBindTexture(GL_TEXTURE_2D, texture[0]);// Bind named texture to 2D target

// The next line specifies a 2D texture image. ‘0’ defines level of detail, ‘3’ is number of colour components
// sizeX is width, sizeY is height, ‘0’ is border width, GL_RGB is pixel data format, GL_UNSIGNED_BYTE is format of pixel data
// m_pBitmap points to a ‘blank’ 1024x1024 texture. Our 1024x680 image will be a subtexture in this.

		glTexImage2D(GL_TEXTURE_2D, 0, 3, 1024,1024, 0, GL_RGB, GL_UNSIGNED_BYTE,m_pBitmap); // our blank 1024x1024 bitmap

// The next two lines define the type of filtering to be used when the texture is smaller or larger

		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering for smaller images

		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering for larger images

// The next line allows us to assign an image that is not a power-of-two to the texture
// ‘0’ defines level of detail, 0 is x-offset for 1024x680 texture in the 1024x1024 texture, 200 is y-offset, 1024 is sub-texture width
// 680 is sub-texture height, GL_RGB is pixel data format, GL_UNSIGNED_BYTE is format of pixel data
// TextureImage[0] is the structure that is temporarily holding the loaded bitmap.

// It is defined in glaux.h as :-

/*

typedef struct _AUX_RGBImageRec
{
GLint sizeX, sizeY; // bitmap width and height
unsigned char *data; // pointer to bitmap data
} AUX_RGBImageRec;

*/

// TextureImage[0]->data) points to the actual bitmap data .

		glTexSubImage2D(GL_TEXTURE_2D,0,0,200,1024,680,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data); // left image 3:2 aspect ratio

		ClearBitmap();													// free-up memory

// Load Second Texture

		CreateCleanBitmap(1024,1024);									//  m_pBitmap points to blank bitmap

		glBindTexture(GL_TEXTURE_2D, texture[1]);						// Bind named texture to 2D target

		glTexImage2D(GL_TEXTURE_2D, 0, 3, 1024,1024, 0, GL_RGB, GL_UNSIGNED_BYTE,m_pBitmap); // our blank 1024x1024 bitmap
														
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering for smaller images

		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering for larger images

		glTexSubImage2D(GL_TEXTURE_2D,0,0,200,1024,680,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[1]->data); // right image 3:2 aspect ratio

		ClearBitmap();													// free-up memory


	}

}

// Destroy First Texture Temporary Data

if (TextureImage[0])		// If Texture Exists

{

	if (TextureImage[0]->data) // and Texture Image also Exists

	{

		free(TextureImage[0]->data); // then Free The Texture Image Memory

	}

	free(TextureImage[0]);		// and Free The Image Structure

}

// Destroy Second Texture Temporary Data

if (TextureImage[1])		// If Texture Exists

{

	if (TextureImage[1]->data) // and Texture Image also Exists

	{

		free(TextureImage[1]->data); // then Free The Texture Image Memory

	}

	free(TextureImage[1]);		// and Free The Image Structure

}

return Status; // Return The Status

}