From d7df76f224c0d0ebb8a3c7bc0c3125ba638206e6 Mon Sep 17 00:00:00 2001 From: lordhavoc Date: Fri, 18 Jan 2002 20:33:38 +0000 Subject: [PATCH 1/1] cleaned up a lot of particle rendering properties (mainly related to rain code), rain looks nice now. added depthdisable to rmeshinfo_t gl_backend now uses glDrawRangeElements on non-win32 (need to use dynamic GL binding to get it on win32), nice speedup rearranged r_speeds2 time reporting code, now times more things (in gl_screen.c especially) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@1365 d7cf8633-e32d-0410-b094-e92efae38249 --- buildnumber.c | 2 +- cl_particles.c | 174 ++++++++++++++++++++++++++++--------------------- client.h | 3 +- gl_backend.c | 50 +++++++++++++- gl_backend.h | 1 + gl_rmain.c | 133 +++++++++---------------------------- gl_rsurf.c | 2 +- gl_screen.c | 93 +++++++++++++++++++++++--- r_particles.c | 125 +++++++++++++++++++++-------------- render.h | 4 ++ 10 files changed, 349 insertions(+), 238 deletions(-) diff --git a/buildnumber.c b/buildnumber.c index 37ef3341..d57640a1 100644 --- a/buildnumber.c +++ b/buildnumber.c @@ -1,4 +1,4 @@ -#define BUILDNUMBER 659 +#define BUILDNUMBER 710 int buildnumber = BUILDNUMBER; diff --git a/cl_particles.c b/cl_particles.c index 6bb31d8c..1196b673 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -32,11 +32,13 @@ ptype_t; typedef struct particle_s { ptype_t type; + int orientation; // typically PARTICLE_BILLBOARD vec3_t org; vec3_t vel; int tex; float die; - float scale; + float scalex; + float scaley; float alpha; // 0-255 float time2; // used for various things (snow fluttering, for example) float bounce; // how much bounce-back from a surface the particle hits (0 = no physics, 1 = stop and slide, 2 = keep bouncing forever, 1.5 is typical) @@ -160,7 +162,7 @@ void CL_Particles_Init (void) r_refdef.particles = cl_renderparticles = Mem_Alloc(cl_part_mempool, cl_maxparticles * sizeof(renderparticle_t)); } -#define particle(ptype, pcolor, ptex, plight, pscale, palpha, ptime, pbounce, px, py, pz, pvx, pvy, pvz, ptime2, pvx2, pvy2, pvz2, pfriction, ppressure)\ +#define particle(ptype, porientation, pcolor, ptex, plight, pscalex, pscaley, palpha, ptime, pbounce, px, py, pz, pvx, pvy, pvz, ptime2, pvx2, pvy2, pvz2, pfriction, ppressure)\ {\ particle_t *part;\ int tempcolor;\ @@ -174,8 +176,10 @@ void CL_Particles_Init (void) part->color[2] = (tempcolor) & 0xFF;\ part->color[3] = 0xFF;\ part->tex = (ptex);\ + part->orientation = (porientation);\ part->dynlight = (plight);\ - part->scale = (pscale);\ + part->scalex = (pscalex);\ + part->scaley = (pscaley);\ part->alpha = (palpha);\ part->die = cl.time + (ptime);\ part->bounce = (pbounce);\ @@ -229,7 +233,7 @@ void CL_EntityParticles (entity_t *ent) forward[1] = cp*sy; forward[2] = -sp; - particle(pt_oneframe, particlepalette[0x6f], tex_particle, false, 2, 255, 9999, 0, ent->render.origin[0] + m_bytenormals[i][0]*dist + forward[0]*beamlength, ent->render.origin[1] + m_bytenormals[i][1]*dist + forward[1]*beamlength, ent->render.origin[2] + m_bytenormals[i][2]*dist + forward[2]*beamlength, 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_oneframe, PARTICLE_BILLBOARD, particlepalette[0x6f], tex_particle, false, 2, 2, 255, 9999, 0, ent->render.origin[0] + m_bytenormals[i][0]*dist + forward[0]*beamlength, ent->render.origin[1] + m_bytenormals[i][1]*dist + forward[1]*beamlength, ent->render.origin[2] + m_bytenormals[i][2]*dist + forward[2]*beamlength, 0, 0, 0, 0, 0, 0, 0, 0, 0); } } @@ -273,7 +277,7 @@ void CL_ReadPointFile_f (void) Con_Printf ("Not enough free particles\n"); break; } - particle(pt_static, particlepalette[(-c)&15], tex_particle, false, 2, 255, 99999, 0, org[0], org[1], org[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_static, PARTICLE_BILLBOARD, particlepalette[(-c)&15], tex_particle, false, 2, 2, 255, 99999, 0, org[0], org[1], org[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); } Mem_Free(pointfile); @@ -327,7 +331,7 @@ void CL_ParticleExplosion (vec3_t org, int smoke) if (i == CONTENTS_SLIME || i == CONTENTS_WATER) { for (i = 0;i < 128;i++) - particle(pt_bubble, 0xFFFFFF, tex_bubble, false, lhrandom(1, 2), 255, 9999, 1.5, org[0] + lhrandom(-16, 16), org[1] + lhrandom(-16, 16), org[2] + lhrandom(-16, 16), lhrandom(-96, 96), lhrandom(-96, 96), lhrandom(-96, 96), 0, 0, 0, 0, 0, 0); + particle(pt_bubble, PARTICLE_BILLBOARD, 0xFFFFFF, tex_bubble, false, 2, 2, 255, 9999, 1.5, org[0] + lhrandom(-16, 16), org[1] + lhrandom(-16, 16), org[2] + lhrandom(-16, 16), lhrandom(-96, 96), lhrandom(-96, 96), lhrandom(-96, 96), 0, 0, 0, 0, 0, 0); ang[2] = lhrandom(0, 360); fractalnoise(noise1, 32, 4); @@ -344,9 +348,9 @@ void CL_ParticleExplosion (vec3_t org, int smoke) AngleVectors(ang, v, NULL, NULL); f = noise1[j*32+i] * 1.5f; VectorScale(v, f, v); - particle(pt_underwaterspark, noise2[j*32+i] * 0x010101, tex_smoke[rand()&7], false, 10, lhrandom(128, 255), 9999, 1.5, end[0], end[1], end[2], v[0], v[1], v[2], 512.0f, 0, 0, 0, 2, 0); + particle(pt_underwaterspark, PARTICLE_BILLBOARD, noise2[j*32+i] * 0x010101, tex_smoke[rand()&7], false, 10, 10, lhrandom(128, 255), 9999, 1.5, end[0], end[1], end[2], v[0], v[1], v[2], 512.0f, 0, 0, 0, 2, 0); VectorScale(v, 0.75, v); - particle(pt_underwaterspark, explosparkramp[(noise2[j*32+i] >> 5)], tex_particle, false, 10, lhrandom(128, 255), 9999, 1.5, end[0], end[1], end[2], v[0], v[1], v[2], 512.0f, 0, 0, 0, 2, 0); + particle(pt_underwaterspark, PARTICLE_BILLBOARD, explosparkramp[(noise2[j*32+i] >> 5)], tex_particle, false, 10, 10, lhrandom(128, 255), 9999, 1.5, end[0], end[1], end[2], v[0], v[1], v[2], 512.0f, 0, 0, 0, 2, 0); } } } @@ -367,12 +371,12 @@ void CL_ParticleExplosion (vec3_t org, int smoke) AngleVectors(ang, v, NULL, NULL); f = noise1[j*32+i] * 1.5f; VectorScale(v, f, v); - particle(pt_spark, noise2[j*32+i] * 0x010101, tex_smoke[rand()&7], false, 10, lhrandom(128, 255), 9999, 1.5, end[0], end[1], end[2], v[0], v[1], v[2] + 160.0f, 512.0f, 0, 0, 0, 2, 0); + particle(pt_spark, PARTICLE_BILLBOARD, noise2[j*32+i] * 0x010101, tex_smoke[rand()&7], false, 10, 10, lhrandom(128, 255), 9999, 1.5, end[0], end[1], end[2], v[0], v[1], v[2] + 160.0f, 512.0f, 0, 0, 0, 2, 0); VectorScale(v, 0.75, v); - particle(pt_spark, explosparkramp[(noise2[j*32+i] >> 5)], tex_particle, false, 10, lhrandom(128, 255), 9999, 1.5, end[0], end[1], end[2], v[0], v[1], v[2] + 160.0f, 512.0f, 0, 0, 0, 2, 0); + particle(pt_spark, PARTICLE_BILLBOARD, explosparkramp[(noise2[j*32+i] >> 5)], tex_particle, false, 10, 10, lhrandom(128, 255), 9999, 1.5, end[0], end[1], end[2], v[0], v[1], v[2] + 160.0f, 512.0f, 0, 0, 0, 2, 0); // VectorRandom(v); // VectorScale(v, 384, v); - // particle(pt_spark, explosparkramp[rand()&7], tex_particle, false, 2, lhrandom(16, 255), 9999, 1.5, end[0], end[1], end[2], v[0], v[1], v[2] + 160.0f, 512.0f, 0, 0, 0, 2, 0); + // particle(pt_spark, PARTICLE_BILLBOARD, explosparkramp[rand()&7], tex_particle, false, 2, 2, lhrandom(16, 255), 9999, 1.5, end[0], end[1], end[2], v[0], v[1], v[2] + 160.0f, 512.0f, 0, 0, 0, 2, 0); } } } @@ -393,7 +397,7 @@ void CL_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength) if (!cl_particles.integer) return; for (i = 0;i < 512;i++) - particle(pt_fade, particlepalette[colorStart + (i % colorLength)], tex_particle, false, 1.5, 255, 0.3, 0, org[0] + lhrandom(-8, 8), org[1] + lhrandom(-8, 8), org[2] + lhrandom(-8, 8), lhrandom(-192, 192), lhrandom(-192, 192), lhrandom(-192, 192), 0, 0, 0, 0, 0.1f, 0); + particle(pt_fade, PARTICLE_BILLBOARD, particlepalette[colorStart + (i % colorLength)], tex_particle, false, 1.5, 1.5, 255, 0.3, 0, org[0] + lhrandom(-8, 8), org[1] + lhrandom(-8, 8), org[2] + lhrandom(-8, 8), lhrandom(-192, 192), lhrandom(-192, 192), lhrandom(-192, 192), 0, 0, 0, 0, 0.1f, 0); } /* @@ -408,9 +412,9 @@ void CL_BlobExplosion (vec3_t org) if (!cl_particles.integer) return; for (i = 0;i < 256;i++) - particle(pt_blob , particlepalette[ 66+(rand()%6)], tex_particle, false, 4, 255, 9999, 0, org[0] + lhrandom(-16, 16), org[1] + lhrandom(-16, 16), org[2] + lhrandom(-16, 16), lhrandom(-4, 4), lhrandom(-4, 4), lhrandom(-128, 128), 0, 0, 0, 0, 0, 0); + particle(pt_blob , PARTICLE_BILLBOARD, particlepalette[ 66+(rand()%6)], tex_particle, false, 4, 4, 255, 9999, 0, org[0] + lhrandom(-16, 16), org[1] + lhrandom(-16, 16), org[2] + lhrandom(-16, 16), lhrandom(-4, 4), lhrandom(-4, 4), lhrandom(-128, 128), 0, 0, 0, 0, 0, 0); for (i = 0;i < 256;i++) - particle(pt_blob2, particlepalette[150+(rand()%6)], tex_particle, false, 4, 255, 9999, 0, org[0] + lhrandom(-16, 16), org[1] + lhrandom(-16, 16), org[2] + lhrandom(-16, 16), lhrandom(-4, 4), lhrandom(-4, 4), lhrandom(-128, 128), 0, 0, 0, 0, 0, 0); + particle(pt_blob2, PARTICLE_BILLBOARD, particlepalette[150+(rand()%6)], tex_particle, false, 4, 4, 255, 9999, 0, org[0] + lhrandom(-16, 16), org[1] + lhrandom(-16, 16), org[2] + lhrandom(-16, 16), lhrandom(-4, 4), lhrandom(-4, 4), lhrandom(-128, 128), 0, 0, 0, 0, 0, 0); } /* @@ -429,7 +433,7 @@ void CL_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count) return; } while (count--) - particle(pt_fade, particlepalette[color + (rand()&7)], tex_particle, false, 1, 128, 9999, 0, org[0] + lhrandom(-8, 8), org[1] + lhrandom(-8, 8), org[2] + lhrandom(-8, 8), lhrandom(-15, 15), lhrandom(-15, 15), lhrandom(-15, 15), 0, 0, 0, 0, 0, 0); + particle(pt_fade, PARTICLE_BILLBOARD, particlepalette[color + (rand()&7)], tex_particle, false, 1, 1, 128, 9999, 0, org[0] + lhrandom(-8, 8), org[1] + lhrandom(-8, 8), org[2] + lhrandom(-8, 8), lhrandom(-15, 15), lhrandom(-15, 15), lhrandom(-15, 15), 0, 0, 0, 0, 0, 0); } // LordHavoc: added this for spawning sparks/dust (which have strong gravity) @@ -446,13 +450,13 @@ void CL_SparkShower (vec3_t org, vec3_t dir, int count) // smoke puff if (cl_particles_smoke.integer) - particle(pt_bulletsmoke, 0xA0A0A0, tex_smoke[rand()&7], true, 5, 255, 9999, 0, org[0], org[1], org[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(0, 16), 0, 0, 0, 0, 0, 0); + particle(pt_bulletsmoke, PARTICLE_BILLBOARD, 0xA0A0A0, tex_smoke[rand()&7], true, 5, 5, 255, 9999, 0, org[0], org[1], org[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(0, 16), 0, 0, 0, 0, 0, 0); if (cl_particles_sparks.integer) { // sparks while(count--) - particle(pt_spark, particlepalette[0x68 + (rand() & 7)], tex_particle, false, 1, lhrandom(0, 255), 9999, 1.5, org[0], org[1], org[2], lhrandom(-64, 64), lhrandom(-64, 64), lhrandom(0, 128), 512.0f, 0, 0, 0, 0.2f, 0); + particle(pt_spark, PARTICLE_BILLBOARD, particlepalette[0x68 + (rand() & 7)], tex_particle, false, 1, 1, lhrandom(0, 255), 9999, 1.5, org[0], org[1], org[2], lhrandom(-64, 64), lhrandom(-64, 64), lhrandom(0, 128), 512.0f, 0, 0, 0, 0.2f, 0); } } @@ -468,7 +472,7 @@ void CL_BloodPuff (vec3_t org, vec3_t vel, int count) bloodcount += count; while(bloodcount >= 10) { - particle(pt_blood, 0x300000, tex_smoke[rand()&7], true, 24, 255, 9999, -1, org[0], org[1], org[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64), 0, 0, 0, 0, 1.0f, 0); + particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, 24, 24, 255, 9999, -1, org[0], org[1], org[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64), 0, 0, 0, 0, 1.0f, 0); bloodcount -= 10; } } @@ -498,7 +502,7 @@ void CL_BloodShower (vec3_t mins, vec3_t maxs, float velspeed, int count) vel[0] = (org[0] - center[0]) * velscale[0]; vel[1] = (org[1] - center[1]) * velscale[1]; vel[2] = (org[2] - center[2]) * velscale[2]; - particle(pt_blood, 0x300000, tex_smoke[rand()&7], true, 24, 255, 9999, -1, org[0], org[1], org[2], vel[0], vel[1], vel[2], 0, 0, 0, 0, 1.0f, 0); + particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, 24, 24, 255, 9999, -1, org[0], org[1], org[2], vel[0], vel[1], vel[2], 0, 0, 0, 0, 1.0f, 0); } } @@ -511,7 +515,7 @@ void CL_ParticleCube (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int color if (maxs[2] <= mins[2]) {t = mins[2];mins[2] = maxs[2];maxs[2] = t;} while (count--) - particle(gravity ? pt_grav : pt_static, particlepalette[colorbase + (rand()&3)], tex_particle, false, 2, 255, lhrandom(1, 2), 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), dir[0] + lhrandom(-randomvel, randomvel), dir[1] + lhrandom(-randomvel, randomvel), dir[2] + lhrandom(-randomvel, randomvel), 0, 0, 0, 0, 0, 0); + particle(gravity ? pt_grav : pt_static, PARTICLE_BILLBOARD, particlepalette[colorbase + (rand()&3)], tex_particle, false, 2, 2, 255, lhrandom(1, 2), 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), dir[0] + lhrandom(-randomvel, randomvel), dir[1] + lhrandom(-randomvel, randomvel), dir[2] + lhrandom(-randomvel, randomvel), 0, 0, 0, 0, 0, 0); } void CL_ParticleRain (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int colorbase, int type) @@ -538,12 +542,14 @@ void CL_ParticleRain (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int color switch(type) { case 0: + count *= 4; // ick, this should be in the mod or maps? + while(count--) { vel[0] = dir[0] + lhrandom(-16, 16); vel[1] = dir[1] + lhrandom(-16, 16); vel[2] = dir[2] + lhrandom(-32, 32); - particle(pt_rain, particlepalette[colorbase + (rand()&3)], tex_rain, true, 3, 255, t, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), z, vel[0], vel[1], vel[2], 0, vel[0], vel[1], vel[2], 0, 0); + particle(pt_rain, PARTICLE_UPRIGHT_FACING, particlepalette[colorbase + (rand()&3)], tex_particle, true, 1, 64, 64, t, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), z, vel[0], vel[1], vel[2], 0, vel[0], vel[1], vel[2], 0, 0); } break; case 1: @@ -552,7 +558,7 @@ void CL_ParticleRain (vec3_t mins, vec3_t maxs, vec3_t dir, int count, int color vel[0] = dir[0] + lhrandom(-16, 16); vel[1] = dir[1] + lhrandom(-16, 16); vel[2] = dir[2] + lhrandom(-32, 32); - particle(pt_snow, particlepalette[colorbase + (rand()&3)], tex_particle, false, 2, 255, t, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), z, vel[0], vel[1], vel[2], 0, vel[0], vel[1], vel[2], 0, 0); + particle(pt_snow, PARTICLE_BILLBOARD, particlepalette[colorbase + (rand()&3)], tex_particle, false, 2, 2, 255, t, 0, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), z, vel[0], vel[1], vel[2], 0, vel[0], vel[1], vel[2], 0, 0); } break; default: @@ -569,7 +575,7 @@ void CL_FlameCube (vec3_t mins, vec3_t maxs, int count) if (maxs[2] <= mins[2]) {t = mins[2];mins[2] = maxs[2];maxs[2] = t;} while (count--) - particle(pt_flame, particlepalette[224 + (rand()&15)], tex_particle, false, 8, 255, 9999, 1.1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), lhrandom(-32, 32), lhrandom(-32, 32), lhrandom(-32, 64), 0, 0, 0, 0, 0.1f, 0); + particle(pt_flame, PARTICLE_BILLBOARD, particlepalette[224 + (rand()&15)], tex_particle, false, 8, 8, 255, 9999, 1.1, lhrandom(mins[0], maxs[0]), lhrandom(mins[1], maxs[1]), lhrandom(mins[2], maxs[2]), lhrandom(-32, 32), lhrandom(-32, 32), lhrandom(-32, 64), 0, 0, 0, 0, 0.1f, 0); } void CL_Flames (vec3_t org, vec3_t vel, int count) @@ -577,7 +583,7 @@ void CL_Flames (vec3_t org, vec3_t vel, int count) if (!cl_particles.integer) return; while (count--) - particle(pt_flame, particlepalette[224 + (rand()&15)], tex_particle, false, 8, 255, 9999, 1.1, org[0], org[1], org[2], vel[0] + lhrandom(-128, 128), vel[1] + lhrandom(-128, 128), vel[2] + lhrandom(-128, 128), 0, 0, 0, 0, 0.1f, 0); + particle(pt_flame, PARTICLE_BILLBOARD, particlepalette[224 + (rand()&15)], tex_particle, false, 8, 8, 255, 9999, 1.1, org[0], org[1], org[2], vel[0] + lhrandom(-128, 128), vel[1] + lhrandom(-128, 128), vel[2] + lhrandom(-128, 128), 0, 0, 0, 0, 0.1f, 0); } @@ -606,7 +612,7 @@ void CL_LavaSplash (vec3_t origin) org[1] = origin[1] + dir[1]; org[2] = origin[2] + lhrandom(0, 64); vel = lhrandom(50, 120) / VectorLength(dir); // normalize and scale - particle(pt_lavasplash, particlepalette[224 + (rand()&7)], tex_particle, false, 7, 255, 9999, 0, org[0], org[1], org[2], dir[0] * vel, dir[1] * vel, dir[2] * vel, 0, 0, 0, 0, 0, 0); + particle(pt_lavasplash, PARTICLE_BILLBOARD, particlepalette[224 + (rand()&7)], tex_particle, false, 7, 7, 255, 9999, 0, org[0], org[1], org[2], dir[0] * vel, dir[1] * vel, dir[2] * vel, 0, 0, 0, 0, 0, 0); } } } @@ -625,7 +631,7 @@ void CL_TeleportSplash (vec3_t org) for (i=-16 ; i<16 ; i+=8) for (j=-16 ; j<16 ; j+=8) for (k=-24 ; k<32 ; k+=8) - particle(pt_fade, 0xFFFFFF, tex_particle, false, 1, lhrandom(64, 128), 9999, 0, org[0] + i + lhrandom(0, 8), org[1] + j + lhrandom(0, 8), org[2] + k + lhrandom(0, 8), i*2 + lhrandom(-12.5, 12.5), j*2 + lhrandom(-12.5, 12.5), k*2 + lhrandom(27.5, 52.5), 0, 0, 0, 0, 0.1f, -512.0f); + particle(pt_fade, PARTICLE_BILLBOARD, 0xFFFFFF, tex_particle, false, 1, 1, lhrandom(64, 128), 9999, 0, org[0] + i + lhrandom(0, 8), org[1] + j + lhrandom(0, 8), org[2] + k + lhrandom(0, 8), i*2 + lhrandom(-12.5, 12.5), j*2 + lhrandom(-12.5, 12.5), k*2 + lhrandom(27.5, 52.5), 0, 0, 0, 0, 0.1f, -512.0f); } void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) @@ -640,7 +646,7 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) VectorNormalize(dir); if (type == 0 && host_frametime != 0) // rocket glow - particle(pt_oneframe, 0xFFFFFF, tex_rocketglow, false, 24, 255, 9999, 0, end[0] - 12 * dir[0], end[1] - 12 * dir[1], end[2] - 12 * dir[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_oneframe, PARTICLE_BILLBOARD, 0xFFFFFF, tex_rocketglow, false, 24, 24, 255, 9999, 0, end[0] - 12 * dir[0], end[1] - 12 * dir[1], end[2] - 12 * dir[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); t = ent->persistent.trail_time; if (t >= cl.time) @@ -685,18 +691,18 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) else if (bubbles && cl_particles_bubbles.integer) { dec = 0.005f; - particle(pt_bubble, 0xFFFFFF, tex_bubble, false, lhrandom(1, 2), 255, 9999, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16), 0, 0, 0, 0, 0, 0); - particle(pt_bubble, 0xFFFFFF, tex_bubble, false, lhrandom(1, 2), 255, 9999, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16), 0, 0, 0, 0, 0, 0); - particle(pt_smoke, 0xFFFFFF, tex_smoke[rand()&7], false, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_bubble, PARTICLE_BILLBOARD, 0xFFFFFF, tex_bubble, false, 2, 2, 255, 9999, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16), 0, 0, 0, 0, 0, 0); + particle(pt_bubble, PARTICLE_BILLBOARD, 0xFFFFFF, tex_bubble, false, 2, 2, 255, 9999, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16), 0, 0, 0, 0, 0, 0); + particle(pt_smoke, PARTICLE_BILLBOARD, 0xFFFFFF, tex_smoke[rand()&7], false, 2, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); } else { dec = 0.005f; - particle(pt_smoke, 0xC0C0C0, tex_smoke[rand()&7], true, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); - //particle(pt_spark, particlepalette[0x68 + (rand() & 7)], tex_particle, false, 1, lhrandom(128, 255), 9999, 1.5, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.0625, lhrandom(-64, 64) - vel[1] * 0.0625, lhrandom(-64, 64) - vel[2] * 0.0625, 512.0f, 0, 0, 0, 0.1f, 0); - //particle(pt_spark, particlepalette[0x68 + (rand() & 7)], tex_particle, false, 1, lhrandom(128, 255), 9999, 1.5, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.0625, lhrandom(-64, 64) - vel[1] * 0.0625, lhrandom(-64, 64) - vel[2] * 0.0625, 512.0f, 0, 0, 0, 0.1f, 0); - //particle(pt_spark, particlepalette[0x68 + (rand() & 7)], tex_particle, false, 1, lhrandom(128, 255), 9999, 1.5, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.0625, lhrandom(-64, 64) - vel[1] * 0.0625, lhrandom(-64, 64) - vel[2] * 0.0625, 512.0f, 0, 0, 0, 0.1f, 0); - //particle(pt_spark, particlepalette[0x68 + (rand() & 7)], tex_particle, false, 1, lhrandom(128, 255), 9999, 1.5, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.0625, lhrandom(-64, 64) - vel[1] * 0.0625, lhrandom(-64, 64) - vel[2] * 0.0625, 512.0f, 0, 0, 0, 0.1f, 0); + particle(pt_smoke, PARTICLE_BILLBOARD, 0xC0C0C0, tex_smoke[rand()&7], true, 2, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + //particle(pt_spark, PARTICLE_BILLBOARD, particlepalette[0x68 + (rand() & 7)], tex_particle, false, 1, 1, lhrandom(128, 255), 9999, 1.5, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.0625, lhrandom(-64, 64) - vel[1] * 0.0625, lhrandom(-64, 64) - vel[2] * 0.0625, 512.0f, 0, 0, 0, 0.1f, 0); + //particle(pt_spark, PARTICLE_BILLBOARD, particlepalette[0x68 + (rand() & 7)], tex_particle, false, 1, 1, lhrandom(128, 255), 9999, 1.5, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.0625, lhrandom(-64, 64) - vel[1] * 0.0625, lhrandom(-64, 64) - vel[2] * 0.0625, 512.0f, 0, 0, 0, 0.1f, 0); + //particle(pt_spark, PARTICLE_BILLBOARD, particlepalette[0x68 + (rand() & 7)], tex_particle, false, 1, 1, lhrandom(128, 255), 9999, 1.5, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.0625, lhrandom(-64, 64) - vel[1] * 0.0625, lhrandom(-64, 64) - vel[2] * 0.0625, 512.0f, 0, 0, 0, 0.1f, 0); + //particle(pt_spark, PARTICLE_BILLBOARD, particlepalette[0x68 + (rand() & 7)], tex_particle, false, 1, 1, lhrandom(128, 255), 9999, 1.5, start[0], start[1], start[2], lhrandom(-64, 64) - vel[0] * 0.0625, lhrandom(-64, 64) - vel[1] * 0.0625, lhrandom(-64, 64) - vel[2] * 0.0625, 512.0f, 0, 0, 0, 0.1f, 0); } break; @@ -707,14 +713,14 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) else if (bubbles && cl_particles_bubbles.integer) { dec = 0.02f; - particle(pt_bubble, 0xFFFFFF, tex_bubble, false, lhrandom(1, 2), 255, 9999, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16), 0, 0, 0, 0, 0, 0); - particle(pt_bubble, 0xFFFFFF, tex_bubble, false, lhrandom(1, 2), 255, 9999, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16), 0, 0, 0, 0, 0, 0); - particle(pt_smoke, 0xFFFFFF, tex_smoke[rand()&7], false, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_bubble, PARTICLE_BILLBOARD, 0xFFFFFF, tex_bubble, false, 2, 2, 255, 9999, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16), 0, 0, 0, 0, 0, 0); + particle(pt_bubble, PARTICLE_BILLBOARD, 0xFFFFFF, tex_bubble, false, 2, 2, 255, 9999, 1.5, start[0], start[1], start[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16), 0, 0, 0, 0, 0, 0); + particle(pt_smoke, PARTICLE_BILLBOARD, 0xFFFFFF, tex_smoke[rand()&7], false, 2, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); } else { dec = 0.02f; - particle(pt_smoke, 0x808080, tex_smoke[rand()&7], true, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_smoke, PARTICLE_BILLBOARD, 0x808080, tex_smoke[rand()&7], true, 2, 2, 160, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); } break; @@ -725,7 +731,7 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) else { dec = 0.1f; - particle(pt_blood, 0x300000, tex_smoke[rand()&7], true, 24, 255, 9999, -1, start[0], start[1], start[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64), 0, 0, 0, 0, 1.0f, 0); + particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, 24, 24, 255, 9999, -1, start[0], start[1], start[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64), 0, 0, 0, 0, 1.0f, 0); } break; @@ -735,23 +741,23 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) else { dec = 0.15f; - particle(pt_blood, 0x300000, tex_smoke[rand()&7], true, 24, 255, 9999, -1, start[0], start[1], start[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64), 0, 0, 0, 0, 1.0f, 0); + particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, 24, 24, 255, 9999, -1, start[0], start[1], start[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64), 0, 0, 0, 0, 1.0f, 0); } break; case 3: // green tracer dec = 0.02f; - particle(pt_fade, 0x373707, tex_smoke[rand()&7], false, 4, 255, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_fade, PARTICLE_BILLBOARD, 0x373707, tex_smoke[rand()&7], false, 4, 4, 255, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); break; case 5: // flame tracer dec = 0.02f; - particle(pt_fade, 0xCF632B, tex_smoke[rand()&7], false, 4, 255, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_fade, PARTICLE_BILLBOARD, 0xCF632B, tex_smoke[rand()&7], false, 4, 4, 255, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); break; case 6: // voor trail dec = 0.05f; // sparse trail - particle(pt_fade, 0x47232B, tex_smoke[rand()&7], false, 4, 255, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_fade, PARTICLE_BILLBOARD, 0x47232B, tex_smoke[rand()&7], false, 4, 4, 255, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); break; case 7: // Nehahra smoke tracer @@ -760,7 +766,7 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) else { dec = 0.14f; - particle(pt_smoke, 0xC0C0C0, tex_smoke[rand()&7], true, 10, 64, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_smoke, PARTICLE_BILLBOARD, 0xC0C0C0, tex_smoke[rand()&7], true, 10, 10, 64, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); } break; } @@ -786,7 +792,7 @@ void CL_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent) color = particlepalette[color]; while (len--) { - particle(pt_smoke, color, tex_particle, false, 8, 192, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_smoke, PARTICLE_BILLBOARD, color, tex_particle, false, 8, 8, 192, 9999, 0, start[0], start[1], start[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); VectorAdd (start, vec, start); } } @@ -843,7 +849,7 @@ void CL_MoveParticles (void) VectorCopy(v, p->org); if (p->bounce < 0) { - CL_Decal(v, p->tex, p->scale * cl_particles_size.value, p->color[0] * (1.0f / 255.0f), p->color[1] * (1.0f / 255.0f), p->color[2] * (1.0f / 255.0f), p->alpha * (1.0f / 255.0f)); + CL_Decal(v, p->tex, p->scalex * cl_particles_size.value, p->color[0] * (1.0f / 255.0f), p->color[1] * (1.0f / 255.0f), p->color[2] * (1.0f / 255.0f), p->alpha * (1.0f / 255.0f)); p->die = -1; freeparticles[j++] = p; continue; @@ -894,7 +900,8 @@ void CL_MoveParticles (void) a = Mod_PointInLeaf(p->org, cl.worldmodel)->contents; if (a != CONTENTS_EMPTY && a != CONTENTS_SKY) { - vec3_t normal; + p->die = -1; + /* if (a == CONTENTS_SOLID && Mod_PointInLeaf(p->oldorg, cl.worldmodel)->contents == CONTENTS_SOLID) break; // still in solid p->die = cl.time + 1000; @@ -904,26 +911,34 @@ void CL_MoveParticles (void) case CONTENTS_LAVA: case CONTENTS_SLIME: p->tex = tex_smoke[rand()&7]; + p->orientation = PARTICLE_BILLBOARD; p->type = pt_steam; p->alpha = 96; - p->scale = 5; + p->scalex = 5; + p->scaley = 5; p->vel[2] = 96; break; case CONTENTS_WATER: p->tex = tex_smoke[rand()&7]; + p->orientation = PARTICLE_BILLBOARD; p->type = pt_splash; p->alpha = 96; - p->scale = 5; + p->scalex = 5; + p->scaley = 5; p->vel[2] = 96; break; default: // CONTENTS_SOLID and any others TraceLine(p->oldorg, p->org, v, normal, 0); VectorCopy(v, p->org); p->tex = tex_smoke[rand()&7]; + p->orientation = PARTICLE_BILLBOARD; p->type = pt_fade; + p->scalex = 5; + p->scaley = 5; VectorClear(p->vel); break; } + */ } break; case pt_blood: @@ -934,7 +949,8 @@ void CL_MoveParticles (void) if (a == CONTENTS_WATER || a == CONTENTS_SLIME) { p->friction = 5; - p->scale += frametime * 32.0f; + p->scalex += frametime * 32.0f; + p->scaley += frametime * 32.0f; p->alpha -= frametime * 128.0f; p->vel[2] += gravity * 0.125f; if (p->alpha < 1) @@ -961,8 +977,10 @@ void CL_MoveParticles (void) if (Mod_PointInLeaf(p->org, cl.worldmodel)->contents == CONTENTS_EMPTY) { p->tex = tex_smoke[rand()&7]; + p->orientation = PARTICLE_BILLBOARD; p->color[0] = p->color[1] = p->color[2] = 255; - p->scale = 16; + p->scalex = 8; + p->scaley = 8; p->type = pt_explosionsplash; } else @@ -976,7 +994,8 @@ void CL_MoveParticles (void) p->vel[2] -= gravity; else p->alpha = 0; - p->scale += frametime * 64.0f; + p->scalex += frametime * 64.0f; + p->scaley += frametime * 64.0f; p->alpha -= frametime * 1024.0f; if (p->alpha < 1) p->die = -1; @@ -991,8 +1010,10 @@ void CL_MoveParticles (void) if (a != CONTENTS_WATER && a != CONTENTS_SLIME) { p->tex = tex_smoke[rand()&7]; + p->orientation = PARTICLE_BILLBOARD; p->type = pt_splashpuff; - p->scale = 4; + p->scalex = 4; + p->scaley = 4; p->vel[0] = p->vel[1] = p->vel[2] = 0; break; } @@ -1012,21 +1033,24 @@ void CL_MoveParticles (void) p->die = -1; break; case pt_bulletsmoke: - p->scale += frametime * 16; + p->scalex += frametime * 16; + p->scaley += frametime * 16; p->alpha -= frametime * 1024; p->vel[2] += gravity * 0.1; if (p->alpha < 1) p->die = -1; break; case pt_smoke: - p->scale += frametime * 24; + p->scalex += frametime * 24; + p->scaley += frametime * 24; p->alpha -= frametime * 256; p->vel[2] += gravity * 0.1; if (p->alpha < 1) p->die = -1; break; case pt_steam: - p->scale += frametime * 48; + p->scalex += frametime * 48; + p->scaley += frametime * 48; p->alpha -= frametime * 512; p->vel[2] += gravity * 0.05; if (p->alpha < 1) @@ -1048,6 +1072,8 @@ void CL_MoveParticles (void) b = traceline_endcontents; if (f < 1 && b != CONTENTS_EMPTY && b != CONTENTS_SKY) { + p->die = -1; + /* p->die = cl.time + 1000; p->vel[0] = p->vel[1] = p->vel[2] = 0; VectorCopy(v, p->org); @@ -1056,22 +1082,28 @@ void CL_MoveParticles (void) case CONTENTS_LAVA: case CONTENTS_SLIME: p->tex = tex_smoke[rand()&7]; + p->orientation = PARTICLE_BILLBOARD; p->type = pt_steam; - p->scale = 3; + p->scalex = 3; + p->scaley = 3; p->vel[2] = 96; break; default: // water, solid, and anything else p->tex = tex_rainsplash[0]; + p->orientation = PARTICLE_ORIENTED_DOUBLESIDED; p->time2 = 0; VectorCopy(normal, p->vel2); // VectorAdd(p->org, normal, p->org); p->type = pt_raindropsplash; - p->scale = 8; + p->scalex = 8; + p->scaley = 8; break; } + */ } } break; + /* case pt_raindropsplash: p->time2 += frametime * 64.0f; if (p->time2 >= 16.0f) @@ -1080,7 +1112,9 @@ void CL_MoveParticles (void) break; } p->tex = tex_rainsplash[(int) p->time2]; + p->orientation = PARTICLE_ORIENTED_DOUBLESIDED; break; + */ case pt_flame: p->alpha -= frametime * 512; p->vel[2] += gravity; @@ -1109,22 +1143,16 @@ void CL_MoveParticles (void) pressureused = true; // build renderparticle for renderer to use - if (p->type == pt_raindropsplash) - { - r->orientation = PARTICLE_ORIENTED_DOUBLESIDED; - r->dir[0] = p->vel2[0]; - r->dir[1] = p->vel2[1]; - r->dir[2] = p->vel2[2]; - } - else if (p->tex == tex_rain) - r->orientation = PARTICLE_UPRIGHT_FACING; - else - r->orientation = PARTICLE_BILLBOARD; + r->orientation = p->orientation; + r->dir[0] = p->vel2[0]; + r->dir[1] = p->vel2[1]; + r->dir[2] = p->vel2[2]; r->org[0] = p->org[0]; r->org[1] = p->org[1]; r->org[2] = p->org[2]; r->tex = p->tex; - r->scale = p->scale * 0.5f * cl_particles_size.value; + r->scalex = p->scalex * 0.5f * cl_particles_size.value; + r->scaley = p->scaley * 0.5f * cl_particles_size.value; r->dynlight = p->dynlight; r->color[0] = p->color[0] * (1.0f / 255.0f); r->color[1] = p->color[1] * (1.0f / 255.0f); @@ -1164,9 +1192,9 @@ void CL_MoveParticles (void) dist = DotProduct(diff, diff); if (dist < 4096 && dist >= 1) { - dist = freeparticles[j]->scale * 4.0f * frametime / sqrt(dist); + dist = freeparticles[j]->scalex * 4.0f * frametime / sqrt(dist); VectorMA(p->vel, dist, diff, p->vel); - //dist = freeparticles[j]->scale * 4.0f * frametime / dist; + //dist = freeparticles[j]->scalex * 4.0f * frametime / dist; //VectorMA(p->vel, dist, freeparticles[j]->vel, p->vel); } } diff --git a/client.h b/client.h index d9dbbe5b..6f436a42 100644 --- a/client.h +++ b/client.h @@ -438,7 +438,8 @@ typedef struct renderparticle_s int tex; int orientation; int dynlight; - float scale; + float scalex; + float scaley; float org[3]; float dir[3]; float color[4]; diff --git a/gl_backend.c b/gl_backend.c index 16a92c25..7bfd6bfa 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -15,11 +15,14 @@ typedef struct buf_mesh_s { struct buf_mesh_s *next; int depthmask; + int depthtest; int blendfunc1, blendfunc2; int textures[MAX_TEXTUREUNITS]; float texturergbscale[MAX_TEXTUREUNITS]; int firsttriangle; int triangles; + int firstvert; + int lastvert; } buf_mesh_t; @@ -284,7 +287,7 @@ int errornumber = 0; // renders mesh buffers, called to flush buffers when full void R_Mesh_Render(void) { - int i, k, blendfunc1, blendfunc2, blend, depthmask, unit = 0, clientunit = 0, firsttriangle, triangles, texture[MAX_TEXTUREUNITS]; + int i, k, blendfunc1, blendfunc2, blend, depthmask, depthtest, unit = 0, clientunit = 0, firsttriangle, triangles, firstvert, lastvert, texture[MAX_TEXTUREUNITS]; float farclip, texturergbscale[MAX_TEXTUREUNITS]; buf_mesh_t *mesh; if (!backendactive) @@ -307,6 +310,7 @@ CHECKGLERROR CHECKGLERROR glCullFace(GL_FRONT); CHECKGLERROR + depthtest = true; glEnable(GL_DEPTH_TEST); CHECKGLERROR blendfunc1 = GL_ONE; @@ -545,6 +549,14 @@ CHECKGLERROR } } } + if (depthtest != mesh->depthtest) + { + depthtest = mesh->depthtest; + if (depthtest) + glEnable(GL_DEPTH_TEST); + else + glDisable(GL_DEPTH_TEST); + } if (depthmask != mesh->depthmask) { depthmask = mesh->depthmask; @@ -554,6 +566,8 @@ CHECKGLERROR firsttriangle = mesh->firsttriangle; triangles = mesh->triangles; + firstvert = mesh->firstvert; + lastvert = mesh->lastvert; mesh = &buf_mesh[++k]; if (meshmerge) @@ -564,6 +578,7 @@ CHECKGLERROR while (k < currentmesh && mesh->blendfunc1 == blendfunc1 && mesh->blendfunc2 == blendfunc2 + && mesh->depthtest == depthtest && mesh->depthmask == depthmask && mesh->textures[0] == texture[0] && mesh->textures[1] == texture[1] @@ -575,11 +590,20 @@ CHECKGLERROR && mesh->texturergbscale[3] == texturergbscale[3]) { triangles += mesh->triangles; + if (firstvert > mesh->firstvert) + firstvert = mesh->firstvert; + if (lastvert < mesh->lastvert) + lastvert = mesh->lastvert; mesh = &buf_mesh[++k]; } } +#ifdef WIN32 + // FIXME: dynamic link to GL so we can get DrawRangeElements on WIN32 glDrawElements(GL_TRIANGLES, triangles * 3, GL_UNSIGNED_INT, (unsigned int *)&buf_tri[firsttriangle]); +#else + glDrawRangeElements(GL_TRIANGLES, firstvert, lastvert + 1, triangles * 3, GL_UNSIGNED_INT, (unsigned int *)&buf_tri[firsttriangle]); +#endif CHECKGLERROR } @@ -637,6 +661,8 @@ CHECKGLERROR CHECKGLERROR glDisable(GL_BLEND); +CHECKGLERROR + glEnable(GL_DEPTH_TEST); CHECKGLERROR glDepthMask(true); CHECKGLERROR @@ -720,6 +746,8 @@ void R_Mesh_AddTransparent(void) buf_tri[currenttriangle].index[0] = tri->index[0] + currentvertex; buf_tri[currenttriangle].index[1] = tri->index[1] + currentvertex; buf_tri[currenttriangle].index[2] = tri->index[2] + currentvertex; + mesh->firstvert = min(buf_tri[currenttriangle].index[0], min(buf_tri[currenttriangle].index[1], buf_tri[currenttriangle].index[2])); + mesh->lastvert = max(buf_tri[currenttriangle].index[0], max(buf_tri[currenttriangle].index[1], buf_tri[currenttriangle].index[2])); mesh->firsttriangle = currenttriangle++; mesh->triangles = 1; tri = tri->next; @@ -748,7 +776,21 @@ void R_Mesh_Draw(const rmeshinfo_t *m) || !m->numtriangles || m->vertex == NULL || !m->numverts) - return; + return; + // ignore meaningless alpha meshs + if (!m->depthwrite && m->blendfunc1 == GL_SRC_ALPHA && (m->blendfunc2 == GL_ONE || m->blendfunc2 == GL_ONE_MINUS_SRC_ALPHA)) + { + if (m->color) + { + for (i = 0, in = m->color + 3;i < m->numverts;i++, (int)in += m->colorstep) + if (*in >= 0.01f) + break; + if (i == m->numverts) + return; + } + else if (m->ca < 0.01f) + return; + } if (!backendactive) Sys_Error("R_DrawMesh: called when backend is not active\n"); @@ -904,6 +946,7 @@ void R_Mesh_Draw(const rmeshinfo_t *m) mesh->blendfunc1 = m->blendfunc1; mesh->blendfunc2 = m->blendfunc2; mesh->depthmask = false; + mesh->depthtest = !m->depthdisable; j = -1; for (i = 0;i < backendunits;i++) { @@ -935,6 +978,7 @@ void R_Mesh_Draw(const rmeshinfo_t *m) mesh->blendfunc1 = m->blendfunc1; mesh->blendfunc2 = m->blendfunc2; mesh->depthmask = (m->blendfunc2 == GL_ZERO || m->depthwrite); + mesh->depthtest = !m->depthdisable; mesh->firsttriangle = currenttriangle; mesh->triangles = m->numtriangles; j = -1; @@ -953,8 +997,10 @@ void R_Mesh_Draw(const rmeshinfo_t *m) index = (int *)&buf_tri[currenttriangle]; for (i = 0;i < m->numtriangles * 3;i++) index[i] = m->index[i] + currentvertex; + mesh->firstvert = currentvertex; currenttriangle += m->numtriangles; currentvertex += m->numverts; + mesh->lastvert = currentvertex - 1; } c_meshtris += m->numtriangles; diff --git a/gl_backend.h b/gl_backend.h index c9f98d4a..bde446bb 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -7,6 +7,7 @@ typedef struct { int transparent; int depthwrite; // force depth writing enabled even if polygon is not opaque + int depthdisable; // disable depth read/write entirely int blendfunc1; int blendfunc2; int numtriangles; diff --git a/gl_rmain.c b/gl_rmain.c index 66b20cf8..c84eb7ea 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -589,6 +589,13 @@ static void R_SetupGL (void) if (!r_render.integer) return; +// glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: moved to SCR_UpdateScreen + gldepthmin = 0; + gldepthmax = 1; + glDepthFunc (GL_LEQUAL); + + glDepthRange (gldepthmin, gldepthmax); + // update farclip based on previous frame r_farclip = r_newfarclip; @@ -628,24 +635,7 @@ static void R_SetupGL (void) glDepthMask(1); } -/* -============= -R_Clear -============= -*/ -static void R_Clear (void) -{ - if (!r_render.integer) - return; -// glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: moved to SCR_UpdateScreen - gldepthmin = 0; - gldepthmax = 1; - glDepthFunc (GL_LEQUAL); - - glDepthRange (gldepthmin, gldepthmax); -} - -static void GL_BlendView(void) +static void R_BlendView(void) { if (!r_render.integer) return; @@ -654,10 +644,10 @@ static void GL_BlendView(void) return; glMatrixMode(GL_PROJECTION); - glLoadIdentity (); + glLoadIdentity (); glOrtho (0, 1, 1, 0, -99999, 99999); glMatrixMode(GL_MODELVIEW); - glLoadIdentity (); + glLoadIdentity (); glDisable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); glDisable(GL_TEXTURE_2D); @@ -686,76 +676,14 @@ R_RenderView r_refdef must be set before the first call ================ */ -char r_speeds2_string[1024]; -int speedstringcount; - -void timestring(int t, char *desc) -{ - char tempbuf[256]; - int length; - if (t < 1000000) - sprintf(tempbuf, "%6ius %s", t, desc); - else - sprintf(tempbuf, "%6ims %s", t / 1000, desc); - length = strlen(tempbuf); -// while (length < 20) -// tempbuf[length++] = ' '; -// tempbuf[length] = 0; - if (speedstringcount + length > (vid.conwidth / 8)) - { - strcat(r_speeds2_string, "\n"); - speedstringcount = 0; - } - // skip the space at the beginning if it's the first on the line - if (speedstringcount == 0) - { - strcat(r_speeds2_string, tempbuf + 1); - speedstringcount = length - 1; - } - else - { - strcat(r_speeds2_string, tempbuf); - speedstringcount += length; - } -} - -#define TIMEREPORT(NAME) \ - if (r_speeds2.integer)\ - {\ - temptime = currtime;\ - currtime = Sys_DoubleTime();\ - timestring((int) ((currtime - temptime) * 1000000.0), NAME);\ - } - void R_RenderView (void) { - double starttime, currtime, temptime; - if (!cl.worldmodel) Host_Error ("R_RenderView: NULL worldmodel"); - if (r_speeds2.integer) - { - speedstringcount = 0; - sprintf(r_speeds2_string, "org:'%c%6.2f %c%6.2f %c%6.2f' ang:'%c%3.0f %c%3.0f %c%3.0f' dir:'%c%2.3f %c%2.3f %c%2.3f'\n%6i walls %6i dlitwalls %7i modeltris %7i meshtris\nBSP: %6i faces %6i nodes %6i leafs\n%4i models %4i bmodels %4i sprites %5i particles %3i dlights\n", - r_origin[0] < 0 ? '-' : ' ', fabs(r_origin[0]), r_origin[1] < 0 ? '-' : ' ', fabs(r_origin[1]), r_origin[2] < 0 ? '-' : ' ', fabs(r_origin[2]), r_refdef.viewangles[0] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[0]), r_refdef.viewangles[1] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[1]), r_refdef.viewangles[2] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[2]), vpn[0] < 0 ? '-' : ' ', fabs(vpn[0]), vpn[1] < 0 ? '-' : ' ', fabs(vpn[1]), vpn[2] < 0 ? '-' : ' ', fabs(vpn[2]), - c_brush_polys, c_light_polys, c_alias_polys, c_meshtris, - c_faces, c_nodes, c_leafs, - c_models, c_bmodels, c_sprites, c_particles, c_dlights); - - starttime = currtime = Sys_DoubleTime(); - } - else - starttime = currtime = 0; - // FIXME: move to client R_MoveExplosions(); - TIMEREPORT("mexplosion") - - R_Clear(); - TIMEREPORT("clear ") - - // render normal view + R_TimeReport("mexplosion"); R_SetupFrame(); R_SetFrustum(); @@ -767,39 +695,39 @@ void R_RenderView (void) R_Clip_StartFrame(); R_BuildLightList(); - TIMEREPORT("setup ") + R_TimeReport("setup"); R_DrawWorld(); - TIMEREPORT("worldnode ") + R_TimeReport("worldnode"); R_MarkEntities(); - TIMEREPORT("markentity") + R_TimeReport("markentity"); if (r_ser.integer) { R_Clip_EndFrame(); - TIMEREPORT("hiddensurf") + R_TimeReport("hiddensurf"); } R_MarkWorldLights(); - TIMEREPORT("marklights") + R_TimeReport("marklights"); if (skyrendermasked && R_DrawBModelSky()) { - TIMEREPORT("bmodelsky ") + R_TimeReport("bmodelsky"); } R_SetupForWorldRendering(); R_PrepareSurfaces(); - TIMEREPORT("surfprep ") + R_TimeReport("surfprep"); R_DrawSurfacesAll(); - TIMEREPORT("surf ") + R_TimeReport("surfdraw"); if (r_drawportals.integer) { R_DrawPortals(); - TIMEREPORT("portals ") + R_TimeReport("portals"); } // don't let sound skip if going slow @@ -808,29 +736,28 @@ void R_RenderView (void) R_DrawViewModel(); R_DrawModels(); - TIMEREPORT("models ") + R_TimeReport("models"); R_DrawDecals(); - TIMEREPORT("decals ") + R_TimeReport("decals"); R_DrawParticles(); - TIMEREPORT("particles ") + R_TimeReport("particles"); R_DrawExplosions(); - TIMEREPORT("explosions") + R_TimeReport("explosions"); // draw transparent meshs R_Mesh_AddTransparent(); - TIMEREPORT("transmesh ") + R_TimeReport("sorttrans"); // render any queued meshs R_Mesh_Render(); - TIMEREPORT("finishmesh") + R_TimeReport("meshrender"); - GL_BlendView(); - TIMEREPORT("blend ") + R_BlendView(); + R_TimeReport("blendview"); - if (r_speeds2.integer) - timestring((int) ((Sys_DoubleTime() - starttime) * 1000000.0), - "total "); + Mem_CheckSentinelsGlobal(); + R_TimeReport("memtest"); } diff --git a/gl_rsurf.c b/gl_rsurf.c index b0650a99..e27ff410 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -534,7 +534,7 @@ static void RSurfShader_Water_Pass_Base(msurface_t *s) else { m.transparent = false; - m.blendfunc1 = GL_SRC_ALPHA; + m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; } m.numtriangles = s->mesh.numtriangles; diff --git a/gl_screen.c b/gl_screen.c index 54ebddbe..dc542a1c 100644 --- a/gl_screen.c +++ b/gl_screen.c @@ -850,6 +850,59 @@ void GL_BrightenScreen(void) CHECKGLERROR } +char r_speeds2_string[1024]; +int speedstringcount, r_timereport_active; +double r_timereport_temp = 0, r_timereport_current = 0, r_timereport_start = 0; + +void R_TimeReport(char *desc) +{ + char tempbuf[256]; + int length; + int t; + + if (!r_timereport_active) + return; + + r_timereport_temp = r_timereport_current; + r_timereport_current = Sys_DoubleTime(); + t = (int) ((r_timereport_current - r_timereport_temp) * 1000000.0); + + sprintf(tempbuf, "%8i %s", t, desc); + length = strlen(tempbuf); + while (length < 20) + tempbuf[length++] = ' '; + tempbuf[length] = 0; + if (speedstringcount + length > (vid.conwidth / 8)) + { + strcat(r_speeds2_string, "\n"); + speedstringcount = 0; + } + // skip the space at the beginning if it's the first on the line + if (speedstringcount == 0) + { + strcat(r_speeds2_string, tempbuf + 1); + speedstringcount = length - 1; + } + else + { + strcat(r_speeds2_string, tempbuf); + speedstringcount += length; + } +} + +void R_TimeReport_Start(void) +{ + r_timereport_active = r_speeds2.integer && cl.worldmodel && cls.state == ca_connected; + if (r_timereport_active) + r_timereport_start = Sys_DoubleTime(); +} + +void R_TimeReport_End(void) +{ + r_timereport_current = r_timereport_start; + R_TimeReport("total"); +} + /* ================== SCR_UpdateScreen @@ -887,6 +940,25 @@ void SCR_UpdateScreen (void) if (!scr_initialized || !con_initialized) return; // not initialized yet + r_speeds2_string[0] = 0; + if (r_speeds2.integer) + { + speedstringcount = 0; + sprintf(r_speeds2_string, "org:'%c%6.2f %c%6.2f %c%6.2f' ang:'%c%3.0f %c%3.0f %c%3.0f' dir:'%c%2.3f %c%2.3f %c%2.3f'\n%6i walls %6i dlitwalls %7i modeltris %7i meshtris\nBSP: %6i faces %6i nodes %6i leafs\n%4i models %4i bmodels %4i sprites %5i particles %3i dlights\n", + r_origin[0] < 0 ? '-' : ' ', fabs(r_origin[0]), r_origin[1] < 0 ? '-' : ' ', fabs(r_origin[1]), r_origin[2] < 0 ? '-' : ' ', fabs(r_origin[2]), r_refdef.viewangles[0] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[0]), r_refdef.viewangles[1] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[1]), r_refdef.viewangles[2] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[2]), vpn[0] < 0 ? '-' : ' ', fabs(vpn[0]), vpn[1] < 0 ? '-' : ' ', fabs(vpn[1]), vpn[2] < 0 ? '-' : ' ', fabs(vpn[2]), + c_brush_polys, c_light_polys, c_alias_polys, c_meshtris, + c_faces, c_nodes, c_leafs, + c_models, c_bmodels, c_sprites, c_particles, c_dlights); + R_TimeReport_Start(); + } + + Mem_CheckSentinelsGlobal(); + R_TimeReport("memtest"); + + GL_Finish(); + GL_EndRendering (); + + R_TimeReport("finish"); GL_BeginRendering (&vid.realx, &vid.realy, &vid.realwidth, &vid.realheight); @@ -922,6 +994,8 @@ void SCR_UpdateScreen (void) // if (vid.recalc_refdef) SCR_CalcRefdef(); + R_TimeReport("calcrefdef"); + if (r_render.integer) { glClearColor(0,0,0,0); @@ -930,6 +1004,8 @@ void SCR_UpdateScreen (void) CHECKGLERROR } + R_TimeReport("clear"); + if (gl_dither.integer) glEnable(GL_DITHER); else @@ -941,8 +1017,12 @@ void SCR_UpdateScreen (void) // SCR_SetUpToDrawConsole(); + R_TimeReport("setupconsole"); + V_RenderView(); + V_UpdateBlends(); + GL_Set2D(); R_Clip_DisplayBuffer(); @@ -1004,7 +1084,11 @@ void SCR_UpdateScreen (void) Draw_String(vid.conwidth - (8*8), vid.conheight - sb_lines - 8, temp, 9999); } - if (r_speeds2.integer && r_speeds2_string[0]) + R_TimeReport("2d"); + + R_TimeReport_End(); + + if (r_speeds2_string[0] && cls.state == ca_connected && cl.worldmodel) { int i, j, lines, y; lines = 1; @@ -1024,22 +1108,15 @@ void SCR_UpdateScreen (void) i++; y += 8; } - // clear so it won't reprint without renderer being called again - r_speeds2_string[0] = 0; } - V_UpdateBlends(); - GL_BrightenScreen(); - GL_Finish(); - if (r_speeds.integer) { time2 = Sys_DoubleTime (); Con_Printf ("%3i ms %4i wpoly %4i epoly %6i meshtris %4i lightpoly %4i BSPnodes %4i BSPleafs %4i BSPfaces %4i models %4i bmodels %4i sprites %4i particles %3i dlights\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys, c_meshtris, c_light_polys, c_nodes, c_leafs, c_faces, c_models, c_bmodels, c_sprites, c_particles, c_dlights); } - GL_EndRendering (); } // for profiling, this is separated diff --git a/r_particles.c b/r_particles.c index 88b8f01c..dbd3f003 100644 --- a/r_particles.c +++ b/r_particles.c @@ -87,6 +87,7 @@ static void R_InitParticleTexture (void) memset(particletexturedata, 255, sizeof(particletexturedata)); // the particletexture[][] array numbers must match the cl_part.c textures + // smoke/blood for (i = 0;i < 8;i++) { do @@ -122,6 +123,7 @@ static void R_InitParticleTexture (void) setuptex(i + 0, 1, i + 8, &data[0][0][0], particletexturedata); } + // bullet hole for (i = 0;i < 8;i++) { float p[32][32]; @@ -179,6 +181,7 @@ static void R_InitParticleTexture (void) setuptex(i + 8, 1, i + 16, &data[0][0][0], particletexturedata); } + // rain splash for (i = 0;i < 16;i++) { radius = i * 3.0f / 16.0f; @@ -199,6 +202,7 @@ static void R_InitParticleTexture (void) setuptex(i + 16, 1, i + 24, &data[0][0][0], particletexturedata); } + // normal particle for (y = 0;y < 32;y++) { dy = y - 16; @@ -214,6 +218,7 @@ static void R_InitParticleTexture (void) setuptex(32, 0, 40, &data[0][0][0], particletexturedata); setuptex(32, 1, 40, &data[0][0][0], particletexturedata); + // rain light[0] = 1;light[1] = 1;light[2] = 1; VectorNormalize(light); for (y = 0;y < 32;y++) @@ -227,6 +232,7 @@ static void R_InitParticleTexture (void) setuptex(33, 0, 41, &data[0][0][0], particletexturedata); setuptex(33, 1, 41, &data[0][0][0], particletexturedata); + // bubble light[0] = 1;light[1] = 1;light[2] = 1; VectorNormalize(light); for (y = 0;y < 32;y++) @@ -240,6 +246,7 @@ static void R_InitParticleTexture (void) setuptex(34, 0, 42, &data[0][0][0], particletexturedata); setuptex(34, 1, 42, &data[0][0][0], particletexturedata); + // rocket flare for (y = 0;y < 32;y++) { dy = y - 16; @@ -339,13 +346,13 @@ void R_DrawParticles (void) VectorCopy(r->org, org); if (r->orientation == PARTICLE_BILLBOARD) { - VectorScale(vright, r->scale, right); - VectorScale(vup, r->scale, up); + VectorScale(vright, r->scalex, right); + VectorScale(vup, r->scaley, up); } else if (r->orientation == PARTICLE_UPRIGHT_FACING) { - VectorScale(right2, r->scale, right); - VectorScale(up2, r->scale, up); + VectorScale(right2, r->scalex, right); + VectorScale(up2, r->scaley, up); } else if (r->orientation == PARTICLE_ORIENTED_DOUBLESIDED) { @@ -357,8 +364,8 @@ void R_DrawParticles (void) } else VectorVectors(r->dir, right, up); - VectorScale(right, r->scale, right); - VectorScale(up, r->scale, up); + VectorScale(right, r->scalex, right); + VectorScale(up, r->scaley, up); } else Host_Error("R_DrawParticles: unknown particle orientation %i\n", r->orientation); @@ -378,29 +385,6 @@ void R_DrawParticles (void) tex = &particletexture[r->tex][0]; texfog = &particletexture[r->tex][1]; - fog = 0; - if (fogenabled) - { - VectorSubtract(org, r_origin, diff); - fog = exp(fogdensity/DotProduct(diff,diff)); - if (fog >= 0.01f) - { - if (fog > 1) - fog = 1; - m.cr *= 1 - fog; - m.cg *= 1 - fog; - m.cb *= 1 - fog; - if (tex->s1 == texfog->s1 && tex->t1 == texfog->t1) - { - m.cr += fogcolor[0] * fog; - m.cg += fogcolor[1] * fog; - m.cb += fogcolor[2] * fog; - } - } - else - fog = 0; - } - tv[0][0] = org[0] - right[0] - up[0]; tv[0][1] = org[1] - right[1] - up[1]; tv[0][2] = org[2] - right[2] - up[2]; @@ -422,27 +406,70 @@ void R_DrawParticles (void) tv[3][3] = tex->s2; tv[3][4] = tex->t1; - R_Mesh_Draw(&m); - - if (fog && (tex->s1 != texfog->s1 || tex->t1 != texfog->t1)) + fog = 0; + if (fogenabled) { - m.blendfunc2 = GL_ONE; - m.cr = fogcolor[0]; - m.cg = fogcolor[1]; - m.cb = fogcolor[2]; - m.ca = r->color[3] * fog; - - tv[0][3] = texfog->s1; - tv[0][4] = texfog->t1; - tv[1][3] = texfog->s1; - tv[1][4] = texfog->t2; - tv[2][3] = texfog->s2; - tv[2][4] = texfog->t2; - tv[3][3] = texfog->s2; - tv[3][4] = texfog->t1; - - R_Mesh_Draw(&m); - m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; + VectorSubtract(org, r_origin, diff); + fog = exp(fogdensity/DotProduct(diff,diff)); + if (fog >= 0.01f) + { + if (fog >= 0.99f) + { + // fully fogged, just use the fog texture and render as alpha + m.cr = fogcolor[0]; + m.cg = fogcolor[1]; + m.cb = fogcolor[2]; + m.ca = r->color[3]; + tv[0][3] = texfog->s1; + tv[0][4] = texfog->t1; + tv[1][3] = texfog->s1; + tv[1][4] = texfog->t2; + tv[2][3] = texfog->s2; + tv[2][4] = texfog->t2; + tv[3][3] = texfog->s2; + tv[3][4] = texfog->t1; + R_Mesh_Draw(&m); + } + else + { + // partially fogged, darken the first pass + m.cr *= 1 - fog; + m.cg *= 1 - fog; + m.cb *= 1 - fog; + if (tex->s1 == texfog->s1 && tex->t1 == texfog->t1) + { + // fog texture is the same as the base, just change the color + m.cr += fogcolor[0] * fog; + m.cg += fogcolor[1] * fog; + m.cb += fogcolor[2] * fog; + R_Mesh_Draw(&m); + } + else + { + // render the first pass (alpha), then do additive fog + R_Mesh_Draw(&m); + m.blendfunc2 = GL_ONE; + m.cr = fogcolor[0]; + m.cg = fogcolor[1]; + m.cb = fogcolor[2]; + m.ca = r->color[3] * fog; + tv[0][3] = texfog->s1; + tv[0][4] = texfog->t1; + tv[1][3] = texfog->s1; + tv[1][4] = texfog->t2; + tv[2][3] = texfog->s2; + tv[2][4] = texfog->t2; + tv[3][3] = texfog->s2; + tv[3][4] = texfog->t1; + R_Mesh_Draw(&m); + m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; + } + } + } + else + R_Mesh_Draw(&m); } + else + R_Mesh_Draw(&m); } } diff --git a/render.h b/render.h index 0053ca0b..6c5d6f22 100644 --- a/render.h +++ b/render.h @@ -217,3 +217,7 @@ particletexture_t; #define MAX_PARTICLETEXTURES 64 // [0] is normal, [1] is fog, they may be the same extern particletexture_t particletexture[MAX_PARTICLETEXTURES][2]; + +void R_TimeReport(char *name); +void R_TimeReport_Start(void); +void R_TimeReport_End(void); -- 2.39.2