OpenGLEAN
OpenGLEAN User Support
Home page | Introduction | Documentation | Files | Examples | Proposals | Authors | Links


OpenGLEAN Development
Summary | CVS | (discussion via home page) | (contact via home page) | (suggestion box) | License | Todo | Bugs

unmanaged.c File Reference

Include dependency graph for unmanaged.c:


Detailed Description

OpenGLEAN client menu window example.

Usage:

unmanaged [standard GLUT options]

Some suggested uses for menu windows:

Programming notes:

Author:
Copyright 2004, 2005, the OpenGLEAN Project.

Copyright (C) 2004, the OpenGLUT project contributors.

openglean_unmanaged.png

OpenGLEAN Client Menu Window Example

#include <stdlib.h>

#include <GL/openglean.h>
#include <GL/openglean_exp.h>


int window_id;
int object;

#define MENU_WIDTH  100
#define MENU_HEIGHT 300
int menu_id;
int in_menu;

/*
 * menu_x and menu_y hold the menu window coordinates on-screen.
 * x and y are the menu coordinates relative to the parent window
 * This is a bit hokey, I know; the code evolved a bit and needs to
 * be consolidated.  Sorry.
 */
int x;
int y;
int menu_x;
int menu_y;
int menu_select;

enum {MENU_QUIT = 1, MENU_TEAPOT, MENU_CUBE, MENU_SPHERE, MENU_SPONGE};

GLfloat light_color [4] = {1,   1,   .9, 1};
GLfloat light_amb   [4] = {.05, .01, .1, 1};
GLfloat light_pos   [4] = {3,   4,   5,  1};

/*
 * A filter for glColor(); usurps with white the {item} is {menu_select}ed.
 *
 * Used to simplify the logic of coloring menu items when they are to be
 * highlighted.
 */
void set_menu_color (const int item, double r, double g, double b)
{
    if (item == menu_select)
        r = g = b = 1;
    glColor3d (r, g, b);
}

/*
 * Draws a rod, intended to be used for the borders of menus.
 */
void draw_border_rod (double len)
{
    glutSolidCylinder (3, len, 10, 2);
}

/*
 * Draws a ball of the same radius as the above rod.
 *
 * Used for capping rods with round tips.
 */
void draw_corner_ball (void)
{
    glutSolidSphere (3, 10, 10);
}


void menu_display (void)
{
    static const GLdouble sponge_offset [3] = {0, 0, 0};
    int w = glutGet (GLUT_WINDOW_WIDTH);
    int h = glutGet (GLUT_WINDOW_HEIGHT);

    glClearColor (.5, .5, .5, 0);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable (GL_LIGHTING);
    glPushMatrix ();
    glTranslated (3, 3, -5);
    glRotated (-90, 1, 0, 0);
    draw_border_rod (h - 6);
    glTranslated (w - 6, 0, 0);
    draw_border_rod (h - 6);
    glPopMatrix ();
    glPushMatrix ();
    glTranslated (3, 3, -5);
    glRotated (90, 0, 1, 0);
    draw_border_rod (w - 6);
    glTranslated (0, h - 6, 0);
    draw_border_rod (w - 6);
    glPopMatrix ();

    glPushMatrix ();
    glTranslated (3, 3, -5);
    draw_corner_ball ();
    glTranslated (w - 6, 0, 0);
    draw_corner_ball ();
    glTranslated (0, h - 6, 0);
    draw_corner_ball ();
    glTranslated (6 - w, 0, 0);
    draw_corner_ball ();
    glPopMatrix ();

    glDisable (GL_LIGHTING);
    set_menu_color (MENU_QUIT, 0, 0, 0);
    glRasterPos3d (30, h - 30, -5);
    glutBitmapString (GLUT_BITMAP_TIMES_ROMAN_24, (unsigned char *) "Quit");

    glPushMatrix ();
    set_menu_color (MENU_TEAPOT, 1, 0, 0);
    glTranslated (50, h - 76, -50);
    glutWireTeapot (25);
    glPopMatrix ();

    glPushMatrix ();
    set_menu_color (MENU_CUBE, 1, 0, 0);
    glTranslated (50, h - 126, -50);
    glutWireCube (25);
    glPopMatrix ();
    
    glPushMatrix ();
    set_menu_color (MENU_SPHERE, 1, 0, 0);
    glTranslated (50, h - 176, -50);
    glutWireSphere (25, 8, 8);
    glPopMatrix ();
    
    glPushMatrix ();
    set_menu_color (MENU_SPONGE, 1, 0, 0);
    glTranslated (50, h - 226, -50);
    glutWireSierpinskiSponge (2, sponge_offset, 25);
    glPopMatrix ();

    glEnable (GL_LIGHTING);
    glutSwapBuffers ();
}

