home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / OpenGL / drip / main.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  8.4 KB  |  303 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 "oglwindow.h"
  38. #include "Drip.h"
  39.  
  40. #include <X11/keysym.h>
  41.  
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <math.h>
  46. #include <sys/time.h>
  47.  
  48. oglwindow *window;
  49.  
  50. float back_r = 0, back_g = 0, back_b = 0;
  51.  
  52. float speed = 0.25;            /* Scaling factor for time */
  53.  
  54. const int max_drips = 255;
  55. float drip_position[max_drips][2];
  56. float drip_age[max_drips];        /* Age in seconds */
  57. Drip *drips[max_drips];
  58.  
  59. int first_drip, new_drip;
  60.  
  61. const float time_gran = 0.0001;        /* Granularity of time */
  62. struct timeval old_time;
  63.  
  64. const float scale_radius = 100.0;    /* This relates radius to time */
  65. const float max_ring_radius = 250.0;    /* How big to let them get before
  66.                      * destroying them */
  67.  
  68. const float default_drips_second = 2.0;    /* How many drips should be randomly
  69.                      * created for a full-size screen */
  70.  
  71. float probability(float win_width, float win_height, Display *dpy)
  72. {
  73.   XWindowAttributes winattr;
  74.   float win_area, dpy_area;
  75.  
  76.   XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &winattr);
  77.   win_area = win_width * win_height;
  78.   dpy_area = (float)(winattr.width * winattr.height);
  79.   return (win_area / dpy_area);
  80. }
  81.  
  82. inline float randmax(float max = 1.0) 
  83. {
  84.   return (max * ((float)rand() / (float)RAND_MAX));
  85. }
  86.  
  87. inline float ring_increment(float dt)
  88. {
  89.   return dt * scale_radius;
  90. }
  91.  
  92. inline float outer_increment(float dt) 
  93. {
  94.   return 2.0 * dt * scale_radius;
  95. }
  96.  
  97. float draw() 
  98. {
  99.   struct timeval new_time;
  100.   float dtime;
  101.   float rel_size;
  102.   int i;
  103.  
  104.   gettimeofday(&new_time);
  105.   if (old_time.tv_sec == 0 && old_time.tv_usec == 0) {
  106.     old_time.tv_sec = new_time.tv_sec;
  107.     old_time.tv_usec = new_time.tv_usec;
  108.     dtime = 0.0;
  109.   } else {
  110.     dtime = (new_time.tv_sec - old_time.tv_sec) +
  111.       (new_time.tv_usec - old_time.tv_usec) / 1000000.0;
  112.     dtime *= speed;
  113.     if (dtime < time_gran) dtime = 0.0;
  114.   }
  115.  
  116.   glClear(GL_COLOR_BUFFER_BIT);
  117.  
  118.   for (i = first_drip; i != new_drip; i = (i + 1) % max_drips) {
  119.     glPushMatrix();
  120.     glTranslatef(drip_position[i][0], drip_position[i][1], 0.0);
  121.     drips[i]->draw();
  122.     glPopMatrix();
  123.     
  124.     drip_age[i] += dtime;
  125.     drips[i]->ring_radius += ring_increment(dtime);
  126.     drips[i]->outer_radius += outer_increment(dtime);
  127.  
  128.     rel_size = drips[i]->ring_radius / max_ring_radius;
  129.     drips[i]->ring_color[3] = 1.0 - rel_size*rel_size;
  130.     drips[i]->inner_color[3] = 1.0 - rel_size;
  131.  
  132.     /* This is a bit of a hack, but makes sense */
  133.     if (drips[i]->ring_radius > max_ring_radius) 
  134.       first_drip = (first_drip + 1) % max_drips;
  135.   }
  136.  
  137.   window->swapbuffers();
  138.  
  139.   if (dtime > 0.0) {
  140.     old_time.tv_sec = new_time.tv_sec;
  141.     old_time.tv_usec = new_time.tv_usec;
  142.   }
  143.  
  144.   return dtime;
  145.  
  146. }
  147.  
  148. void create_drip(float x, float y, float r, float g, float b)
  149. {
  150.   drips[new_drip]->inner_color[0] = drips[new_drip]->ring_color[0] = 
  151.     drips[new_drip]->outer_color[0] = r;
  152.   drips[new_drip]->inner_color[1] = drips[new_drip]->ring_color[1] = 
  153.     drips[new_drip]->outer_color[1] = g;
  154.   drips[new_drip]->inner_color[2] = drips[new_drip]->ring_color[2] = 
  155.     drips[new_drip]->outer_color[2] = b;
  156.  
  157.   drips[new_drip]->inner_color[3] = 1.0;
  158.   drips[new_drip]->ring_color[3] = 1.0;
  159.   drips[new_drip]->outer_color[3] = 0.0;
  160.   
  161.   drips[new_drip]->ring_radius = 0.0;
  162.   drips[new_drip]->outer_radius = 0.0;
  163.  
  164.   drip_position[new_drip][0] = x;
  165.   drip_position[new_drip][1] = y;
  166.  
  167.   drip_age[new_drip] = 0.0;
  168.  
  169.   new_drip = (new_drip + 1) % max_drips;
  170.   if (new_drip == first_drip) 
  171.     first_drip = (first_drip + 1) % max_drips;
  172. }
  173.  
  174.  
  175. void setup_fullscreen(Display *dpy) 
  176. {
  177.   XWindowAttributes winattr;
  178.  
  179.   XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &winattr);
  180.   window->set_minsize(winattr.width, winattr.height);
  181. }
  182.  
  183.  
  184. void main(int argc, char **argv)
  185. {
  186.   Display *dpy;
  187.   XEvent event;
  188.   char buffer[5];
  189.   int bufsize = 5;
  190.   KeySym key;
  191.   XComposeStatus compose;
  192.   float win_width, win_height;
  193.   float random_time;
  194.   float random_probability;    
  195.   float drips_second;
  196.  
  197.   int random = 0;
  198.   float *points;
  199.   int create_drips;
  200.   int random_color;
  201.   int fullscreen = 0;
  202.   int i;
  203.   
  204.   for (i = 1; i < argc; i++) 
  205.     switch(argv[i][1]) {
  206.     case 'f':
  207.       fullscreen = 1;
  208.       break;
  209.     case 'r': 
  210.       random = 1;
  211.       drips_second = atof(&argv[i][2]);
  212.       if (drips_second == 0.0) drips_second = default_drips_second;
  213.       break;
  214.     case 'w':
  215.       back_r = back_g = back_b = 1.0;
  216.       break;
  217.     case 'h':
  218.     default:
  219.       fprintf(stderr, "Usage:\n%s [-r[number]] [-f] [-w]\n", argv[0]);
  220.       break;
  221.     }
  222.  
  223.   drips[0] = new Drip();
  224.   drips[0]->alloc_points();
  225.   drips[0]->fill_points();
  226.   points = drips[0]->get_points();
  227.   for (i = 1; i < max_drips; i++) {
  228.     drips[i] = new Drip();
  229.     drips[i]->set_points(points);
  230.   }
  231.  
  232.   first_drip = new_drip = 0;
  233.  
  234.   window = new oglwindow();
  235.   
  236.   window->set_doublebuffer(1);
  237.   window->set_title("drip");
  238.   window->open();
  239.   dpy = window->get_display();
  240.   if (fullscreen) setup_fullscreen(dpy);
  241.   window->map();
  242.   window->winset();
  243.  
  244.   old_time.tv_sec = 0;
  245.   old_time.tv_usec = 0;
  246.  
  247.   random_time = 0.0;
  248.   random_probability = 0.0;
  249.  
  250.   win_width = win_height = 0.0;
  251.  
  252.   glClearColor(back_r, back_g, back_b, 1.0);
  253.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  254.   glEnable(GL_BLEND);
  255.  
  256.   while (1) {
  257.     random_time += draw() * drips_second;
  258.     if (random) {
  259.       create_drips = (int)trunc(random_time);
  260.       for (i = 0; i < create_drips; i++) 
  261.     if (randmax() < random_probability) {
  262.       random_color = (int)randmax(3.0);
  263.       create_drip(randmax(win_width), randmax(win_height), 
  264.               random_color == 0 ? 1.0 : 0.0, 
  265.               random_color == 1 ? 1.0 : 0.0,
  266.               random_color == 2 ? 1.0 : 0.0);
  267.     }
  268.       random_time = random_time - (float)create_drips;
  269.     }
  270.     while (((random || first_drip != new_drip) && XPending(dpy)) ||
  271.        (random == 0 && first_drip == new_drip)) {
  272.       XNextEvent(dpy, &event);
  273.       switch(event.type) {
  274.       case Expose:
  275.         draw();
  276.         break;
  277.       case ConfigureNotify:
  278.         window->resize();
  279.     win_width = window->get_width();
  280.     win_height = window->get_height();
  281.     glMatrixMode(GL_MODELVIEW);
  282.     glLoadIdentity(); 
  283.     glOrtho(0, win_width, 0, win_height, -1, 1);
  284.     random_probability = probability(win_width, win_height, dpy);
  285.         break;
  286.       case ButtonPress:
  287.     create_drip((float)event.xbutton.x, 
  288.             win_height - (float)event.xbutton.y,
  289.             event.xbutton.button == Button1 ? 1.0 : 0.0,
  290.             event.xbutton.button == Button2 ? 1.0 : 0.0,
  291.             event.xbutton.button == Button3 ? 1.0 : 0.0);
  292.     drip_age[new_drip] = 0.0;
  293.     break;
  294.       case KeyPress:
  295.         XLookupString(&event.xkey, buffer, bufsize, &key, &compose);
  296.         if (key == XK_Escape) exit(0);
  297.     else if (key == XK_space) new_drip = first_drip = 0;
  298.     break;
  299.       }
  300.     }
  301.   }
  302. }
  303.