home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / GLUT / progs / contrib / noof.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  9.8 KB  |  479 lines

  1.  
  2. /* XXX Very crufty code follows. */
  3.  
  4. #include <stdlib.h>
  5. #include <GL/glut.h>
  6.  
  7. #include <math.h>
  8. #include <unistd.h>
  9. #include <sys/types.h>
  10. #include <stdio.h>
  11.  
  12. /* For portability... */
  13. #undef fcos
  14. #undef fsin
  15. #define fcos  cos
  16. #define fsin  sin
  17.  
  18. /* --- shape parameters def'n --- */
  19. #define N_SHAPES 7
  20. float pos[N_SHAPES * 3];
  21. float dir[N_SHAPES * 3];
  22. float acc[N_SHAPES * 3];
  23. float col[N_SHAPES * 3];
  24. float hsv[N_SHAPES * 3];
  25. float hpr[N_SHAPES * 3];
  26. float ang[N_SHAPES];
  27. float spn[N_SHAPES];
  28. float sca[N_SHAPES];
  29. float geep[N_SHAPES];
  30. float peep[N_SHAPES];
  31. float speedsq[N_SHAPES];
  32. int blad[N_SHAPES];
  33.  
  34. float ht, wd;
  35.  
  36. void
  37. initshapes(int i)
  38. {
  39.   int k;
  40.   float f;
  41.  
  42.   /* random init of pos, dir, color */
  43.   for (k = i * 3; k <= i * 3 + 2; k++) {
  44.     f = random() / 2147483647.0;
  45.     pos[k] = f;
  46.     f = random() / 2147483647.0;
  47.     f = (f - 0.5) * 0.05;
  48.     dir[k] = f;
  49.     f = random() / 2147483647.0;
  50.     f = (f - 0.5) * 0.0002;
  51.     acc[k] = f;
  52.     f = random() / 2147483647.0;
  53.     col[k] = f;
  54.   }
  55.  
  56.   speedsq[i] = dir[i * 3] * dir[i * 3] + dir[i * 3 + 1] * dir[i * 3 + 1];
  57.   f = random() / 2147483647.0;
  58.   blad[i] = 2 + (int) (f * 17.0);
  59.   f = random() / 2147483647.0;
  60.   ang[i] = f;
  61.   f = random() / 2147483647.0;
  62.   spn[i] = (f - 0.5) * 40.0 / (10 + blad[i]);
  63.   f = random() / 2147483647.0;
  64.   sca[i] = (f * 0.1 + 0.08);
  65.   dir[i * 3] *= sca[i];
  66.   dir[i * 3 + 1] *= sca[i];
  67.  
  68.   f = random() / 2147483647.0;
  69.   hsv[i * 3] = f * 360.0;
  70.  
  71.   f = random() / 2147483647.0;
  72.   hsv[i * 3 + 1] = f * 0.6 + 0.4;
  73.  
  74.   f = random() / 2147483647.0;
  75.   hsv[i * 3 + 2] = f * 0.7 + 0.3;
  76.  
  77.   f = random() / 2147483647.0;
  78.   hpr[i * 3] = f * 0.005 * 360.0;
  79.   f = random() / 2147483647.0;
  80.   hpr[i * 3 + 1] = f * 0.03;
  81.   f = random() / 2147483647.0;
  82.   hpr[i * 3 + 2] = f * 0.02;
  83.  
  84.   geep[i] = 0;
  85.   f = random() / 2147483647.0;
  86.   peep[i] = 0.01 + f * 0.2;
  87. }
  88.  
  89. int tko = 0;
  90.  
  91. float bladeratio[] =
  92. {
  93.   /* nblades = 2..7 */
  94.   0.0, 0.0, 3.00000, 1.73205, 1.00000, 0.72654, 0.57735, 0.48157,
  95.   /* 8..13 */
  96.   0.41421, 0.36397, 0.19076, 0.29363, 0.26795, 0.24648,
  97.   /* 14..19 */
  98.   0.22824, 0.21256, 0.19891, 0.18693, 0.17633, 0.16687,
  99. };
  100.  
  101. void
  102. drawleaf(int l)
  103. {
  104.  
  105.   int b, blades;
  106.   float x, y;
  107.   float wobble;
  108.  
  109.   blades = blad[l];
  110.  
  111.   y = 0.10 * fsin(geep[l] * M_PI / 180.0) + 0.099 * fsin(geep[l] * 5.12 * M_PI / 180.0);
  112.   if (y < 0)
  113.     y = -y;
  114.   x = 0.15 * fcos(geep[l] * M_PI / 180.0) + 0.149 * fcos(geep[l] * 5.12 * M_PI / 180.0);
  115.   if (x < 0.0)
  116.     x = 0.0 - x;
  117.   if (y < 0.001 && x > 0.000002 && ((tko & 0x1) == 0)) {
  118.     initshapes(l);      /* let it become reborn as something
  119.                            else */
  120.     tko++;
  121.     return;
  122.   } {
  123.     float w1 = fsin(geep[l] * 15.3 * M_PI / 180.0);
  124.     wobble = 3.0 + 2.00 * fsin(geep[l] * 0.4 * M_PI / 180.0) + 3.94261 * w1;
  125.   }
  126.  
  127.   /**
  128.   if(blades == 2) if (y > 3.000*x) y = x*3.000;
  129.   if(blades == 3) if (y > 1.732*x) y = x*1.732;
  130.   if(blades == 4) if (y >       x) y = x;
  131.   if(blades == 5) if (y > 0.726*x) y = x*0.726;
  132.   if(blades == 6) if (y > 0.577*x) y = x*0.577;
  133.   if(blades == 7) if (y > 0.481*x) y = x*0.481;
  134.   if(blades == 8) if (y > 0.414*x) y = x*0.414;
  135.   */
  136.   if (y > x * bladeratio[blades])
  137.     y = x * bladeratio[blades];
  138.  
  139.   for (b = 0; b < blades; b++) {
  140.     glPushMatrix();
  141.     glTranslatef(pos[l * 3], pos[l * 3 + 1], pos[l * 3 + 2]);
  142.     glRotatef(ang[l] + b * (360.0 / blades), 0.0, 0.0, 1.0);
  143.     glScalef(wobble * sca[l], wobble * sca[l], wobble * sca[l]);
  144.     /**
  145.     if(tko & 0x40000) glColor3f(col[l*3], col[l*3+1], col[l*3+2]); 
  146.     else
  147.     */
  148.     glColor4ub(0, 0, 0, 0x60);
  149.  
  150.     /* constrain geep cooridinates here XXX */
  151.     glEnable(GL_BLEND);
  152.  
  153.     glBegin(GL_TRIANGLE_STRIP);
  154.     glVertex2f(x * sca[l], 0.0);
  155.     glVertex2f(x, y);
  156.     glVertex2f(x, -y);  /* C */
  157.     glVertex2f(0.3, 0.0);  /* D */
  158.     glEnd();
  159.  
  160.     /**
  161.     if(tko++ & 0x40000) glColor3f(0,0,0);
  162.     else
  163.     */
  164.     glColor3f(col[l * 3], col[l * 3 + 1], col[l * 3 + 2]);
  165.     glBegin(GL_LINE_LOOP);
  166.     glVertex2f(x * sca[l], 0.0);
  167.     glVertex2f(x, y);
  168.     glVertex2f(0.3, 0.0);  /* D */
  169.     glVertex2f(x, -y);  /* C */
  170.     glEnd();
  171.     glDisable(GL_BLEND);
  172.  
  173.     glPopMatrix();
  174.   }
  175. }
  176.  
  177. void
  178. motionUpdate(int t)
  179. {
  180.   float spq;
  181.   int bounce;
  182.  
  183.   bounce = 1;
  184.   if (pos[t * 3] < -sca[t] * wd && dir[t * 3] < 0.0) {
  185.     dir[t * 3] = -dir[t * 3];
  186.   /**
  187.   acc[t*3+1] += 0.8*acc[t*3];
  188.   acc[t*3] = -0.8*acc[t*3];
  189.   */
  190.   } else if (pos[t * 3] > (1 + sca[t]) * wd && dir[t * 3] > 0.0) {
  191.     dir[t * 3] = -dir[t * 3];
  192.     /**
  193.     acc[t*3+1] += 0.8*acc[t*3];
  194.     acc[t*3] = -0.8*acc[t*3];
  195.     */
  196.   } else if (pos[t * 3 + 1] < -sca[t] * ht && dir[t * 3 + 1] < 0.0) {
  197.     dir[t * 3 + 1] = -dir[t * 3 + 1];
  198.     /**
  199.     acc[t*3] += 0.8*acc[t*3+1];
  200.     acc[t*3+1] = -0.8*acc[t*3+1];
  201.     */
  202.   } else if (pos[t * 3 + 1] > (1 + sca[t]) * ht && dir[t * 3 + 1] > 0.0) {
  203.     dir[t * 3 + 1] = -dir[t * 3 + 1];
  204.     /**
  205.     acc[t*3] += 0.8*acc[t*3+1];
  206.     acc[t*3+1] = -0.8*acc[t*3+1];
  207.     */
  208.   } else {
  209.     bounce = 0;
  210.   }
  211.  
  212.   /**
  213.   if( bounce && 
  214.      (spq = (dir[t*3]*dir[t*3]+dir[t*3+1]*dir[t*3+1])) > speedsq[t]){
  215.      dir[t*3  ] *= fsqrt(speedsq[t]/spq);
  216.      dir[t*3+1] *= fsqrt(speedsq[t]/spq);
  217.   }
  218.   */
  219.  
  220.   pos[t * 3] += dir[t * 3];
  221.   pos[t * 3 + 1] += dir[t * 3 + 1];
  222.   /**
  223.   dir[t*3]   += acc[t*3];
  224.   dir[t*3+1] += acc[t*3+1];
  225.   */
  226.   ang[t] += spn[t];
  227.   geep[t] += peep[t];
  228.   if (geep[t] > 360 * 5.0)
  229.     geep[t] -= 360 * 5.0;
  230.   if (ang[t] < 0.0) {
  231.     ang[t] += 360.0;
  232.   }
  233.   if (ang[t] > 360.0) {
  234.     ang[t] -= 360.0;
  235.   }
  236. }
  237.  
  238. void
  239. colorUpdate(int i)
  240. {
  241.   if (hsv[i * 3 + 1] <= 0.5 && hpr[i * 3 + 1] < 0.0)
  242.     hpr[i * 3 + 1] = -hpr[i * 3 + 1];  /* adjust s */
  243.   if (hsv[i * 3 + 1] >= 1.0 && hpr[i * 3 + 1] > 0.0)
  244.     hpr[i * 3 + 1] = -hpr[i * 3 + 1];  /* adjust s */
  245.   if (hsv[i * 3 + 2] <= 0.4 && hpr[i * 3 + 2] < 0.0)
  246.     hpr[i * 3 + 2] = -hpr[i * 3 + 2];  /* adjust s */
  247.   if (hsv[i * 3 + 2] >= 1.0 && hpr[i * 3 + 2] > 0.0)
  248.     hpr[i * 3 + 2] = -hpr[i * 3 + 2];  /* adjust s */
  249.  
  250.   hsv[i * 3] += hpr[i * 3];
  251.   hsv[i * 3 + 1] += hpr[i * 3 + 1];
  252.   hsv[i * 3 + 2] += hpr[i * 3 + 2];
  253.  
  254.   /* --- hsv -> rgb --- */
  255. #define H(hhh) hhh[i*3  ]
  256. #define S(hhh) hhh[i*3+1]
  257. #define V(hhh) hhh[i*3+2]
  258.  
  259. #define R(hhh) hhh[i*3  ]
  260. #define G(hhh) hhh[i*3+1]
  261. #define B(hhh) hhh[i*3+2]
  262.  
  263.   if (V(hsv) < 0.0)
  264.     V(hsv) = 0.0;
  265.   if (V(hsv) > 1.0)
  266.     V(hsv) = 1.0;
  267.   if (S(hsv) <= 0.0) {
  268.     R(col) = V(hsv);
  269.     G(col) = V(hsv);
  270.     B(col) = V(hsv);
  271.   } else {
  272.     float f, h, p, q, t, v;
  273.     int hi;
  274.  
  275.     while (H(hsv) < 0.0)
  276.       H(hsv) += 360.0;
  277.     while (H(hsv) >= 360.0)
  278.       H(hsv) -= 360.0;
  279.  
  280.     if (S(hsv) < 0.0)
  281.       S(hsv) = 0.0;
  282.     if (S(hsv) > 1.0)
  283.       S(hsv) = 1.0;
  284.  
  285.     h = H(hsv) / 60.0;
  286.     hi = (int) (h);
  287.     f = h - hi;
  288.     v = V(hsv);
  289.     p = V(hsv) * (1 - S(hsv));
  290.     q = V(hsv) * (1 - S(hsv) * f);
  291.     t = V(hsv) * (1 - S(hsv) * (1 - f));
  292.  
  293.     if (hi <= 0) {
  294.       R(col) = v;
  295.       G(col) = t;
  296.       B(col) = p;
  297.     } else if (hi == 1) {
  298.       R(col) = q;
  299.       G(col) = v;
  300.       B(col) = p;
  301.     } else if (hi == 2) {
  302.       R(col) = p;
  303.       G(col) = v;
  304.       B(col) = t;
  305.     } else if (hi == 3) {
  306.       R(col) = p;
  307.       G(col) = q;
  308.       B(col) = v;
  309.     } else if (hi == 4) {
  310.       R(col) = t;
  311.       G(col) = p;
  312.       B(col) = v;
  313.     } else {
  314.       R(col) = v;
  315.       G(col) = p;
  316.       B(col) = q;
  317.     }
  318.   }
  319. }
  320.  
  321. void
  322. gravity(float fx)
  323. {
  324.   int a, b;
  325.  
  326.   for (a = 0; a < N_SHAPES; a++) {
  327.     for (b = 0; b < a; b++) {
  328.       float t, d2;
  329.  
  330.       t = pos[b * 3] - pos[a * 3];
  331.       d2 = t * t;
  332.       t = pos[b * 3 + 1] - pos[a * 3 + 1];
  333.       d2 += t * t;
  334.       if (d2 < 0.000001)
  335.         d2 = 0.00001;
  336.       if (d2 < 0.1) {
  337.  
  338.         float v0, v1, z;
  339.         v0 = pos[b * 3] - pos[a * 3];
  340.         v1 = pos[b * 3 + 1] - pos[a * 3 + 1];
  341.  
  342.         z = 0.00000001 * fx / (d2);
  343.  
  344.         dir[a * 3] += v0 * z * sca[b];
  345.         dir[b * 3] += -v0 * z * sca[a];
  346.         dir[a * 3 + 1] += v1 * z * sca[b];
  347.         dir[b * 3 + 1] += -v1 * z * sca[a];
  348.  
  349.       }
  350.     }
  351.     /** apply brakes
  352.     if(dir[a*3]*dir[a*3] + dir[a*3+1]*dir[a*3+1]
  353.       > 0.0001) {
  354.       dir[a*3] *= 0.9;
  355.       dir[a*3+1] *= 0.9;
  356.     }
  357.     */
  358.   }
  359. }
  360. void
  361. oneFrame(void)
  362. {
  363.   int i;
  364.  
  365.   /**
  366.   if((random() & 0xff) == 0x34){
  367.     glClear(GL_COLOR_BUFFER_BIT);
  368.   }
  369.  
  370.   if((tko & 0x1f) == 0x1f){
  371.     glEnable(GL_BLEND);
  372.     glColor4f(0.0, 0.0, 0.0, 0.09);
  373.     glRectf(0.0, 0.0, wd, ht);
  374.     glDisable(GL_BLEND);
  375. #ifdef __sgi
  376.     sginap(0);
  377. #endif
  378.   }
  379.   */
  380.   gravity(-2.0);
  381.   for (i = 0; i < N_SHAPES; i++) {
  382.     motionUpdate(i);
  383. #ifdef __sgi
  384.     sginap(0);
  385. #endif
  386.     colorUpdate(i);
  387. #ifdef __sgi
  388.     sginap(0);
  389. #endif
  390.     drawleaf(i);
  391. #ifdef __sgi
  392.     sginap(0);
  393. #endif
  394.  
  395.   }
  396.   glFlush();
  397. }
  398.  
  399. void
  400. display(void)
  401. {
  402.   glClear(GL_COLOR_BUFFER_BIT);
  403. }
  404.  
  405. void
  406. myReshape(int w, int h)
  407. {
  408.   glViewport(0, 0, w, h);
  409.   glMatrixMode(GL_PROJECTION);
  410.   glLoadIdentity();
  411.   if (w <= h) {
  412.     wd = 1.0;
  413.     ht = (GLfloat) h / (GLfloat) w;
  414.     glOrtho(0.0, 1.0,
  415.       0.0, 1.0 * (GLfloat) h / (GLfloat) w,
  416.       -16.0, 4.0);
  417.   } else {
  418.     wd = (GLfloat) w / (GLfloat) h;
  419.     ht = 1.0;
  420.     glOrtho(0.0, 1.0 * (GLfloat) w / (GLfloat) h,
  421.       0.0, 1.0,
  422.       -16.0, 4.0);
  423.   }
  424.   glMatrixMode(GL_MODELVIEW);
  425.   glLoadIdentity();
  426. }
  427.  
  428. void
  429. visibility(int status)
  430. {
  431.   if (status == GLUT_VISIBLE) {
  432.     glutIdleFunc(oneFrame);
  433.   } else {
  434.     glutIdleFunc(NULL);
  435.   }
  436.  
  437. }
  438.  
  439. void
  440. myinit(void)
  441. {
  442.   int i;
  443.   srandom(getpid());
  444.   glClearColor(0.0, 0.0, 0.0, 1.0);
  445.   glEnable(GL_LINE_SMOOTH);
  446.   glShadeModel(GL_FLAT);
  447.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  448.   for (i = 0; i < N_SHAPES; i++)
  449.     initshapes(i);
  450.   myReshape(200, 200);
  451. }
  452.  
  453. void
  454. keys(unsigned char c, int x, int y)
  455. {
  456.  
  457.   if (c == 0x1b)
  458.     exit(0);            /* escape */
  459. }
  460.  
  461. int
  462. main(int argc, char **argv)
  463. {
  464.   glutInit(&argc, argv);
  465.   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
  466.   glutInitWindowSize(300, 300);
  467.   glutCreateWindow(argv[0]);
  468.  
  469.   myinit();
  470.   glutReshapeFunc(myReshape);
  471.   glutDisplayFunc(display);
  472.   glutKeyboardFunc(keys);
  473.   glutVisibilityFunc(visibility);
  474.   glutIdleFunc(oneFrame);
  475.   glutPostRedisplay();
  476.   glutMainLoop();
  477.   return 0;             /* ANSI C requires main to return int. */
  478. }
  479.