home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / OpenGL 1.0 SDK / Source / Examples / aux / samples / star.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-18  |  5.7 KB  |  302 lines  |  [TEXT/CWIE]

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <time.h>
  6. #include "gl.h"
  7. #include "glu.h"
  8. #include "tk.h"
  9.  
  10.  
  11. #define PI 3.141592657
  12.  
  13. enum {
  14.     NORMAL = 0,
  15.     WEIRD = 1
  16. };
  17.  
  18. enum {
  19.     STREAK = 0,
  20.     CIRCLE = 1
  21. };
  22.  
  23. #define MAXSTARS 400
  24. #define MAXPOS 10000
  25. #define MAXWARP 10
  26. #define MAXANGLES 6000
  27.  
  28.  
  29. typedef struct _starRec {
  30.     GLint type;
  31.     float x[2], y[2], z[2];
  32.     float offsetX, offsetY, offsetR, rotation;
  33. } starRec;
  34.  
  35.  
  36. GLenum doubleBuffer, directRender;
  37. GLint windW, windH;
  38.  
  39. GLenum flag = NORMAL;
  40. GLint starCount = MAXSTARS / 2;
  41. float speed = 1.0;
  42. GLint nitro = 0;
  43. starRec stars[MAXSTARS];
  44. float sinTable[MAXANGLES];
  45.  
  46.  
  47. float Sin(float angle)
  48. {
  49.     return (sinTable[(GLint)angle]);
  50. }
  51.  
  52. float Cos(float angle)
  53. {
  54.  
  55.     return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
  56. }
  57.  
  58. void NewStar(GLint n, GLint d)
  59. {
  60.  
  61.     if (rand()%4 == 0) {
  62.     stars[n].type = CIRCLE;
  63.     } else {
  64.     stars[n].type = STREAK;
  65.     }
  66.     stars[n].x[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
  67.     stars[n].y[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
  68.     stars[n].z[0] = (float)(rand() % MAXPOS + d);
  69.     if (rand()%4 == 0 && flag == WEIRD) {
  70.     stars[n].offsetX = (float)(rand() % 100 - 100 / 2);
  71.     stars[n].offsetY = (float)(rand() % 100 - 100 / 2);
  72.     stars[n].offsetR = (float)(rand() % 25 - 25 / 2);
  73.     } else {
  74.     stars[n].offsetX = 0.0;
  75.     stars[n].offsetY = 0.0;
  76.     stars[n].offsetR = 0.0;
  77.     }
  78. }
  79.  
  80. void RotatePoint(float *x, float *y, float rotation)
  81. {
  82.     float tmpX, tmpY;
  83.  
  84.     tmpX = *x * Cos(rotation) - *y * Sin(rotation);
  85.     tmpY = *y * Cos(rotation) + *x * Sin(rotation);
  86.     *x = tmpX;
  87.     *y = tmpY;
  88. }
  89.  
  90. void MoveStars(void)
  91. {
  92.     float offset;
  93.     GLint n;
  94.  
  95.     offset = speed * 60.0;
  96.  
  97.     for (n = 0; n < starCount; n++) {
  98.     stars[n].x[1] = stars[n].x[0];
  99.     stars[n].y[1] = stars[n].y[0];
  100.     stars[n].z[1] = stars[n].z[0];
  101.     stars[n].x[0] += stars[n].offsetX;
  102.     stars[n].y[0] += stars[n].offsetY;
  103.     stars[n].z[0] -= offset;
  104.         stars[n].rotation += stars[n].offsetR;
  105.         if (stars[n].rotation > MAXANGLES) {
  106.             stars[n].rotation = 0.0;
  107.     }
  108.     }
  109. }
  110.  
  111. GLenum StarPoint(GLint n)
  112. {
  113.     float x0, y0, x1, y1, width;
  114.     GLint i;
  115.  
  116.     x0 = stars[n].x[0] * windW / stars[n].z[0];
  117.     y0 = stars[n].y[0] * windH / stars[n].z[0];
  118.     RotatePoint(&x0, &y0, stars[n].rotation);
  119.     x0 += windW / 2.0;
  120.     y0 += windH / 2.0;
  121.  
  122.     if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) {
  123.     if (stars[n].type == STREAK) {
  124.         x1 = stars[n].x[1] * windW / stars[n].z[1];
  125.         y1 = stars[n].y[1] * windH / stars[n].z[1];
  126.         RotatePoint(&x1, &y1, stars[n].rotation);
  127.         x1 += windW / 2.0;
  128.         y1 += windH / 2.0;
  129.  
  130.         glLineWidth(MAXPOS/100.0/stars[n].z[0]+1.0);
  131.         glColor3f(1.0, (MAXWARP-speed)/MAXWARP, (MAXWARP-speed)/MAXWARP);
  132.         if (fabs(x0-x1) < 1.0 && fabs(y0-y1) < 1.0) {
  133.         glBegin(GL_POINTS);
  134.             glVertex2f(x0, y0);
  135.         glEnd();
  136.         } else {
  137.         glBegin(GL_LINES);
  138.             glVertex2f(x0, y0);
  139.             glVertex2f(x1, y1);
  140.         glEnd();
  141.         }
  142.     } else {
  143.         width = MAXPOS / 10.0 / stars[n].z[0] + 1.0;
  144.         glColor3f(1.0, 0.0, 0.0);
  145.         glBegin(GL_POLYGON);
  146.         for (i = 0; i < 8; i++) {
  147.             float x = x0 + width * Cos((float)i*MAXANGLES/8.0);
  148.             float y = y0 + width * Sin((float)i*MAXANGLES/8.0);
  149.             glVertex2f(x, y);
  150.         };
  151.         glEnd();
  152.     }
  153.     return GL_TRUE;
  154.     } else {
  155.     return GL_FALSE;
  156.     }
  157. }
  158.  
  159. void ShowStars(void)
  160. {
  161.     GLint n;
  162.  
  163.     glClear(GL_COLOR_BUFFER_BIT);
  164.  
  165.     for (n = 0; n < starCount; n++) {
  166.     if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) {
  167.         if (StarPoint(n) == GL_FALSE) {
  168.         NewStar(n, MAXPOS);
  169.         }
  170.     } else {
  171.         NewStar(n, MAXPOS);
  172.     }
  173.     }
  174. }
  175.  
  176. static void Init(void)
  177. {
  178.     float angle;
  179.     GLint n;
  180.  
  181.     srand((unsigned int)time(NULL));
  182.  
  183.     for (n = 0; n < MAXSTARS; n++) {
  184.     NewStar(n, 100);
  185.     }
  186.  
  187.     angle = 0.0;
  188.     for (n = 0; n < MAXANGLES ; n++) {
  189.     sinTable[n] = sin(angle);
  190.         angle += PI / (MAXANGLES / 2.0);
  191.     }
  192.  
  193.     glClearColor(0.0, 0.0, 0.0, 0.0);
  194.     glDisable(GL_DITHER);
  195. }
  196.  
  197. void Reshape(int width, int height)
  198. {
  199.     windW = (GLint)width;
  200.     windH = (GLint)height;
  201.  
  202.     glViewport(0, 0, windW, windH);
  203.  
  204.     glMatrixMode(GL_PROJECTION);
  205.     glLoadIdentity();
  206.     gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
  207.     glMatrixMode(GL_MODELVIEW);
  208. }
  209.  
  210. static GLenum Key(int key, GLenum mask)
  211. {
  212.  
  213.     switch (key) {
  214.       case TK_ESCAPE:
  215.     tkQuit();
  216.       case TK_SPACE:
  217.     flag = (flag == NORMAL) ? WEIRD : NORMAL;
  218.     break;
  219.       case TK_t:
  220.     nitro = 1;
  221.     break;
  222.       default:
  223.     return GL_FALSE;
  224.     }
  225.     return GL_TRUE;
  226. }
  227.  
  228. void Idle(void)
  229. {
  230.  
  231.     MoveStars();
  232.     ShowStars();
  233.     if (nitro > 0) {
  234.     speed = (float)(nitro / 10) + 1.0;
  235.     if (speed > MAXWARP) {
  236.         speed = MAXWARP;
  237.     }
  238.     if (++nitro > MAXWARP*10) {
  239.         nitro = -nitro;
  240.     }
  241.     } else if (nitro < 0) {
  242.     nitro++;
  243.     speed = (float)(-nitro / 10) + 1.0;
  244.     if (speed > MAXWARP) {
  245.         speed = MAXWARP;
  246.     }
  247.     }
  248.  
  249.     glFlush();
  250. }
  251.  
  252. static GLenum Args(int argc, char **argv)
  253. {
  254.     GLint i;
  255.  
  256.     doubleBuffer = GL_FALSE;
  257.     directRender = GL_TRUE;
  258.  
  259.     for (i = 1; i < argc; i++) {
  260.     if (strcmp(argv[i], "-sb") == 0) {
  261.         doubleBuffer = GL_FALSE;
  262.     } else if (strcmp(argv[i], "-db") == 0) {
  263.         doubleBuffer = GL_TRUE;
  264.     } else if (strcmp(argv[i], "-dr") == 0) {
  265.         directRender = GL_TRUE;
  266.     } else if (strcmp(argv[i], "-ir") == 0) {
  267.         directRender = GL_FALSE;
  268.     }
  269.     }
  270.     return GL_TRUE;
  271. }
  272.  
  273. void main(int argc, char **argv)
  274. {
  275.     GLenum type;
  276.  
  277.     if (Args(argc, argv) == GL_FALSE) {
  278.     tkQuit();
  279.     }
  280.  
  281.     windW = 300;
  282.     windH = 300;
  283.     tkInitPosition(30, 60, 300, 300);
  284.  
  285.     type = TK_RGB;
  286.     type |= (doubleBuffer) ? TK_DOUBLE : TK_SINGLE;
  287.     type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  288.     tkInitDisplayMode(type);
  289.  
  290.     if (tkInitWindow("Stars") == GL_FALSE) {
  291.     tkQuit();
  292.     }
  293.  
  294.     Init();
  295.  
  296.     tkExposeFunc(Reshape);
  297.     tkReshapeFunc(Reshape);
  298.     tkKeyDownFunc(Key);
  299.     tkIdleFunc(Idle);
  300.     tkExec();
  301. }
  302.