Working with Colors in OpenGL for Game Programming with SDL

Colors magically bring a scene to life. No matter how interesting the plot is, how engrossing the special effects are, if the color combinations are not accurate or the colors are tepid, the liveliness of the game suffers. In short, it is the combination of and correct usage of colors that decide what the scene and eventually the whole game will be like.

The next two discussions (starting with the current article) will be dedicated to the details and the usage of colors in OpenGL. The first section of this discussion will focus on modes available for color. The second section will explain how to use these modes from within OpenGL. The third section will focus on testing the concepts that were introduced in first two sections. So here we go.

About Colors

Any shade of any color can be decomposed into the three primary colors: red, blue and green. Every color rendering device (including computer monitors) works on this basis. If we consider a monitor with a color screen, the hardware causes each pixel on the screen to emit varied amounts of red, blue and green light. The emission of these can be controlled either by specifically controlling the primary color packs or by working with an index specifying the entry in a table that defines a particular set of red, green and blue values. So on the basis of specifying the colors, there are two modes of colors, which are:

1. RGB Mode

2. Indexed Mode


Both of these modes are based on the concept of bit-planes in frame-buffer. Though both these concepts will be discussed in the second and third part of this series, I will go into an overview of bit-planes to refresh your memory.

In either of the above, the data of colors are saved at each pixel. The amount of data saved at each pixel is decided by the bit-plane. A bit-plane contains one bit of data for each pixel. If there are 8 color bitplanes, there are eight color bits per pixel, and hence 28 =256 different values or colors that can be stored at that pixel.

One generalization about bitplanes is that they are divided evenly in terms of storage of red, blue and green components of color. For example, if the bitplane is 24 bit, then each component would get 8 bits. But this generalization is not always true. With this in mind, let’s have a look at the modes.

{mospagebreak title=RGB and Indexed Mode}

1. RGB Mode:

RGB Mode is also known as the RGBA mode when the Alpha component is used. RGB stands for red, green, and blue. The A in RGBA is the Alpha component. It defines transparency for red (R), blue (B), and green (G) components. In this mode, the hardware sets aside a certain number of bit-planes for each red, blue, and green component. The R, G, B values are stored as integer values rather than floating point numbers. The values of these components can vary from 0 to 255. The range can be more. The range of the acceptable value for a given component is based on the number of bits available for that component. Typically, on most systems the number of available bits is 8. Hence, the number 255 is used for specifying a particular intensity of a color component.

Now, the number of bits available directly corresponds to the bit-planes of a component. In this case, since 8 bits are there, there are 28=256 bit-planes in a system supporting 8 bits for each of the red, blue and green components. The integer values of a component can be converted into their floating point by dividing the integer value of a component with the number of bit-planes available for that component. For example, in an 8-bit system there are 256 bit-planes available for the red color component. The value in each plane is from 0-255. Thus 0 in the bit-plane would correspond to 0/255=0.0 in floating point value of R. The values range from 0.0 to 1.0 for all the components. Pictorially, the RGBA would be represented as follows:

 


2. Indexed Mode:

Indexed Mode, or color index mode, derives its name from the fact that it uses a lookup table to mix the colors. It is metaphorically similar to a painter who uses a numbered palette to create different colors. To take the metaphor further, as a painter’s palette has spaces to mix the colors and these spaces act as an index for new colors, in the same way a color map or lookup table indexes where the components can be mixed. This map is stored in the bit-planes. Then those bit-plane values reference the color map, and the screen is painted with the corresponding red, green, and blue values from the color map. Pictorially a color map would look like:

 


 

OpenGL manages both of these very easily without letting the developer know the low-level system calls and device-dependent API mappings. The steps involved in invoking the OpenGL commands that perform these functions are the focus of the next section.

{mospagebreak title=Manipulating Color}

OpenGL APIs: Manipulating Color

The core of OpenGL color manipulation is two functions: glColor() and glIndex(). The former is for RGBA mode and the latter is for color-index/color-map mode. Here are the details:


1. glColor*():

The * is used to represent the fact that there are multiple versions of the function. In the case of glColor() there are 14 different versions, each taking different data-types as data-type parameters. The differentiation is done on the basis of a suffix applied to the function.

For example, the version that takes integer parameters has i as the suffix, i.e. glColor3i(). All the versions having 3 as part of the suffix take three parameters: the values of the red, blue, and green components. The alpha is set to max implicitly. To explicitly set the value of alpha, the version with 4 as a part of its suffix needs to be used. It takes one extra parameter: the value of alpha component. For example, to set the current color to green without alpha set to max and to have the values to be supplied in integers, the statement would be:


glColor3i(0,255,0,0);


To set the current color to red with alpha set to maximum using integer values, the statement would be:

 

glColor3i(255,0,0,1);



2. glIndex*():

This function comes into play when the requirement is color-index mode. It updates the current color index. The main thing to keep in mind is that the current index is saved as a floating point value. If the integer is passed as an argument, then it is converted to a floating point number.

Just like its RGBA counterpart, glIndex*() has different versions based on the data-type of the parameter. In all the variants, this function takes one parameter: the color index to be used as the current color index. The variants include integer, float, and vector. Vector specified with V accepts array values. The v suffix is used in conjunction with integer (i) and float (f). For example, to set the color index to 25 in integer, the statement would be:


glIndexi(25);


Just as with glColor*(), glIndex*() can be called any time to update the current index. Also, it can be used between glBegin and glEnd. 


That covers the main APIs for color manipulation. In the next section, I will be testing the APIs in the created test bed, which was used in previous parts of the series.

{mospagebreak title=Testing the Colors} 

Testing the Colors

So here is the code. I will be using the RGBA mode. Each vertex of the triangle to be created will have different colors. The points where the colors intersect are of no concern as OpenGL takes care of that. For your information, it is the same one that was developed for testing the animation.


void Draw3D(SDL_Surface *S) // OpenGL drawing code here

{

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//clear screen and

//depth buffer. Screen color has been cleared

//at init

glRotatef(angle,0.0f,1.0f,0.0f);// Rotate The Triangle On The Y axis

glLoadIdentity(); // reset the modelview matrix

glBegin(GL_TRIANGLES);

glVertex3f( 0.0f, 1.0f, 0.0f);

glVertex3f(-1.0f,-1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f);

glEnd();



glFlush(); // flush the gl rendering pipelines


return;

}


So now I will be adding the color display code. Each vertex will have different colors — red, blue and green.


void Draw3D(SDL_Surface *S) // OpenGL drawing code here

{

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//clear screen and

//depth buffer. Screen color has been cleared

//at init

glRotatef(angle,0.0f,1.0f,0.0f);// Rotate The Triangle On The Y axis

glLoadIdentity(); // reset the modelview matrix

glBegin(GL_TRIANGLES);

glColor3f(1.0f,0.0f,0.0f);//the vertex displayed after this

//statement would be red

glVertex3f( 0.0f, 1.0f, 0.0f);


glColor3f(0.0f,1.0f,0.0f);//the vertex displayed after this

//statement would be green

 

glVertex3f(-1.0f,-1.0f, 0.0f);


glColor3f(0.0f,0.0f,1.0f);//the vertex displayed after this

//statement would be blue


glVertex3f( 1.0f,-1.0f, 0.0f);

glEnd();



glFlush(); // flush the gl rendering pipelines


return;

}


That completes adding colors to our test application. It is simple when compared to what can be achieved using OpenGL. The aspects that this article doesn’t discuss include dithering and smoothing of the rendered image. These aspects will be the focus of the next part of this series. Till next time…

[gp-comments width="770" linklove="off" ]

chat sex hikayeleri Ensest hikaye