home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / OpenGL / stonehenge / scene.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  18.5 KB  |  794 lines

  1. /*
  2.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  * Permission to use, copy, modify, and distribute this software for
  5.  * any purpose and without fee is hereby granted, provided that the above
  6.  * copyright notice appear in all copies and that both the copyright notice
  7.  * and this permission notice appear in supporting documentation, and that
  8.  * the name of Silicon Graphics, Inc. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.
  11.  *
  12.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  16.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  21.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  *
  25.  * US Government Users Restricted Rights
  26.  * Use, duplication, or disclosure by the Government is subject to
  27.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29.  * clause at DFARS 252.227-7013 and/or in similar or successor
  30.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  31.  * Unpublished-- rights reserved under the copyright laws of the
  32.  * United States.  Contractor/manufacturer is Silicon Graphics,
  33.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  34.  *
  35.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  36.  */
  37. #include <stdlib.h>
  38. #include <stdio.h>
  39.  
  40. #include <GL/glu.h>
  41. #include <GL/glx.h>
  42.  
  43. extern "C" {
  44. #include <tk.h>
  45. };
  46.  
  47. #include "Point.h"
  48. #include "Ring.h"
  49. #include "Roundwall.h"
  50. #include "Ellipse.h"
  51. #include "Telescope.h"
  52.  
  53. #define SCENE_EXTERN
  54. #include "scene.h"
  55.  
  56. GLfloat mat_view[16];
  57. GLfloat view_rotx = 0;
  58. GLfloat fov = 45.0, aspect = 1.0;
  59. static Point eyep = {0, 0, .5};
  60. static Point lookp = {0, 1, .25};
  61.  
  62. TimeDate current_time;
  63.  
  64. static int list_ground;
  65. static int list_texture_ground;
  66. static int list_trees;
  67. static int list_texture_trees;
  68. static int list_ring;
  69. static int list_ellipse;
  70. static int list_texture_stones;
  71. static int list_shadows;
  72. static int list_telescope;
  73. static int list_texture_telescope;
  74. int draw_ground = 1;
  75. int draw_trees = 0;
  76. int draw_ring = 1;
  77. int draw_ellipse = 1;
  78. int draw_shadows = 1;
  79.  
  80. int use_lighting = 1;
  81. int use_textures = 0;
  82. int use_normal_fog = 1;
  83. int use_fancy_fog = 0;
  84. int use_telescope = 0;
  85. int use_antialias = 0;
  86.  
  87. static void scene_identity();
  88. static void scene_project(GLfloat f = fov, float dx = 0, float dy = 0);
  89. static void scene_draw(int rend = 1);
  90. static void scene_render_telescope();
  91.  
  92. static void draw_background();
  93.  
  94. Point sun_position = {0., .707, .707, 0.};
  95. Color ambient(.25, .25, .25, 1.);
  96. static void lights_init();
  97.  
  98. static void lists_init();
  99.  
  100. static void ground_list_init();
  101. static void ground_draw();
  102.  
  103. Roundwall trees;
  104. static void trees_list_init();
  105. static void trees_draw();
  106.  
  107. Ring ring;
  108. static void ring_list_init();
  109. static void ring_draw();
  110.  
  111. Ellipse ellipse;
  112. static void ellipse_list_init();
  113. static void ellipse_draw();
  114.  
  115. static void shadows_list_init();
  116. static void shadows_draw();
  117.  
  118. Weather weather;
  119.  
  120. Telescope telescope;
  121. GLfloat magnif = .5;
  122. static void telescope_list_init();
  123. static void telescope_draw();
  124.  
  125. /* Read the back buffer into the accum buffer, adding in the appropriate
  126.  * alpha values */
  127. static void fog_read_image();
  128. /* Add the accum buffer to the back buffer */
  129. static void fog_write_image();
  130.  
  131.  
  132. inline float clamp(float x, float min, float max)
  133. {
  134.   if (x < min) return min;
  135.   else if (x > max) return max;
  136.   else return x;
  137. }
  138.  
  139. void scene_init() 
  140. {
  141.   scene_identity();
  142.   scene_viewer_center();
  143.  
  144.   glEnable(GL_CULL_FACE);
  145.   glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
  146.  
  147.   glEnable(GL_NORMALIZE);
  148.  
  149.   /* Initial time will be four in the afternoon */
  150.   scene_set_time(TimeDate(16, 0));
  151.   scene_set_weather(weathers[def_weather_index]);
  152.  
  153.   lights_init();
  154.   lists_init();
  155. }
  156.  
  157.  
  158. inline double time_minutes(int hour, int minute, int second)
  159. {
  160.   return (double)hour*60.0 + (double)minute + (double)second / 60.0;
  161. }
  162.  
  163. static void scene_time_changed()
  164. {
  165.   sun_position = current_time.sun_direction();
  166.      
  167.   weather.apply(sun_position);
  168.  
  169.   lights_init();
  170.   shadows_list_init();
  171. }
  172.   
  173. void scene_set_time(TimeDate t)
  174. {
  175.   current_time = t;
  176.   scene_time_changed();
  177. }
  178.  
  179. void scene_inc_time(TimeDate t)
  180. {
  181.   current_time += t;
  182.   scene_time_changed();
  183. }
  184.  
  185. /* This is a hack -- has to be called several times to get the antialiasing
  186.  * to work */
  187. static void scene_inner_render(GLfloat dx = 0, GLfloat dy = 0)
  188. {
  189.   /* This draws layered fog if the use_fancy_fog flag is on --
  190.    * it's going to be slow on anything but high-end stuff */
  191.   if (use_fancy_fog && weather.fog_density != 0.) {
  192.     glMatrixMode(GL_PROJECTION);
  193.     glLoadIdentity();
  194.     glMatrixMode(GL_MODELVIEW);
  195.     glLoadIdentity();
  196.  
  197.     glEnable(GL_FOG);
  198.     draw_background();
  199.     scene_project(fov, dx, dy);
  200.     glClear(GL_DEPTH_BUFFER_BIT);
  201.     if (use_lighting) glEnable(GL_LIGHTING);
  202.     scene_draw();
  203.     if (use_lighting) glDisable(GL_LIGHTING);
  204.     fog_read_image();
  205.     glDisable(GL_FOG);
  206.   } else 
  207.     if (use_normal_fog && weather.fog_density != 0.) glEnable(GL_FOG);
  208.     else glDisable(GL_FOG);
  209.  
  210.   glMatrixMode(GL_PROJECTION);
  211.   glLoadIdentity();
  212.   glMatrixMode(GL_MODELVIEW);
  213.   glLoadIdentity();
  214.  
  215.   /* This is the part where we actually draw the image */
  216.   glClear(GL_DEPTH_BUFFER_BIT);
  217.   draw_background();
  218.   scene_project(fov, dx, dy);
  219.   glClear(GL_DEPTH_BUFFER_BIT);
  220.   if (use_lighting) glEnable(GL_LIGHTING);
  221.   scene_draw();
  222.   if (use_lighting) glDisable(GL_LIGHTING);
  223.  
  224.   if (use_fancy_fog && weather.fog_density != 0.) {
  225.     fog_write_image();
  226.   }
  227.  
  228.   if (use_telescope) scene_render_telescope();
  229.  
  230. }
  231.  
  232. void scene_render()
  233. {
  234.   GLint vp[4];
  235.  
  236.   scene_inner_render();
  237.   if (!use_antialias) return;
  238.  
  239.   if (use_fancy_fog) {
  240.     fprintf(stderr, "Cannot antialias while using fancy fog.\n");
  241.     return;
  242.   }
  243.  
  244.  
  245.   glGetIntegerv(GL_VIEWPORT, vp);
  246.   glAccum(GL_LOAD, .5);
  247.  
  248.   scene_inner_render(2. / (float)vp[2], 2. / (float)vp[3]);
  249.   glAccum(GL_ACCUM, .5);
  250.  
  251. /*
  252.   scene_inner_render(-2. / (float)vp[2], -2. / (float)vp[3]);
  253.   glAccum(GL_ACCUM, .25); 
  254. */
  255.   glAccum(GL_RETURN, 1);
  256.   glDrawBuffer(GL_BACK);
  257. }
  258.  
  259. static void scene_render_telescope()
  260. {
  261.   telescope.draw_setup(fov, aspect);
  262.  
  263.   /* Don't fog the telescope - moisture makes it rust.
  264.    * Seriously, it's in a strange coordinate system and fog will look
  265.    * bad on it. */
  266.   glPushAttrib(GL_ENABLE_BIT);
  267.   glDisable(GL_FOG);
  268.   if (use_textures) {
  269.     glCallList(list_texture_telescope);
  270.     glEnable(GL_TEXTURE_2D);
  271.   }
  272.   glCallList(list_telescope);
  273.   glPopAttrib();
  274.  
  275.   if (use_lighting) glEnable(GL_LIGHTING);
  276.   glEnable(GL_STENCIL_TEST);
  277.   glClearStencil(0);
  278.   glClear(GL_STENCIL_BUFFER_BIT);
  279.   glStencilFunc(GL_ALWAYS, 0x1, 0x1);
  280.   glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); 
  281.  
  282.   glDisable(GL_CULL_FACE);
  283.   telescope.draw_lens();
  284.   glEnable(GL_CULL_FACE);
  285.  
  286.   telescope.draw_takedown();
  287.  
  288.   if (use_lighting) glDisable(GL_LIGHTING);
  289.  
  290.   glStencilFunc(GL_NOTEQUAL, 0x0, 0xffffffff);
  291.   glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  292.  
  293.   scene_identity();
  294.  
  295.   draw_background();
  296.  
  297.   glMatrixMode(GL_PROJECTION);
  298.   glTranslatef(telescope.xpos / magnif, -telescope.ypos / magnif, 0);
  299.   scene_project(fov * magnif);
  300.  
  301.   glClear(GL_DEPTH_BUFFER_BIT);
  302.  
  303.   /* Pushing the lighting bit used to do really bad things, but 
  304.    * hopefully they've all gone away */
  305.   glPushAttrib(GL_LIGHTING_BIT);
  306.   lights_init();
  307.   if (use_lighting) glEnable(GL_LIGHTING);
  308.   scene_draw();
  309.   if (use_lighting) glDisable(GL_LIGHTING);
  310.   glPopAttrib();
  311.  
  312.   glDisable(GL_STENCIL_TEST);
  313. }
  314.  
  315. static void scene_identity()
  316. {
  317.   glMatrixMode(GL_PROJECTION);
  318.   glLoadIdentity();
  319.   glMatrixMode(GL_MODELVIEW);
  320.   glLoadIdentity();
  321. }
  322.  
  323. static void scene_project(GLfloat f, float dx, float dy)
  324. {
  325.   glMatrixMode(GL_PROJECTION);
  326.   glOrtho(-1 - dx, 1, -1 - dy, 1, 0, -1);
  327.   gluPerspective(f, aspect, 0.01, 40.0);
  328.   glMatrixMode(GL_MODELVIEW);
  329.   glRotatef(view_rotx, 1, 0, 0);
  330.   gluLookAt(eyep.pt[0], eyep.pt[1], eyep.pt[2], 
  331.         lookp.pt[0], lookp.pt[1], lookp.pt[2],
  332.             0, 0, 1);
  333.   glMultMatrixf(mat_view);
  334. lights_init();
  335. }
  336.  
  337. /* scene_draw() just draws the geometry - it's used for rendering and
  338.  * picking. */
  339. static void scene_draw(int rend)
  340. {
  341.   if (draw_ground) {
  342.     if (rend) {
  343.       if (use_textures) {
  344.     glCallList(list_texture_ground);
  345.     glEnable(GL_TEXTURE_2D);
  346.       } else glEnable(GL_COLOR_MATERIAL);
  347.     }
  348.     glCallList(list_ground);
  349.  
  350.     if (rend) {
  351.       glDisable(GL_TEXTURE_2D);
  352.       glDisable(GL_COLOR_MATERIAL);
  353.     }
  354.   }
  355.  
  356.   if (draw_shadows) {
  357.     if (use_textures && rend && !draw_ground) {
  358.       glCallList(list_texture_ground);
  359.       glEnable(GL_TEXTURE_2D);
  360.     }
  361.     glCallList(list_shadows);
  362.     if (use_textures && rend) glDisable(GL_TEXTURE_2D);
  363.   }
  364.  
  365.   if (draw_trees) {
  366.     if (use_textures && rend) {
  367.       glCallList(list_texture_trees);
  368.       glEnable(GL_TEXTURE_2D);
  369.     }
  370.     glCallList(list_trees);
  371.     if (use_textures && rend) glDisable(GL_TEXTURE_2D);
  372.   }
  373.  
  374.   glClear(GL_DEPTH_BUFFER_BIT);
  375.  
  376.   if (draw_ring) {
  377.     if (rend) {
  378.       if (use_textures) {
  379.     glCallList(list_texture_stones);
  380.     glEnable(GL_TEXTURE_2D);
  381.       }
  382.       glEnable(GL_COLOR_MATERIAL);
  383.       glColor3f(.5, .5, .5);
  384.     }
  385.     glCallList(list_ring);
  386.     if (rend) {
  387.       if (use_textures) glDisable(GL_TEXTURE_2D);
  388.       glDisable(GL_COLOR_MATERIAL);
  389.     }
  390.   }
  391.  
  392.   if (draw_ellipse) {
  393.     if (use_textures && rend) {
  394.       // Hack to avoid doing something expensive twice in a row
  395.       if (!draw_ring) glCallList(list_texture_stones);
  396.       glEnable(GL_TEXTURE_2D);
  397.     }
  398.     glCallList(list_ellipse);
  399.     if (use_textures && rend) glDisable(GL_TEXTURE_2D);
  400.   }
  401. }
  402.  
  403. static void draw_background()
  404. {
  405.   weather.draw_sky(sun_position);
  406. }
  407.  
  408. void scene_viewer_center()
  409. {
  410.   glPushMatrix();
  411.   glLoadIdentity();
  412.   glGetFloatv(GL_MODELVIEW_MATRIX, mat_view);
  413.   glPopMatrix();
  414.   view_rotx = 0;
  415. }
  416.  
  417. void scene_viewer_rotate_worldz(GLfloat degrees)
  418. {
  419.   glMatrixMode(GL_MODELVIEW);
  420.   glPushMatrix();
  421.   glLoadIdentity();
  422.   glRotatef(degrees, 0, 0, 1);
  423.   glMultMatrixf(mat_view);
  424.   glGetFloatv(GL_MODELVIEW_MATRIX, mat_view);
  425.   glPopMatrix();
  426.   glMatrixMode(GL_MODELVIEW);
  427. }
  428.  
  429. void scene_viewer_rotatez(GLfloat degrees)
  430. {
  431.   glMatrixMode(GL_PROJECTION);
  432.   glPushMatrix();
  433.   glLoadIdentity();
  434.   glRotatef(degrees, 0, 0, 1);
  435.   glMultMatrixf(mat_view);
  436.   glGetFloatv(GL_PROJECTION_MATRIX, mat_view);
  437.   glPopMatrix();
  438.   glMatrixMode(GL_MODELVIEW);
  439. }
  440.  
  441. void scene_viewer_rotatex(GLfloat degrees)
  442. {
  443.   view_rotx += degrees;
  444.   view_rotx = clamp(view_rotx, -60, 60);
  445.   scene_identity();
  446.   scene_project();
  447.   lights_init();
  448. }
  449.  
  450. void scene_viewer_translate(GLfloat dist)
  451. {
  452.   glMatrixMode(GL_PROJECTION);
  453.   glPushMatrix();
  454.   glLoadIdentity();
  455.   glTranslatef(0, dist, 0);
  456.   glMultMatrixf(mat_view);
  457.   glGetFloatv(GL_PROJECTION_MATRIX, mat_view);
  458.   glPopMatrix();
  459.   glMatrixMode(GL_MODELVIEW);
  460.   scene_identity();
  461.   scene_project();
  462.   lights_init();
  463. }
  464.  
  465. void scene_position_telescope(GLfloat x, GLfloat y)
  466. {
  467.   telescope.xpos = x;
  468.   telescope.ypos = y;
  469. }
  470.  
  471. void scene_get_position_telescope(GLfloat *x, GLfloat *y)
  472. {
  473.   *x = telescope.xpos;
  474.   *y = telescope.ypos;
  475. }
  476.  
  477. void scene_get_radius_telescope(GLfloat *r)
  478. {
  479.   *r = telescope.get_radius();
  480. }
  481.  
  482. void scene_set_weather(Weather w)
  483. {
  484.   weather = w;
  485.   weather.apply(sun_position);
  486.   shadows_list_init();
  487. }
  488.  
  489. static int get_lists(int size)
  490. {
  491.   int i;
  492.   i = glGenLists(size);
  493.   if (size && !i) {
  494.     fprintf(stderr, "Unable to allocate %d display lists.\n");
  495.     exit(1);
  496.   }
  497.   return i;
  498. }
  499.  
  500. static void lights_init()
  501. {
  502.   glLightfv(GL_LIGHT0, GL_POSITION, sun_position.pt);
  503.  
  504.   /* This light gives a diffuse coefficient when the sun is off - 
  505.    * it's used for drawing shadows */
  506.   glLightfv(GL_LIGHT1, GL_AMBIENT, black.c);
  507.   glLightfv(GL_LIGHT1, GL_DIFFUSE, black.c);
  508.   glLightfv(GL_LIGHT1, GL_SPECULAR, black.c);
  509. }
  510.  
  511. static void textures_list_init()
  512. {
  513.   TK_RGBImageRec *teximage = NULL;
  514.   
  515.   teximage = tkRGBImageLoad((char *)texfile_stones);
  516.   glNewList(list_texture_stones, GL_COMPILE);
  517.   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, teximage->sizeX, teximage->sizeY, 
  518.             GL_RGB, GL_UNSIGNED_BYTE, teximage->data);
  519.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
  520.          GL_NEAREST_MIPMAP_NEAREST);
  521.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  522.          GL_LINEAR);
  523.   glMatrixMode(GL_TEXTURE);
  524.   glLoadIdentity();
  525.   glMatrixMode(GL_MODELVIEW);
  526.   glDisable(GL_TEXTURE_GEN_S);
  527.   glDisable(GL_TEXTURE_GEN_T);
  528.   glEndList();
  529.  
  530.   /* tk is obnoxious and doesn't seem to provide any mechanism for this */
  531.   free(teximage->data);
  532.   free(teximage);
  533.  
  534.   teximage = tkRGBImageLoad((char *)texfile_ground);
  535.   glNewList(list_texture_ground, GL_COMPILE);
  536.   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, teximage->sizeX, teximage->sizeY, 
  537.             GL_RGB, GL_UNSIGNED_BYTE, teximage->data);
  538.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
  539.           GL_NEAREST_MIPMAP_NEAREST);
  540.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  541.           GL_LINEAR);
  542.   glMatrixMode(GL_TEXTURE);
  543.   glLoadIdentity();
  544.   glScalef(100, 100, 1);
  545.   glMatrixMode(GL_MODELVIEW);
  546.   glDisable(GL_TEXTURE_GEN_S);
  547.   glDisable(GL_TEXTURE_GEN_T);
  548.   glEndList();
  549.  
  550.   free(teximage->data);
  551.   free(teximage);
  552.  
  553.   /* Figure out some way to get an alpha component out of the tk --
  554.    * otherwise we're really hosed */
  555.   teximage = tkRGBImageLoad((char *)texfile_trees);
  556.   glNewList(list_texture_trees, GL_COMPILE);
  557.   /* In the final scenerio we probably won't want to mipmap this, but it's
  558.    * not square and I don't feel like bothering to scale it */
  559.   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, teximage->sizeX, teximage->sizeY,
  560.             GL_RGB, GL_UNSIGNED_BYTE, teximage->data);
  561.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
  562.           GL_NEAREST_MIPMAP_NEAREST);
  563.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  564.           GL_LINEAR);
  565.   glMatrixMode(GL_TEXTURE);
  566.   glLoadIdentity();
  567.   glMatrixMode(GL_MODELVIEW);
  568.   glDisable(GL_TEXTURE_GEN_S);
  569.   glDisable(GL_TEXTURE_GEN_T);
  570.   glEndList();
  571.  
  572.   free(teximage->data);
  573.   free(teximage);
  574.  
  575.   teximage = tkRGBImageLoad((char *)texfile_telescope);
  576.   glNewList(list_texture_telescope, GL_COMPILE);
  577.   glTexImage2D(GL_TEXTURE_2D, 0, 3, teximage->sizeX, teximage->sizeY,
  578.            0, GL_RGB, GL_UNSIGNED_BYTE, teximage->data);
  579.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  580.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  581.   glMatrixMode(GL_TEXTURE);
  582.   glLoadIdentity();
  583.   glMatrixMode(GL_MODELVIEW);
  584.   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  585.   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  586.   glEnable(GL_TEXTURE_GEN_S);
  587.   glEnable(GL_TEXTURE_GEN_T);
  588.   glEndList();
  589.  
  590.   free(teximage->data);
  591.   free(teximage);
  592. }
  593.  
  594. static void lists_init()
  595. {
  596.   list_ground = get_lists(1);
  597.   list_texture_ground = get_lists(1);
  598.   list_trees = get_lists(1);
  599.   list_texture_trees = get_lists(1);
  600.   list_ring = get_lists(1);
  601.   list_ellipse = get_lists(1);
  602.   list_texture_stones = get_lists(1);
  603.   list_shadows = get_lists(1);
  604.   list_telescope = get_lists(1);
  605.   list_texture_telescope = get_lists(1);
  606.  
  607.   ground_list_init();
  608.   trees_list_init();
  609.   shadows_list_init();
  610.   ring_list_init();
  611.   ellipse_list_init();
  612.   textures_list_init();
  613.   telescope_list_init();
  614. }
  615.  
  616. static void ground_list_init()
  617. {
  618.   glNewList(list_ground, GL_COMPILE);
  619.   ground_draw();
  620.   glEndList();
  621. }
  622.  
  623. static void ground_draw() 
  624. {
  625.   glColor3f(0, .75, 0);
  626.  
  627.   glLoadName(name_ground);
  628.  
  629.   glNormal3f(0, 0, 1);
  630.  
  631.   glPushMatrix();
  632.   /* Making something this big would confuse the zbuffer, but we're 
  633.    * clearing that AFTER drawing this, so it's ok */
  634.   glScalef(100, 100, 1);
  635.   glBegin(GL_QUADS);
  636.   glTexCoord2f(0, 0);
  637.   glVertex2f(-1, -1);
  638.   glTexCoord2f(1, 0);
  639.   glVertex2f(1, -1);
  640.   glTexCoord2f(1, 1);
  641.   glVertex2f(1, 1);
  642.   glTexCoord2f(0, 1);
  643.   glVertex2f(-1, 1);
  644.   glEnd();
  645.   glPopMatrix();
  646. }
  647.  
  648. static void trees_list_init()
  649. {
  650.   glNewList(list_trees, GL_COMPILE);
  651.   trees_draw();
  652.   glEndList();
  653. }
  654.  
  655. static void trees_draw()
  656. {
  657.   glEnable(GL_COLOR_MATERIAL);
  658.   glColor3f(0, .5, 0);
  659.  
  660.   glLoadName(name_trees);
  661.   
  662.   glEnable(GL_BLEND);
  663.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  664.   trees.draw();
  665.   glDisable(GL_BLEND);
  666.  
  667.   glDisable(GL_COLOR_MATERIAL);
  668. }
  669.  
  670. static void ring_list_init()
  671. {
  672.   glNewList(list_ring, GL_COMPILE);
  673.   ring_draw();
  674.   glEndList();
  675. }
  676.  
  677. static void ring_draw()
  678. {
  679.   glLoadName(name_ring);
  680.  
  681.   glEnable(GL_DEPTH_TEST);
  682.   ring.erode(.1);
  683.   ring.draw();
  684.   glDisable(GL_DEPTH_TEST);
  685. }
  686.  
  687. static void ellipse_list_init()
  688. {
  689.   glNewList(list_ellipse, GL_COMPILE);
  690.   ellipse_draw();
  691.   glEndList();
  692. }
  693.  
  694. static void ellipse_draw()
  695. {
  696.   glEnable(GL_COLOR_MATERIAL);
  697.   glColor3f(.5, .5, .5);
  698.   
  699.   glEnable(GL_DEPTH_TEST);
  700.  
  701.   glLoadName(name_ellipse);
  702.  
  703.   ellipse.erode(.1);
  704.   ellipse.draw();
  705.  
  706.   glDisable(GL_DEPTH_TEST);
  707.  
  708.   glDisable(GL_COLOR_MATERIAL);
  709. }
  710.  
  711. static void shadows_list_init()
  712. {
  713.   glNewList(list_shadows, GL_COMPILE);
  714.   shadows_draw();
  715.   glEndList();
  716. }
  717.  
  718. static void shadows_draw()
  719. {
  720.   Color grass(0, .75, 0);
  721.  
  722.   glPushAttrib(GL_ENABLE_BIT);
  723.  
  724.   /* Turn the sun off */
  725.   glDisable(GL_LIGHT0);
  726.   glEnable(GL_LIGHT1);
  727.   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, grass.c);
  728.   glColor3fv((grass * .5).c);
  729.  
  730.   glDisable(GL_CULL_FACE);
  731.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  732.   glEnable(GL_BLEND);
  733.   ring.draw_shadow(sun_position, weather.shadow_blur(), 
  734.            grass * .5, grass);
  735.   ellipse.draw_shadow(sun_position, weather.shadow_blur(), 
  736.               grass * .5, grass);
  737.   glPopAttrib();
  738. }
  739.  
  740. static void telescope_list_init()
  741. {
  742.   glNewList(list_telescope, GL_COMPILE);
  743.   telescope_draw();
  744.   glEndList();
  745. }
  746.  
  747. static void telescope_draw()
  748. {
  749.   glLoadName(name_telescope);
  750.   glEnable(GL_COLOR_MATERIAL);
  751.   glDisable(GL_CULL_FACE);
  752.   glClear(GL_DEPTH_BUFFER_BIT);
  753.   glEnable(GL_DEPTH_TEST);
  754.   telescope.draw_body();
  755.   glDisable(GL_DEPTH_TEST);
  756.   glEnable(GL_CULL_FACE);
  757.   glDisable(GL_COLOR_MATERIAL);
  758. }
  759.  
  760. static void fog_read_image()
  761. {
  762.   glPushMatrix();
  763.   glLoadIdentity();
  764.  
  765.   /* This creates an alpha gradient across the image */
  766. /*  glColorMask(0, 0, 0, 1);
  767.   glBegin(GL_QUADS);
  768.   glColor4f(1, 1, 1, 1);
  769.   glVertex2f(-1, -1);
  770.   glVertex2f(1, -1);
  771.   glColor4f(1, 1, 1, 0);
  772.   glVertex2f(1, 1);
  773.   glVertex2f(-1, 1);
  774.   glEnd();
  775.   glColorMask(1, 1, 1, 1);
  776. */
  777.   glDrawBuffer(GL_BACK);
  778.   glReadBuffer(GL_BACK);
  779.   glAccum(GL_LOAD, 1);
  780.  
  781.   glPopMatrix();
  782. }
  783.  
  784. static void fog_write_image()
  785. {
  786.   glDrawBuffer(GL_BACK);
  787.  
  788.   /* Put this back in once we're done testing */
  789. //  glEnable(GL_BLEND);
  790.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  791.   glAccum(GL_RETURN, 1);  
  792.   glDisable(GL_BLEND);
  793. }
  794.