From a16b2c00707588045edf7bcb9a4ce276256d4ee2 Mon Sep 17 00:00:00 2001 From: "Zephaniah E. Hull" Date: Fri, 6 Apr 2001 18:37:23 +0000 Subject: [PATCH] Borrowed LH's VectorVectors. Changed smoke trails a good bit. --- include/QF/mathlib.h | 3 +- libs/util/mathlib.c | 17 ++- qw/source/gl_dyn_part.c | 56 ++++++---- qw/source/gl_dyn_textures.c | 48 ++++++++- qw/source/gl_rlight.c | 202 +++++++++++++++++++++++++++++------- qw/source/gl_screen.c | 6 +- 6 files changed, 269 insertions(+), 63 deletions(-) diff --git a/include/QF/mathlib.h b/include/QF/mathlib.h index 5319c48b6..a921e8e86 100644 --- a/include/QF/mathlib.h +++ b/include/QF/mathlib.h @@ -77,7 +77,7 @@ void _VectorCopy (vec3_t in, vec3_t out); int VectorCompare (vec3_t v1, vec3_t v2); vec_t Length (vec3_t v); -void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross); +void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross); float VectorNormalize (vec3_t v); // returns vector length void VectorInverse (vec3_t v); void VectorScale (vec3_t in, vec_t scale, vec3_t out); @@ -93,6 +93,7 @@ fixed16_t Mul16_30(fixed16_t multiplier, fixed16_t multiplicand); int GreatestCommonDivisor (int i1, int i2); void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); +void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up); int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane); float anglemod(float a); diff --git a/libs/util/mathlib.c b/libs/util/mathlib.c index d1a9f6e5c..b42a23ade 100644 --- a/libs/util/mathlib.c +++ b/libs/util/mathlib.c @@ -104,6 +104,21 @@ PerpendicularVector (vec3_t dst, const vec3_t src) #pragma optimize( "", off ) #endif +void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up) +{ + float d; + + right[0] = forward[2]; + right[1] = -forward[0]; + right[2] = forward[1]; + + d = DotProduct(forward, right); + right[0] -= d * forward[0]; + right[1] -= d * forward[1]; + right[2] -= d * forward[2]; + VectorNormalize(right); + CrossProduct(right, forward, up); +} void RotatePointAroundVector (vec3_t dst, const vec3_t dir, const vec3_t point, @@ -410,7 +425,7 @@ _VectorCopy (vec3_t in, vec3_t out) } void -CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross) +CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross) { cross[0] = v1[1] * v2[2] - v1[2] * v2[1]; cross[1] = v1[2] * v2[0] - v1[0] * v2[2]; diff --git a/qw/source/gl_dyn_part.c b/qw/source/gl_dyn_part.c index cc429de6f..e20ca5f66 100644 --- a/qw/source/gl_dyn_part.c +++ b/qw/source/gl_dyn_part.c @@ -54,8 +54,9 @@ typedef enum { } ptype_t; typedef struct particle_s { - // driver-usable fields vec3_t org; + vec3_t up; + vec3_t right; int tex; float color; float alpha; @@ -80,15 +81,16 @@ extern qboolean lighthalf; extern cvar_t *cl_max_particles; +extern int part_tex_smoke_ring[8]; +extern int part_tex_smoke[8]; extern int part_tex_dot; extern int part_tex_spark; -extern int part_tex_smoke[8]; int ramp[8] = { 0x6d, 0x6b, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; inline particle_t * particle_new (ptype_t type, int texnum, vec3_t org, float scale, vec3_t vel, - float die, byte color, byte alpha) + float die, byte color, byte alpha, vec3_t up, vec3_t right) { particle_t *part; @@ -108,6 +110,9 @@ particle_new (ptype_t type, int texnum, vec3_t org, float scale, vec3_t vel, part->tex = texnum; part->scale = scale; + VectorScale (up, 1.5, part->up); + VectorScale (right, 1.5, part->right); + return part; } @@ -125,7 +130,7 @@ particle_new_random (ptype_t type, int texnum, vec3_t org, int org_fuzz, if (vel_fuzz) pvel[j] = lhrandom (-vel_fuzz, vel_fuzz); } - return particle_new (type, texnum, porg, scale, pvel, die, color, alpha); + return particle_new (type, texnum, porg, scale, pvel, die, color, alpha, vec3_origin, vec3_origin); } /* @@ -226,7 +231,7 @@ R_ReadPointFile_f (void) c++; if (!particle_new (pt_static, part_tex_dot, org, 1.5, vec3_origin, - 99999, (-c) & 15, 255)) { + 99999, (-c) & 15, 255, vec3_origin, vec3_origin)) { Con_Printf ("Not enough free particles\n"); break; } @@ -281,7 +286,7 @@ R_RunSparkEffect (vec3_t org, int count, int ofuzz) particle_new (pt_smokecloud, part_tex_smoke[rand () & 7], org, (ofuzz / 8) * .75, vec3_origin, cl.time + 99, - 12 + (rand () & 3), 96); + 12 + (rand () & 3), 96, vec3_origin, vec3_origin); while (count--) particle_new_random (pt_fallfadespark, part_tex_spark, org, ofuzz * .75, 1, 96, cl.time + 5, ramp[rand () % 6], @@ -312,7 +317,8 @@ R_BloodPuff (vec3_t org, int count) return; particle_new (pt_bloodcloud, part_tex_smoke[rand () & 7], org, 9, - vec3_origin, cl.time + 99, 68 + (rand () & 3), 128); + vec3_origin, cl.time + 99, 68 + (rand () & 3), 128, + vec3_origin, vec3_origin); } /* @@ -362,7 +368,7 @@ R_RunParticleEffect (vec3_t org, int color, int count) } particle_new (pt_grav, part_tex_dot, porg, 1.5, vec3_origin, (cl.time + 0.1 * (rand () % 5)), - (color & ~7) + (rand () & 7), 255); + (color & ~7) + (rand () & 7), 255, vec3_origin, vec3_origin); } } @@ -413,7 +419,7 @@ R_LavaSplash (vec3_t org) VectorScale (dir, vel, pvel); particle_new (pt_grav, part_tex_dot, porg, 3, pvel, (cl.time + 2 + (rand () & 31) * 0.02), - (224 + (rand () & 7)), 193); + (224 + (rand () & 7)), 193, vec3_origin, vec3_origin); } } } @@ -447,7 +453,7 @@ R_TeleportSplash (vec3_t org) VectorScale (dir, vel, pvel); particle_new (pt_grav, part_tex_spark, porg, 0.6, pvel, (cl.time + 0.2 + (rand () & 7) * 0.02), - (7 + (rand () & 7)), 255); + (7 + (rand () & 7)), 255, vec3_origin, vec3_origin); } } @@ -458,7 +464,7 @@ R_RocketTrail (int type, entity_t *ent) float len; int j, ptex; ptype_t ptype; - vec3_t porg, pvel; + vec3_t porg, pvel, up, right; float pdie, pscale; byte palpha, pcolor; @@ -471,6 +477,8 @@ R_RocketTrail (int type, entity_t *ent) VectorSubtract (ent->origin, ent->old_origin, vec); len = VectorNormalize (vec); while (len > 0) { + VectorCopy (vec3_origin, up); + VectorCopy (vec3_origin, right); VectorCopy (vec3_origin, pvel); pdie = cl.time + 2; ptype = pt_static; @@ -489,11 +497,12 @@ R_RocketTrail (int type, entity_t *ent) common_rocket_gren_trail: len -= 4; - ptex = part_tex_smoke[rand () & 7]; - pscale = lhrandom (6, 9); + ptex = part_tex_smoke_ring[rand () & 7]; + pscale = lhrandom (10, 15); palpha = 48 + (rand () & 31); ptype = pt_smoke; pdie = cl.time + 1; + VectorVectors(vec, right, up); VectorCopy (ent->old_origin, porg); break; case 4: // slight blood @@ -548,7 +557,8 @@ R_RocketTrail (int type, entity_t *ent) VectorAdd (ent->old_origin, vec, ent->old_origin); - particle_new (ptype, ptex, porg, pscale, pvel, pdie, pcolor, palpha); + particle_new (ptype, ptex, porg, pscale, pvel, pdie, pcolor, palpha, + up, right); } } @@ -564,15 +574,18 @@ R_DrawParticles (void) float minparticledist; unsigned char *at; byte alpha; - vec3_t up, right; float scale; particle_t *part; + vec3_t up, right, o_up, o_right; int activeparticles, maxparticle, j, k, vnum; varray_t vertex_array[4]; // LordHavoc: particles should not affect zbuffer glDepthMask (GL_FALSE); + VectorScale (up, 1.5, o_up); + VectorScale (right, 1.5, o_right); + glInterleavedArrays (GL_T2F_C4UB_V3F, 0, (void *) &(vertex_array[0])); vertex_array[0].texcoord[0] = 0; vertex_array[0].texcoord[1] = 1; @@ -582,9 +595,6 @@ R_DrawParticles (void) vnum = 0; - VectorScale (vup, 1.5, up); - VectorScale (vright, 1.5, right); - grav = (fast_grav = host_frametime * 800) * 0.05; dvel = 4 * host_frametime; @@ -611,6 +621,14 @@ R_DrawParticles (void) at = (byte *) & d_8to24table[(byte) part->color]; alpha = part->alpha; + if (VectorCompare(part->up, part->right)) { + VectorCopy(o_up, up); + VectorCopy(o_right, right); + } else { + VectorCopy(part->up, up); + VectorCopy(part->right, right); + } + if (lighthalf) { vertex_array[0].color[0] = (byte) ((int) at[0] >> 1); vertex_array[0].color[1] = (byte) ((int) at[1] >> 1); @@ -680,7 +698,7 @@ R_DrawParticles (void) case pt_smoke: if ((part->alpha -= host_frametime * 90) < 1) part->die = -1; - part->scale += host_frametime * 6; + part->scale += host_frametime * 10; part->org[2] += host_frametime * 30; break; case pt_smokecloud: diff --git a/qw/source/gl_dyn_textures.c b/qw/source/gl_dyn_textures.c index c8939bc7f..9edfdcb5d 100644 --- a/qw/source/gl_dyn_textures.c +++ b/qw/source/gl_dyn_textures.c @@ -40,10 +40,12 @@ extern void noise_plasma(unsigned char *noise, int size); static void GDT_InitDotParticleTexture (void); static void GDT_InitSparkParticleTexture (void); static void GDT_InitSmokeParticleTexture (void); +static void GDT_InitSmokeRingParticleTexture (void); +int part_tex_smoke_ring[8]; +int part_tex_smoke[8]; int part_tex_dot; int part_tex_spark; -int part_tex_smoke[8]; void GDT_Init (void) @@ -51,6 +53,7 @@ GDT_Init (void) GDT_InitDotParticleTexture (); GDT_InitSparkParticleTexture (); GDT_InitSmokeParticleTexture (); + GDT_InitSmokeRingParticleTexture (); } static void @@ -152,3 +155,46 @@ GDT_InitSmokeParticleTexture (void) GL_UNSIGNED_BYTE, data); } } + +static void +GDT_InitSmokeRingParticleTexture (void) +{ + int i, x, y, b; + float dx, dy, c, c2; + byte d, data[32][32][2], noise1[32][32], noise2[32][32]; + + for (i = 0; i < 8; i++) { + noise_diamondsquare (&noise1[0][0], 32); + noise_plasma (&noise2[0][0], 32); + for (y = 0; y < 32; y++) + { + dy = y - 16; + dy *= dy; + for (x = 0; x < 32; x++) { + dx = x - 16; + dx *= dx; + c = 255 - (dx + dy); + c2 = (dx + dy); + if (c < 1) c = 0; + if (c2 < 1) c2 = 0; + //b = ((c / 255) * (c2 / 255)) * 512; + b = (c * c2) * 512 / (255*255); + if (b < 1) b = 0; + d = (noise1[y][x] + noise2[y][x]) / 3; + if (d > 0) { + data[y][x][0] = 255; + data[y][x][1] = (d * b)/255; + } else { + data[y][x][0] = 255; + data[y][x][1] = 0; + } + } + } + part_tex_smoke_ring[i] = texture_extension_number++; + glBindTexture (GL_TEXTURE_2D, part_tex_smoke_ring[i]); + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D (GL_TEXTURE_2D, 0, 2, 32, 32, 0, GL_LUMINANCE_ALPHA, + GL_UNSIGNED_BYTE, data); + } +} diff --git a/qw/source/gl_rlight.c b/qw/source/gl_rlight.c index 0f9850293..303899d3b 100644 --- a/qw/source/gl_rlight.c +++ b/qw/source/gl_rlight.c @@ -198,65 +198,89 @@ void R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node) { mplane_t *splitplane; - float dist, l, maxdist; + float ndist, maxdist; msurface_t *surf; - int i, j, s, t; - vec3_t impact; + int i; + maxdist = light->radius * light->radius; + +loc0: if (node->contents < 0) return; splitplane = node->plane; - dist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist; + ndist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist; - if (dist > light->radius) { - if (node->children[0]->contents >= 0) // save some time by not - // pushing another stack - // frame - R_MarkLights (lightorigin, light, bit, node->children[0]); + if (ndist > light->radius) { + // Save time by not pushing another stack frame. + if (node->children[0]->contents >= 0) { + node = node->children[0]; + goto loc0; + } return; } - if (dist < -light->radius) { - if (node->children[1]->contents >= 0) // save some time by not - // pushing another stack - // frame - R_MarkLights (lightorigin, light, bit, node->children[1]); + if (ndist < -light->radius) { + // Save time by not pushing another stack frame. + if (node->children[1]->contents >= 0) { + node = node->children[1]; + goto loc0; + } return; } - maxdist = light->radius * light->radius; - // mark the polygons surf = cl.worldmodel->surfaces + node->firstsurface; for (i = 0; i < node->numsurfaces; i++, surf++) { - // LordHavoc: MAJOR dynamic light speedup here, eliminates marking of - // surfaces that are too far away from light, thus preventing - // unnecessary renders and uploads - for (j = 0; j < 3; j++) - impact[j] = lightorigin[j] - surf->plane->normal[j] * dist; + int s, t; + float l, dist, dist2; + vec3_t impact; - // clamp center of light to corner and check brightness - l = - DotProduct (impact, - surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - - surf->texturemins[0]; + dist = ndist; + + dist2 = dist * dist; + if (dist2 >= maxdist) + continue; + + impact[0] = light->origin[0] - surf->plane->normal[0] * dist; + impact[1] = light->origin[1] - surf->plane->normal[1] * dist; + impact[2] = light->origin[2] - surf->plane->normal[2] * dist; + + l = DotProduct (impact, surf->texinfo->vecs[0]) + + surf->texinfo->vecs[0][3] - surf->texturemins[0]; s = l + 0.5; if (s < 0) s = 0; else if (s > surf->extents[0]) s = surf->extents[0]; s = l - s; - l = - DotProduct (impact, - surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - - surf->texturemins[1]; + l = DotProduct (impact, surf->texinfo->vecs[1]) + + surf->texinfo->vecs[1][3] - surf->texturemins[1]; t = l + 0.5; if (t < 0) t = 0; else if (t > surf->extents[1]) t = surf->extents[1]; t = l - t; - // compare to minimum light + + /* + for (j = 0; j < 2; j++) { + d = DotProduct (impact, surf->texinfo->vecs[j]) + surf->texinfo->vecs[j][3] - surf->texturemins[j]; + + if (d < 0) { + dist2 += d * d; + if (dist2 >= maxdist) + continue; + } else { + d -= surf->extents[j] + 16; + if (d > 0) { + dist2 += d * d; + if (dist2 >= maxdist) + continue; + } + } + } + */ + if ((s * s + t * t + dist * dist) < maxdist) { if (surf->dlightframe != r_framecount) { surf->dlightframe = r_framecount; @@ -267,14 +291,117 @@ R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node) } } - if (node->children[0]->contents >= 0) // save some time by not pushing - // another stack frame - R_MarkLights (lightorigin, light, bit, node->children[0]); - if (node->children[1]->contents >= 0) // save some time by not pushing - // another stack frame - R_MarkLights (lightorigin, light, bit, node->children[1]); + if (node->children[0]->contents >= 0) { + if (node->children[1]->contents >= 0) + R_MarkLights (lightorigin, light, bit, node->children[1]); + + node = node->children[0]; + goto loc0; + } else if (node->children[1]->contents >= 0) { + node = node->children[1]; + goto loc0; + } } +#if 0 +void +R_MarkLights (vec3_t lightorigin, dlight_t *light, int bit, mnode_t *node) +{ + mplane_t *splitplane; + float ndist, maxdist; + msurface_t *surf; + int i; + + maxdist = light->radius * light->radius; + +loc0: + if (node->contents < 0) + return; + + splitplane = node->plane; + ndist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist; + + if (ndist > light->radius) { + // Save time by not pushing another stack frame. + if (node->children[0]->contents >= 0) { + node = node->children[0]; + goto loc0; + } + return; + } + if (ndist < -light->radius) { + // Save time by not pushing another stack frame. + if (node->children[1]->contents >= 0) { + node = node->children[1]; + goto loc0; + } + return; + } + +// mark the polygons + surf = cl.worldmodel->surfaces + node->firstsurface; + for (i = 0; i < node->numsurfaces; i++, surf++) { + int j, d; + float dist, dist2, impact[3]; + + if (surf->flags & SURF_PLANEBACK) + dist = -ndist; + else + dist = ndist; + + if (dist < -0.25f) + continue; + /* + if (dist < -0.25f && !(surf->flags & SURF_LIGHTBOTHSIDES)) + continue; + */ + + dist2 = dist * dist; + if (dist2 >= maxdist) + continue; + + impact[0] = light->origin[0] - surf->plane->normal[0] * dist; + impact[1] = light->origin[1] - surf->plane->normal[1] * dist; + impact[2] = light->origin[2] - surf->plane->normal[2] * dist; + + for (j = 0; j < 2; j++) { + d = DotProduct (impact, surf->texinfo->vecs[j]) + surf->texinfo->vecs[j][3] - surf->texturemins[j]; + + if (d < 0) { + dist2 += d * d; + if (dist2 >= maxdist) + continue; + } else { + d -= surf->extents[j] + 16; + if (d > 0) { + dist2 += d * d; + if (dist2 >= maxdist) + continue; + } + } + } + + if (surf->dlightframe != r_framecount) { + surf->dlightframe = r_framecount; + surf->dlightbits = bit; + } else { + surf->dlightbits |= bit; + } + } + + if (node->children[0]->contents >= 0) { + if (node->children[1]->contents >= 0) + R_MarkLights (lightorigin, light, bit, node->children[1]); + + node = node->children[0]; + goto loc0; + } else if (node->children[1]->contents >= 0) { + node = node->children[1]; + goto loc0; + } +} +#endif + /* R_PushDlights */ @@ -294,6 +421,7 @@ R_PushDlights (vec3_t entorigin) if (l->die < cl.time || !l->radius) continue; VectorSubtract (l->origin, entorigin, lightorigin); + //R_MarkLights (lightorigin, l, 1 << i, cl.worldmodel->nodes + cl.worldmodel->hulls[0].firstclipnode); R_MarkLights (lightorigin, l, 1 << i, cl.worldmodel->nodes); } } diff --git a/qw/source/gl_screen.c b/qw/source/gl_screen.c index 942204cbb..abfea2ff6 100644 --- a/qw/source/gl_screen.c +++ b/qw/source/gl_screen.c @@ -1015,16 +1015,14 @@ SCR_UpdateScreen (void) glDisable (GL_TEXTURE_2D); Cvar_SetValue (brightness, bound (1, brightness->value, 5)); - if (lighthalf) { // LordHavoc: render was done at half - // brightness + if (lighthalf) { // LordHavoc: render was done at half brightness f = brightness->value * 2; } else { Cvar_SetValue (brightness, bound (1, brightness->value, 5)); f = brightness->value; } - if (f >= 1.002) { // Make sure we don't get bit by - // roundoff errors + if (f >= 1.002) { // Make sure we don't get bit by roundoff errors glBlendFunc (GL_DST_COLOR, GL_ONE); glBegin (GL_QUADS); while (f >= 1.002) { // precision