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.
- */
-
- /* selectSolar.c
- * Selection is demonstrated here. A simple solar system
- * is drawn first in render mode, then in selection mode with
- * a narrower perspective, selecting the center of the scene.
- * Names are assigned to the shapes, and if they score hits
- * within the selected region the selected names can be retrieved.
- *
- * SPACE key - toggle selection mode
- * <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 );
-
- void updateViewVolume( GLdouble, GLdouble, GLdouble, GLdouble );
- 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 GLdouble aspect;
-
- static GLuint viewVolumeList;
-
- static GLboolean selectionFlag = GL_TRUE;
- static GLboolean rotateFlag = GL_TRUE;
-
- static GLdouble depthNormalizeFactor, znear = 6.0, zfar = 14.0;
-
- /* matrices and midpoint for gluUnProject */
- static GLdouble modelview[16], projection[16];
- static GLint viewport[4], midX, midY;
-
- /* objects to be drawn */
- static enum shapes { SUN, EARTH, MOON };
- static char *shapeNames[] = { "Sun", "Earth", "Moon" };
-
- 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();
-
- glutKeyboardFunc( keyboard );
- glutReshapeFunc( reshape );
- glutIdleFunc( animate );
- glutVisibilityFunc( visibility );
- glutDisplayFunc( drawScene );
-
- printHelp( argv[0] );
-
- glutMainLoop();
- }
-
- GLvoid
- printHelp( char *progname )
- {
- fprintf(stdout, "\n%s\nThis program demonstrates selection\n"
- "SPACE key - toggle selection mode \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 );
-
- viewVolumeList = glGenLists( 1 );
-
- /* 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 ' ': /* toggle selection when SPACE BAR is pressed */
- selectionFlag = !selectionFlag;
- glutPostRedisplay();
- break;
-
- 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
- reshape( GLsizei width, GLsizei height )
- {
- 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 );
-
- updateViewVolume( 15.0, aspect, znear+0.01, zfar-0.01 );
- }
-
- 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
- drawSolar( GLboolean selecting )
- {
- 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 using an infinite light */
- static GLfloat sun_position[] = { -1.0, 0.0, 0.0, 0.0 };
-
- glPushMatrix();
- /* sun surface lit by light attached to eye */
- glLightfv(GL_LIGHT0, GL_POSITION, position);
-
- /* viewing transformation */
- 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);
- 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);
- glutSolidSphere(0.5, 15, 15);
- glPopMatrix();
- glPushMatrix();
- glRotatef( fmodf((year*20.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);
- glutSolidSphere(0.2, 15, 15);
- glPopMatrix();
- glPopMatrix();
-
- glPopMatrix();
-
- (selecting ? glFlush(): glutSwapBuffers());
- }
-
- GLvoid
- drawScene( GLvoid )
- {
- GLuint selectBuf[BUFSIZE];
- GLint hits;
-
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
- /* draw selection viewing volume slightly inside
- * actual selection volume so that it is visible
- */
- glDisable( GL_LIGHTING );
- glCallList( viewVolumeList );
- glEnable( GL_LIGHTING );
-
- drawSolar( GL_FALSE );
- if ( selectionFlag ) {
- glSelectBuffer (BUFSIZE, selectBuf);
- (GLvoid) glRenderMode( GL_SELECT );
- glInitNames();
- glPushName( UNNAMED_OBJECT );
-
- glMatrixMode( GL_PROJECTION );
- glPushMatrix();
- glLoadIdentity();
- /* set fovy much smaller than normal to select
- * only center of scene
- */
- gluPerspective( 15.0, aspect, znear, zfar );
- glMatrixMode( GL_MODELVIEW );
- drawSolar( GL_TRUE );
-
- hits = glRenderMode( GL_RENDER );
- printHits( hits, midX, midY, selectBuf );
- glMatrixMode( GL_PROJECTION );
- glPopMatrix();
- glMatrixMode( GL_MODELVIEW );
- }
- }
-
- /* draw a perspective viewing volume indicating selected region */
- GLvoid
- updateViewVolume( GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far )
- {
- GLfloat halfFovyRadians;
- GLfloat farLeft, farRight, farBottom, farTop;
- GLfloat nearLeft, nearRight, nearBottom, nearTop;
-
- halfFovyRadians = (fovy/2.0) * (M_PI/180.0);
-
- farTop = far * tan( halfFovyRadians );
- farBottom = -farTop;
- farRight = aspect * farTop;
- farLeft = -farRight;
-
- /* offset near clipping plane slightly inwards
- * so that it will be visible. */
- nearTop = near * tan( halfFovyRadians ) - 0.03;
- nearBottom = -nearTop;
- nearRight = aspect * nearTop;
- nearLeft = -nearRight;
-
- midX = nearLeft - nearRight;
- midY = nearTop - nearBottom;
-
- glNewList( viewVolumeList, GL_COMPILE );
- glColor3f (1.0, 0.0, 0.0);
- /* draw far clipping plane */
- glBegin( GL_LINE_LOOP );
- glVertex3f (farLeft, farBottom, -far);
- glVertex3f (farRight, farBottom, -far);
- glVertex3f (farRight, farTop, -far);
- glVertex3f (farLeft, farTop, -far);
- glEnd();
-
- glColor3f( 1.0, 1.0, 0.0 );
- /* draw near clipping plane */
- glBegin( GL_LINE_LOOP );
- glVertex3f (nearLeft, nearBottom, -near);
- glVertex3f (nearRight, nearBottom, -near);
- glVertex3f (nearRight, nearTop, -near);
- glVertex3f (nearLeft, nearTop, -near);
- glEnd();
-
- /* connect clipping planes */
- glBegin( GL_LINES ); /* 4 lines */
- glVertex3f (nearLeft, nearBottom, -near);
- glVertex3f (farLeft, farBottom, -far);
-
- glVertex3f (nearRight, nearBottom, -near);
- glVertex3f (farRight, farBottom, -far);
-
- glVertex3f (nearRight, nearTop, -near);
- glVertex3f (farRight, farTop, -far);
-
- glVertex3f (nearLeft, nearTop, -near);
- glVertex3f (farLeft, farTop, -far);
- glEnd();
- glEndList( );
- }
-
- GLvoid
- printHits (GLint hits, GLint winx, GLint winy, 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( winx, winy, min_depth,
- modelview, projection, viewport,
- &objx, &objy, &objz);
- printf( " z1 = %f", objz );
-
- max_depth = ((GLdouble)(*bufp)/depthNormalizeFactor); bufp++;
- gluUnProject( winx, winy, 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 {
- fprintf( stdout, "\t%s", shapeNames[*bufp] );
- }
- }
- printf( "\n\n" );
- }
- }
-