void menu_reshape (int w, int h)
{
    glEnable (GL_DEPTH_TEST);
    glEnable (GL_CULL_FACE);
    glEnable (GL_LIGHTING);
    glEnable (GL_LIGHT0);
    glLightfv (GL_LIGHT0, GL_AMBIENT, light_amb);
    glLightfv (GL_LIGHT0, GL_POSITION, light_pos);
    glLightfv (GL_LIGHT0, GL_DIFFUSE, light_color);
    glLightfv (GL_LIGHT0, GL_SPECULAR, light_color);
    glViewport (0, 0, w, h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    glOrtho (
        0, w,
        0, h,
        1, 100
    );
    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity ();
    glutPostRedisplay ();
}

void cb_motion (int x, int y);
void cb_mouse (int button, int state, int x, int y);
void sync_menu (void)
{
    if (in_menu)
    {
        if (!menu_id)
        {
            glutInitDisplayMode (GLUT_DEPTH | GLUT_DOUBLE);
            menu_id = glutCreateMenuWindow (
                window_id, x, y, MENU_WIDTH, MENU_HEIGHT
            );
            glutDisplayFunc (menu_display);
            glutReshapeFunc (menu_reshape);

            /* XXX Hack; maybe no longer necessary */
            menu_reshape (MENU_WIDTH, MENU_HEIGHT); /* XXX */
        }
    }
    else if (menu_id)
    {
        glutDestroyWindow (menu_id);
        menu_id = 0;
    }
}


void cb_display (void)
{
    int msecs = glutGet (GLUT_ELAPSED_TIME);
    GLdouble theta = .01 * msecs;
    static const GLdouble sponge_offset [3] = {0, 0, 0};
    
    glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    glColorMaterial (GL_FRONT_AND_BACK, GL_DIFFUSE);
    glEnable (GL_COLOR_MATERIAL);
    glColor3d (1, 1, 1);
    glPushMatrix ();
    glRotated (theta, 0, 1, 0);
    switch (object)
    {
    case 0:
        glPopMatrix ();
        glPushMatrix ();
        glNormal3d (0, 0, 1);
        glColor3d( 1, 1, 1 );
        glRasterPos2d (-1.9, .3);
        glDisable (GL_LIGHTING);
        glutBitmapString (
            GLUT_BITMAP_TIMES_ROMAN_24,
            (unsigned char *) "Click on me for menus!"
        );
        glEnable (GL_LIGHTING);
        break;
    case MENU_TEAPOT:
        glutSolidTeapot (1);
        break;
    case MENU_CUBE:
        glutSolidCube (1);
        break;
    case MENU_SPHERE:
        glutSolidSphere (1, 50, 50);
        break;
    case MENU_SPONGE:
        glutSolidSierpinskiSponge (
            abs (((msecs / 400) % 15) - 7) , sponge_offset, 1
        );
        break;
    default:
        break;
    }
    glPopMatrix ();
    glutSwapBuffers ();
}

void cb_motion (int _x, int _y)
{
    int x; /* = _x + glutGet (GLUT_WINDOW_X) - menu_x; */
    int y; /* = _y + glutGet (GLUT_WINDOW_Y) - menu_y; */
    glutSetWindow (window_id);
    x = _x + glutGet (GLUT_WINDOW_X) - menu_x;
    y = _y + glutGet (GLUT_WINDOW_Y) - menu_y;

    menu_select = 0;
    if ((6 < x) && ((MENU_WIDTH - 6) > x) &&
        (6 < y) && ((MENU_HEIGHT - 6) > y))
    {
        if (30 > y)
            menu_select = MENU_QUIT;
        else if (100 > y)
            menu_select = MENU_TEAPOT;
        else if (150 > y)
            menu_select = MENU_CUBE;
        else if (200 > y)
            menu_select = MENU_SPHERE;
        else if (250 > y)
            menu_select = 5;
        else if (300 > y)
            menu_select = 6;
        else
            menu_select = 7;
        glutSetWindow (menu_id);
        glutPostRedisplay ();
    }
}



void cb_mouse (int button, int state, int _x, int _y)
{
    x = _x;
    y = _y;
    if (!in_menu && (GLUT_DOWN == state))
    {
        in_menu = button+1;
        menu_x = x + glutGet (GLUT_WINDOW_X);
        menu_y = y + glutGet (GLUT_WINDOW_Y);
    }
    else if (((in_menu - 1) == button) && (GLUT_UP == state))
    {
        if (MENU_QUIT == menu_select)
            exit (0);
        object = menu_select;
        glutPostRedisplay ();
        in_menu = 0;
    }
    sync_menu ();
}


void cb_idle (void)
{
    glutSetWindow (window_id);
    glutPostRedisplay ();
}

void cb_reshape (int w, int h)
{
    double ar = w / (1.0 * h);

    glViewport (
        0, 0,
        w, h
    );
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    if (w > h)
        glFrustum (
            -ar, ar,
            -1,   1,
             1,  50
        );
    else
        glFrustum (
             -1,    1,
             -1/ar, 1/ar,
              1,    50
        );
    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity ();
    glTranslated (0, 0, -3);

    glEnable (GL_DEPTH_TEST);
    glEnable (GL_CULL_FACE);
    glCullFace (GL_BACK);
    glEnable (GL_LIGHTING);
    glEnable (GL_LIGHT0);
    glLightfv (GL_LIGHT0, GL_POSITION, light_pos);
    glLightfv (GL_LIGHT0, GL_DIFFUSE, light_color);
    glLightfv (GL_LIGHT0, GL_SPECULAR, light_color);
}


int main (int argc, char **argv)
{
    glutInit (&argc, argv);

    glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowPosition (100, 100);
    window_id = glutCreateWindow ("Unmanaged window demo");
    glutReshapeFunc (cb_reshape);
    glutDisplayFunc (cb_display);
    glutMouseFunc (cb_mouse);
    glutMotionFunc (cb_motion);

    glutIdleFunc (cb_idle);

    glutMainLoop ();

    return EXIT_SUCCESS;
}




SourceForge.net Logo Supported in part by SourceForge.net.

Generated on Fri Sep 16 20:15:31 2005 for OpenGLEAN by doxygen 1.4.3
The OpenGLEAN project is hosted by olib.org and SourceForge.