# Color class

This topic is 4727 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

This is my class to hold a color. It is written to work with OpenGL.
#ifndef _CCOLOR_H_
#define _CCOLOR_H_

#include <iostream>
using namespace std;

#include <windows.h>
#include <gl/gl.h>		// Header file for OpenGL32 Library
#include <gl/glu.h>		// Header file for the GLu32 library
#include <gl/glaux.h>	// Header file for the GLaux library

/**
* This is a class that will represent a color with 4 parts.
* Alpha, Red, Green, Blue. Within the class, the color will be represented
* by a 32-bit unsigned integer.
* Eg. First 8 bits will represent alpha, second 8, red, third 8, green, last 8, blue.
* So, each value can only be from 0-255.
*/
class CColor
{
private:
size_t color;	///< 32-bit unsigned integer representing the color

public:
/** Constructor that inits 'color' to 0 */
CColor()	:	color(0) { }

/** Constructor that inits the color when given the four parts.
* \param a Unsigned integer value from 0-255 representing the alpha value of the color.
* \param r Unsigned integer value from 0-255 representing the red value of the color.
* \param g Unsigned integer value from 0-255 representing the green value of the color.
* \param b Unsigned integer value from 0-255 representing the blue value of the color.
*/
CColor(size_t a, size_t r, size_t g, size_t b)
{
// Set the color
set(a, r, g, b);
}

/** Constructor that inits the color when given three parts.
* \param r Unsigned integer value from 0-255 representing the red value of the color.
* \param g Unsigned integer value from 0-255 representing the green value of the color.
* \param b Unsigned integer value from 0-255 representing the blue value of the color.
*/
CColor(size_t r, size_t g, size_t b)
{
// Set the color
set(255, r, g, b);
}

/**
* This function sets the various values of the color.
* \param a Unsigned integer value from 0-255 representing the alpha value of the color.
* \param r Unsigned integer value from 0-255 representing the red value of the color.
* \param g Unsigned integer value from 0-255 representing the green value of the color.
* \param b Unsigned integer value from 0-255 representing the blue value of the color.
*/
void set(size_t a, size_t r, size_t g, size_t b)
{
// Check for invalid color values
if( a > 255 || r > 255 || g > 255 || b > 255 ){
cout << "Invalid color values. Color not set." << endl;
return;
}

// reset color
color = 0;

// init alpha
color = color | (a << 24);
// init red
color = color | (r << 16);
// init green
color = color | (g << 8);
// init blue
color = color | b;
}

/**
* Sets the values of this CColor object to the current openGL color.
*/
void setToOpenGLColor()
{
float openglcolor[4];	// Store the 4 opengl color elements in here

// Get the 4 color elements and store them in the float array.
glGetFloatv(GL_CURRENT_COLOR, openglcolor );

setRed( (size_t)(openglcolor[0] * 255) );	// Set red element of color
setBlue( (size_t)(openglcolor[1] * 255) );	// Set blue element of color
setGreen( (size_t)(openglcolor[2] * 255) );	// Set green element of color
setAlpha( (size_t)(openglcolor[3] * 255) );	// Set alpha element of color
}

/**
* Sets the current openGL color to the values of this CColor object.
*/
void setOpenGLColor()
{
// Set the opengl color
glColor4f(	(float)(getRed()/255.0f), (float)(getGreen()/255.0f),
(float)(getBlue()/255.0f), (float)(getAlpha()/255.0f) );
}

/**
* This function sets the alpha value of the color.
* \param a Unsigned integer from 0-255 representing the alpha value of the color.
*/
void setAlpha(size_t a)
{
if( a > 255 ){
cout << "Invalid alpha value. Alpha not set." << endl;
return;
}

color = color | (a << 24);
}

/**
* This function sets the red value of the color.
* \param r Unsigned integer from 0-255 representing the red value of the color.
*/
void setRed(size_t r)
{
if( r > 255 ){
cout << "Invalid red value. Red not set." << endl;
return;
}

color = color | (r << 16);
}

/**
* This function sets the green value of the color.
* \param g Unsigned integer from 0-255 representing the green value of the color.
*/
void setGreen(size_t g)
{
if( g > 255 ){
cout << "Invalid green value. Green not set." << endl;
return;
}

color = color | (g << 8);
}

/**
* This function sets the blue value of the color.
* \param r Unsigned integer from 0-255 representing the blue value of the color.
*/
void setBlue(size_t b)
{
if( b > 255 ){
cout << "Invalid blue value. Blue not set." << endl;
return;
}

color = color | b;
}

/**
* Returns a value from 0-255 representing the alpha value of the color.
*/
size_t getAlpha()
{
return ( (color&0xFF000000) >> 24 );
}

/**
* Returns a value from 0-255 representing the red value of the color.
*/
size_t getRed()
{
return ( (color&0x00FF0000) >> 16 );
}

/**
* Returns a value from 0-255 representing the green value of the color.
*/
size_t getGreen()
{
return ( (color&0x0000FF00) >> 8 );
}

/**
* Returns a value from 0-255 representing the blue value of the color.
*/
size_t getBlue()
{
return (color & 0x000000FF);
}

/**
* \param c A const reference to another CColor object.
* \return A boolean value indicating whether the two CColor objects are equal
* to each other.
*/
bool operator==(const CColor& c)	{	return color == c.color;	}

/**
* \param c A const reference to another CColor object.
* \return A boolean value indicating whether the two CColor objects are not equal
* to each other.
*/
bool operator!=(const CColor& c)	{	return color != c.color;	}

/**
* \param c A const reference to another CColor object.
* \return A reference to 'this' CColor object.
*/
CColor& operator=(const CColor& c)	{	color = c.color;	return *this;	}

};
#endif


