home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl1 / answers / viewing.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  10.2 KB  |  422 lines

  1. /*
  2.  * Copyright 1993, 1996, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /* viewing.c - open a window and clear the background.
  19.  *    Set up callbacks to handle keyboard input.
  20.  *      Model some objects.  Use perspective projection.
  21.  *    Use independent modeling transformations to position objects.
  22.  *    Added reshape callback to reset the viewport and viewing volume.
  23.  *    Add depth buffering.
  24.  *    Add a viewing transformation and control it using mouse input.
  25.  *
  26.  *    F1 key            - print help information
  27.  *    Left Arrow Key        - move the reference point to the left
  28.  *    Right Arrow Key        - move the reference point to the right
  29.  *    Up Arrow Key        - move the reference point up
  30.  *    Down Arrow Key        - move the reference point down
  31.  *    <f> key            - toggle front/back face culling
  32.  *    <s> key            - toggle smooth/flat shading
  33.  *    SPACE key        - generates a random background color
  34.  *    Escape Key        - exit program
  35.  */
  36. #include <GL/gl.h>
  37. #include <GL/glu.h>
  38. #include <GL/glut.h>
  39.  
  40. #include <stdio.h>
  41. #include <math.h>
  42.  
  43. /* Function Prototypes */
  44.  
  45. GLvoid initgfx( GLvoid );
  46. GLvoid keyboard( GLubyte, GLint, GLint );
  47. GLvoid specialkeys( GLint, GLint, GLint );
  48. GLvoid reshape( GLsizei, GLsizei );
  49. GLvoid drawScene( GLvoid );
  50.  
  51. void checkError( char * );
  52. void printHelp( char * );
  53.  
  54. /* Global Variables */
  55.  
  56. static GLdouble        xRef = 0.0, yRef = 0.0;
  57.  
  58. static char *progname; 
  59.  
  60. /* Global Definitions */
  61.  
  62. #define KEY_ESC    27    /* ascii value for the escape key */
  63.  
  64. void
  65. main( int argc, char *argv[] )
  66. {
  67.     GLsizei width, height;
  68.  
  69.     glutInit( &argc, argv );
  70.  
  71.     /* create a window that is 1/4 the size of the screen,
  72.      * and position it in the middle of the screen.
  73.      */
  74.     width = glutGet( GLUT_SCREEN_WIDTH ); 
  75.     height = glutGet( GLUT_SCREEN_HEIGHT );
  76.     glutInitWindowPosition( width / 4, height / 4 );
  77.     glutInitWindowSize( width / 2, height / 2 );
  78.     glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH );
  79.     glutCreateWindow( argv[0] );
  80.  
  81.     initgfx();
  82.  
  83.     glutReshapeFunc( reshape );
  84.     glutKeyboardFunc( keyboard );
  85.     glutSpecialFunc( specialkeys );
  86.     glutDisplayFunc( drawScene ); 
  87.  
  88.     progname = argv[0];
  89.  
  90.     printHelp( progname );
  91.  
  92.     glutMainLoop();
  93. }
  94.  
  95. void
  96. printHelp( char *progname )
  97. {
  98.     fprintf(stdout, 
  99.         "\n%s - create a scene and handle resizing\n\n"
  100.         "F1 key        - print help information\n"
  101.         "Left Arrow Key        - move reference point to the left\n"
  102.         "Right Arrow Key    - move reference point to the right\n"
  103.         "Up Arrow Key        - move reference point up\n"
  104.         "Down Arrow Key        - move reference point down\n"
  105.         "SPACE Key    - generates a random background color\n"
  106.         "<f> key        - toggle front/back face culling\n"
  107.         "<s> key        - toggle smooth/flat shading\n"
  108.         "Escape Key    - exit the program\n\n",
  109.         progname);
  110. }
  111.  
  112. GLvoid
  113. initgfx( GLvoid )
  114. {
  115.  
  116.     /* set clear color to blue */
  117.     glClearColor( 0.0, 0.0, 1.0, 1.0 );
  118.  
  119.     /* enable the depth buffer */
  120.     glEnable( GL_DEPTH_TEST );
  121.  
  122.     /* enable the face culling */
  123.     glEnable( GL_CULL_FACE );
  124. }
  125.  
  126. GLvoid 
  127. reshape( GLsizei width, GLsizei height )
  128. {
  129.     GLdouble    aspect;
  130.  
  131.     glViewport( 0, 0, width, height );
  132.  
  133.     /* compute aspect ratio */
  134.     aspect = (GLdouble) width / (GLdouble) height;
  135.  
  136.     glMatrixMode( GL_PROJECTION );
  137.  
  138.     /* Reset world coordinates first ... */
  139.     glLoadIdentity();
  140.  
  141.     /* Reset the viewing volume based on the new aspect ratio */
  142.     gluPerspective( 45.0, aspect, 3.0, 7.0 );
  143.  
  144.     glMatrixMode( GL_MODELVIEW );
  145. }
  146.  
  147. void 
  148. checkError( char *label )
  149. {
  150.     GLenum error;
  151.     while ( (error = glGetError()) != GL_NO_ERROR )
  152.         printf( "%s: %s\n", label, gluErrorString(error) );
  153. }
  154.  
  155. GLvoid 
  156. keyboard( GLubyte key, GLint x, GLint y )
  157. {
  158.     static GLboolean flat = GL_FALSE;
  159.     static GLboolean cullFront = GL_FALSE;
  160.  
  161.     switch (key) {
  162.     case ' ':    /* SPACE key */
  163.         /* generate a random background color */
  164.         glClearColor( drand48(), drand48(), drand48(), 1.0 ); 
  165.         glutPostRedisplay();
  166.         break;
  167.     case 'f':    /* f key */
  168.         /* toggle between back and front face culling */
  169.         cullFront = !cullFront;
  170.         if (cullFront) {
  171.             glCullFace( GL_FRONT );
  172.             printf("Culling FRONT faces\n");
  173.         } else { 
  174.             glCullFace( GL_BACK );
  175.             printf("Culling BACK faces\n");
  176.         }
  177.         glutPostRedisplay();
  178.         break;
  179.     case 's':    /* s key */
  180.         /* toggle between smooth and flat shading */
  181.         flat = !flat;
  182.         if (flat)
  183.             glShadeModel( GL_FLAT );
  184.         else 
  185.             glShadeModel( GL_SMOOTH );
  186.         glutPostRedisplay();
  187.         break;
  188.     case KEY_ESC:    /* Exit when the Escape key is pressed */
  189.         exit(0);
  190.     }
  191. }
  192.  
  193. GLvoid 
  194. specialkeys( GLint key, GLint x, GLint y )
  195. {
  196.     switch (key) {
  197.     case GLUT_KEY_F1:    /* Function key #1 */
  198.         /* print help information */
  199.         printHelp( progname );
  200.         break;
  201.  
  202.     case GLUT_KEY_LEFT:    /* move reference point to the left */
  203.         xRef -= 0.5;
  204.         if (xRef < -4.0) xRef = -4.0;
  205.         glutPostRedisplay();
  206.          break;
  207.  
  208.     case GLUT_KEY_RIGHT:    /* move reference point to the right */
  209.         xRef += 0.5;
  210.         if (xRef > 4.0) xRef = 4.0;
  211.         glutPostRedisplay();
  212.         break;
  213.  
  214.     case GLUT_KEY_UP:    /* move reference point up */
  215.         yRef += 0.5;
  216.         if (yRef > 3.0) yRef = 3.0;
  217.         glutPostRedisplay();
  218.         break;
  219.  
  220.     case GLUT_KEY_DOWN:    /* move reference point down */
  221.         yRef -= 0.5;
  222.         if (yRef < -3.0) yRef = -3.0;
  223.         glutPostRedisplay();
  224.         break;
  225.     }
  226. }
  227.  
  228. GLvoid
  229. drawWindow()
  230. {
  231.     /* window */
  232.     static GLfloat v0[] = { 0.0, 0.4 };
  233.     static GLfloat v1[] = { 0.0, 0.0 };
  234.     static GLfloat v2[] = { 0.1, 0.4 };
  235.     static GLfloat v3[] = { 0.1, 0.0 };
  236.     static GLfloat v4[] = { 0.2, 0.4 };
  237.     static GLfloat v5[] = { 0.2, 0.0 };
  238.  
  239.     /* draw 2 quadrilateral strip to make a window */
  240.     glBegin( GL_QUAD_STRIP );
  241.         glColor3f( 1.0, 0.0, 0.0 );
  242.         glVertex2fv (v0);
  243.         glColor3f( 0.9, 0.0, 1.0 );
  244.         glVertex2fv (v1);
  245.         glColor3f( 0.8, 0.1, 0.0 );
  246.         glVertex2fv (v2);
  247.         glColor3f( 0.7, 0.2, 1.0 );
  248.         glVertex2fv (v3);
  249.         glColor3f( 0.6, 0.3, 0.0 );
  250.         glVertex2fv (v4);
  251.         glColor3f( 0.5, 0.4, 1.0 );
  252.         glVertex2fv (v5);
  253.         glColor3f( 0.4, 0.5, 0.0 );
  254.     glEnd();
  255. }
  256.  
  257. /* draw a "circle" using a triangle fan; set the
  258.  * center of the circle to white, and the outside
  259.  * to the color passed in
  260.  */
  261. GLvoid
  262. drawFan( GLfloat *color )
  263. {
  264.     /* Draw a triangle fan centered at the current coordinate
  265.      * system origin 
  266.      */
  267.     glBegin( GL_TRIANGLE_FAN );
  268.         glColor3f( 1.0, 1.0, 1.0 );
  269.         glVertex2f( 0.0, 0.0 );
  270.         glColor3fv( color );
  271.         glVertex2f( 0.0, -0.2 );
  272.         glVertex2f( 0.2, -0.1 );
  273.         glVertex2f( 0.2, 0.1 );
  274.         glVertex2f( 0.0, 0.2 );
  275.         glVertex2f( -0.2, 0.1 );
  276.         glVertex2f( -0.2, -0.1 );
  277.         glVertex2f( 0.0, -0.2 );
  278.     glEnd();
  279. }
  280.  
  281. /* draw a flower with the base of the stem 
  282.  * at the current location 
  283.  */
  284. GLvoid
  285. drawFlower( GLfloat *color )
  286. {
  287.     static GLfloat darkgreen[] = { 0.0, 0.25, 0.0 };
  288.     /* draw the stem with 2 leaves */
  289.  
  290.     glColor3fv( darkgreen );
  291.     glBegin( GL_LINES );
  292.         glVertex2f( 0.0, 0.0 );         /* stem */
  293.         glVertex2f( 0.0, 0.25 );
  294.         glVertex2f( 0.0, 0.1 );         /* leaf */
  295.         glVertex2f( 0.05, 0.15 ); 
  296.         glVertex2f( 0.0, 0.05 );     /* leaf */
  297.         glVertex2f( -0.05, 0.2 );
  298.     glEnd();
  299.  
  300.     glPushMatrix();
  301.         /* move to the top of the stem */
  302.         glTranslatef( 0.0, 0.25, 0.0 );
  303.  
  304.         /* use a scaled triangle fan for the flower head */
  305.         glScalef( 0.1, 0.1, 1.0 );
  306.         drawFan( color );  
  307.     glPopMatrix();
  308. }
  309.  
  310. /* draw a house centered at the current origin;
  311.  * the bounding box for the house is 1.0 x 2.0 units
  312.  */
  313. GLvoid
  314. drawHouse()
  315. {
  316.     /* draw a 3D house */
  317.     glColor3f( 1.0, 1.0, 1.0 ); /* white */
  318.     SolidBox( 1.0, 1.5, 1.0 );
  319.  
  320.     glPushMatrix();
  321.         /* move to the peak of the roof */
  322.         glTranslatef( 0.0, 1.25, 0.0 );
  323.  
  324.         /* draw a triangle fan for the roof */
  325.         glColor3f( 0.0, 0.0, 0.0 ); /* black */
  326.         glBegin( GL_TRIANGLE_FAN );
  327.             glVertex3f( 0.0, 0.0, 0.0 ); /* peak */
  328.             glVertex3f( -0.5, -0.5, 0.5 ); /* front left */
  329.             glVertex3f( 0.5, -0.5, 0.5 ); /* front right */
  330.             glVertex3f( 0.5, -0.5, -0.5 ); /* back right */
  331.             glVertex3f( -0.5, -0.5, -0.5 ); /* back left */
  332.             glVertex3f( -0.5, -0.5, 0.5 ); /* front left */
  333.         glEnd();
  334.     glPopMatrix();
  335.  
  336.     glPushMatrix();
  337.         /* move to just in front of the house */
  338.         glTranslatef( 0.0, 0.0, 0.50001 );
  339.  
  340.         /* draw the door */
  341.         glColor3f( 0.5, 0.2, 0.1 ); /* brown */
  342.         glRectf( -0.2, -0.75, 0.2, 0.0 );
  343.  
  344.         glPushMatrix();
  345.             /* move to the location for the left window */
  346.             glTranslatef( -0.4, 0.2, 0.0 );
  347.             drawWindow();
  348.         glPopMatrix();
  349.  
  350.         glPushMatrix();
  351.             /* move to the location for the right window */
  352.             glTranslatef( 0.2, 0.2, 0.0 );
  353.             drawWindow();
  354.         glPopMatrix();
  355.     glPopMatrix();
  356. }
  357.  
  358. GLvoid
  359. drawScene( GLvoid )
  360. {
  361.     static GLfloat red[] = { 1.0, 0.0, 0.0 };
  362.     static GLfloat magenta[] = { 1.0, 0.0, 1.0 };
  363.     static GLfloat yellow[] = { 1.0, 1.0, 0.0 };
  364.     static GLfloat blue[] = { 0.0, 0.0, 1.0 };
  365.     static GLfloat green[] = { 0.0, 1.0, 0.0 };
  366.     static GLfloat darkgreen[] = { 0.0, 0.25, 0.0 };
  367.  
  368.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  369.  
  370.     glPushMatrix();
  371.  
  372.         /* Move the reference point */
  373.         gluLookAt( 0.0, 0.0, 4.0, xRef, yRef, 0.0, 0.0, 1.0, 0.0 );
  374.  
  375.         /* draw the ground in different shades of green */
  376.         glBegin( GL_POLYGON );
  377.             glColor3fv( green );
  378.             glVertex2f( -3.0, -2.0 );
  379.             glVertex2f( 3.0, -2.0 );
  380.             glColor3fv( darkgreen );
  381.             glVertex2f( 3.0, 0.0 );
  382.             glVertex2f( -3.0, 0.0 );
  383.         glEnd();
  384.  
  385.         /* draw the house */
  386.         glPushMatrix();
  387.             /* move to where the center of the house should be */
  388.             glTranslatef( -0.5, 0.0, 0.0 );
  389.  
  390.             /* shrink the house slightly */
  391.             glScalef( 0.7, 0.7, 0.7 );
  392.             drawHouse();
  393.         glPopMatrix();
  394.  
  395.         /* draw the sun */
  396.         glPushMatrix();
  397.             /* move to the location of the sun */
  398.             glTranslatef( 2.0, 2.0, -1.5 );
  399.             glColor3fv( yellow );
  400.             glutSolidSphere( 0.2, 8, 15 );
  401.         glPopMatrix();
  402.  
  403.         /* draw several tulips in the foreground */
  404.         glPushMatrix();
  405.             glTranslatef( 1.0, -1.0, 1.0 );
  406.             drawFlower( red );
  407.             glTranslatef( 0.0, 0.0, -0.5 );
  408.             drawFlower( yellow );
  409.         glPopMatrix();
  410.         glPushMatrix();
  411.             glTranslatef( -1.0, -1.0, 1.0 );
  412.             drawFlower( blue );
  413.             glTranslatef( 0.0, 0.0, -0.5 );
  414.             drawFlower( magenta );
  415.         glPopMatrix();
  416.  
  417.     glPopMatrix();
  418.  
  419.     checkError( "drawScene" );
  420.     glFlush();
  421. }
  422.