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 "glut_wrap.h" 31 32 33#ifndef PI 34#define PI 3.141592657 35#endif 36 37 38enum { 39 NORMAL = 0, 40 WEIRD = 1 41}; 42 43enum { 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 54typedef struct _starRec { 55 GLint type; 56 float x[2], y[2], z[2]; 57 float offsetX, offsetY, offsetR, rotation; 58} starRec; 59 60 61GLenum doubleBuffer; 62GLint windW, windH; 63 64GLenum flag = NORMAL, overlayInit = GL_FALSE; 65GLint starCount = MAXSTARS / 2; 66float speed = 1.0; 67GLint nitro = 0; 68starRec stars[MAXSTARS]; 69float sinTable[MAXANGLES]; 70 71 72static float Sin(float angle) 73{ 74 75 return (sinTable[(GLint)angle]); 76} 77 78static float Cos(float angle) 79{ 80 81 return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]); 82} 83 84static 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 106static 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 116static 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 137static 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 185static 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 202static 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 224static 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 248static 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 265static 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 325static 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 341int 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