~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to progs/demos/spriteblast.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* Copyright (c) Mark J. Kilgard, 1997.  */
 
3
 
 
4
/* This program is freely distributable without licensing fees 
 
5
   and is provided without guarantee or warrantee expressed or 
 
6
   implied. This program is -not- in the public domain. */
 
7
 
 
8
/* This example demonstrates how to render particle effects
 
9
   with OpenGL.  A cloud of pinkish/orange particles explodes with the
 
10
   particles bouncing off the ground.  When the EXT_point_parameters
 
11
   is present , the particle size is attenuated based on eye distance. */
 
12
 
 
13
 
 
14
/* Modified by Brian Paul to test GL_ARB_point_sprite */
 
15
 
 
16
 
 
17
#include <stdio.h>
 
18
#include <stdlib.h>
 
19
#include <string.h>
 
20
#include <math.h>       /* for cos(), sin(), and sqrt() */
 
21
#ifdef _WIN32
 
22
#include <windows.h>
 
23
#endif
 
24
#define GL_GLEXT_PROTOTYPES
 
25
#include <GL/glut.h>
 
26
 
 
27
/* Some <math.h> files do not define M_PI... */
 
28
#ifndef M_PI
 
29
#define M_PI 3.14159265
 
30
#endif
 
31
 
 
32
#if 0  /* For debugging. */
 
33
#undef GL_EXT_point_parameters
 
34
#endif
 
35
 
 
36
static GLfloat angle = -150;   /* in degrees */
 
37
static int spin = 0;
 
38
static int moving, begin;
 
39
static float theTime;
 
40
static int repeat = 1;
 
41
static int blend = 1;
 
42
int useMipmaps = 1;
 
43
int linearFiltering = 1;
 
44
 
 
45
static GLfloat constant[3] = { .2,  0.0,     0.0 };
 
46
static GLfloat linear[3]   = { .0,   .1,     0.0 };
 
47
static GLfloat theQuad[3]  = { .005, 0.1, 1/600.0 };
 
48
 
 
49
#define MAX_POINTS 2000
 
50
 
 
51
static int numPoints = 200;
 
52
 
 
53
static GLfloat pointList[MAX_POINTS][3];
 
54
static GLfloat pointTime[MAX_POINTS];
 
55
static GLfloat pointVelocity[MAX_POINTS][2];
 
56
static GLfloat pointDirection[MAX_POINTS][2];
 
57
static int colorList[MAX_POINTS];
 
58
static int animate = 1, motion = 0, org = 0, sprite = 1, smooth = 1;
 
59
 
 
60
static GLfloat colorSet[][4] = {
 
61
  /* Shades of red. */
 
62
  { 0.7, 0.2, 0.4, 0.5 },
 
63
  { 0.8, 0.0, 0.7, 0.5 },
 
64
  { 1.0, 0.0, 0.0, 0.5 },
 
65
  { 0.9, 0.3, 0.6, 0.5 },
 
66
  { 1.0, 0.4, 0.0, 0.5 },
 
67
  { 1.0, 0.0, 0.5, 0.5 },
 
68
};
 
69
 
 
70
#define NUM_COLORS (sizeof(colorSet)/sizeof(colorSet[0]))
 
71
 
 
72
#define DEAD (NUM_COLORS+1)
 
73
 
 
74
 
 
75
/* GL */
 
