blob: 570c3e19f9d2228e915277e4b00bc1c062a3976b [file] [log] [blame]
jtgafb833d1999-08-19 00:55:39 +00001/*
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 <GL/glut.h>
30
31
32#ifndef PI
33#define PI 3.141592657
34#endif
35
36enum {
37 NORMAL = 0,
38 WEIRD = 1
39};
40
41enum {
42 STREAK = 0,
43 CIRCLE = 1
44};
45
46#define MAXSTARS 400
47#define MAXPOS 10000
48#define MAXWARP 10
49#define MAXANGLES 6000
50
51
52typedef struct _starRec {
53 GLint type;
54 float x[2], y[2], z[2];
55 float offsetX, offsetY, offsetR, rotation;
56} starRec;
57
58
59GLenum doubleBuffer;
60GLint windW, windH;
61
62GLenum flag = NORMAL;
63GLint starCount = MAXSTARS / 2;
64float speed = 1.0;
65GLint nitro = 0;
66starRec stars[MAXSTARS];
67float sinTable[MAXANGLES];
68
69
70float Sin(float angle)
71{
72
73 return (sinTable[(GLint)angle]);
74}
75
76float Cos(float angle)
77{
78
79 return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
80}
81
82void NewStar(GLint n, GLint d)
83{
84
85 if (rand()%4 == 0) {
86 stars[n].type = CIRCLE;
87 } else {
88 stars[n].type = STREAK;
89 }
90 stars[n].x[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
91 stars[n].y[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
92 stars[n].z[0] = (float)(rand() % MAXPOS + d);
93 if (rand()%4 == 0 && flag == WEIRD) {
94 stars[n].offsetX = (float)(rand() % 100 - 100 / 2);
95 stars[n].offsetY = (float)(rand() % 100 - 100 / 2);
96 stars[n].offsetR = (float)(rand() % 25 - 25 / 2);
97 } else {
98 stars[n].offsetX = 0.0;
99 stars[n].offsetY = 0.0;
100 stars[n].offsetR = 0.0;
101 }
102}
103
104void RotatePoint(float *x, float *y, float rotation)
105{
106 float tmpX, tmpY;
107
108 tmpX = *x * Cos(rotation) - *y * Sin(rotation);
109 tmpY = *y * Cos(rotation) + *x * Sin(rotation);
110 *x = tmpX;
111 *y = tmpY;
112}
113
114void MoveStars(void)
115{
116 float offset;
117 GLint n;
118
119 offset = speed * 60.0;
120
121 for (n = 0; n < starCount; n++) {
122 stars[n].x[1] = stars[n].x[0];
123 stars[n].y[1] = stars[n].y[0];
124 stars[n].z[1] = stars[n].z[0];
125 stars[n].x[0] += stars[n].offsetX;
126 stars[n].y[0] += stars[n].offsetY;
127 stars[n].z[0] -= offset;
128 stars[n].rotation += stars[n].offsetR;
129 if (stars[n].rotation > MAXANGLES) {
130 stars[n].rotation = 0.0;
131 }
Brian Paul7b9ff482001-05-09 17:14:19 +0000132 else if (stars[n].rotation < 0.0) {
133 stars[n].rotation += 360.0;
134 }
jtgafb833d1999-08-19 00:55:39 +0000135 }
136}
137
138GLenum StarPoint(GLint n)
139{
140 float x0, y0, x1, y1, width;
141 GLint i;
142
143 x0 = stars[n].x[0] * windW / stars[n].z[0];
144 y0 = stars[n].y[0] * windH / stars[n].z[0];
145 RotatePoint(&x0, &y0, stars[n].rotation);
146 x0 += windW / 2.0;
147 y0 += windH / 2.0;
148
149 if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) {
150 if (stars[n].type == STREAK) {
151 x1 = stars[n].x[1] * windW / stars[n].z[1];
152 y1 = stars[n].y[1] * windH / stars[n].z[1];
153 RotatePoint(&x1, &y1, stars[n].rotation);
154 x1 += windW / 2.0;
155 y1 += windH / 2.0;
156
157 glLineWidth(MAXPOS/100.0/stars[n].z[0]+1.0);
158 glColor3f(1.0, (MAXWARP-speed)/MAXWARP, (MAXWARP-speed)/MAXWARP);
159 if (fabs(x0-x1) < 1.0 && fabs(y0-y1) < 1.0) {
160 glBegin(GL_POINTS);
161 glVertex2f(x0, y0);
162 glEnd();
163 } else {
164 glBegin(GL_LINES);
165 glVertex2f(x0, y0);
166 glVertex2f(x1, y1);
167 glEnd();
168 }
169 } else {
170 width = MAXPOS / 10.0 / stars[n].z[0] + 1.0;
171 glColor3f(1.0, 0.0, 0.0);
172 glBegin(GL_POLYGON);
173 for (i = 0; i < 8; i++) {
174 float x = x0 + width * Cos((float)i*MAXANGLES/8.0);
175 float y = y0 + width * Sin((float)i*MAXANGLES/8.0);
176 glVertex2f(x, y);
177 };
178 glEnd();
179 }
180 return GL_TRUE;
181 } else {
182 return GL_FALSE;
183 }
184}
185
186void ShowStars(void)
187{
188 GLint n;
189
190 glClear(GL_COLOR_BUFFER_BIT);
191
192 for (n = 0; n < starCount; n++) {
193 if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) {
194 if (StarPoint(n) == GL_FALSE) {
195 NewStar(n, MAXPOS);
196 }
197 } else {
198 NewStar(n, MAXPOS);
199 }
200 }
201}
202
203static void Init(void)
204{
205 float angle;
206 GLint n;
207
208 srand((unsigned int) glutGet(GLUT_ELAPSED_TIME) );
209
210 for (n = 0; n < MAXSTARS; n++) {
211 NewStar(n, 100);
212 }
213
214 angle = 0.0;
215 for (n = 0; n < MAXANGLES ; n++) {
216 sinTable[n] = sin(angle);
217 angle += PI / (MAXANGLES / 2.0);
218 }
219
220 glClearColor(0.0, 0.0, 0.0, 0.0);
221
222 glDisable(GL_DITHER);
223}
224
225void Reshape(int width, int height)
226{
227
228 windW = (GLint)width;
229 windH = (GLint)height;
230
231 glViewport(0, 0, windW, windH);
232
233 glMatrixMode(GL_PROJECTION);
234 glLoadIdentity();
235 gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
236 glMatrixMode(GL_MODELVIEW);
237}
238
239static void Key(unsigned char key, int x, int y)
240{
241
242 switch (key) {
243 case 27:
244 exit(1);
245 case 32:
246 flag = (flag == NORMAL) ? WEIRD : NORMAL;
247 break;
248 case 't':
249 nitro = 1;
250 break;
251 default:
252 return;
253 }
254}
255
256void Draw(void)
257{
258
259 MoveStars();
260 ShowStars();
261 if (nitro > 0) {
262 speed = (float)(nitro / 10) + 1.0;
263 if (speed > MAXWARP) {
264 speed = MAXWARP;
265 }
266 if (++nitro > MAXWARP*10) {
267 nitro = -nitro;
268 }
269 } else if (nitro < 0) {
270 nitro++;
271 speed = (float)(-nitro / 10) + 1.0;
272 if (speed > MAXWARP) {
273 speed = MAXWARP;
274 }
275 }
276
277 glFlush();
278 if (doubleBuffer) {
279 glutSwapBuffers();
280 }
281}
282
283static GLenum Args(int argc, char **argv)
284{
285 GLint i;
286
Gareth Hughesba58a662000-10-27 02:49:17 +0000287 doubleBuffer = GL_TRUE;
jtgafb833d1999-08-19 00:55:39 +0000288
289 for (i = 1; i < argc; i++) {
290 if (strcmp(argv[i], "-sb") == 0) {
291 doubleBuffer = GL_FALSE;
292 } else if (strcmp(argv[i], "-db") == 0) {
293 doubleBuffer = GL_TRUE;
294 }
295 }
296 return GL_TRUE;
297}
298
299void GLUTCALLBACK glut_post_redisplay_p(void)
300{
301 glutPostRedisplay();
302}
303
304int main(int argc, char **argv)
305{
306 GLenum type;
307
308 glutInit(&argc, argv);
309
310 if (Args(argc, argv) == GL_FALSE) {
311 exit(1);
312 }
313
314 windW = 300;
315 windH = 300;
316 glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
317
318 type = GLUT_RGB;
319 type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
320 glutInitDisplayMode(type);
321
322 if (glutCreateWindow("Stars") == GL_FALSE) {
323 exit(1);
324 }
325
326 Init();
327
328 glutReshapeFunc(Reshape);
329 glutKeyboardFunc(Key);
330 glutDisplayFunc(Draw);
331 glutIdleFunc(glut_post_redisplay_p);
332 glutMainLoop();
333 return 0;
334}