132001f49Smrg/*
232001f49Smrg * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
332001f49Smrg *
432001f49Smrg * Permission to use, copy, modify, distribute, and sell this software and
532001f49Smrg * its documentation for any purpose is hereby granted without fee, provided
632001f49Smrg * that (i) the above copyright notices and this permission notice appear in
732001f49Smrg * all copies of the software and related documentation, and (ii) the name of
832001f49Smrg * Silicon Graphics may not be used in any advertising or
932001f49Smrg * publicity relating to the software without the specific, prior written
1032001f49Smrg * permission of Silicon Graphics.
1132001f49Smrg *
1232001f49Smrg * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
1332001f49Smrg * ANY KIND,
1432001f49Smrg * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
1532001f49Smrg * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
1632001f49Smrg *
1732001f49Smrg * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
1832001f49Smrg * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
1932001f49Smrg * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
2032001f49Smrg * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
2132001f49Smrg * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
2232001f49Smrg * OF THIS SOFTWARE.
2332001f49Smrg */
2432001f49Smrg
2532001f49Smrg#include <stdio.h>
2632001f49Smrg#include <string.h>
2732001f49Smrg#include <stdlib.h>
2832001f49Smrg#include <math.h>
2932001f49Smrg#include <time.h>
3032001f49Smrg#include "glut_wrap.h"
3132001f49Smrg
3232001f49Smrg
3332001f49Smrg#ifndef PI
3432001f49Smrg#define PI 3.141592657
3532001f49Smrg#endif
3632001f49Smrg
3732001f49Smrg
3832001f49Smrgenum {
3932001f49Smrg    NORMAL = 0,
4032001f49Smrg    WEIRD = 1
4132001f49Smrg};
4232001f49Smrg
4332001f49Smrgenum {
4432001f49Smrg    STREAK = 0,
4532001f49Smrg    CIRCLE = 1
4632001f49Smrg};
4732001f49Smrg
4832001f49Smrg#define MAXSTARS 400
4932001f49Smrg#define MAXPOS 10000
5032001f49Smrg#define MAXWARP 10
5132001f49Smrg#define MAXANGLES 6000
5232001f49Smrg
5332001f49Smrg
5432001f49Smrgtypedef struct _starRec {
5532001f49Smrg    GLint type;
5632001f49Smrg    float x[2], y[2], z[2];
5732001f49Smrg    float offsetX, offsetY, offsetR, rotation;
5832001f49Smrg} starRec;
5932001f49Smrg
6032001f49Smrg
6132001f49SmrgGLenum doubleBuffer;
6232001f49SmrgGLint windW, windH;
6332001f49Smrg
6432001f49SmrgGLenum flag = NORMAL, overlayInit = GL_FALSE;
6532001f49SmrgGLint starCount = MAXSTARS / 2;
6632001f49Smrgfloat speed = 1.0;
6732001f49SmrgGLint nitro = 0;
6832001f49SmrgstarRec stars[MAXSTARS];
6932001f49Smrgfloat sinTable[MAXANGLES];
7032001f49Smrg
7132001f49Smrg
7232001f49Smrgstatic float Sin(float angle)
7332001f49Smrg{
7432001f49Smrg
7532001f49Smrg    return (sinTable[(GLint)angle]);
7632001f49Smrg}
7732001f49Smrg
7832001f49Smrgstatic float Cos(float angle)
7932001f49Smrg{
8032001f49Smrg
8132001f49Smrg    return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
8232001f49Smrg}
8332001f49Smrg
8432001f49Smrgstatic void NewStar(GLint n, GLint d)
8532001f49Smrg{
8632001f49Smrg
8732001f49Smrg    if (rand()%4 == 0) {
8832001f49Smrg	stars[n].type = CIRCLE;
8932001f49Smrg    } else {
9032001f49Smrg	stars[n].type = STREAK;
9132001f49Smrg    }
9232001f49Smrg    stars[n].x[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
9332001f49Smrg    stars[n].y[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
9432001f49Smrg    stars[n].z[0] = (float)(rand() % MAXPOS + d);
9532001f49Smrg    if (rand()%4 == 0 && flag == WEIRD) {
9632001f49Smrg	stars[n].offsetX = (float)(rand() % 100 - 100 / 2);
9732001f49Smrg	stars[n].offsetY = (float)(rand() % 100 - 100 / 2);
9832001f49Smrg	stars[n].offsetR = (float)(rand() % 25 - 25 / 2);
9932001f49Smrg    } else {
10032001f49Smrg	stars[n].offsetX = 0.0;
10132001f49Smrg	stars[n].offsetY = 0.0;
10232001f49Smrg	stars[n].offsetR = 0.0;
10332001f49Smrg    }
10432001f49Smrg}
10532001f49Smrg
10632001f49Smrgstatic void RotatePoint(float *x, float *y, float rotation)
10732001f49Smrg{
10832001f49Smrg    float tmpX, tmpY;
10932001f49Smrg
11032001f49Smrg    tmpX = *x * Cos(rotation) - *y * Sin(rotation);
11132001f49Smrg    tmpY = *y * Cos(rotation) + *x * Sin(rotation);
11232001f49Smrg    *x = tmpX;
11332001f49Smrg    *y = tmpY;
11432001f49Smrg}
11532001f49Smrg
11632001f49Smrgstatic void MoveStars(void)
11732001f49Smrg{
11832001f49Smrg    float offset;
11932001f49Smrg    GLint n;
12032001f49Smrg
12132001f49Smrg    offset = speed * 60.0;
12232001f49Smrg
12332001f49Smrg    for (n = 0; n < starCount; n++) {
12432001f49Smrg	stars[n].x[1] = stars[n].x[0];
12532001f49Smrg	stars[n].y[1] = stars[n].y[0];
12632001f49Smrg	stars[n].z[1] = stars[n].z[0];
12732001f49Smrg	stars[n].x[0] += stars[n].offsetX;
12832001f49Smrg	stars[n].y[0] += stars[n].offsetY;
12932001f49Smrg	stars[n].z[0] -= offset;
13032001f49Smrg        stars[n].rotation += stars[n].offsetR;
13132001f49Smrg        if (stars[n].rotation > MAXANGLES) {
13232001f49Smrg            stars[n].rotation = 0.0;
13332001f49Smrg	}
13432001f49Smrg    }
13532001f49Smrg}
13632001f49Smrg
13732001f49Smrgstatic GLenum StarPoint(GLint n)
13832001f49Smrg{
13932001f49Smrg    float x0, y0, x1, y1, width;
14032001f49Smrg    GLint i;
14132001f49Smrg
14232001f49Smrg    x0 = stars[n].x[0] * windW / stars[n].z[0];
14332001f49Smrg    y0 = stars[n].y[0] * windH / stars[n].z[0];
14432001f49Smrg    RotatePoint(&x0, &y0, stars[n].rotation);
14532001f49Smrg    x0 += windW / 2.0;
14632001f49Smrg    y0 += windH / 2.0;
14732001f49Smrg
14832001f49Smrg    if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) {
14932001f49Smrg	if (stars[n].type == STREAK) {
15032001f49Smrg	    x1 = stars[n].x[1] * windW / stars[n].z[1];
15132001f49Smrg	    y1 = stars[n].y[1] * windH / stars[n].z[1];
15232001f49Smrg	    RotatePoint(&x1, &y1, stars[n].rotation);
15332001f49Smrg	    x1 += windW / 2.0;
15432001f49Smrg	    y1 += windH / 2.0;
15532001f49Smrg
15632001f49Smrg	    glLineWidth(MAXPOS/100.0/stars[n].z[0]+1.0);
15732001f49Smrg	    glColor3f(1.0, (MAXWARP-speed)/MAXWARP, (MAXWARP-speed)/MAXWARP);
15832001f49Smrg	    if (fabs(x0-x1) < 1.0 && fabs(y0-y1) < 1.0) {
15932001f49Smrg		glBegin(GL_POINTS);
16032001f49Smrg		    glVertex2f(x0, y0);
16132001f49Smrg		glEnd();
16232001f49Smrg	    } else {
16332001f49Smrg		glBegin(GL_LINES);
16432001f49Smrg		    glVertex2f(x0, y0);
16532001f49Smrg		    glVertex2f(x1, y1);
16632001f49Smrg		glEnd();
16732001f49Smrg	    }
16832001f49Smrg	} else {
16932001f49Smrg	    width = MAXPOS / 10.0 / stars[n].z[0] + 1.0;
17032001f49Smrg	    glColor3f(1.0, 0.0, 0.0);
17132001f49Smrg	    glBegin(GL_POLYGON);
17232001f49Smrg		for (i = 0; i < 8; i++) {
17332001f49Smrg		    float x = x0 + width * Cos((float)i*MAXANGLES/8.0);
17432001f49Smrg		    float y = y0 + width * Sin((float)i*MAXANGLES/8.0);
17532001f49Smrg		    glVertex2f(x, y);
17632001f49Smrg		};
17732001f49Smrg	    glEnd();
17832001f49Smrg	}
17932001f49Smrg	return GL_TRUE;
18032001f49Smrg    } else {
18132001f49Smrg	return GL_FALSE;
18232001f49Smrg    }
18332001f49Smrg}
18432001f49Smrg
18532001f49Smrgstatic void ShowStars(void)
18632001f49Smrg{
18732001f49Smrg    GLint n;
18832001f49Smrg
18932001f49Smrg    glClear(GL_COLOR_BUFFER_BIT);
19032001f49Smrg
19132001f49Smrg    for (n = 0; n < starCount; n++) {
19232001f49Smrg	if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) {
19332001f49Smrg	    if (StarPoint(n) == GL_FALSE) {
19432001f49Smrg		NewStar(n, MAXPOS);
19532001f49Smrg	    }
19632001f49Smrg	} else {
19732001f49Smrg	    NewStar(n, MAXPOS);
19832001f49Smrg	}
19932001f49Smrg    }
20032001f49Smrg}
20132001f49Smrg
20232001f49Smrgstatic void Init(void)
20332001f49Smrg{
20432001f49Smrg    float angle;
20532001f49Smrg    GLint n;
20632001f49Smrg
20732001f49Smrg    srand((unsigned int)time(NULL));
20832001f49Smrg
20932001f49Smrg    for (n = 0; n < MAXSTARS; n++) {
21032001f49Smrg	NewStar(n, 100);
21132001f49Smrg    }
21232001f49Smrg
21332001f49Smrg    angle = 0.0;
21432001f49Smrg    for (n = 0; n < MAXANGLES ; n++) {
21532001f49Smrg	sinTable[n] = sin(angle);
21632001f49Smrg        angle += PI / (MAXANGLES / 2.0);
21732001f49Smrg    }
21832001f49Smrg
21932001f49Smrg    glClearColor(0.0, 0.0, 0.0, 0.0);
22032001f49Smrg
22132001f49Smrg    glDisable(GL_DITHER);
22232001f49Smrg}
22332001f49Smrg
22432001f49Smrgstatic void Reshape(int width, int height)
22532001f49Smrg{
22632001f49Smrg
22732001f49Smrg    windW = (GLint)width;
22832001f49Smrg    windH = (GLint)height;
22932001f49Smrg
23032001f49Smrg    glutUseLayer(GLUT_OVERLAY);
23132001f49Smrg
23232001f49Smrg    glViewport(0, 0, windW, windH);
23332001f49Smrg    glMatrixMode(GL_PROJECTION);
23432001f49Smrg    glLoadIdentity();
23532001f49Smrg    gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
23632001f49Smrg    glMatrixMode(GL_MODELVIEW);
23732001f49Smrg    overlayInit = GL_FALSE;
23832001f49Smrg
23932001f49Smrg    glutUseLayer(GLUT_NORMAL);
24032001f49Smrg
24132001f49Smrg    glViewport(0, 0, windW, windH);
24232001f49Smrg    glMatrixMode(GL_PROJECTION);
24332001f49Smrg    glLoadIdentity();
24432001f49Smrg    gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
24532001f49Smrg    glMatrixMode(GL_MODELVIEW);
24632001f49Smrg}
24732001f49Smrg
24832001f49Smrgstatic void Key(unsigned char key, int x, int y)
24932001f49Smrg{
25032001f49Smrg
25132001f49Smrg    switch (key) {
25232001f49Smrg      case 27:
25332001f49Smrg	exit(1);
25432001f49Smrg      case 32:
25532001f49Smrg	flag = (flag == NORMAL) ? WEIRD : NORMAL;
25632001f49Smrg	break;
25732001f49Smrg      case 't':
25832001f49Smrg	nitro = 1;
25932001f49Smrg	break;
26032001f49Smrg      default:
26132001f49Smrg	return;
26232001f49Smrg    }
26332001f49Smrg}
26432001f49Smrg
26532001f49Smrgstatic void Idle(void)
26632001f49Smrg{
26732001f49Smrg
26832001f49Smrg    if (overlayInit == GL_FALSE) {
26932001f49Smrg	glutUseLayer(GLUT_OVERLAY);
27032001f49Smrg	glClear(GL_COLOR_BUFFER_BIT);
27132001f49Smrg/*	    glColor3f(1.0, 0.0, 0.0);*/
27232001f49Smrg
27332001f49Smrg	glIndexf( 2.0 );
27432001f49Smrg	glBegin(GL_POLYGON);
27532001f49Smrg	    glVertex2i(windW/4-10, windH/4-10);
27632001f49Smrg	    glVertex2i(windW/2-10, windH/4-10);
27732001f49Smrg	    glVertex2i(windW/2-10, windH/2-10);
27832001f49Smrg	    glVertex2i(windW/4-10, windH/2-10);
27932001f49Smrg	glEnd();
28032001f49Smrg
28132001f49Smrg        glIndexf( 0.0 );
28232001f49Smrg	glBegin(GL_POLYGON);
28332001f49Smrg	    glVertex2i(windW/4, windH/4);
28432001f49Smrg	    glVertex2i(windW/2, windH/4);
28532001f49Smrg	    glVertex2i(windW/2, windH/2);
28632001f49Smrg	    glVertex2i(windW/4, windH/2);
28732001f49Smrg	glEnd();
28832001f49Smrg
28932001f49Smrg        glIndexf( 1.0 );
29032001f49Smrg	glBegin(GL_POLYGON);
29132001f49Smrg	    glVertex2i(windW/4+10, windH/4+10);
29232001f49Smrg	    glVertex2i(windW/2+10, windH/4+10);
29332001f49Smrg	    glVertex2i(windW/2+10, windH/2+10);
29432001f49Smrg	    glVertex2i(windW/4+10, windH/2+10);
29532001f49Smrg	glEnd();
29632001f49Smrg
29732001f49Smrg	glutUseLayer(GLUT_NORMAL);
29832001f49Smrg	overlayInit = GL_TRUE;
29932001f49Smrg    }
30032001f49Smrg
30132001f49Smrg    MoveStars();
30232001f49Smrg    ShowStars();
30332001f49Smrg    if (nitro > 0) {
30432001f49Smrg	speed = (float)(nitro / 10) + 1.0;
30532001f49Smrg	if (speed > MAXWARP) {
30632001f49Smrg	    speed = MAXWARP;
30732001f49Smrg	}
30832001f49Smrg	if (++nitro > MAXWARP*10) {
30932001f49Smrg	    nitro = -nitro;
31032001f49Smrg	}
31132001f49Smrg    } else if (nitro < 0) {
31232001f49Smrg	nitro++;
31332001f49Smrg	speed = (float)(-nitro / 10) + 1.0;
31432001f49Smrg	if (speed > MAXWARP) {
31532001f49Smrg	    speed = MAXWARP;
31632001f49Smrg	}
31732001f49Smrg    }
31832001f49Smrg
31932001f49Smrg    glFlush();
32032001f49Smrg    if (doubleBuffer) {
32132001f49Smrg	glutSwapBuffers();
32232001f49Smrg    }
32332001f49Smrg}
32432001f49Smrg
32532001f49Smrgstatic GLenum Args(int argc, char **argv)
32632001f49Smrg{
32732001f49Smrg    GLint i;
32832001f49Smrg
32932001f49Smrg    doubleBuffer = GL_TRUE;
33032001f49Smrg
33132001f49Smrg    for (i = 1; i < argc; i++) {
33232001f49Smrg	if (strcmp(argv[i], "-sb") == 0) {
33332001f49Smrg	    doubleBuffer = GL_FALSE;
33432001f49Smrg	} else if (strcmp(argv[i], "-db") == 0) {
33532001f49Smrg	    doubleBuffer = GL_TRUE;
33632001f49Smrg	}
33732001f49Smrg    }
33832001f49Smrg    return GL_TRUE;
33932001f49Smrg}
34032001f49Smrg
34132001f49Smrgint main(int argc, char **argv)
34232001f49Smrg{
34332001f49Smrg    GLenum type;
34432001f49Smrg
34532001f49Smrg    glutInit(&argc, argv);
34632001f49Smrg
34732001f49Smrg    if (!glutLayerGet(GLUT_OVERLAY_POSSIBLE))
34832001f49Smrg    {
34932001f49Smrg	fprintf(stderr, "Overlay not available\n");
35032001f49Smrg	return(1);
35132001f49Smrg    }
35232001f49Smrg
35332001f49Smrg    if (Args(argc, argv) == GL_FALSE) {
35432001f49Smrg	return(1);
35532001f49Smrg    }
35632001f49Smrg
35732001f49Smrg    windW = 300;
35832001f49Smrg    windH = 300;
35932001f49Smrg    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
36032001f49Smrg
36132001f49Smrg    type = GLUT_RGB;
36232001f49Smrg    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
36332001f49Smrg    glutInitDisplayMode(type);
36432001f49Smrg
36532001f49Smrg    if (glutCreateWindow("Overlay Test") == GL_FALSE) {
36632001f49Smrg	return(1);
36732001f49Smrg    }
36832001f49Smrg
36932001f49Smrg    glutEstablishOverlay();
37032001f49Smrg
37132001f49Smrg    Init();
37232001f49Smrg
37332001f49Smrg    glutReshapeFunc(Reshape);
37432001f49Smrg    glutKeyboardFunc(Key);
37532001f49Smrg    glutIdleFunc(Idle);
37632001f49Smrg    glutMainLoop();
37732001f49Smrg	return 0;
37832001f49Smrg}
379