Example 08

Example 08

This OpenGL program displays a color wheel and allows users to pick a color. The RGB value will be display to the user in both as floating point [0.0, 1.0] and as an integer [0, 255].

ex_08/color_wheel.png

Source Code

color_wheel.cc:

// Peter Bui
// CSE 40166 Computer Graphics (Fall 2010)
// Example 8: color wheel
 
#include <cmath>
#include <cstdio>
#include <cstdlib>

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

// Global variables ------------------------------------------------------------

static GLint Mode = GL_RENDER;

static size_t WindowWidth  = 640;
static size_t WindowHeight = 480;

static GLfloat CurrentColor[3] = {0.0, 0.0, 0.0};

#define NCOLORS 12

static GLfloat ColorTable[NCOLORS][3] = {
    { 1.0, 0.0, 0.0 },
    { 1.0, 0.5, 0.0 },
    { 1.0, 1.0, 0.0 },
    { 0.5, 1.0, 0.0 },
    { 0.0, 1.0, 0.0 },
    { 0.0, 1.0, 0.5 },
    { 0.0, 1.0, 1.0 },
    { 0.0, 0.5, 1.0 },
    { 0.0, 0.0, 1.0 },
    { 0.5, 0.0, 1.0 },
    { 1.0, 0.0, 1.0 },
    { 1.0, 0.0, 0.5 },
};

// Print color component -------------------------------------------------------

void
print_color_component(char component)
{
    char message[32];
    char *c;
    int i;

    switch (component) {
        case 'R':
            glColor3f(1.0, 0.0, 0.0);
            i = 0;
            break;
        case 'G':
            glColor3f(0.0, 1.0, 0.0);
            i = 1;
            break;
        case 'B':
            glColor3f(0.0, 0.0, 1.0);
            i = 2;
            break;
    }

    glRasterPos2f(1.10, 0.40 - 0.10 * i);
    snprintf(message, 32, "%c: %f (%d)", component, CurrentColor[i], (int)(CurrentColor[i] * 255));
    for (c = message; *c; c++)
        glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *c);
}

// Draw scene ------------------------------------------------------------------

void
draw_scene()
{
    // Color wheel 
    glBegin(GL_TRIANGLE_FAN); {
        double ox = 2.0, oy = 1.25 + sqrt(1.0)/2.0, radius = 1.0;
        
        glColor3f(0.0, 0.0, 0.0);
        glVertex2f(ox, oy);

        for (size_t c = 0; c <= NCOLORS; c++) {
            double angle = c * 2.0 * M_PI / NCOLORS;
            glColor3fv(ColorTable[c % NCOLORS]);
            glVertex2f(ox + radius * cos(angle), oy + radius * sin(angle));
        }
    } glEnd();
    
    // Current color box
    glBegin(GL_QUADS); {
        glColor3fv(CurrentColor);
        glVertex2f(0.05, 0.05);
        glVertex2f(1.05, 0.05);
        glVertex2f(1.05, 0.55);
        glVertex2f(0.05, 0.55);
    } glEnd();

    // Display RGB values
    print_color_component('R');
    print_color_component('G');
    print_color_component('B');
}

// Initialize scene ------------------------------------------------------------

void
init_scene()
{
    GLdouble aspect_ratio = (GLdouble)WindowWidth/(GLdouble)WindowHeight;

    glViewport(0, 0, WindowWidth, WindowHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    if (aspect_ratio < 1.0)
        gluOrtho2D(0.0, 3.0, 0, 3.0/aspect_ratio);
    else
        gluOrtho2D(0.0, 3.0*aspect_ratio, 0, 3.0);

    glMatrixMode(GL_MODELVIEW);    
}

// Display callback ------------------------------------------------------------

void
display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    draw_scene();
    glutSwapBuffers();
}

// Reshape callback ------------------------------------------------------------

void
reshape(GLsizei nw, GLsizei nh)
{
    WindowWidth  = nw;
    WindowHeight = nh;

    init_scene();
}

// Mouse callback --------------------------------------------------------------

void 
mouse(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
        Mode = GL_SELECT;
        glReadPixels(x, WindowHeight - y, 1, 1, GL_RGB, GL_FLOAT, CurrentColor);
    } else {
        Mode = GL_RENDER;
    }
        
    glutPostRedisplay();
}

// Motion callback --------------------------------------------------------------

void
motion(int x, int y)
{
    if (Mode == GL_SELECT) {
        glReadPixels(x, WindowHeight - y, 1, 1, GL_RGB, GL_FLOAT, CurrentColor);
        glutPostRedisplay();
    }
}

// Keyboard callback ------------------------------------------------------------

void
keyboard(unsigned char key, int x, int y)
{
    if (key == 'q' || key == 'Q')
        exit(EXIT_SUCCESS);
}

// Main execution ---------------------------------------------------------------

int
main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    glutInitWindowSize(WindowWidth, WindowHeight);
    glutCreateWindow("color wheel");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);

    init_scene();

    glutMainLoop();

    return (EXIT_SUCCESS);
}

// vim: sts=4 sw=4 ts=8 ft=cpp


Files