mirror of
https://git.code.sf.net/p/quake/quakeforge-old
synced 2024-11-21 19:32:30 +00:00
Here's the fireball code I promised, implemented from an email which told
me pretty much how. It's a meshing of the GL flashblend bubble and the particle engine. More emphasis on dlights though. This code should be very similar to an effect that was in QL. It was described to me in very explicit detail in an email. It's probably based on the QL source but is a legitimate clean-room implementation. The email described how to make the flame trail found in newer QL too but I've not decided whether or not to code that yet - I think I can do better instead by adding smoke.
This commit is contained in:
parent
9993d2c301
commit
07d8d044b9
3 changed files with 193 additions and 6 deletions
|
@ -970,6 +970,7 @@ R_RenderScene ( void ) {
|
|||
GL_DisableMultitexture();
|
||||
|
||||
R_RenderDlights ();
|
||||
R_DrawFireballs ();
|
||||
R_DrawParticles ();
|
||||
|
||||
#ifdef GLTEST
|
||||
|
|
|
@ -37,10 +37,9 @@
|
|||
#include <console.h>
|
||||
#include <server.h>
|
||||
|
||||
#define MAX_PARTICLES 2048 // default max # of particles at one
|
||||
// time
|
||||
#define ABSOLUTE_MIN_PARTICLES 512 // no fewer than this no matter what's
|
||||
// on the command line
|
||||
#define MAX_PARTICLES 2048 // max particles at once
|
||||
#define ABSOLUTE_MIN_PARTICLES 512 // min particle clamp
|
||||
#define MAX_FIREBALLS 128 // rocket flames
|
||||
|
||||
int ramp1[8] = {0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61};
|
||||
int ramp2[8] = {0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66};
|
||||
|
@ -56,6 +55,8 @@ vec3_t r_pright, r_pup, r_ppn;
|
|||
|
||||
extern cvar_t *gl_particles;
|
||||
|
||||
fball_t r_fireballs[MAX_FIREBALLS];
|
||||
|
||||
/*
|
||||
===============
|
||||
R_InitParticles
|
||||
|
@ -611,6 +612,7 @@ R_RocketTrail (vec3_t start, vec3_t end, int type)
|
|||
|
||||
switch (type) {
|
||||
case 0: // rocket trail
|
||||
R_FireballTrail (start, end);
|
||||
p->ramp = (rand()&3);
|
||||
p->color = ramp3[(int)p->ramp];
|
||||
p->type = pt_fire;
|
||||
|
@ -861,3 +863,164 @@ void R_DrawParticles (void)
|
|||
} // if (gl_particles->value)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
R_FireballTrail
|
||||
|
||||
Nifty ball of fire GL effect. Kinda a meshing of the dlight and
|
||||
particle engine code.
|
||||
*/
|
||||
void
|
||||
R_FireballTrail (vec3_t start, vec3_t end)
|
||||
{
|
||||
float len;
|
||||
fball_t *f;
|
||||
vec3_t vec;
|
||||
|
||||
VectorSubtract (end, start, vec);
|
||||
len = VectorNormalize (vec);
|
||||
|
||||
if (len)
|
||||
{
|
||||
f = R_AllocFireball (0);
|
||||
VectorCopy (end, f->origin);
|
||||
VectorCopy (start, f->owner);
|
||||
f->size = 20;
|
||||
f->die = cl.time + 0.5;
|
||||
f->decay = -1;
|
||||
f->color[0] = 0.9;
|
||||
f->color[1] = 0.7;
|
||||
f->color[2] = 0.3;
|
||||
f->color[3] = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
R_AllocFireball
|
||||
|
||||
Clears out and returns a new fireball
|
||||
*/
|
||||
fball_t *
|
||||
R_AllocFireball (int key)
|
||||
{
|
||||
int i;
|
||||
fball_t *f;
|
||||
|
||||
if (key) // first try to find/reuse a keyed spot
|
||||
{
|
||||
f = r_fireballs;
|
||||
for (i = 0; i < MAX_FIREBALLS; i++, f++)
|
||||
if (f->key == key)
|
||||
{
|
||||
memset (f, 0, sizeof(*f));
|
||||
f->key = key;
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
f = r_fireballs; // no match, look for a free spot
|
||||
for (i = 0; i < MAX_FIREBALLS; i++, f++)
|
||||
{
|
||||
if (f->die > cl.time)
|
||||
{
|
||||
memset (f, 0, sizeof(*f));
|
||||
f->key = key;
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
f = &r_fireballs[0];
|
||||
memset (f, 0, sizeof(*f));
|
||||
f->key = key;
|
||||
return f;
|
||||
}
|
||||
|
||||
/*
|
||||
R_DrawFireball
|
||||
|
||||
draws one fireball - probably never need to call this directly
|
||||
*/
|
||||
void
|
||||
R_DrawFireball (fball_t *f)
|
||||
{
|
||||
int i, j;
|
||||
vec3_t vec;
|
||||
float radius;
|
||||
float *b_sin, *b_cos;
|
||||
|
||||
b_sin = bubble_sintable;
|
||||
b_cos = bubble_costable;
|
||||
|
||||
radius = f->size + 0.35;
|
||||
|
||||
// figure out if we're inside the area of effect
|
||||
VectorSubtract (f->origin, r_origin, vec);
|
||||
if (Length (vec) < radius)
|
||||
{
|
||||
AddLightBlend (1, 0.5, 0, f->size * 0.0003); // we are
|
||||
return;
|
||||
}
|
||||
|
||||
// we're not - draw it
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
glColor4fv (f->color);
|
||||
for (i=0 ; i<3 ; i++)
|
||||
vec[i] = f->origin[i] - vpn[i] * radius;
|
||||
glVertex3fv (vec);
|
||||
glColor3f (0.0, 0.0, 0.0);
|
||||
|
||||
// don't panic, this just draws a bubble...
|
||||
for (i=16 ; i>=0 ; i--)
|
||||
{
|
||||
for (j=0 ; j<3 ; j++)
|
||||
vec[j] = f->origin[j] + (*b_cos * vright[j]
|
||||
+ vup[j]*(*b_sin)) * radius;
|
||||
glVertex3fv (vec);
|
||||
|
||||
for (j=0 ; j<3 ; j++)
|
||||
vec[j] = f->owner[j] + (*b_cos * vright[j]
|
||||
+ vup[j]*(*b_sin)) * radius;
|
||||
glVertex3fv (vec);
|
||||
|
||||
b_sin++;
|
||||
b_cos++;
|
||||
}
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
/*
|
||||
R_DrawFireballs
|
||||
|
||||
Draws each fireball in sequence
|
||||
*/
|
||||
void
|
||||
R_DrawFireballs (void)
|
||||
{
|
||||
int i;
|
||||
fball_t *f;
|
||||
|
||||
f = r_fireballs;
|
||||
|
||||
glDepthMask (0);
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glShadeModel (GL_SMOOTH);
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
|
||||
for (i = 0; i < MAX_FIREBALLS; i++)
|
||||
{
|
||||
if (f->die < cl.time || !f->size)
|
||||
continue;
|
||||
|
||||
f->size += f->decay;
|
||||
f->color[3] /= 2.0;
|
||||
R_DrawFireball (f);
|
||||
}
|
||||
|
||||
glColor3f (1.0, 1.0, 1.0);
|
||||
glDisable (GL_BLEND);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthMask (1);
|
||||
}
|
||||
|
||||
|
|
|
@ -105,8 +105,6 @@ extern PROC glTexturePointerEXT;
|
|||
extern PROC glVertexPointerEXT;
|
||||
#endif
|
||||
|
||||
// r_local.h -- private refresh defs
|
||||
|
||||
#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0)
|
||||
// normalizing factor so player model works out to about
|
||||
// 1 pixel per triangle
|
||||
|
@ -242,6 +240,24 @@ extern qboolean gl_mtexable;
|
|||
void GL_DisableMultitexture(void);
|
||||
void GL_EnableMultitexture(void);
|
||||
|
||||
//
|
||||
// gl_rpart.c
|
||||
//
|
||||
typedef struct {
|
||||
int key; // allows reusability
|
||||
vec3_t origin, owner;
|
||||
float size;
|
||||
float die, decay; // duration settings
|
||||
float minlight; // lighting threshold
|
||||
float color[4]; // RGBA
|
||||
} fball_t;
|
||||
|
||||
void R_FireballTrail (vec3_t, vec3_t);
|
||||
fball_t *R_AllocFireball (int);
|
||||
void R_DrawFireball (fball_t *);
|
||||
void R_DrawFireballs (void);
|
||||
|
||||
|
||||
//
|
||||
// gl_warp.c
|
||||
//
|
||||
|
@ -269,6 +285,8 @@ void R_RotateForEntity (entity_t *e);
|
|||
//
|
||||
// gl_rlight.c
|
||||
//
|
||||
extern float bubble_sintable[17], bubble_costable[17];
|
||||
|
||||
void R_MarkLights (dlight_t *light, int bit, mnode_t *node);
|
||||
void R_AnimateLight (void);
|
||||
void R_RenderDlights (void);
|
||||
|
@ -295,4 +313,9 @@ void GL_BuildLightmaps (void);
|
|||
// gl_ngraph.c
|
||||
//
|
||||
void R_NetGraph (void);
|
||||
|
||||
//
|
||||
// gl_rlight.c
|
||||
//
|
||||
void AddLightBlend (float, float, float, float);
|
||||
#endif // _GLQUAKE_H
|
||||
|
|
Loading…
Reference in a new issue