Merge branch '7.8'
[mesa.git] / progs / samples / overlay.c
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 static float Sin(float angle)
73 {
74
75 return (sinTable[(GLint)angle]);
76 }
77
78 static float Cos(float angle)
79 {
80
81 return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
82 }
83
84 static 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 static 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 static 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 static 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 static 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 static 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 static 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_TRUE;
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 }