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 / labels.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  18.5 KB  |  757 lines

  1. /*
  2.  * Copyright 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. /* labels.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.  *    Add continuous animation and a menu to control it.
  26.  *    Add a local light with distance attenuation, and a spot light.
  27.  *    Add two-sided lighting, and a back face material for one object.
  28.  *    Add 3D text.
  29.  *
  30.  *    F1 key            - print help information
  31.  *    Right Mouse Button    - popup menu
  32.  *    Left Arrow Key        - move the reference point to the left
  33.  *    Right Arrow Key        - move the reference point to the right
  34.  *    Up Arrow Key        - move the reference point up
  35.  *    Down Arrow Key        - move the reference point down
  36.  *    <b> key            - toggle between bitmap/stroke fonts
  37.  *    <f> key            - toggle front/back face culling
  38.  *    <n> key            - toggle between night/day
  39.  *    <s> key            - toggle smooth/flat shading
  40.  *    SPACE key        - generates a random background color
  41.  *    Escape Key        - exit program
  42.  */
  43. #include <GL/gl.h>
  44. #include <GL/glu.h>
  45. #include <GL/glut.h>
  46.  
  47. #include <stdio.h>
  48. #include <math.h>
  49.  
  50. /* Function Prototypes */
  51.  
  52. GLvoid initgfx( GLvoid );
  53. GLvoid keyboard( GLubyte, GLint, GLint );
  54. GLvoid specialkeys( GLint, GLint, GLint );
  55. GLvoid reshape( GLsizei, GLsizei );
  56. GLvoid animate( GLvoid );
  57. GLvoid visibility( GLint );
  58. GLvoid drawScene( GLvoid );
  59. GLvoid menuFunc( GLint );
  60.  
  61. void initGround( GLvoid );
  62.  
  63. void checkError( char * );
  64. void printHelp( char * );
  65.  
  66. /* Global Variables */
  67.  
  68. static GLdouble        xRef = 0.0, yRef = 0.0;
  69.  
  70. static GLfloat        sunPosition = 2.5;
  71. static GLboolean    night = GL_FALSE;
  72. static GLboolean    use_bitmap_fonts = GL_FALSE;
  73.  
  74. static GLfloat         green[] = { 0.0, 1.0, 0.0 };
  75. static GLfloat         darkgreen[] = { 0.0, 0.25, 0.0 };
  76. static GLfloat         red[] = { 1.0, 0.0, 0.0 };
  77. static GLfloat         magenta[] = { 1.0, 0.0, 1.0 };
  78. static GLfloat         yellow[] = { 1.0, 1.0, 0.0 };
  79. static GLfloat         blue[] = { 0.0, 0.0, 1.0 };
  80.  
  81. static GLfloat         white[] = { 1.0, 1.0, 1.0, 1.0 };
  82. static GLfloat         black[] = { 0.0, 0.0, 0.0, 0.0 };
  83.  
  84. static void           *fixedFont, *romanFont;
  85.  
  86. static char *progname; 
  87.  
  88. /* Global Definitions */
  89.  
  90. #define KEY_ESC    27    /* ascii value for the escape key */
  91.  
  92. /* menu options */
  93. #define MENU_ANIMATE    1    /* animation control option */
  94. #define MENU_EXIT    2    /* exit option */
  95.  
  96. #define GRIDPOINTS    41    /* number of vertices in ground mesh */
  97.  
  98. static GLfloat         groundMesh[GRIDPOINTS][GRIDPOINTS][3] = { 0 };
  99.  
  100. static GLboolean     animateFlag = GL_TRUE;
  101.  
  102. void
  103. main( int argc, char *argv[] )
  104. {
  105.     GLsizei width, height;
  106.  
  107.     glutInit( &argc, argv );
  108.  
  109.     /* create a window that is 1/4 the size of the screen,
  110.      * and position it in the middle of the screen.
  111.      */
  112.     width = glutGet( GLUT_SCREEN_WIDTH ); 
  113.     height = glutGet( GLUT_SCREEN_HEIGHT );
  114.     glutInitWindowPosition( width / 4, height / 4 );
  115.     glutInitWindowSize( width / 2, height / 2 );
  116.     glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
  117.     glutCreateWindow( argv[0] );
  118.  
  119.     initgfx();
  120.  
  121.     glutIdleFunc( animate );
  122.     glutVisibilityFunc( visibility );
  123.     glutReshapeFunc( reshape );
  124.     glutKeyboardFunc( keyboard );
  125.     glutSpecialFunc( specialkeys );
  126.     glutDisplayFunc( drawScene ); 
  127.  
  128.     /* create menu and add menu options */
  129.     glutCreateMenu( menuFunc );
  130.     glutAddMenuEntry( "Stop Animation", MENU_ANIMATE );
  131.     glutAddMenuEntry( "Exit", MENU_EXIT );
  132.     glutAttachMenu( GLUT_RIGHT_BUTTON );
  133.  
  134.     progname = argv[0];
  135.  
  136.     printHelp( progname );
  137.  
  138.     glutMainLoop();
  139. }
  140.  
  141. void
  142. printHelp( char *progname )
  143. {
  144.     fprintf(stdout, 
  145.         "\n%s - create a scene with a local light and attenuation\n\n"
  146.         "F1 key        - print help information\n"
  147.         "Left Arrow Key        - move reference point to the left\n"
  148.         "Right Arrow Key    - move reference point to the right\n"
  149.         "Up Arrow Key        - move reference point up\n"
  150.         "Down Arrow Key        - move reference point down\n"
  151.         "SPACE Key    - generates a random background color\n"
  152.         "<f> key        - toggle front/back face culling\n"
  153.         "<n> key        - toggle between night/day\n"
  154.         "<s> key        - toggle smooth/flat shading\n"
  155.         "Escape Key    - exit the program\n\n",
  156.         progname);
  157. }
  158.  
  159. GLvoid
  160. initgfx( GLvoid )
  161. {
  162.     GLfloat sunAmbient[4] = { 0.5, 0.5, 0.5, 1.0 };
  163.  
  164.     /* set clear color to blue */
  165.     glClearColor( 0.0, 0.0, 1.0, 1.0 );
  166.  
  167.     /* enable the depth buffer */
  168.     glEnable( GL_DEPTH_TEST );
  169.  
  170.     /* enable the face culling */
  171.     glEnable( GL_CULL_FACE );
  172.  
  173.     initGround();
  174.  
  175.     glMaterialfv( GL_BACK, GL_AMBIENT_AND_DIFFUSE, yellow );
  176.  
  177.     glMaterialfv( GL_FRONT, GL_SPECULAR, white );
  178.     glMaterialf( GL_FRONT, GL_SHININESS, 10.0 );
  179.  
  180.     /* Add a light for the sun */
  181.     glLightfv( GL_LIGHT0, GL_DIFFUSE, white );
  182.     glLightfv( GL_LIGHT0, GL_AMBIENT, sunAmbient );
  183.     glEnable( GL_LIGHT0 );
  184.     glEnable( GL_LIGHTING );
  185.  
  186.     /* have OpenGL automatically normalize the normals,
  187.      * since we have lighting turned on and are scaling
  188.       */
  189.     glEnable( GL_NORMALIZE );
  190.  
  191.     /* Enable fast material changes for diffuse material */
  192.     glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
  193.     glEnable( GL_COLOR_MATERIAL );
  194.  
  195.     /* Set up two fonts to use for rendering */
  196.     fixedFont = GLUT_BITMAP_9_BY_15;
  197.     romanFont = GLUT_STROKE_ROMAN;
  198. }
  199.  
  200. GLvoid 
  201. reshape( GLsizei width, GLsizei height )
  202. {
  203.     GLdouble    aspect;
  204.  
  205.     glViewport( 0, 0, width, height );
  206.  
  207.     /* compute aspect ratio */
  208.     aspect = (GLdouble) width / (GLdouble) height;
  209.  
  210.     glMatrixMode( GL_PROJECTION );
  211.  
  212.     /* Reset world coordinates first ... */
  213.     glLoadIdentity();
  214.  
  215.     /* Reset the viewing volume based on the new aspect ratio */
  216.     gluPerspective( 45.0, aspect, 3.0, 7.0 );
  217.  
  218.     glMatrixMode( GL_MODELVIEW );
  219. }
  220.  
  221. void 
  222. checkError( char *label )
  223. {
  224.     GLenum error;
  225.     while ( (error = glGetError()) != GL_NO_ERROR )
  226.         printf( "%s: %s\n", label, gluErrorString(error) );
  227. }
  228.  
  229. GLvoid 
  230. keyboard( GLubyte key, GLint x, GLint y )
  231. {
  232.     static GLboolean flat = GL_FALSE;
  233.     static GLboolean cullFront = GL_FALSE;
  234.  
  235.     switch (key) {
  236.     case ' ':    /* SPACE key */
  237.         /* generate a random background color */
  238.         glClearColor( drand48(), drand48(), drand48(), 1.0 ); 
  239.         glutPostRedisplay();
  240.         break;
  241.     case 'b':    /* b key */
  242.         /* toggle between bitmap and stroke fonts */
  243.         use_bitmap_fonts = !use_bitmap_fonts;
  244.         break;
  245.     case 'f':    /* f key */
  246.         /* toggle between back and front face culling */
  247.         cullFront = !cullFront;
  248.         if (cullFront) {
  249.             glCullFace( GL_FRONT );
  250.             printf("Culling FRONT faces\n");
  251.         } else { 
  252.             glCullFace( GL_BACK );
  253.             printf("Culling BACK faces\n");
  254.         }
  255.         glutPostRedisplay();
  256.         break;
  257.     case 'n':    /* n key */
  258.         /* toggle between night and day */
  259.         night = !night;
  260.         if (night) {
  261.             /* make the light fall off with distance much
  262.              * more quickly when it is night 
  263.              */
  264.             glLightf( GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.1 );
  265.         } else { 
  266.             glLightf( GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0 );
  267.         }
  268.         glutPostRedisplay();
  269.         break;
  270.     case 's':    /* s key */
  271.         /* toggle between smooth and flat shading */
  272.         flat = !flat;
  273.         if (flat)
  274.             glShadeModel( GL_FLAT );
  275.         else 
  276.             glShadeModel( GL_SMOOTH );
  277.         glutPostRedisplay();
  278.         break;
  279.     case KEY_ESC:    /* Exit when the Escape key is pressed */
  280.         exit(0);
  281.     }
  282. }
  283.  
  284. GLvoid 
  285. specialkeys( GLint key, GLint x, GLint y )
  286. {
  287.     switch (key) {
  288.     case GLUT_KEY_F1:    /* Function key #1 */
  289.         /* print help information */
  290.         printHelp( progname );
  291.         break;
  292.  
  293.     case GLUT_KEY_LEFT:    /* move reference point to the left */
  294.         xRef -= 0.5;
  295.         if (xRef < -4.0) xRef = -4.0;
  296.         glutPostRedisplay();
  297.          break;
  298.  
  299.     case GLUT_KEY_RIGHT:    /* move reference point to the right */
  300.         xRef += 0.5;
  301.         if (xRef > 4.0) xRef = 4.0;
  302.         glutPostRedisplay();
  303.         break;
  304.  
  305.     case GLUT_KEY_UP:    /* move reference point up */
  306.         yRef += 0.5;
  307.         if (yRef > 3.0) yRef = 3.0;
  308.         glutPostRedisplay();
  309.         break;
  310.  
  311.     case GLUT_KEY_DOWN:    /* move reference point down */
  312.         yRef -= 0.5;
  313.         if (yRef < -3.0) yRef = -3.0;
  314.         glutPostRedisplay();
  315.         break;
  316.     }
  317. }
  318.  
  319. GLvoid 
  320. animate( GLvoid )
  321. {
  322.     /* update the position of the sun */
  323.     sunPosition -= 0.01;
  324.     if (sunPosition < -3.0) sunPosition = 2.5;
  325.  
  326.     /* Tell GLUT to redraw the scene */
  327.     glutPostRedisplay();
  328. }
  329.  
  330. GLvoid
  331. visibility( int state ) 
  332. {
  333.     if (state == GLUT_VISIBLE && animateFlag) {
  334.         glutIdleFunc( animate );
  335.     } else {
  336.         glutIdleFunc( NULL );
  337.     }
  338. }
  339.  
  340. GLvoid
  341. menuFunc( int value )
  342. {
  343.     switch (value) {
  344.     case MENU_ANIMATE:
  345.         animateFlag = !animateFlag;
  346.         if (animateFlag) {
  347.             glutIdleFunc( animate );
  348.             glutChangeToMenuEntry( MENU_ANIMATE, "Stop Animation",
  349.                         MENU_ANIMATE );
  350.         } else {
  351.             glutIdleFunc( NULL );
  352.             glutChangeToMenuEntry( MENU_ANIMATE, "Start Animation",
  353.                         MENU_ANIMATE );
  354.         }
  355.         break;
  356.     case MENU_EXIT:
  357.         exit(0);
  358.     }
  359. }
  360.  
  361. void
  362. initGround( void )
  363. {
  364.     int i, j;
  365.     GLfloat     x, y, spacing;
  366.  
  367.     /* Create a flat grid composed of points with the z value = 0 */
  368.     
  369.     /* spacing = distance between adjacent grid points in x and y */
  370.     spacing = 2.0 / (float)(GRIDPOINTS - 1);
  371.  
  372.     /* x and z range from -1.0 to 1.0 by spacing interval */
  373.     for ( x = -1.0, i = 0; i < GRIDPOINTS; x += spacing, i++ ) {
  374.         for ( y = -1.0, j = 0; j < GRIDPOINTS; y += spacing, j++ ) {
  375.             groundMesh[i][j][0] = x;
  376.             groundMesh[i][j][1] = y;
  377.             groundMesh[i][j][2] = 0.0;
  378.         }
  379.     }
  380. }
  381.  
  382. GLvoid
  383. drawGround( GLvoid )
  384. {
  385.     register int i, j;
  386.  
  387.     glNormal3f( 0.0, 0.0, 1.0 );
  388.     
  389.     /* Draw quad strips connecting grid points. 
  390.      * Grid is drawn column by column, 
  391.      * where each column is one quad strip.
  392.      * Every pair of vertices after first two vertices
  393.      * adds a new quad to the strip.
  394.      */
  395.     for ( i = 0; i < (GRIDPOINTS - 1); i++ ) {
  396.         glBegin( GL_QUAD_STRIP );
  397.         for ( j = 0; j < (GRIDPOINTS); j++ ) {
  398.             glColor3f( 0.0, 1.0 - (GLfloat) j/GRIDPOINTS, 0.0 );
  399.             glVertex3fv( &groundMesh[i][j][0] );
  400.             glVertex3fv( &groundMesh[i + 1][j][0] );
  401.         }
  402.         glEnd();
  403.     }
  404. }
  405.  
  406. GLvoid
  407. drawWindow()
  408. {
  409.     /* window */
  410.     static GLfloat v0[] = { 0.0, 0.4 };
  411.     static GLfloat v1[] = { 0.0, 0.0 };
  412.     static GLfloat v2[] = { 0.1, 0.4 };
  413.     static GLfloat v3[] = { 0.1, 0.0 };
  414.     static GLfloat v4[] = { 0.2, 0.4 };
  415.     static GLfloat v5[] = { 0.2, 0.0 };
  416.  
  417.     /* draw 2 quadrilateral strip to make a window */
  418.     glNormal3f( 0.0, 0.0, 1.0 );
  419.     glBegin( GL_QUAD_STRIP );
  420.         glColor3f( 1.0, 0.0, 0.0 );
  421.         glVertex2fv (v0);
  422.         glColor3f( 0.9, 0.0, 1.0 );
  423.         glVertex2fv (v1);
  424.         glColor3f( 0.8, 0.1, 0.0 );
  425.         glVertex2fv (v2);
  426.         glColor3f( 0.7, 0.2, 1.0 );
  427.         glVertex2fv (v3);
  428.         glColor3f( 0.6, 0.3, 0.0 );
  429.         glVertex2fv (v4);
  430.         glColor3f( 0.5, 0.4, 1.0 );
  431.         glVertex2fv (v5);
  432.         glColor3f( 0.4, 0.5, 0.0 );
  433.     glEnd();
  434. }
  435.  
  436. /* draw a "circle" using a triangle fan; set the
  437.  * center of the circle to white, and the outside
  438.  * to the color passed in
  439.  */
  440. GLvoid
  441. drawFan( GLfloat *color )
  442. {
  443.     /* Draw a triangle fan centered at the current coordinate
  444.      * system origin 
  445.      */
  446.     glNormal3f( 0.0, 0.0, 1.0 );
  447.     glBegin( GL_TRIANGLE_FAN );
  448.         glColor3f( 1.0, 1.0, 1.0 );
  449.         glVertex2f( 0.0, 0.0 );
  450.         glColor3fv( color );
  451.         glVertex2f( 0.0, -0.2 );
  452.         glVertex2f( 0.2, -0.1 );
  453.         glVertex2f( 0.2, 0.1 );
  454.         glVertex2f( 0.0, 0.2 );
  455.         glVertex2f( -0.2, 0.1 );
  456.         glVertex2f( -0.2, -0.1 );
  457.         glVertex2f( 0.0, -0.2 );
  458.     glEnd();
  459. }
  460.  
  461. /* draw a flower with the base of the stem 
  462.  * at the current location 
  463.  */
  464. GLvoid
  465. drawFlower( GLfloat *color )
  466. {
  467.     /* draw the stem with 2 leaves */
  468.     glColor3fv( darkgreen );
  469.     glNormal3f( 0.0, 0.0, 1.0 );
  470.     glBegin( GL_LINES );
  471.         glVertex2f( 0.0, 0.0 );         /* stem */
  472.         glVertex2f( 0.0, 0.25 );
  473.         glVertex2f( 0.0, 0.1 );         /* leaf */
  474.         glVertex2f( 0.05, 0.15 ); 
  475.         glVertex2f( 0.0, 0.05 );     /* leaf */
  476.         glVertex2f( -0.05, 0.2 );
  477.     glEnd();
  478.  
  479.     glPushMatrix();
  480.         /* move to the top of the stem */
  481.         glTranslatef( 0.0, 0.25, 0.0 );
  482.  
  483.         /* use a scaled triangle fan for the flower head */
  484.         glScalef( 0.1, 0.1, 1.0 );
  485.         drawFan( color );  
  486.     glPopMatrix();
  487. }
  488.  
  489. /* draw a house centered at the current origin;
  490.  * the bounding box for the house is 1.0 x 2.0 units
  491.  */
  492. GLvoid
  493. drawHouse()
  494. {
  495.     /* draw a 3D house */
  496.     glColor3f( 1.0, 1.0, 1.0 ); /* white */
  497.     SolidBox( 1.0, 1.5, 1.0 );
  498.  
  499.     glPushMatrix();
  500.         /* move to the peak of the roof */
  501.         glTranslatef( 0.0, 1.25, 0.0 );
  502.  
  503.         /* draw a triangle fan for the roof */
  504.         glColor3f( 0.0, 0.0, 0.0 ); /* black */
  505.         glNormal3f( 0.0, 1.0, 1.0 );
  506.         glBegin( GL_TRIANGLE_FAN );
  507.             glVertex3f( 0.0, 0.0, 0.0 ); /* peak */
  508.             glVertex3f( -0.5, -0.5, 0.5 ); /* front left */
  509.             glVertex3f( 0.5, -0.5, 0.5 ); /* front right */
  510.             glVertex3f( 0.5, -0.5, -0.5 ); /* back right */
  511.             glVertex3f( -0.5, -0.5, -0.5 ); /* back left */
  512.             glVertex3f( -0.5, -0.5, 0.5 ); /* front left */
  513.         glEnd();
  514.     glPopMatrix();
  515.  
  516.     glPushMatrix();
  517.         /* move to just in front of the house */
  518.         glTranslatef( 0.0, 0.0, 0.50001 );
  519.  
  520.         /* draw the door */
  521.         glColor3f( 0.5, 0.2, 0.1 ); /* brown */
  522.         glNormal3f( 0.0, 0.0, 1.0 );
  523.         glRectf( -0.2, -0.75, 0.2, 0.0 );
  524.  
  525.         glPushMatrix();
  526.             /* move to the location for the left window */
  527.             glTranslatef( -0.4, 0.2, 0.0 );
  528.             drawWindow();
  529.         glPopMatrix();
  530.  
  531.         glPushMatrix();
  532.             /* move to the location for the right window */
  533.             glTranslatef( 0.2, 0.2, 0.0 );
  534.             drawWindow();
  535.         glPopMatrix();
  536.     glPopMatrix();
  537. }
  538.  
  539. /* draw a lamp post centered at the current origin;
  540.  * the bounding box for the lamp is 0.5 x 3.0 units
  541.  */
  542. GLvoid
  543. drawLamp( GLint light )
  544. {
  545.     GLfloat spot_color[] = { 1.0, 1.0, 0.0, 1.0 };
  546.  
  547.     GLfloat spot_dir[] = { 0.0, 0.0, -1.0 };
  548.     GLfloat spot_cutoff = 30.0;
  549.     GLfloat spot_exp = 20.0;
  550.  
  551.     /* Note that a spotlight is a local light */
  552.     GLfloat light_position[] = { 0.0, 0.0, 0.0, 1.0 };
  553.  
  554.     /* draw lamp post */
  555.     glColor3f( 0.0, 0.0, 0.0 );
  556.     SolidCylinder( 0.05, 3.0 );
  557.  
  558.     glPushMatrix();
  559.         glTranslatef( 0.0, 1.5, 0.0 );
  560.         glRotatef( -90, 0.0, 0.0, 1.0 );
  561.         glTranslatef( 0.0, 0.25, 0.0 );
  562.         SolidCylinder( 0.02, 0.5 );
  563.  
  564.         glTranslatef( 0.0, 0.2, 0.0 );
  565.         glRotatef( -90.0, 0.0, 1.0, 0.0 );
  566.         glTranslatef( 0.0, 0.0, -0.1 );
  567.         glutSolidCone( 0.05, 0.1, 15, 15 );
  568.  
  569.         if ( night ) { /* turn on the lamp */
  570.             glLightfv( light, GL_DIFFUSE, spot_color );
  571.             glLightfv( light, GL_SPECULAR, spot_color );
  572.             glLightfv( light, GL_SPOT_DIRECTION, spot_dir );
  573.             glLightf( light, GL_SPOT_CUTOFF, spot_cutoff );
  574.             glLightf( light, GL_SPOT_EXPONENT, spot_exp );
  575.             glLightfv( light, GL_POSITION, light_position );
  576.  
  577.             glEnable( light );
  578.         } else
  579.             glDisable( light );
  580.     glPopMatrix();
  581.  
  582. }
  583.  
  584. GLvoid
  585. renderBitmapString( void *font, char *string )
  586. {
  587.         int i;
  588.         int len = (int) strlen(string);
  589.         for (i = 0; i < len; i++) {
  590.                 glutBitmapCharacter(font, string[i]);
  591.         }
  592. }
  593.  
  594. GLvoid
  595. renderStrokeString( void *font, char *string )
  596. {
  597.         int i;
  598.         int len = (int) strlen(string);
  599.         for (i = 0; i < len; i++) {
  600.                 glutStrokeCharacter(font, string[i]);
  601.         }
  602. }
  603.  
  604. void
  605. drawSign( GLvoid )
  606. {
  607.     /* draw sign post */
  608.     glColor3f( 0.0, 0.0, 0.0 );
  609.     SolidCylinder( 0.01, 0.5 );
  610.  
  611.     /* draw sign */
  612.     glPushMatrix();
  613.         glTranslatef( 0.0, 0.25, 0.01 );
  614.         glColor3f( 1.0, 1.0, 1.0 );
  615.         glRectf( -0.11, -0.11, 0.11, 0.11 );
  616.  
  617.         glColor3f( 0.0, 0.0, 0.0 );
  618.         if (use_bitmap_fonts) {
  619.             glRasterPos3f( -0.1, 0.04, 0.01 );
  620.             renderBitmapString( fixedFont, "Beware" );
  621.             glRasterPos3f( -0.03, -0.02, 0.01 );
  622.             renderBitmapString( fixedFont, "of" );
  623.             glRasterPos3f( -0.06, -0.08, 0.01 );
  624.             renderBitmapString( fixedFont, "Dog" );
  625.         } else {
  626.             glPushMatrix();
  627.                 glTranslatef( -0.1, 0.04, 0.01 );
  628.                 glScalef( 0.0005, 0.0005, 0.0005 );
  629.                 renderStrokeString( romanFont, "Beware" );
  630.             glPopMatrix();
  631.             glPushMatrix();
  632.                 glTranslatef( -0.03, -0.02, 0.01 );
  633.                 glScalef( 0.0005, 0.0005, 0.0005 );
  634.                 renderStrokeString( romanFont, "of" );
  635.             glPopMatrix();
  636.             glPushMatrix();
  637.                 glTranslatef( -0.06, -0.08, 0.01 );
  638.                 glScalef( 0.0005, 0.0005, 0.0005 );
  639.                 renderStrokeString( romanFont, "Dog" );
  640.             glPopMatrix();
  641.         }
  642.     glPopMatrix();
  643. }
  644.  
  645. GLvoid
  646. drawScene( GLvoid )
  647. {
  648.     /* local light */
  649.     GLfloat   lightPosition[] = { 0.0, 0.0, 0.0, 1.0 };
  650.  
  651.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  652.  
  653.     glPushMatrix();
  654.  
  655.         /* Move the reference point */
  656.         gluLookAt( 0.0, 0.0, 4.0, xRef, yRef, 0.0, 0.0, 1.0, 0.0 );
  657.  
  658.         /* draw the sun */
  659.         glPushMatrix();
  660.             /* move to the location of the sun */
  661.             glTranslatef( sunPosition, 2.0, -1.5 );
  662.  
  663.             /* use a local light for the sun */
  664.             glLightfv( GL_LIGHT0, GL_POSITION, lightPosition );
  665.  
  666.             if ( night ) {
  667.                 glColor3fv( white );
  668.                 glMaterialfv( GL_FRONT, GL_EMISSION, white );
  669.             } else {
  670.                 glColor3fv( yellow );
  671.             }
  672.             glutSolidSphere( 0.2, 8, 15 );
  673.             if ( night ) 
  674.                 glMaterialfv( GL_FRONT, GL_EMISSION, black );
  675.         glPopMatrix();
  676.  
  677.         glPushMatrix();
  678.             glTranslatef( -1.5, 0.0, 0.5 );
  679.             glScalef( 0.7, 0.7, 0.7 );
  680.             drawLamp( GL_LIGHT1 );
  681.         glPopMatrix();
  682.  
  683.         /* draw the ground as a quad mesh so that it will
  684.          * be lit properly
  685.          */
  686.         glPushMatrix();
  687.             glTranslatef( 0.0, -1.0, 0.0 );
  688.             glRotatef( -45.0, 1.0, 0.0, 0.0 );
  689.             glScalef( 3.0, 1.0, 1.0 );
  690.             drawGround();
  691.         glPopMatrix();
  692.  
  693.         /* draw a sign in the foreground */
  694.         glPushMatrix();
  695.             glTranslatef( -1.5, -1.0, 0.9 );
  696.             glScalef( 0.5, 0.5, 1.0 );
  697.             drawSign();
  698.         glPopMatrix();
  699.  
  700.         /* draw a sign in the background */
  701.         glPushMatrix();
  702.             glTranslatef( 1.0, -1.0, 0.0 );
  703.             drawSign();
  704.         glPopMatrix();
  705.  
  706.         /* draw the house */
  707.         glPushMatrix();
  708.             /* move to where the center of the house should be */
  709.             glTranslatef( -0.5, 0.0, 0.0 );
  710.  
  711.             /* shrink the house slightly */
  712.             glScalef( 0.7, 0.7, 0.7 );
  713.             drawHouse();
  714.  
  715.             /* draw a knocked over trash can next to the house */
  716.             glDisable( GL_CULL_FACE );
  717.             glLightModelf( GL_LIGHT_MODEL_TWO_SIDE, 1.0 ); 
  718.  
  719.             glTranslatef( 0.7, -0.75, 0.5 );
  720.             glRotatef( 90.0, 1.0, 0.0, 0.0 );
  721.             glRotatef( 45.0, 0.0, 0.0, 1.0 );
  722.             glColor3f( 0.0, 0.0, 0.5 ); /* blue */
  723.             SolidCylinder( 0.15, 0.4 );
  724.  
  725.             glLightModelf( GL_LIGHT_MODEL_TWO_SIDE, 0.0 ); 
  726.             glEnable( GL_CULL_FACE );
  727.  
  728.             /* put a label on it */
  729.             glTranslatef( 0.16, 0.2, 0.05 );
  730.             glRotatef( 90.0, 0.0, 1.0, 0.0 );
  731.             glRotatef( -90.0, 0.0, 0.0, 1.0 );
  732.             glScalef( 0.001, 0.001, 0.001 );
  733.             glColor3f( 1.0, 1.0, 1.0 ); /* white */
  734.             renderStrokeString( romanFont, "Trash" );
  735.             
  736.         glPopMatrix();
  737.  
  738.         /* draw several tulips in the foreground */
  739.         glPushMatrix();
  740.             glTranslatef( 1.0, -1.0, 1.0 );
  741.             drawFlower( red );
  742.             glTranslatef( 0.0, 0.0, -0.5 );
  743.             drawFlower( yellow );
  744.         glPopMatrix();
  745.         glPushMatrix();
  746.             glTranslatef( -1.0, -1.0, 1.0 );
  747.             drawFlower( blue );
  748.             glTranslatef( 0.0, 0.0, -0.5 );
  749.             drawFlower( magenta );
  750.         glPopMatrix();
  751.  
  752.     glPopMatrix();
  753.  
  754.     checkError( "drawScene" );
  755.     glutSwapBuffers();
  756. }
  757.