From 1a89978d8301803d4f90825c41c01876ea47e825 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 24 Sep 2003 20:41:53 +0000 Subject: GL_ARB_point_sprite demo --- progs/demos/spriteblast.c | 520 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 520 insertions(+) create mode 100644 progs/demos/spriteblast.c (limited to 'progs/demos/spriteblast.c') diff --git a/progs/demos/spriteblast.c b/progs/demos/spriteblast.c new file mode 100644 index 0000000000..c604536ab3 --- /dev/null +++ b/progs/demos/spriteblast.c @@ -0,0 +1,520 @@ + +/* Copyright (c) Mark J. Kilgard, 1997. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +/* This example demonstrates how to render particle effects + with OpenGL. A cloud of pinkish/orange particles explodes with the + particles bouncing off the ground. When the EXT_point_parameters + is present , the particle size is attenuated based on eye distance. */ + + +/* Modified by Brian Paul to test GL_ARB_point_sprite */ + + +#include +#include +#include +#include /* for cos(), sin(), and sqrt() */ +#ifdef _WIN32 +#include +#endif +#define GL_GLEXT_PROTOTYPES +#include + +/* Some files do not define M_PI... */ +#ifndef M_PI +#define M_PI 3.14159265 +#endif + +#if 0 /* For debugging. */ +#undef GL_EXT_point_parameters +#endif + +static GLfloat angle = -150; /* in degrees */ +static int spin = 0; +static int moving, begin; +static int newModel = 1; +static float theTime; +static int repeat = 1; +static int blend = 1; +int useMipmaps = 1; +int linearFiltering = 1; + +static GLfloat constant[3] = { .2, 0.0, 0.0 }; +static GLfloat linear[3] = { .0, .1, 0.0 }; +static GLfloat theQuad[3] = { .005, 0.1, 1/600.0 }; + +#define MAX_POINTS 2000 + +static int numPoints = 200; + +static GLfloat pointList[MAX_POINTS][3]; +static GLfloat pointTime[MAX_POINTS]; +static GLfloat pointVelocity[MAX_POINTS][2]; +static GLfloat pointDirection[MAX_POINTS][2]; +static int colorList[MAX_POINTS]; +static int animate = 1, motion = 0; + +static GLfloat colorSet[][4] = { + /* Shades of red. */ + { 0.7, 0.2, 0.4, 0.5 }, + { 0.8, 0.0, 0.7, 0.5 }, + { 1.0, 0.0, 0.0, 0.5 }, + { 0.9, 0.3, 0.6, 0.5 }, + { 1.0, 0.4, 0.0, 0.5 }, + { 1.0, 0.0, 0.5, 0.5 }, +}; + +#define NUM_COLORS (sizeof(colorSet)/sizeof(colorSet[0])) + +#define DEAD (NUM_COLORS+1) + + +/* GL */ +static GLint spritePattern[16][16] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 }, + { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0 }, + { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0 }, + { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 }, + { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 }, + { 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0 }, + { 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0 }, + { 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0 }, + { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0 }, + { 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; + + + + +#if 0 /* drand48 might be better on Unix machines */ +#define RANDOM_RANGE(lo, hi) ((lo) + (hi - lo) * drand48()) +#else +static float float_rand(void) { return rand() / (float) RAND_MAX; } +#define RANDOM_RANGE(lo, hi) ((lo) + (hi - lo) * float_rand()) +#endif + +#define MEAN_VELOCITY 3.0 +#define GRAVITY 2.0 +#define TIME_DELTA 0.025 /* The speed of time. */ + +/* Modeling units of ground extent in each X and Z direction. */ +#define EDGE 12 + +static void +makePointList(void) +{ + float angle, velocity, direction; + int i; + + motion = 1; + for (i=0; i EDGE) { + /* Particle has hit ground past the distance duration of + the particles. Mark particle as dead. */ + colorList[i] = NUM_COLORS; /* Not moving. */ + continue; + } + + pointVelocity[i][1] *= 0.8; /* 80% of previous up velocity. */ + pointTime[i] = 0.0; /* Reset the particles sense of up time. */ + } + motion = 1; + pointTime[i] += TIME_DELTA; + } + theTime += TIME_DELTA; + if (!motion && !spin) { + if (repeat) { + makePointList(); + } else { + glutIdleFunc(NULL); + } + } +} + +static void +idle(void) +{ + updatePointList(); + if (spin) { + angle += 0.3; + newModel = 1; + } + glutPostRedisplay(); +} + +static void +visible(int vis) +{ + if (vis == GLUT_VISIBLE) { + if (animate && (motion || spin)) { + glutIdleFunc(idle); + } + } else { + glutIdleFunc(NULL); + } +} + +static void +recalcModelView(void) +{ + glPopMatrix(); + glPushMatrix(); + glRotatef(angle, 0.0, 1.0, 0.0); + newModel = 0; +} + +static void +redraw(void) +{ + int i; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if (newModel) + recalcModelView(); + + glDepthMask(GL_FALSE); + + /* Draw the floor. */ +/* glEnable(GL_TEXTURE_2D);*/ + glColor3f(0.1, 0.5, 1.0); + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); + glVertex3f(-EDGE, -0.05, -EDGE); + glTexCoord2f(20.0, 0.0); + glVertex3f(EDGE, -0.05, -EDGE); + glTexCoord2f(20.0, 20.0); + glVertex3f(EDGE, -0.05, EDGE); + glTexCoord2f(0.0, 20.0); + glVertex3f(-EDGE, -0.05, EDGE); + glEnd(); + + /* Allow particles to blend with each other. */ + glDepthMask(GL_TRUE); + + if (blend) + glEnable(GL_BLEND); + + glEnable(GL_TEXTURE_2D); +#ifdef GL_ARB_point_sprite + glEnable(GL_POINT_SPRITE_ARB); +#endif + + glColor3f(1,1,1); + glBegin(GL_POINTS); + for (i=0; i