home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 2000 April & May / AMIGA_2000_04.iso / patches / mesa3.1 / samples / overlay.c < prev    next >
C/C++ Source or Header  |  2000-01-01  |  8KB  |  379 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <math.h>
  29. #include <time.h>
  30. #include <GL/glut.h>
  31.  
  32.  
  33. #ifndef PI
  34. #define PI 3.141592657
  35. #endif
  36.  
  37.  
  38. enum {
  39.     NORMAL = 0,
  40.     WEIRD = 1
  41. };
  42.  
  43. enum {
  44.     STREAK = 0,
  45.     CIRCLE = 1
  46. };
  47.  
  48. #define MAXSTARS 400
  49. #define MAXPOS 10000
  50. #define MAXWARP 10
  51. #define MAXANGLES 6000
  52.  
  53.  
  54. typedef struct _starRec {
  55.     GLint type;
  56.     float x[2], y[2], z[2];
  57.     float offsetX, offsetY, offsetR, rotation;
  58. } starRec;
  59.  
  60.  
  61. GLenum doubleBuffer;
  62. GLint windW, windH;
  63.  
  64. GLenum flag = NORMAL, overlayInit = GL_FALSE;
  65. GLint starCount = MAXSTARS / 2;
  66. float speed = 1.0;
  67. GLint nitro = 0;
  68. starRec stars[MAXSTARS];
  69. float sinTable[MAXANGLES];
  70.  
  71.  
  72. float Sin(float angle)
  73. {
  74.  
  75.     return (sinTable[(GLint)angle]);
  76. }
  77.  
  78. float Cos(float angle)
  79. {
  80.  
  81.     return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
  82. }
  83.  
  84. void NewStar(GLint n, GLint d)
  85. {
  86.  
  87.     if (rand()%4 == 0) {
  88.     stars[n].type = CIRCLE;
  89.     } else {
  90.     stars[n].type = STREAK;
  91.     }
  92.     stars[n].x[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
  93.     stars[n].y[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
  94.     stars[n].z[0] = (float)(rand() % MAXPOS + d);
  95.     if (rand()%4 == 0 && flag == WEIRD) {
  96.     stars[n].offsetX = (float)(rand() % 100 - 100 / 2);
  97.     stars[n].offsetY = (float)(rand() % 100 - 100 / 2);
  98.     stars[n].offsetR = (float)(rand() % 25 - 25 / 2);
  99.     } else {
  100.     stars[n].offsetX = 0.0;
  101.     stars[n].offsetY = 0.0;
  102.     stars[n].offsetR = 0.0;
  103.     }
  104. }
  105.  
  106. void RotatePoint(float *x, float *y, float rotation)
  107. {
  108.     float tmpX, tmpY;
  109.  
  110.     tmpX = *x * Cos(rotation) - *y * Sin(rotation);
  111.     tmpY = *y * Cos(rotation) + *x * Sin(rotation);
  112.     *x = tmpX;
  113.     *y = tmpY;
  114. }
  115.  
  116. void MoveStars(void)
  117. {
  118.     float offset;
  119.     GLint n;
  120.  
  121.     offset = speed * 60.0;
  122.  
  123.     for (n = 0; n < starCount; n++) {
  124.     stars[n].x[1] = stars[n].x[0];
  125.     stars[n].y[1] = stars[n].y[0];
  126.     stars[n].z[1] = stars[n].z[0];
  127.     stars[n].x[0] += stars[n].offsetX;
  128.     stars[n].y[0] += stars[n].offsetY;
  129.     stars[n].z[0] -= offset;
  130.         stars[n].rotation += stars[n].offsetR;
  131.         if (stars[n].rotation > MAXANGLES) {
  132.             stars[n].rotation = 0.0;
  133.     }
  134.     }
  135. }
  136.  
  137. GLenum StarPoint(GLint n)
  138. {
  139.     float x0, y0, x1, y1, width;
  140.     GLint i;
  141.  
  142.     x0 = stars[n].x[0] * windW / stars[n].z[0];
  143.     y0 = stars[n].y[0] * windH / stars[n].z[0];
  144.     RotatePoint(&x0, &y0, stars[n].rotation);
  145.     x0 += windW / 2.0;
  146.     y0 += windH / 2.0;
  147.  
  148.     if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) {
  149.     if (stars[n].type == STREAK) {
  150.         x1 = stars[n].x[1] * windW / stars[n].z[1];
  151.         y1 = stars[n].y[1] * windH / stars[n].z[1];
  152.         RotatePoint(&x1, &y1, stars[n].rotation);
  153.         x1 += windW / 2.0;
  154.         y1 += windH / 2.0;
  155.  
  156.         glLineWidth(MAXPOS/100.0/stars[n].z[0]+1.0);
  157.         glColor3f(1.0, (MAXWARP-speed)/MAXWARP, (MAXWARP-speed)/MAXWARP);
  158.         if (fabs(x0-x1) < 1.0 && fabs(y0-y1) < 1.0) {
  159.         glBegin(GL_POINTS);
  160.             glVertex2f(x0, y0);
  161.         glEnd();
  162.         } else {
  163.         glBegin(GL_LINES);
  164.             glVertex2f(x0, y0);
  165.             glVertex2f(x1, y1);
  166.         glEnd();
  167.         }
  168.     } else {
  169.         width = MAXPOS / 10.0 / stars[n].z[0] + 1.0;
  170.         glColor3f(1.0, 0.0, 0.0);
  171.         glBegin(GL_POLYGON);
  172.         for (i = 0; i < 8; i++) {
  173.             float x = x0 + width * Cos((float)i*MAXANGLES/8.0);
  174.             float y = y0 + width * Sin((float)i*MAXANGLES/8.0);
  175.             glVertex2f(x, y);
  176.         };
  177.         glEnd();
  178.     }
  179.     return GL_TRUE;
  180.     } else {
  181.     return GL_FALSE;
  182.     }
  183. }
  184.  
  185. void ShowStars(void)
  186. {
  187.     GLint n;
  188.  
  189.     glClear(GL_COLOR_BUFFER_BIT);
  190.  
  191.     for (n = 0; n < starCount; n++) {
  192.     if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) {
  193.         if (StarPoint(n) == GL_FALSE) {
  194.         NewStar(n, MAXPOS);
  195.         }
  196.     } else {
  197.         NewStar(n, MAXPOS);
  198.     }
  199.     }
  200. }
  201.  
  202. static void Init(void)
  203. {
  204.     float angle;
  205.     GLint n;
  206.  
  207.     srand((unsigned int)time(NULL));
  208.  
  209.     for (n = 0; n < MAXSTARS; n++) {
  210.     NewStar(n, 100);
  211.     }
  212.  
  213.     angle = 0.0;
  214.     for (n = 0; n < MAXANGLES ; n++) {
  215.     sinTable[n] = sin(angle);
  216.         angle += PI / (MAXANGLES / 2.0);
  217.     }
  218.  
  219.     glClearColor(0.0, 0.0, 0.0, 0.0);
  220.  
  221.     glDisable(GL_DITHER);
  222. }
  223.  
  224. void Reshape(int width, int height)
  225. {
  226.  
  227.     windW = (GLint)width;
  228.     windH = (GLint)height;
  229.  
  230.     glutUseLayer(GLUT_OVERLAY);
  231.  
  232.     glViewport(0, 0, windW, windH);
  233.     glMatrixMode(GL_PROJECTION);
  234.     glLoadIdentity();
  235.     gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
  236.     glMatrixMode(GL_MODELVIEW);
  237.     overlayInit = GL_FALSE;
  238.  
  239.     glutUseLayer(GLUT_NORMAL);
  240.  
  241.     glViewport(0, 0, windW, windH);
  242.     glMatrixMode(GL_PROJECTION);
  243.     glLoadIdentity();
  244.     gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
  245.     glMatrixMode(GL_MODELVIEW);
  246. }
  247.  
  248. static void Key(unsigned char key, int x, int y)
  249. {
  250.  
  251.     switch (key) {
  252.       case 27:
  253.     exit(1);
  254.       case 32:
  255.     flag = (flag == NORMAL) ? WEIRD : NORMAL;
  256.     break;
  257.       case 't':
  258.     nitro = 1;
  259.     break;
  260.       default:
  261.     return;
  262.     }
  263. }
  264.  
  265. void Idle(void)
  266. {
  267.  
  268.     if (overlayInit == GL_FALSE) {
  269.     glutUseLayer(GLUT_OVERLAY);
  270.     glClear(GL_COLOR_BUFFER_BIT);
  271. /*        glColor3f(1.0, 0.0, 0.0);*/
  272.  
  273.     glIndexf( 2.0 );
  274.     glBegin(GL_POLYGON);
  275.         glVertex2i(windW/4-10, windH/4-10);
  276.         glVertex2i(windW/2-10, windH/4-10);
  277.         glVertex2i(windW/2-10, windH/2-10);
  278.         glVertex2i(windW/4-10, windH/2-10);
  279.     glEnd();
  280.  
  281.         glIndexf( 0.0 );
  282.     glBegin(GL_POLYGON);
  283.         glVertex2i(windW/4, windH/4);
  284.         glVertex2i(windW/2, windH/4);
  285.         glVertex2i(windW/2, windH/2);
  286.         glVertex2i(windW/4, windH/2);
  287.     glEnd();
  288.  
  289.         glIndexf( 1.0 );
  290.     glBegin(GL_POLYGON);
  291.         glVertex2i(windW/4+10, windH/4+10);
  292.         glVertex2i(windW/2+10, windH/4+10);
  293.         glVertex2i(windW/2+10, windH/2+10);
  294.         glVertex2i(windW/4+10, windH/2+10);
  295.     glEnd();
  296.  
  297.     glutUseLayer(GLUT_NORMAL);
  298.     overlayInit = GL_TRUE;
  299.     }
  300.  
  301.     MoveStars();
  302.     ShowStars();
  303.     if (nitro > 0) {
  304.     speed = (float)(nitro / 10) + 1.0;
  305.     if (speed > MAXWARP) {
  306.         speed = MAXWARP;
  307.     }
  308.     if (++nitro > MAXWARP*10) {
  309.         nitro = -nitro;
  310.     }
  311.     } else if (nitro < 0) {
  312.     nitro++;
  313.     speed = (float)(-nitro / 10) + 1.0;
  314.     if (speed > MAXWARP) {
  315.         speed = MAXWARP;
  316.     }
  317.     }
  318.  
  319.     glFlush();
  320.     if (doubleBuffer) {
  321.     glutSwapBuffers();
  322.     }
  323. }
  324.  
  325. static GLenum Args(int argc, char **argv)
  326. {
  327.     GLint i;
  328.  
  329.     doubleBuffer = GL_FALSE;
  330.  
  331.     for (i = 1; i < argc; i++) {
  332.     if (strcmp(argv[i], "-sb") == 0) {
  333.         doubleBuffer = GL_FALSE;
  334.     } else if (strcmp(argv[i], "-db") == 0) {
  335.         doubleBuffer = GL_TRUE;
  336.     }
  337.     }
  338.     return GL_TRUE;
  339. }
  340.  
  341. int main(int argc, char **argv)
  342. {
  343.     GLenum type;
  344.  
  345.     glutInit(&argc, argv);
  346.  
  347.     if (!glutLayerGet(GLUT_OVERLAY_POSSIBLE))
  348.     {
  349.     fprintf(stderr, "Overlay not available\n");
  350.     return(1);
  351.     }
  352.  
  353.     if (Args(argc, argv) == GL_FALSE) {
  354.     return(1);
  355.     }
  356.  
  357.     windW = 300;
  358.     windH = 300;
  359.     glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
  360.  
  361.     type = GLUT_RGB;
  362.     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  363.     glutInitDisplayMode(type);
  364.  
  365.     if (glutCreateWindow("Overlay Test") == GL_FALSE) {
  366.     return(1);
  367.     }
  368.  
  369.     glutEstablishOverlay();
  370.  
  371.     Init();
  372.  
  373.     glutReshapeFunc(Reshape);
  374.     glutKeyboardFunc(Key);
  375.     glutIdleFunc(Idle);
  376.     glutMainLoop();
  377.     return 0;
  378. }
  379.