3. GLSL Coloring

Jump To:

main.cpp Source
shader.vert Source
shader.frag Source
Download

From now on, I won’t be listing the source code for the shader.h and shader.cpp files, as these will not be changing. We have everything we need in place to play with our shaders.

What we are trying to do in this tutorial is simulate our fixed function pipeline in GLSL. In standard OpenGL, we are used to coloring objects with their respective glColor3f or glColor4f methods.

This tutorial will allow us to use the values assigned as the color, inside our shader.

Main.CPP File:

Now this code, isn’t going to change at all, but the key line to focus on is:

    glColor4f(1.0, 0.0, 0.0, 1.0);

Changing this line will change the output colour of the fragment shader.

And I have also changed from using a wire cube, just to show the color of the shape more clearly.

    glutSolidCube(2);

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.

    #if ( (defined(__MACH__)) && (defined(__APPLE__)) )   
#include <stdlib.h>
#include <OpenGL/gl.h>
#include <GLUT/glut.h>
#include <OpenGL/glext.h>
#else
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/glext.h>
#endif

#include “shader.h”

Shader shader;

GLfloat angle = 0.0; //set the angle of rotation

void init(void) {
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    
    shader.init(“shader.vert”, “shader.frag”);
}

void cube (void) {
    glRotatef(angle, 1.0, 0.0, 0.0); //rotate on the x axis
    glRotatef(angle, 0.0, 1.0, 0.0); //rotate on the y axis
    glRotatef(angle, 0.0, 0.0, 1.0); //rotate on the z axis
    glColor4f(1.0, 0.0, 0.0, 1.0);
    glutSolidCube(2);
}

void display (void) {
    glClearColor (0.0,0.0,0.0,1.0);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();  
    gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    
    shader.bind();
    cube();
    shader.unbind();
    
    glutSwapBuffers();
    angle += 0.1f;
}

void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
    glMatrixMode (GL_MODELVIEW);
}

int main (int argc, char **argv) {
    glutInit(&argc, argv);
    //set up
the double buffering

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH;

    glutInitWindowSize(500, 500);
    glutInitWindowPosition(100, 100);
    glutCreateWindow(“A basic OpenGL Window);
    
    glewInit();

    glutDisplayFunc(display);
    glutIdleFunc(display);
    
    glutReshapeFunc(reshape);
    
    init();
    
    glutMainLoop();
    
    return 0;
}

Vertex Shader Source:

Our change here, is going to be the introduction of a new line. This line will look like:

    gl_FrontColor = gl_Color;     

And what this means, is that we want the set the front face color for our objects, to that of the color entered in by the glColor3f and glColor4f functions.

If we have a shape with some back facing shapes, then we can also set gl_BackColor to the same value, and this will give us the same color for both front and back facing shapes. Or you could even change this value, so that the front of a shape has one color, and the back of a shape has another color.

1.
2.
3.
4.
5.
    void main() {     
    // Set the front color to the color passed through with glColor*f 
    gl_FrontColor = gl_Color;        
    // Set the position of the current vertex 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

 

Fragment Shader Source:

The only difference here, is the replacement of our vec4(1.0) color value, with the value gl_Color.

*Note that the gl_Color read in by the vertex shader, is different to that of the gl_Color value read in by the fragment shader. The one in the fragment shader, refers to the gl_Color value we get from the vertex shader, whilst the gl_Color value in our vertex shader is read in from our application.*

And that is all there is to it. It is often handy to set the colours, lighting values, etc in regular OpenGL mode, so that if our shader fails on a certain system, we will still get a similar result. It just won’t look as pretty.

If you have any questions, please email me at swiftless@gmail.com

1.
2.
3.
4.
    void main() {
    // Set the output color of our current pixel
    gl_FragColor = gl_Color;
}

 

Download:

Download shader.h Source Code for this Tutorial

Download shader.cpp Source Code for this Tutorial

Download main.cpp Source Code for this Tutorial

Download shader.vert Source Code for this Tutorial

Download shader.frag Source Code for this Tutorial

  • March 25, 2010
  • 9