OpenGLUT Documentation
Introduction | Documentation | Examples | Proposals | Authors | Copying | Todo | Bugs | Links

unmanaged.c File Reference


Detailed Description

OpenGLUT client menu window example.

Usage:

unmanaged [standard GLUT options]

Some suggested uses for menu windows:

Programming notes:

Author:
Copyright (C) 2004, the OpenGLUT project contributors.
openglut_unmanaged.png

OpenGLUT Client Menu Window Example

#include <stdlib.h>

#include <GL/openglut.h>
#include <GL/openglut_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[ 3 ] = { ( GLfloat )1, ( GLfloat )1, ( GLfloat ).9 };
GLfloat light_pos[ 3 ] =   { ( GLfloat )3, ( GLfloat )4, ( GLfloat )5 };

/*
 * 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.0;
    glColor3d( ( GLdouble )r, ( GLdouble )g, ( GLdouble )b );
}

/*
 * Draws a rod, intended to be used for the borders of menus.
 */
void draw_border_rod( double len )
{
    glutSolidCylinder( ( GLdouble )3,
                       ( GLdouble )len, ( GLint )10, ( GLint )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( ( GLdouble )3, ( GLint )10, ( GLint )10 );
}


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

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

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

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

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

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

    glPushMatrix( );
    set_menu_color( MENU_CUBE, 1, 0, 0 );
    glTranslated( ( GLdouble )50, ( GLdouble )( h - 126 ), ( GLdouble )-50 );
    glutWireCube( ( GLdouble )25 );
    glPopMatrix( );
    
    glPushMatrix( );
    set_menu_color( MENU_SPHERE, 1, 0, 0 );
    glTranslated( ( GLdouble )50, ( GLdouble )( h - 176 ), ( GLdouble )-50 );
    glutWireSphere( ( GLdouble )25, ( GLint )8, ( GLint )8 );
    glPopMatrix( );
    
    glPushMatrix( );
    set_menu_color( MENU_SPONGE, 1, 0, 0 );
    glTranslated( ( GLdouble )50, ( GLdouble )( h - 226 ), ( GLdouble )-50 );
    glutWireSierpinskiSponge( 2, sponge_offset, ( GLdouble )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_POSITION, light_pos );
    glLightfv( GL_LIGHT0, GL_DIFFUSE, light_color );
    glLightfv( GL_LIGHT0, GL_SPECULAR, light_color );
    glViewport( ( GLint )0, ( GLint )0, ( GLsizei )w, ( GLsizei )h );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity( );
    glOrtho(
        ( GLdouble )0, ( GLdouble )w,
        ( GLdouble )0, ( GLdouble )h,
        ( GLdouble )1, ( GLdouble )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 = ( GLdouble )( .01 * msecs );
    static const GLdouble sponge_offset[ 3 ] =
        { ( GLdouble )0, ( GLdouble )0, ( GLdouble )0 };
    
    glClear( ( GLbitfield )( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ) );
    glColor3d( ( GLdouble )1, ( GLdouble )1, ( GLdouble )1 );
    glPushMatrix( );
    glRotated( theta, ( GLdouble )0, ( GLdouble )1, ( GLdouble )0 );
    switch( object )
    {
    case 0:
        glPopMatrix( );
        glPushMatrix( );
        glNormal3d( ( GLdouble )0, ( GLdouble )0, ( GLdouble )1 );
        glColor3d( ( GLdouble )1, ( GLdouble )1, ( GLdouble )1 );
        glRasterPos2d( ( GLdouble )-1.9, ( GLdouble )0.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( ( GLdouble )1 );
        break;
    case MENU_CUBE:
        glutSolidCube( ( GLdouble )1 );
        break;
    case MENU_SPHERE:
        glutSolidSphere( ( GLdouble )1, ( GLint )50, ( GLint )50 );
        break;
    case MENU_SPONGE:
        glutSolidSierpinskiSponge(
            abs( ( ( msecs / 400 ) % 15 ) - 7 ) , sponge_offset, ( GLdouble )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(
        ( GLint )0, ( GLint )0,
        ( GLsizei )w, ( GLsizei )h
    );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity( );
    if( w > h )
        glFrustum(
            ( GLdouble )-ar, ( GLdouble )ar,
            ( GLdouble )-1,  ( GLdouble )1,
            ( GLdouble )1,   ( GLdouble )50
        );
    else
        glFrustum(
            ( GLdouble ) -1,       ( GLdouble )1,
            ( GLdouble )( -1/ar ), ( GLdouble )( 1/ar ),
            ( GLdouble )1,         ( GLdouble )50
        );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity( );
    glTranslated( ( GLdouble )0, ( GLdouble )0, ( GLdouble )-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;
}




OpenGLUT Development @ Sourceforge
Homepage | Summary | Files | CVS | Forums | Lists | Bugs | RFE

Generated on Sat Feb 5 01:47:27 2005 for OpenGLUT by doxygen 1.3.9.1
The OpenGLUT project is hosted by sourceforge.net.