76
static GLint spritePattern[16][16] = {
 
77
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
 
78
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
 
79
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
 
80
   { 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
 
81
   { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
 
82
   { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0 },
 
83
   { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
 
84
   { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
 
85
   { 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0 },
 
86
   { 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0 },
 
87
   { 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0 },
 
88
   { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0 },
 
89
   { 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0 },
 
90
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
 
91
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
 
92
   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
 
93
};
 
94
 
 
95
 
 
96
 
 
97
 
 
98
#if 0  /* drand48 might be better on Unix machines */
 
99
#define RANDOM_RANGE(lo, hi) ((lo) + (hi - lo) * drand48())
 
100
#else
 
101
static float float_rand(void) { return rand() / (float) RAND_MAX; }
 
102
#define RANDOM_RANGE(lo, hi) ((lo) + (hi - lo) * float_rand())
 
103
#endif
 
104
 
 
105
#define MEAN_VELOCITY 3.0
 
106
#define GRAVITY 2.0
 
107
 
 
108
/* Modeling units of ground extent in each X and Z direction. */
 
109
#define EDGE 12
 
110
 
 
111
static void
 
112
makePointList(void)
 
113
{
 
114
  float angle, velocity, direction;
 
115
  int i;
 
116
 
 
117
  motion = 1;
 
118
  for (i=0; i<numPoints; i++) {
 
119
    pointList[i][0] = 0.0;
 
120
    pointList[i][1] = 0.0;
 
121
    pointList[i][2] = 0.0;
 
122
    pointTime[i] = 0.0;
 
123
    angle = (RANDOM_RANGE(60.0, 70.0)) * M_PI/180.0;
 
124
    direction = RANDOM_RANGE(0.0, 360.0) * M_PI/180.0;
 
125
    pointDirection[i][0] = cos(direction);
 
126
    pointDirection[i][1] = sin(direction);
 
127
    velocity = MEAN_VELOCITY + RANDOM_RANGE(-0.8, 1.0);
 
128
    pointVelocity[i][0] = velocity * cos(angle);
 
129
    pointVelocity[i][1] = velocity * sin(angle);
 
130
    colorList[i] = rand() % NUM_COLORS;
 
131
  }
 
132
  theTime = 0.0;
 
133
}
 
134
 
 
135
static void
 
136
updatePointList(void)
 
137
{
 
138
  float distance;
 
139
  int i;
 
140
 
 
141
  static double t0 = -1.;
 
142
  double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
 
143
  if (t0 < 0.0)
 
144
    t0 = t;
 
145
  dt = t - t0;
 
146
  t0 = t;
 
147
 
 
148
  motion = 0;
 
149
  for (i=0; i<numPoints; i++) {
 
150
    distance = pointVelocity[i][0] * theTime;
 
151
 
 
152
    /* X and Z */
 
153
    pointList[i][0] = pointDirection[i][0] * distance;
 
154
    pointList[i][2] = pointDirection[i][1] * distance;
 
155
 
 
156
    /* Z */
 
157
    pointList[i][1] =
 
158
      (pointVelocity[i][1] - 0.5 * GRAVITY * pointTime[i])*pointTime[i];
 
159
 
 
160
    /* If we hit the ground, bounce the point upward again. */
 
161
    if (pointList[i][1] <= 0.0) {
 
162
      if (distance > EDGE) {
 
163
        /* Particle has hit ground past the distance duration of
 
164
          the particles.  Mark particle as dead. */
 
165
       colorList[i] = NUM_COLORS;  /* Not moving. */
 
166
       continue;
 
167
      }
 
168
 
 
169
      pointVelocity[i][1] *= 0.8;  /* 80% of previous up velocity. */
 
170
      pointTime[i] = 0.0;  /* Reset the particles sense of up time. */
 
171
    }
 
172
    motion = 1;
 
173
    pointTime[i] += dt;
 
174
  }
 
175
  theTime += dt;
 
176
  if (!motion && !spin) {
 
177
    if (repeat) {
 
178
      makePointList();
 
179
    } else {
 
180
      glutIdleFunc(NULL);
 
181
    }
 
182
  }
 
183
}
 
184
 
 
185
static void
 
186
idle(void)
 
187
{
 
188
  updatePointList();
 
189
  if (spin) {
 
190
    angle += 0.3;
 
191
  }
 
192
  glutPostRedisplay();
 
193
}
 
194
 
 
195
static void
 
196
visible(int vis)
 
197
{
 
198
  if (vis == GLUT_VISIBLE) {
 
199
    if (animate && (motion || spin)) {
 
200
      glutIdleFunc(idle);
 
201
    }
 
202
  } else {
 
203
    glutIdleFunc(NULL);
 
204
  }
 
205
}
 
206
 
 
207
static void
 
208
redraw(void)
 
209
{
 
210
  int i;
 
211
 
 
212
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
213
 
 
214
  glPushMatrix();
 
215
  glRotatef(15.0, 1.0, 0.0, 0.0);
 
216
  glRotatef(angle, 0.0, 1.0, 0.0);
 
217
 
 
218
  glDepthMask(GL_FALSE);
 
219
 
 
220
  /* Draw the floor. */
 
221
/*  glEnable(GL_TEXTURE_2D);*/
 
222
  glColor3f(0.1, 0.5, 1.0);
 
223
  glBegin(GL_QUADS);
 
224
    glTexCoord2f(0.0, 0.0);
 
225
    glVertex3f(-EDGE, -0.05, -EDGE);
 
226
    glTexCoord2f(20.0, 0.0);
 
227
    glVertex3f(EDGE, -0.05, -EDGE);
 
228
    glTexCoord2f(20.0, 20.0);
 
229
    glVertex3f(EDGE, -0.05, EDGE);
 
230
    glTexCoord2f(0.0, 20.0);
 
231
    glVertex3f(-EDGE, -0.05, EDGE);
 
232
  glEnd();
 
233
 
 
234
  /* Allow particles to blend with each other. */
 
235
  glDepthMask(GL_TRUE);
 
236
 
 
237
  if (blend)
 
238
     glEnable(GL_BLEND);
 
239
 
 
240
  if (sprite) {
 
241
     glEnable(GL_TEXTURE_2D);
 
242
#ifdef GL_ARB_point_sprite
 
243
     glEnable(GL_POINT_SPRITE_ARB);
 
244
#endif
 
245
  }
 
246
 
 
247
  glColor3f(1,1,1);
 
248
  glBegin(GL_POINTS);
 
249
    for (i=0; i<numPoints; i++) {
 
250
      /* Draw alive particles. */
 
251
      if (colorList[i] != DEAD) {
 
252
        if (!sprite) glColor4fv(colorSet[colorList[i]]);
 
253
        glVertex3fv(pointList[i]);
 
254
      }
 
255
    }
 
256
  glEnd();
 
257
 
 
258
  glDisable(GL_TEXTURE_2D);
 
259
#ifdef GL_ARB_point_sprite
 
260
  glDisable(GL_POINT_SPRITE_ARB);
 
261
#endif
 
262
  glDisable(GL_BLEND);
 
263
 
 
264
  glPopMatrix();
 
265
 
 
266
  glutSwapBuffers();
 
267
}
 
268
 
 
269
/* ARGSUSED2 */
 
270
static void
 
271
mouse(int button, int state, int x, int y)
 
272
{
 
273
  /* Scene can be spun around Y axis using left
 
274
     mouse button movement. */
 
275
  if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
 
276
    moving = 1;
 
277
    begin = x;
 
278
  }
 
279
  if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
 
280
    moving = 0;
 
281
  }
 
282
}
 
283
 
 
284
/* ARGSUSED1 */
 
285
static void
 
286
mouseMotion(int x, int y)
 
287
{
 
288
  if (moving) {
 
289
    angle = angle + (x - begin);
 
290
    begin = x;
 
291
    glutPostRedisplay();
 
292
  }
 
293
}
 
294
 
 
295
static void
 
296
menu(int option)
 
297
{
 
298
  switch (option) {
 
299
  case 0:
 
300
    makePointList();
 
301
    break;
 
302
#ifdef GL_ARB_point_parameters
 
303
  case 1:
 
304
    glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, constant);
 
305
    break;
 
306
  case 2:
 
307
    glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, linear);
 
308
    break;
 
309
  case 3:
 
310
    glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, theQuad);
 
311
    break;
 
312
#endif
 
313
  case 4:
 
314
    blend = 1;
 
315
    break;
 
316
  case 5:
 
317
    blend = 0;
 
318
    break;
 
319
#ifdef GL_ARB_point_parameters
 
320
  case 6:
 
321
    glPointParameterfARB(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 1.0);
 
322
    break;
 
323
  case 7:
 
324
    glPointParameterfARB(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 10.0);
 
325
    break;
 
326
#endif
 
327
  case 8:
 
328
    glEnable(GL_POINT_SMOOTH);
 
329
    smooth = 1;
 
330
    break;
 
331
  case 9:
 
332
    glDisable(GL_POINT_SMOOTH);
 
333
    smooth = 0;
 
334
    break;
 
335
  case 10:
 
336
    glPointSize(4.0);
 
337
    break;
 
338
  case 11:
 
339
    glPointSize(8.0);
 
340
    break;
 
341
  case 12:
 
342
    glPointSize(16.0);
 
343
    break;
 
344
  case 13:
 
345
    spin = 1 - spin;
 
346
    if (animate && (spin || motion)) {
 
347
      glutIdleFunc(idle);
 
348
    } else {
 
349
      glutIdleFunc(NULL);
 
350
    }
 
351
    break;
 
352
  case 14:
 
353
    numPoints = 200;
 
354
    break;
 
355
  case 15:
 
356
    numPoints = 500;
 
357
    break;
 
358
  case 16:
 
359
    numPoints = 1000;
 
360
    break;
 
361
  case 17:
 
362
    numPoints = 2000;
 
363
    break;
 
364
  case 666:
 
365
    exit(0);
 
366
  }
 
