aboutsummaryrefslogtreecommitdiff
path: root/progs/samples/overlay.c
diff options
context:
space:
mode:
Diffstat (limited to 'progs/samples/overlay.c')
-rw-r--r--progs/samples/overlay.c378
1 files changed, 378 insertions, 0 deletions
diff --git a/progs/samples/overlay.c b/progs/samples/overlay.c
new file mode 100644
index 000000000..23b5a4793
--- /dev/null
+++ b/progs/samples/overlay.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+#include <GL/glut.h>
+
+
+#ifndef PI
+#define PI 3.141592657
+#endif
+
+
+enum {
+ NORMAL = 0,
+ WEIRD = 1
+};
+
+enum {
+ STREAK = 0,
+ CIRCLE = 1
+};
+
+#define MAXSTARS 400
+#define MAXPOS 10000
+#define MAXWARP 10
+#define MAXANGLES 6000
+
+
+typedef struct _starRec {
+ GLint type;
+ float x[2], y[2], z[2];
+ float offsetX, offsetY, offsetR, rotation;
+} starRec;
+
+
+GLenum doubleBuffer;
+GLint windW, windH;
+
+GLenum flag = NORMAL, overlayInit = GL_FALSE;
+GLint starCount = MAXSTARS / 2;
+float speed = 1.0;
+GLint nitro = 0;
+starRec stars[MAXSTARS];
+float sinTable[MAXANGLES];
+
+
+float Sin(float angle)
+{
+
+ return (sinTable[(GLint)angle]);
+}
+
+float Cos(float angle)
+{
+
+ return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
+}
+
+void NewStar(GLint n, GLint d)
+{
+
+ if (rand()%4 == 0) {
+ stars[n].type = CIRCLE;
+ } else {
+ stars[n].type = STREAK;
+ }
+ stars[n].x[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
+ stars[n].y[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
+ stars[n].z[0] = (float)(rand() % MAXPOS + d);
+ if (rand()%4 == 0 && flag == WEIRD) {
+ stars[n].offsetX = (float)(rand() % 100 - 100 / 2);
+ stars[n].offsetY = (float)(rand() % 100 - 100 / 2);
+ stars[n].offsetR = (float)(rand() % 25 - 25 / 2);
+ } else {
+ stars[n].offsetX = 0.0;
+ stars[n].offsetY = 0.0;
+ stars[n].offsetR = 0.0;
+ }
+}
+
+void RotatePoint(float *x, float *y, float rotation)
+{
+ float tmpX, tmpY;
+
+ tmpX = *x * Cos(rotation) - *y * Sin(rotation);
+ tmpY = *y * Cos(rotation) + *x * Sin(rotation);
+ *x = tmpX;
+ *y = tmpY;
+}
+
+void MoveStars(void)
+{
+ float offset;
+ GLint n;
+
+ offset = speed * 60.0;
+
+ for (n = 0; n < starCount; n++) {
+ stars[n].x[1] = stars[n].x[0];
+ stars[n].y[1] = stars[n].y[0];
+ stars[n].z[1] = stars[n].z[0];
+ stars[n].x[0] += stars[n].offsetX;
+ stars[n].y[0] += stars[n].offsetY;
+ stars[n].z[0] -= offset;
+ stars[n].rotation += stars[n].offsetR;
+ if (stars[n].rotation > MAXANGLES) {
+ stars[n].rotation = 0.0;
+ }
+ }
+}
+
+GLenum StarPoint(GLint n)
+{
+ float x0, y0, x1, y1, width;
+ GLint i;
+
+ x0 = stars[n].x[0] * windW / stars[n].z[0];
+ y0 = stars[n].y[0] * windH / stars[n].z[0];
+ RotatePoint(&x0, &y0, stars[n].rotation);
+ x0 += windW / 2.0;
+ y0 += windH / 2.0;
+
+ if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) {
+ if (stars[n].type == STREAK) {
+ x1 = stars[n].x[1] * windW / stars[n].z[1];
+ y1 = stars[n].y[1] * windH / stars[n].z[1];
+ RotatePoint(&x1, &y1, stars[n].rotation);
+ x1 += windW / 2.0;
+ y1 += windH / 2.0;
+
+ glLineWidth(MAXPOS/100.0/stars[n].z[0]+1.0);
+ glColor3f(1.0, (MAXWARP-speed)/MAXWARP, (MAXWARP-speed)/MAXWARP);
+ if (fabs(x0-x1) < 1.0 && fabs(y0-y1) < 1.0) {
+ glBegin(GL_POINTS);
+ glVertex2f(x0, y0);
+ glEnd();
+ } else {
+ glBegin(GL_LINES);
+ glVertex2f(x0, y0);
+ glVertex2f(x1, y1);
+ glEnd();
+ }
+ } else {
+ width = MAXPOS / 10.0 / stars[n].z[0] + 1.0;
+ glColor3f(1.0, 0.0, 0.0);
+ glBegin(GL_POLYGON);
+ for (i = 0; i < 8; i++) {
+ float x = x0 + width * Cos((float)i*MAXANGLES/8.0);
+ float y = y0 + width * Sin((float)i*MAXANGLES/8.0);
+ glVertex2f(x, y);
+ };
+ glEnd();
+ }
+ return GL_TRUE;
+ } else {
+ return GL_FALSE;
+ }
+}
+
+void ShowStars(void)
+{
+ GLint n;
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ for (n = 0; n < starCount; n++) {
+ if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) {
+ if (StarPoint(n) == GL_FALSE) {
+ NewStar(n, MAXPOS);
+ }
+ } else {
+ NewStar(n, MAXPOS);
+ }
+ }
+}
+
+static void Init(void)
+{
+ float angle;
+ GLint n;
+
+ srand((unsigned int)time(NULL));
+
+ for (n = 0; n < MAXSTARS; n++) {
+ NewStar(n, 100);
+ }
+
+ angle = 0.0;
+ for (n = 0; n < MAXANGLES ; n++) {
+ sinTable[n] = sin(angle);
+ angle += PI / (MAXANGLES / 2.0);
+ }
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+
+ glDisable(GL_DITHER);
+}
+
+void Reshape(int width, int height)
+{
+
+ windW = (GLint)width;
+ windH = (GLint)height;
+
+ glutUseLayer(GLUT_OVERLAY);
+
+ glViewport(0, 0, windW, windH);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
+ glMatrixMode(GL_MODELVIEW);
+ overlayInit = GL_FALSE;
+
+ glutUseLayer(GLUT_NORMAL);
+
+ glViewport(0, 0, windW, windH);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
+ glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+ switch (key) {
+ case 27:
+ exit(1);
+ case 32:
+ flag = (flag == NORMAL) ? WEIRD : NORMAL;
+ break;
+ case 't':
+ nitro = 1;
+ break;
+ default:
+ return;
+ }
+}
+
+void Idle(void)
+{
+
+ if (overlayInit == GL_FALSE) {
+ glutUseLayer(GLUT_OVERLAY);
+ glClear(GL_COLOR_BUFFER_BIT);
+/* glColor3f(1.0, 0.0, 0.0);*/
+
+ glIndexf( 2.0 );
+ glBegin(GL_POLYGON);
+ glVertex2i(windW/4-10, windH/4-10);
+ glVertex2i(windW/2-10, windH/4-10);
+ glVertex2i(windW/2-10, windH/2-10);
+ glVertex2i(windW/4-10, windH/2-10);
+ glEnd();
+
+ glIndexf( 0.0 );
+ glBegin(GL_POLYGON);
+ glVertex2i(windW/4, windH/4);
+ glVertex2i(windW/2, windH/4);
+ glVertex2i(windW/2, windH/2);
+ glVertex2i(windW/4, windH/2);
+ glEnd();
+
+ glIndexf( 1.0 );
+ glBegin(GL_POLYGON);
+ glVertex2i(windW/4+10, windH/4+10);
+ glVertex2i(windW/2+10, windH/4+10);
+ glVertex2i(windW/2+10, windH/2+10);
+ glVertex2i(windW/4+10, windH/2+10);
+ glEnd();
+
+ glutUseLayer(GLUT_NORMAL);
+ overlayInit = GL_TRUE;
+ }
+
+ MoveStars();
+ ShowStars();
+ if (nitro > 0) {
+ speed = (float)(nitro / 10) + 1.0;
+ if (speed > MAXWARP) {
+ speed = MAXWARP;
+ }
+ if (++nitro > MAXWARP*10) {
+ nitro = -nitro;
+ }
+ } else if (nitro < 0) {
+ nitro++;
+ speed = (float)(-nitro / 10) + 1.0;
+ if (speed > MAXWARP) {
+ speed = MAXWARP;
+ }
+ }
+
+ glFlush();
+ if (doubleBuffer) {
+ glutSwapBuffers();
+ }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+ GLint i;
+
+ doubleBuffer = GL_TRUE;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-sb") == 0) {
+ doubleBuffer = GL_FALSE;
+ } else if (strcmp(argv[i], "-db") == 0) {
+ doubleBuffer = GL_TRUE;
+ }
+ }
+ return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+ GLenum type;
+
+ glutInit(&argc, argv);
+
+ if (!glutLayerGet(GLUT_OVERLAY_POSSIBLE))
+ {
+ fprintf(stderr, "Overlay not available\n");
+ return(1);
+ }
+
+ if (Args(argc, argv) == GL_FALSE) {
+ return(1);
+ }
+
+ windW = 300;
+ windH = 300;
+ glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+ type = GLUT_RGB;
+ type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+ glutInitDisplayMode(type);
+
+ if (glutCreateWindow("Overlay Test") == GL_FALSE) {
+ return(1);
+ }
+
+ glutEstablishOverlay();
+
+ Init();
+
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutIdleFunc(Idle);
+ glutMainLoop();
+ return 0;
+}