home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1993, 1996, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
-
- /* pickSolar.c
- * This program demonstrates how to pick objects in a scene.
- *
- * Left Mouse Button, down - pick object(s)
- * <r> key - toggle rotation on/off
- * Escape key - exit the program
- */
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include <GL/glut.h>
-
- #include <stdio.h>
- #include <math.h>
-
- /* Function Prototypes */
-
- GLvoid initgfx( GLvoid );
- GLvoid drawScene( GLvoid );
- GLvoid reshape( GLsizei, GLsizei );
- GLvoid keyboard( GLubyte, GLint, GLint );
- GLvoid animate( GLvoid );
- GLvoid visibility( int );
- GLvoid mouse( GLint, GLint, GLint, GLint );
-
- void doPicking( int x, int y );
- void printHits( GLint, GLint, GLint, GLuint [] );
- void printHelp( char * );
-
- /* Global Definitions */
-
- #define KEY_ESC 27 /* ascii value for the escape key */
-
- #define BUFSIZE 512 /* hit buffer size */
-
- #define UNNAMED_OBJECT (-1) /* marks empty name stack */
-
- /* Global Variables */
-
- static GLboolean picking = GL_FALSE;
- static GLboolean rotateFlag = GL_TRUE;
-
- static GLdouble depthNormalizeFactor, znear = 6.0, zfar = 14.0;
-
- /* matrices for gluUnProject */
- static GLdouble modelview[16], projection[16];
- static GLint viewport[4];
-
- static enum shapes { SUN, EARTH, MOON };
- static char *shapeNames[] = { "Sun", "Earth", "Moon" };
-
- static GLboolean pickedFlag[ MOON + 1 ] = { GL_FALSE };
-
- static GLfloat year = 0;
-
- void
- main( int argc, char **argv )
- {
- GLsizei width, height;
-
- glutInit( &argc, argv );
-
- width = glutGet( GLUT_SCREEN_WIDTH );
- height = glutGet( GLUT_SCREEN_HEIGHT );
- glutInitWindowPosition( width / 4, height / 4 );
- glutInitWindowSize( (width / 2) - 4, height / 2 );
- glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
- glutCreateWindow( argv[0] );
-
- initgfx();
-
- glutMouseFunc( mouse );
- glutKeyboardFunc( keyboard );
- glutReshapeFunc( reshape );
- glutIdleFunc( animate );
- glutVisibilityFunc( visibility );
- glutDisplayFunc( drawScene );
-
- printHelp( argv[0] );
-
- glutMainLoop();
- }
-
- GLvoid
- printHelp( char *progname )
- {
- fprintf(stdout, "%s - program demonstrates picking\n\n"
- "Left Mouse Button, down - pick object(s)\n"
- "<r> key - toggle rotation on/off \n"
- "Escape key - exit the program \n\n",
- progname );
- }
-
- void
- initgfx()
- {
- GLfloat mat_specular[] = { 0.8, 0.8, 0.8, 1.0 };
- GLfloat mat_shininess[] = { 10.0 };
- GLfloat mat_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
-
- glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
- glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
- glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
- glEnable( GL_LIGHTING );
- glEnable( GL_LIGHT0 );
-
- glClearColor( 0, 0, 0, 1 );
- glEnable( GL_DEPTH_TEST );
-
- /* depth values in hit record are in the range 0 to 2**32 - 1 */
- depthNormalizeFactor = pow(2, 32) - 1;
- }
-
- GLvoid
- keyboard( GLubyte key, GLint x, GLint y )
- {
- switch (key) {
- case 'r': /* toggle rotation on/off */
- rotateFlag = !rotateFlag;
- if ( rotateFlag )
- glutIdleFunc( animate );
- else
- glutIdleFunc( NULL );
- glutPostRedisplay();
- break;
-
- case KEY_ESC: /* Exit whenever the Escape key is pressed */
- exit(0);
- }
- }
-
- GLvoid
- mouse( GLint button, GLint state, GLint x, GLint y )
- {
- if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
- doPicking( x, y );
- }
- }
-
- GLvoid
- doPicking( int mouseX, int mouseY )
- {
- GLuint selectBuf[BUFSIZE];
- GLint hits;
- GLdouble aspect;
-
- aspect = (GLdouble) viewport[2] / (GLdouble) viewport[3];
-
- mouseY = viewport[3] - mouseY;
-
- picking = GL_TRUE;
-
- glSelectBuffer (BUFSIZE, selectBuf);
- (GLvoid) glRenderMode( GL_SELECT );
- glInitNames();
- glPushName( UNNAMED_OBJECT );
-
- glMatrixMode( GL_PROJECTION );
- glPushMatrix();
- glLoadIdentity();
- gluPickMatrix( (GLdouble) mouseX, (GLdouble) mouseY,
- 5, 5, /* x, y pixel tolerance for pick */
- viewport );
- gluPerspective( 45.0, aspect, 6.0, 14.0 );
- glMatrixMode( GL_MODELVIEW );
-
- drawScene();
-
- hits = glRenderMode( GL_RENDER );
- printHits( hits, mouseX, mouseY, selectBuf );
-
- picking = GL_FALSE;
-
- glMatrixMode( GL_PROJECTION );
- glPopMatrix();
- glMatrixMode( GL_MODELVIEW );
- glutPostRedisplay(); /* make sure scene is redrawn */
- }
-
- GLvoid
- reshape( GLsizei width, GLsizei height )
- {
- GLdouble aspect;
-
- glViewport( 0, 0, width, height );
-
- aspect = (GLdouble) width / (GLdouble) height;
-
- glMatrixMode( GL_PROJECTION );
- glLoadIdentity();
- gluPerspective( 45.0, aspect, znear, zfar);
- glMatrixMode( GL_MODELVIEW );
- glLoadIdentity();
-
- glGetIntegerv( GL_VIEWPORT, viewport );
- glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
- glGetDoublev( GL_PROJECTION_MATRIX, projection );
- }
-
- GLvoid
- animate( GLvoid )
- {
- /* update the current year */
- year = fmodf((year + 0.2), 360);
-
- /* Tell GLUT to redraw the scene */
- glutPostRedisplay();
- }
-
- GLvoid
- visibility( int state )
- {
- if (state == GLUT_VISIBLE && rotateFlag) {
- glutIdleFunc( animate );
- } else {
- glutIdleFunc( NULL );
- }
- }
-
- GLvoid
- drawScene( GLvoid )
- {
- static GLfloat sun_diffuse[] = { 1.0, 1.0, 0.0, 1.0 };
- static GLfloat sun_specular[] = { 1.0, 1.0, 1.0, 1.0 };
- static GLfloat no_specular[] = { 0.0, 0.0, 0.0, 1.0 };
- static GLfloat earth_diffuse[] = { 0.0, 0.3, 1.0, 1.0 };
- static GLfloat moon_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
- static GLfloat position[] = { 0.0, 0.0, 1.0, 0.0 };
-
- /* simulate local light centered at sun by rotating an
- * infinite light */
- static GLfloat sun_position[] = { -1.0, 0.0, 0.0, 0.0 };
-
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
- glPushMatrix();
-
- /* sun surface lit by light attached to eye,
- * thus before viewing */
- glLightfv(GL_LIGHT0, GL_POSITION, position);
-
- /* accomplish a viewing transformation by moving
- * the world relative to the eye
- */
- glTranslatef(0.0, 0.0, -10.0);
- glRotatef( 10.0, 1.0, 0.0, 0.0 );
-
- glPushMatrix();
- glRotatef (90.0, 1.0, 0.0, 0.0);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, sun_diffuse);
- glMaterialfv(GL_FRONT, GL_SPECULAR, sun_specular);
- glLoadName(SUN);
- if ( pickedFlag[SUN] && !picking )
- glutWireSphere(0.7, 15, 15);
- else
- glutSolidSphere(0.7, 15, 15);
- glPopMatrix();
-
- glPushMatrix();
- glRotatef (year, 0.0, 1.0, 0.0);
- glTranslatef (2.5, 0.0, 0.0);
- glPushMatrix();
- /* infinite light looks like local light at
- * sun because rotating in sync with planet */
- glLightfv(GL_LIGHT0, GL_POSITION, sun_position);
- glRotatef (90.0, 1.0, 0.0, 0.0);
- glMaterialfv(GL_FRONT, GL_SPECULAR, no_specular);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_diffuse);
- glLoadName(EARTH);
- if ( pickedFlag[EARTH] && !picking )
- glutWireSphere(0.5, 15, 15);
- else
- glutSolidSphere(0.5, 15, 15);
- glPopMatrix();
-
- glPushMatrix();
- glRotatef ( fmodf( (year * 5.0), 360.0 ),
- 0.0, 1.0, 0.0);
- glTranslatef (1.0, 0.0, 0.0);
- glRotatef (90.0, 1.0, 0.0, 0.0);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, moon_diffuse);
- glPushName(MOON);
- if ( pickedFlag[MOON] && !picking )
- glutWireSphere(0.2, 15, 15);
- else
- glutSolidSphere(0.2, 15, 15);
- glPopMatrix();
- glPopMatrix();
-
- glPopMatrix();
-
- ( picking ? glFlush() : glutSwapBuffers() );
- }
-
- GLvoid
- printHits (GLint hits, GLint x, GLint y, GLuint buffer[] )
- {
- unsigned int i, j, nameCount;
- GLuint *bufp;
- GLdouble min_depth, max_depth, objx, objy, objz;
-
- printf ("hits = %d\n", hits);
- bufp = (GLuint *) buffer;
- for (i = 0; i < hits; i++)
- { /* for each hit */
- nameCount = *bufp; bufp++;
- printf( " number of names for this hit = %d\n",
- nameCount );
-
- min_depth = ((GLdouble)(*bufp)/depthNormalizeFactor); bufp++;
- gluUnProject( x, y, min_depth, modelview, projection,
- viewport, &objx, &objy, &objz);
- printf( " z1 = %f", objz );
-
- max_depth = ((GLdouble)(*bufp)/depthNormalizeFactor); bufp++;
- gluUnProject( 0.0, 0.0, max_depth, modelview, projection,
- viewport, &objx, &objy, &objz);
- printf( " z2 = %f\n", objz );
-
- printf( " names are: " );
- for ( j = 0; j < nameCount; j++, bufp++ )
- { /* for each name */
- if ((GLint) *bufp == UNNAMED_OBJECT ) {
- fprintf( stdout, "UNNAMED_OBJECT\n" );
- } else {
- if (j == (nameCount - 1))
- pickedFlag[*bufp] = !pickedFlag[*bufp];
- fprintf( stdout, "\t%s", shapeNames[*bufp] );
- }
- }
- printf( "\n\n" );
- }
- }
-