367
  glutPostRedisplay();
 
368
}
 
369
 
 
370
/* ARGSUSED1 */
 
371
static void
 
372
key(unsigned char c, int x, int y)
 
373
{
 
374
  switch (c) {
 
375
  case 13:
 
376
    animate = 1 - animate;  /* toggle. */
 
377
    if (animate && (motion || spin)) {
 
378
      glutIdleFunc(idle);
 
379
    } else {
 
380
      glutIdleFunc(NULL);
 
381
    }
 
382
    break;
 
383
  case ' ':
 
384
    animate = 1;
 
385
    makePointList();
 
386
    glutIdleFunc(idle);
 
387
    break;
 
388
  case 'o':
 
389
  case 'O':
 
390
    org ^= 1;
 
391
#ifdef GL_VERSION_2_0
 
392
#ifdef GL_ARB_point_parameters
 
393
    glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN,
 
394
                      org ? GL_LOWER_LEFT : GL_UPPER_LEFT);
 
395
#endif
 
396
#endif
 
397
    glutPostRedisplay();
 
398
    break;
 
399
  case 't':
 
400
  case 'T':
 
401
    sprite ^= 1;
 
402
    glutPostRedisplay();
 
403
    break;
 
404
  case 's':
 
405
  case 'S':
 
406
    (smooth ^= 1) ? glEnable(GL_POINT_SMOOTH) : glDisable(GL_POINT_SMOOTH);
 
407
    glutPostRedisplay();
 
408
    break;
 
409
  case '0':
 
410
    glPointSize(1.0);
 
411
    glutPostRedisplay();
 
412
    break;
 
413
  case '1':
 
414
    glPointSize(2.0);
 
415
    glutPostRedisplay();
 
416
    break;
 
417
  case '2':
 
418
    glPointSize(4.0);
 
419
    glutPostRedisplay();
 
420
    break;
 
421
  case '3':
 
422
    glPointSize(8.0);
 
423
    glutPostRedisplay();
 
424
    break;
 
425
  case '4':
 
426
    glPointSize(16.0);
 
427
    glutPostRedisplay();
 
428
    break;
 
429
  case 27:
 
430
    exit(0);
 
431
  }
 