Perhaps a little long, but I'm having a specific problem. When I change the color for an object, the alpha doesn't seem to have an effect.
// Line that changes the color
plane.setColor(CShape::COLORITEM_SURFACE, CColor(255,255,0,0) );

// This is basically the function
void CShape::setColor(ColorItem citem, CColor& c)
{
switch(citem){
case COLORITEM_SURFACE:
shape_color = c;
break;
};
}

// and then, later on, my render function calls this
void drawSurface()
{
// Save the current open gl color
CColor temp;
temp.setToOpenGLColor();

// Set surface color
color.setOpenGLColor();

glBegin(GL_TRIANGLES);

glVertex3f(vertex_buffer[0].x, vertex_buffer[0].y, vertex_buffer[0].z);
glVertex3f(vertex_buffer[1].x, vertex_buffer[1].y, vertex_buffer[1].z);
glVertex3f(vertex_buffer[2].x, vertex_buffer[2].y, vertex_buffer[2].z);

glVertex3f(vertex_buffer[1].x, vertex_buffer[1].y, vertex_buffer[1].z);
glVertex3f(vertex_buffer[2].x, vertex_buffer[2].y, vertex_buffer[2].z);
glVertex3f(vertex_buffer[3].x, vertex_buffer[3].y, vertex_buffer[3].z);

glEnd();	// Stop drawing triangles

temp.setOpenGLColor();		// Restore the opengl color
}


Its important to note, that the render function doesn't change anything. It calls push matrix, and then depending on what should be drawn for the object, it calls the right functions. All the functions that draw something are exactly the same as the drawSurface function. Here is my problem: with this line of code: "plane.setColor(CShape::COLORITEM_SURFACE, CColor(255,255,0,0) );", it doens't matter whether the first param in CColor constructor (which is the alpha value) is 0 or 255. It makes absolutely no difference either way. The thing being drawn does not change one iota. Can anyone spot a bug, or something I should have done another way to avoid a problem like this?

##### Share on other sites
If changing the alpha doesn't change the display then it is likely that your blending setup is not right. Does changing the color work?

Anyway, here are some unrelated tips:
1. Don't use size_t like that. size_t is the type returned by the sizeof operator and is totally wrong for what you are using it for. size_t is not always 32 bits. If you want a 32-bit type, use the types provided by the compiler (e.g. __int32 in MSVC) or make your own if they aren't provided.
2. The OpenGL glGet* functions are generally very slow and should be avoided.
3. setAlpha, setRed, setGreen, and setBlue are broken because they don't reset the old value before oring in the new value. setAlpha should look like this:
    color &= ~( 0xff << 24 );    color |= a << 24;

##### Share on other sites
Quote:
 Original post by JohnBoltonIf changing the alpha doesn't change the display then it is likely that your blending setup is not right. Does changing the color work?Anyway, here are some unrelated tips: Don't use size_t like that. size_t is the type returned by the sizeof operator and is totally wrong for what you are using it for. size_t is not always 32 bits. If you want a 32-bit type, use the types provided by the compiler (e.g. __int32 in MSVC) or make your own if they aren't provided. The OpenGL glGet* functions are generally very slow and should be avoided. setAlpha, setRed, setGreen, and setBlue are broken because they don't reset the old value before oring in the new value. setAlpha should look like this:  color &= ~( 0xff << 24 ); color |= a << 24;

Yeah, changing the color in the constructor does work. So, changing from CColor(255,255,0,0) to CColor(255,100,100,0) does work.

I'm only using size_t to make sure that whoever's using it knows that its an unsigned int, and it doens't matter if its 32 or not, just as long as its at least 8 bits. I don't really use size_t anywhere else.

I changed the setAlpha, etc functions, thanks for that. I can't raelly believe that I didn't see that. Anyway, the contructor doens't use those functions, it uses a set(size_t, size_t, size_t, size_t) function, which resets the whole color to 0.

YOu say the OpenGL get functions are slow? Whats another way to get, the color, or something else? Are there extra functions?

##### Share on other sites
Quote:
 Original post by EndarI'm only using size_t to make sure that whoever's using it knows that its an unsigned int, and it doens't matter if its 32 or not, just as long as its at least 8 bits.

Well, the member variable color is a size_t and it must be 32 bits. Regardless, using size_t is wrong here -- use unsigned int if you want the type to be an unsigned int.

Quote:
 Original post by EndarYou say the OpenGL get functions are slow? Whats another way to get, the color, or something else? Are there extra functions?

Normally, you simply don't save and restore the state, or you cache the values yourself. Generally, getting the state requires the hardware to stop what it is doing, wait for the pipeline to be empty, return the state, and then start up again. Also, state changes are slow and saving/restoring the state like that could double the number of state changes.