432
}
 
433
 
 
434
 
 
435
 
 
436
static void
 
437
makeSprite(void)
 
438
{
 
439
   GLubyte texture[16][16][4];
 
440
   int i, j;
 
441
 
 
442
   if (!glutExtensionSupported("GL_ARB_point_sprite")) {
 
443
      printf("Sorry, this demo requires GL_ARB_point_sprite.\n");
 
444
      exit(0);
 
445
   }
 
446
   if (!glutExtensionSupported("GL_ARB_point_parameters")) {
 
447
      printf("Sorry, this demo requires GL_ARB_point_parameters.\n");
 
448
      exit(0);
 
449
   }
 
450
 
 
451
   for (i = 0; i < 16; i++) {
 
452
      for (j = 0; j < 16; j++) {
 
453
         if (spritePattern[i][j]) {
 
454
            texture[i][j][0] = 255;
 
455
            texture[i][j][1] = 255;
 
456
            texture[i][j][2] = 255;
 
457
            texture[i][j][3] = 255;
 
458
         }
 
459
         else {
 
460
            texture[i][j][0] = 255;
 
461
            texture[i][j][1] = 0;
 
462
            texture[i][j][2] = 0;
 
463
            texture[i][j][3] = 0;
 
464
         }
 
465
      }
 
466
   }
 
467
 
 
468
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 
469
                texture);
 
470
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
471
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
472
#ifdef GL_ARB_point_sprite
 
473
   glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
 
474
#endif
 
475
}
 
476
 
 
477
 
 
478
static void
 
479
reshape(int width, int height)
 
480
{
 
481
  GLfloat h = (GLfloat) height / (GLfloat) width;
 
482
 
 
483
  glViewport(0, 0, (GLint) width, (GLint) height);
 
484
  glMatrixMode(GL_PROJECTION);
 
485
  glLoadIdentity();
 
486
  glFrustum(-1.0, 1.0, -h, h, 2.0, 30.0);
 
487
  glMatrixMode(GL_MODELVIEW);
 
488
  glLoadIdentity();
 
489
  glTranslatef(0.0, 0.0, -10.0);
 
490
}
 
491
 
 
492
int
 
493
main(int argc, char **argv)
 
494
{
 
495
  int i;
 
496
  glutInit(&argc, argv);
 
497
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
 
498
 
 
499
  for (i=1; i<argc; i++) {
 
500
    if(!strcmp("-noms", argv[i])) {
 
501
      glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
 
502
      printf("forcing no multisampling\n");
 
503
    } else if(!strcmp("-nomipmaps", argv[i])) {
 
504
      useMipmaps = 0;
 
505
    } else if(!strcmp("-nearest", argv[i])) {
 
506
      linearFiltering = 0;
 
507
    }
 
508
  }
 
509
  glutInitWindowPosition(0, 0);
 
510
  glutInitWindowSize(600,300);
 
511
  glutCreateWindow("sprite blast");
 
512
  glutReshapeFunc(reshape);
 
513
  glutDisplayFunc(redraw);
 
514
  glutMouseFunc(mouse);
 
515
  glutMotionFunc(mouseMotion);
 
516
  glutVisibilityFunc(visible);
 
517
  glutKeyboardFunc(key);
 
518
  glutCreateMenu(menu);
 
519
  glutAddMenuEntry("Reset time", 0);
 
520
  glutAddMenuEntry("Constant", 1);
 
521
  glutAddMenuEntry("Linear", 2);
 
522
  glutAddMenuEntry("Quadratic", 3);
 
523
  glutAddMenuEntry("Blend on", 4);
 
524
  glutAddMenuEntry("Blend off", 5);
 
525
  glutAddMenuEntry("Threshold 1", 6);
 
526
  glutAddMenuEntry("Threshold 10", 7);
 
527
  glutAddMenuEntry("Point smooth on", 8);
 
528
  glutAddMenuEntry("Point smooth off", 9);
 
529
  glutAddMenuEntry("Point size 4", 10);
 
530
  glutAddMenuEntry("Point size 8", 11);
 
531
  glutAddMenuEntry("Point size 16", 12);
 
532
  glutAddMenuEntry("Toggle spin", 13);
 
533
  glutAddMenuEntry("200 points ", 14);
 
534
  glutAddMenuEntry("500 points ", 15);
 
535
  glutAddMenuEntry("1000 points ", 16);
 
536
  glutAddMenuEntry("2000 points ", 17);
 
537
  glutAddMenuEntry("Quit", 666);
 
538
  glutAttachMenu(GLUT_RIGHT_BUTTON);
 
539
 
 
540
  makePointList();
 
541
  makeSprite();
 
542
 
 
543
  glShadeModel(GL_FLAT);
 
544
  glEnable(GL_DEPTH_TEST);
 
545
  glEnable(GL_POINT_SMOOTH);
 
546
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
547
  glPointSize(16.0);
 
548
#ifdef GL_ARB_point_parameters
 
549
  glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, theQuad);
 
550
#endif
 
551
 
 
552
  glutMainLoop();
 
553
  return 0;             /* ANSI C requires main to return int. */
 
554
}