X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=cl_particles.c;h=a93be5e772b62e4d865b4149c5a32cfd1ea13688;hp=4247755d8d18188dee35a57a0526655c7eab3045;hb=2bc7dbd0fb505681037e78da63a863bd97f87ecc;hpb=c045878e6948f00e52f17c9df6beefa2dfdfd868 diff --git a/cl_particles.c b/cl_particles.c index 4247755d..a93be5e7 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -274,41 +274,39 @@ particleeffectinfo_t baselineparticleeffectinfo = {0.0f, 360.0f, 0.0f, 0.0f}, //float rotate[4]; // min/max base angle, min/max rotation over time }; -cvar_t cl_particles = {CVAR_SAVE, "cl_particles", "1", "enables particle effects"}; -cvar_t cl_particles_quality = {CVAR_SAVE, "cl_particles_quality", "1", "multiplies number of particles"}; -cvar_t cl_particles_alpha = {CVAR_SAVE, "cl_particles_alpha", "1", "multiplies opacity of particles"}; -cvar_t cl_particles_size = {CVAR_SAVE, "cl_particles_size", "1", "multiplies particle size"}; -cvar_t cl_particles_quake = {CVAR_SAVE, "cl_particles_quake", "0", "makes particle effects look mostly like the ones in Quake"}; -cvar_t cl_particles_blood = {CVAR_SAVE, "cl_particles_blood", "1", "enables blood effects"}; -cvar_t cl_particles_blood_alpha = {CVAR_SAVE, "cl_particles_blood_alpha", "1", "opacity of blood, does not affect decals"}; -cvar_t cl_particles_blood_decal_alpha = {CVAR_SAVE, "cl_particles_blood_decal_alpha", "1", "opacity of blood decal"}; -cvar_t cl_particles_blood_decal_scalemin = {CVAR_SAVE, "cl_particles_blood_decal_scalemin", "1.5", "minimal random scale of decal"}; -cvar_t cl_particles_blood_decal_scalemax = {CVAR_SAVE, "cl_particles_blood_decal_scalemax", "2", "maximal random scale of decal"}; -cvar_t cl_particles_blood_bloodhack = {CVAR_SAVE, "cl_particles_blood_bloodhack", "1", "make certain quake particle() calls create blood effects instead"}; -cvar_t cl_particles_bulletimpacts = {CVAR_SAVE, "cl_particles_bulletimpacts", "1", "enables bulletimpact effects"}; -cvar_t cl_particles_explosions_sparks = {CVAR_SAVE, "cl_particles_explosions_sparks", "1", "enables sparks from explosions"}; -cvar_t cl_particles_explosions_shell = {CVAR_SAVE, "cl_particles_explosions_shell", "0", "enables polygonal shell from explosions"}; -cvar_t cl_particles_rain = {CVAR_SAVE, "cl_particles_rain", "1", "enables rain effects"}; -cvar_t cl_particles_snow = {CVAR_SAVE, "cl_particles_snow", "1", "enables snow effects"}; -cvar_t cl_particles_smoke = {CVAR_SAVE, "cl_particles_smoke", "1", "enables smoke (used by multiple effects)"}; -cvar_t cl_particles_smoke_alpha = {CVAR_SAVE, "cl_particles_smoke_alpha", "0.5", "smoke brightness"}; -cvar_t cl_particles_smoke_alphafade = {CVAR_SAVE, "cl_particles_smoke_alphafade", "0.55", "brightness fade per second"}; -cvar_t cl_particles_sparks = {CVAR_SAVE, "cl_particles_sparks", "1", "enables sparks (used by multiple effects)"}; -cvar_t cl_particles_bubbles = {CVAR_SAVE, "cl_particles_bubbles", "1", "enables bubbles (used by multiple effects)"}; -cvar_t cl_particles_visculling = {CVAR_SAVE, "cl_particles_visculling", "0", "perform a costly check if each particle is visible before drawing"}; -cvar_t cl_particles_collisions = {CVAR_SAVE, "cl_particles_collisions", "1", "allow costly collision detection on particles (sparks that bounce, particles not going through walls, blood hitting surfaces, etc)"}; -cvar_t cl_particles_forcetraileffects = {0, "cl_particles_forcetraileffects", "0", "force trails to be displayed even if a non-trail draw primitive was used (debug/compat feature)"}; -cvar_t cl_decals = {CVAR_SAVE, "cl_decals", "1", "enables decals (bullet holes, blood, etc)"}; -cvar_t cl_decals_visculling = {CVAR_SAVE, "cl_decals_visculling", "1", "perform a very cheap check if each decal is visible before drawing"}; -cvar_t cl_decals_time = {CVAR_SAVE, "cl_decals_time", "20", "how long before decals start to fade away"}; -cvar_t cl_decals_fadetime = {CVAR_SAVE, "cl_decals_fadetime", "1", "how long decals take to fade away"}; -cvar_t cl_decals_newsystem = {CVAR_SAVE, "cl_decals_newsystem", "1", "enables new advanced decal system"}; -cvar_t cl_decals_newsystem_intensitymultiplier = {CVAR_SAVE, "cl_decals_newsystem_intensitymultiplier", "2", "boosts intensity of decals (because the distance fade can make them hard to see otherwise)"}; -cvar_t cl_decals_newsystem_immediatebloodstain = {CVAR_SAVE, "cl_decals_newsystem_immediatebloodstain", "2", "0: no on-spawn blood stains; 1: on-spawn blood stains for pt_blood; 2: always use on-spawn blood stains"}; -cvar_t cl_decals_newsystem_bloodsmears = {CVAR_SAVE, "cl_decals_newsystem_bloodsmears", "1", "enable use of particle velocity as decal projection direction rather than surface normal"}; -cvar_t cl_decals_models = {CVAR_SAVE, "cl_decals_models", "0", "enables decals on animated models (if newsystem is also 1)"}; -cvar_t cl_decals_bias = {CVAR_SAVE, "cl_decals_bias", "0.125", "distance to bias decals from surface to prevent depth fighting"}; -cvar_t cl_decals_max = {CVAR_SAVE, "cl_decals_max", "4096", "maximum number of decals allowed to exist in the world at once"}; +cvar_t cl_particles = {CVAR_CLIENT | CVAR_SAVE, "cl_particles", "1", "enables particle effects"}; +cvar_t cl_particles_quality = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_quality", "1", "multiplies number of particles"}; +cvar_t cl_particles_alpha = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_alpha", "1", "multiplies opacity of particles"}; +cvar_t cl_particles_size = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_size", "1", "multiplies particle size"}; +cvar_t cl_particles_quake = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_quake", "0", "makes particle effects look mostly like the ones in Quake"}; +cvar_t cl_particles_blood = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_blood", "1", "enables blood effects"}; +cvar_t cl_particles_blood_alpha = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_blood_alpha", "1", "opacity of blood, does not affect decals"}; +cvar_t cl_particles_blood_decal_alpha = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_blood_decal_alpha", "1", "opacity of blood decal"}; +cvar_t cl_particles_blood_decal_scalemin = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_blood_decal_scalemin", "1.5", "minimal random scale of decal"}; +cvar_t cl_particles_blood_decal_scalemax = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_blood_decal_scalemax", "2", "maximal random scale of decal"}; +cvar_t cl_particles_blood_bloodhack = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_blood_bloodhack", "1", "make certain quake particle() calls create blood effects instead"}; +cvar_t cl_particles_bulletimpacts = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_bulletimpacts", "1", "enables bulletimpact effects"}; +cvar_t cl_particles_explosions_sparks = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_explosions_sparks", "1", "enables sparks from explosions"}; +cvar_t cl_particles_explosions_shell = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_explosions_shell", "0", "enables polygonal shell from explosions"}; +cvar_t cl_particles_rain = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_rain", "1", "enables rain effects"}; +cvar_t cl_particles_snow = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_snow", "1", "enables snow effects"}; +cvar_t cl_particles_smoke = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_smoke", "1", "enables smoke (used by multiple effects)"}; +cvar_t cl_particles_smoke_alpha = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_smoke_alpha", "0.5", "smoke brightness"}; +cvar_t cl_particles_smoke_alphafade = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_smoke_alphafade", "0.55", "brightness fade per second"}; +cvar_t cl_particles_sparks = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_sparks", "1", "enables sparks (used by multiple effects)"}; +cvar_t cl_particles_bubbles = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_bubbles", "1", "enables bubbles (used by multiple effects)"}; +cvar_t cl_particles_visculling = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_visculling", "0", "perform a costly check if each particle is visible before drawing"}; +cvar_t cl_particles_collisions = {CVAR_CLIENT | CVAR_SAVE, "cl_particles_collisions", "1", "allow costly collision detection on particles (sparks that bounce, particles not going through walls, blood hitting surfaces, etc)"}; +cvar_t cl_particles_forcetraileffects = {CVAR_CLIENT, "cl_particles_forcetraileffects", "0", "force trails to be displayed even if a non-trail draw primitive was used (debug/compat feature)"}; +cvar_t cl_decals = {CVAR_CLIENT | CVAR_SAVE, "cl_decals", "1", "enables decals (bullet holes, blood, etc)"}; +cvar_t cl_decals_time = {CVAR_CLIENT | CVAR_SAVE, "cl_decals_time", "20", "how long before decals start to fade away"}; +cvar_t cl_decals_fadetime = {CVAR_CLIENT | CVAR_SAVE, "cl_decals_fadetime", "1", "how long decals take to fade away"}; +cvar_t cl_decals_newsystem_intensitymultiplier = {CVAR_CLIENT | CVAR_SAVE, "cl_decals_newsystem_intensitymultiplier", "2", "boosts intensity of decals (because the distance fade can make them hard to see otherwise)"}; +cvar_t cl_decals_newsystem_immediatebloodstain = {CVAR_CLIENT | CVAR_SAVE, "cl_decals_newsystem_immediatebloodstain", "2", "0: no on-spawn blood stains; 1: on-spawn blood stains for pt_blood; 2: always use on-spawn blood stains"}; +cvar_t cl_decals_newsystem_bloodsmears = {CVAR_CLIENT | CVAR_SAVE, "cl_decals_newsystem_bloodsmears", "1", "enable use of particle velocity as decal projection direction rather than surface normal"}; +cvar_t cl_decals_models = {CVAR_CLIENT | CVAR_SAVE, "cl_decals_models", "0", "enables decals on animated models"}; +cvar_t cl_decals_bias = {CVAR_CLIENT | CVAR_SAVE, "cl_decals_bias", "0.125", "distance to bias decals from surface to prevent depth fighting"}; +cvar_t cl_decals_max = {CVAR_CLIENT | CVAR_SAVE, "cl_decals_max", "4096", "maximum number of decals allowed to exist in the world at once"}; static void CL_Particles_ParseEffectInfo(const char *textstart, const char *textend, const char *filename) @@ -571,9 +569,9 @@ static void CL_Particles_LoadEffectInfo(const char *customfile) } } -static void CL_Particles_LoadEffectInfo_f(void) +static void CL_Particles_LoadEffectInfo_f(cmd_state_t *cmd) { - CL_Particles_LoadEffectInfo(Cmd_Argc() > 1 ? Cmd_Argv(1) : NULL); + CL_Particles_LoadEffectInfo(Cmd_Argc(cmd) > 1 ? Cmd_Argv(cmd, 1) : NULL); } /* @@ -581,11 +579,11 @@ static void CL_Particles_LoadEffectInfo_f(void) CL_InitParticles =============== */ -void CL_ReadPointFile_f (void); +void CL_ReadPointFile_f(cmd_state_t *cmd); void CL_Particles_Init (void) { - Cmd_AddCommand ("pointfile", CL_ReadPointFile_f, "display point file produced by qbsp when a leak was detected in the map (a line leading through the leak hole, to an entity inside the level)"); - Cmd_AddCommand ("cl_particles_reloadeffects", CL_Particles_LoadEffectInfo_f, "reloads effectinfo.txt and maps/levelname_effectinfo.txt (where levelname is the current map) if parameter is given, loads from custom file (no levelname_effectinfo are loaded in this case)"); + Cmd_AddCommand(&cmd_client, "pointfile", CL_ReadPointFile_f, "display point file produced by qbsp when a leak was detected in the map (a line leading through the leak hole, to an entity inside the level)"); + Cmd_AddCommand(&cmd_client, "cl_particles_reloadeffects", CL_Particles_LoadEffectInfo_f, "reloads effectinfo.txt and maps/levelname_effectinfo.txt (where levelname is the current map) if parameter is given, loads from custom file (no levelname_effectinfo are loaded in this case)"); Cvar_RegisterVariable (&cl_particles); Cvar_RegisterVariable (&cl_particles_quality); @@ -612,10 +610,8 @@ void CL_Particles_Init (void) Cvar_RegisterVariable (&cl_particles_collisions); Cvar_RegisterVariable (&cl_particles_forcetraileffects); Cvar_RegisterVariable (&cl_decals); - Cvar_RegisterVariable (&cl_decals_visculling); Cvar_RegisterVariable (&cl_decals_time); Cvar_RegisterVariable (&cl_decals_fadetime); - Cvar_RegisterVariable (&cl_decals_newsystem); Cvar_RegisterVariable (&cl_decals_newsystem_intensitymultiplier); Cvar_RegisterVariable (&cl_decals_newsystem_immediatebloodstain); Cvar_RegisterVariable (&cl_decals_newsystem_bloodsmears); @@ -810,7 +806,7 @@ static void CL_ImmediateBloodStain(particle_t *part) int staintex; // blood creates a splash at spawn, not just at impact, this makes monsters bloody where they are shot - if (part->staintexnum >= 0 && cl_decals_newsystem.integer && cl_decals.integer) + if (part->staintexnum >= 0 && cl_decals.integer) { VectorCopy(part->vel, v); VectorNormalize(v); @@ -819,7 +815,7 @@ static void CL_ImmediateBloodStain(particle_t *part) } // blood creates a splash at spawn, not just at impact, this makes monsters bloody where they are shot - if (part->typeindex == pt_blood && cl_decals_newsystem.integer && cl_decals.integer) + if (part->typeindex == pt_blood && cl_decals.integer) { VectorCopy(part->vel, v); VectorNormalize(v); @@ -831,7 +827,6 @@ static void CL_ImmediateBloodStain(particle_t *part) void CL_SpawnDecalParticleForSurface(int hitent, const vec3_t org, const vec3_t normal, int color1, int color2, int texnum, float size, float alpha) { int l1, l2; - decal_t *decal; entity_render_t *ent = &cl.entities[hitent].render; unsigned char color[3]; if (!cl_decals.integer) @@ -845,57 +840,10 @@ void CL_SpawnDecalParticleForSurface(int hitent, const vec3_t org, const vec3_t color[1] = ((((color1 >> 8) & 0xFF) * l1 + ((color2 >> 8) & 0xFF) * l2) >> 8) & 0xFF; color[2] = ((((color1 >> 0) & 0xFF) * l1 + ((color2 >> 0) & 0xFF) * l2) >> 8) & 0xFF; - if (cl_decals_newsystem.integer) - { - if (vid.sRGB3D) - R_DecalSystem_SplatEntities(org, normal, Image_LinearFloatFromsRGB(color[0]), Image_LinearFloatFromsRGB(color[1]), Image_LinearFloatFromsRGB(color[2]), alpha*(1.0f/255.0f), particletexture[texnum].s1, particletexture[texnum].t1, particletexture[texnum].s2, particletexture[texnum].t2, size); - else - R_DecalSystem_SplatEntities(org, normal, color[0]*(1.0f/255.0f), color[1]*(1.0f/255.0f), color[2]*(1.0f/255.0f), alpha*(1.0f/255.0f), particletexture[texnum].s1, particletexture[texnum].t1, particletexture[texnum].s2, particletexture[texnum].t2, size); - return; - } - - for (;cl.free_decal < cl.max_decals && cl.decals[cl.free_decal].typeindex;cl.free_decal++); - if (cl.free_decal >= cl.max_decals) - return; - decal = &cl.decals[cl.free_decal++]; - if (cl.num_decals < cl.free_decal) - cl.num_decals = cl.free_decal; - memset(decal, 0, sizeof(*decal)); - decal->decalsequence = cl.decalsequence++; - decal->typeindex = pt_decal; - decal->texnum = texnum; - VectorMA(org, cl_decals_bias.value, normal, decal->org); - VectorCopy(normal, decal->normal); - decal->size = size; - decal->alpha = alpha; - decal->time2 = cl.time; - decal->color[0] = color[0]; - decal->color[1] = color[1]; - decal->color[2] = color[2]; if (vid.sRGB3D) - { - decal->color[0] = (unsigned char)(Image_LinearFloatFromsRGB(decal->color[0]) * 256.0f); - decal->color[1] = (unsigned char)(Image_LinearFloatFromsRGB(decal->color[1]) * 256.0f); - decal->color[2] = (unsigned char)(Image_LinearFloatFromsRGB(decal->color[2]) * 256.0f); - } - decal->owner = hitent; - decal->clusterindex = -1000; // no vis culling unless we're sure - if (hitent) - { - // these relative things are only used to regenerate p->org and p->vel if decal->owner is not world (0) - decal->ownermodel = cl.entities[decal->owner].render.model; - Matrix4x4_Transform(&cl.entities[decal->owner].render.inversematrix, org, decal->relativeorigin); - Matrix4x4_Transform3x3(&cl.entities[decal->owner].render.inversematrix, normal, decal->relativenormal); - } + R_DecalSystem_SplatEntities(org, normal, Image_LinearFloatFromsRGB(color[0]), Image_LinearFloatFromsRGB(color[1]), Image_LinearFloatFromsRGB(color[2]), alpha*(1.0f/255.0f), particletexture[texnum].s1, particletexture[texnum].t1, particletexture[texnum].s2, particletexture[texnum].t2, size); else - { - if(r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.PointInLeaf) - { - mleaf_t *leaf = r_refdef.scene.worldmodel->brush.PointInLeaf(r_refdef.scene.worldmodel, decal->org); - if(leaf) - decal->clusterindex = leaf->clusterindex; - } - } + R_DecalSystem_SplatEntities(org, normal, color[0]*(1.0f/255.0f), color[1]*(1.0f/255.0f), color[2]*(1.0f/255.0f), alpha*(1.0f/255.0f), particletexture[texnum].s1, particletexture[texnum].t1, particletexture[texnum].s2, particletexture[texnum].t2, size); } void CL_SpawnDecalParticleForPoint(const vec3_t org, float maxdist, float size, float alpha, int texnum, int color1, int color2) @@ -1728,7 +1676,7 @@ void CL_EntityParticles (const entity_t *ent) } -void CL_ReadPointFile_f (void) +void CL_ReadPointFile_f(cmd_state_t *cmd) { double org[3], leakorg[3]; vec3_t vecorg; @@ -2007,12 +1955,12 @@ void CL_ParticleRain (const vec3_t mins, const vec3_t maxs, const vec3_t dir, in } } -cvar_t r_drawparticles = {0, "r_drawparticles", "1", "enables drawing of particles"}; -static cvar_t r_drawparticles_drawdistance = {CVAR_SAVE, "r_drawparticles_drawdistance", "2000", "particles further than drawdistance*size will not be drawn"}; -static cvar_t r_drawparticles_nearclip_min = {CVAR_SAVE, "r_drawparticles_nearclip_min", "4", "particles closer than drawnearclip_min will not be drawn"}; -static cvar_t r_drawparticles_nearclip_max = {CVAR_SAVE, "r_drawparticles_nearclip_max", "4", "particles closer than drawnearclip_min will be faded"}; -cvar_t r_drawdecals = {0, "r_drawdecals", "1", "enables drawing of decals"}; -static cvar_t r_drawdecals_drawdistance = {CVAR_SAVE, "r_drawdecals_drawdistance", "500", "decals further than drawdistance*size will not be drawn"}; +cvar_t r_drawparticles = {CVAR_CLIENT, "r_drawparticles", "1", "enables drawing of particles"}; +static cvar_t r_drawparticles_drawdistance = {CVAR_CLIENT | CVAR_SAVE, "r_drawparticles_drawdistance", "2000", "particles further than drawdistance*size will not be drawn"}; +static cvar_t r_drawparticles_nearclip_min = {CVAR_CLIENT | CVAR_SAVE, "r_drawparticles_nearclip_min", "4", "particles closer than drawnearclip_min will not be drawn"}; +static cvar_t r_drawparticles_nearclip_max = {CVAR_CLIENT | CVAR_SAVE, "r_drawparticles_nearclip_max", "4", "particles closer than drawnearclip_min will be faded"}; +cvar_t r_drawdecals = {CVAR_CLIENT, "r_drawdecals", "1", "enables drawing of decals"}; +static cvar_t r_drawdecals_drawdistance = {CVAR_CLIENT | CVAR_SAVE, "r_drawdecals_drawdistance", "500", "decals further than drawdistance*size will not be drawn"}; #define PARTICLETEXTURESIZE 64 #define PARTICLEFONTSIZE (PARTICLETEXTURESIZE*8) @@ -2325,7 +2273,7 @@ static void R_InitParticleTexture (void) Image_WriteTGABGRA ("particles/particlefont.tga", PARTICLEFONTSIZE, PARTICLEFONTSIZE, particletexturedata); #endif - decalskinframe = R_SkinFrame_LoadInternalBGRA("particlefont", TEXF_ALPHA | TEXF_FORCELINEAR | TEXF_RGBMULTIPLYBYALPHA, particletexturedata, PARTICLEFONTSIZE, PARTICLEFONTSIZE, false); + decalskinframe = R_SkinFrame_LoadInternalBGRA("particlefont", TEXF_ALPHA | TEXF_FORCELINEAR | TEXF_RGBMULTIPLYBYALPHA, particletexturedata, PARTICLEFONTSIZE, PARTICLEFONTSIZE, 0, 0, 0, false); particlefonttexture = decalskinframe->base; Mem_Free(particletexturedata); @@ -2486,157 +2434,6 @@ void R_Particles_Init (void) R_RegisterModule("R_Particles", r_part_start, r_part_shutdown, r_part_newmap, NULL, NULL); } -static void R_DrawDecal_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist) -{ - int surfacelistindex; - const decal_t *d; - float *v3f, *t2f, *c4f; - particletexture_t *tex; - vec_t right[3], up[3], size, ca; - float alphascale = (1.0f / 65536.0f) * cl_particles_alpha.value; - - RSurf_ActiveModelEntity(r_refdef.scene.worldentity, false, false, false); - - r_refdef.stats[r_stat_drawndecals] += numsurfaces; -// R_Mesh_ResetTextureState(); - GL_DepthMask(false); - GL_DepthRange(0, 1); - GL_PolygonOffset(0, 0); - GL_DepthTest(true); - GL_CullFace(GL_NONE); - - // generate all the vertices at once - for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) - { - d = cl.decals + surfacelist[surfacelistindex]; - - // calculate color - c4f = particle_color4f + 16*surfacelistindex; - ca = d->alpha * alphascale; - // ensure alpha multiplier saturates properly - if (ca > 1.0f / 256.0f) - ca = 1.0f / 256.0f; - if (r_refdef.fogenabled) - ca *= RSurf_FogVertex(d->org); - Vector4Set(c4f, d->color[0] * ca, d->color[1] * ca, d->color[2] * ca, 1); - Vector4Copy(c4f, c4f + 4); - Vector4Copy(c4f, c4f + 8); - Vector4Copy(c4f, c4f + 12); - - // calculate vertex positions - size = d->size * cl_particles_size.value; - VectorVectors(d->normal, right, up); - VectorScale(right, size, right); - VectorScale(up, size, up); - v3f = particle_vertex3f + 12*surfacelistindex; - v3f[ 0] = d->org[0] - right[0] - up[0]; - v3f[ 1] = d->org[1] - right[1] - up[1]; - v3f[ 2] = d->org[2] - right[2] - up[2]; - v3f[ 3] = d->org[0] - right[0] + up[0]; - v3f[ 4] = d->org[1] - right[1] + up[1]; - v3f[ 5] = d->org[2] - right[2] + up[2]; - v3f[ 6] = d->org[0] + right[0] + up[0]; - v3f[ 7] = d->org[1] + right[1] + up[1]; - v3f[ 8] = d->org[2] + right[2] + up[2]; - v3f[ 9] = d->org[0] + right[0] - up[0]; - v3f[10] = d->org[1] + right[1] - up[1]; - v3f[11] = d->org[2] + right[2] - up[2]; - - // calculate texcoords - tex = &particletexture[d->texnum]; - t2f = particle_texcoord2f + 8*surfacelistindex; - t2f[0] = tex->s1;t2f[1] = tex->t2; - t2f[2] = tex->s1;t2f[3] = tex->t1; - t2f[4] = tex->s2;t2f[5] = tex->t1; - t2f[6] = tex->s2;t2f[7] = tex->t2; - } - - // now render the decals all at once - // (this assumes they all use one particle font texture!) - GL_BlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - R_SetupShader_Generic(particletexture[63].texture, NULL, GL_MODULATE, 1, false, false, true); - R_Mesh_PrepareVertices_Generic_Arrays(numsurfaces * 4, particle_vertex3f, particle_color4f, particle_texcoord2f); - R_Mesh_Draw(0, numsurfaces * 4, 0, numsurfaces * 2, NULL, NULL, 0, particle_elements, NULL, 0); -} - -void R_DrawDecals (void) -{ - int i; - int drawdecals = r_drawdecals.integer; - decal_t *decal; - float frametime; - float decalfade; - float drawdist2; - unsigned int killsequence = cl.decalsequence - bound(0, (unsigned int) cl_decals_max.integer, cl.decalsequence); - - frametime = bound(0, cl.time - cl.decals_updatetime, 1); - cl.decals_updatetime = bound(cl.time - 1, cl.decals_updatetime + frametime, cl.time + 1); - - // LordHavoc: early out conditions - if (!cl.num_decals) - return; - - decalfade = frametime * 256 / cl_decals_fadetime.value; - drawdist2 = r_drawdecals_drawdistance.value * r_refdef.view.quality; - drawdist2 = drawdist2*drawdist2; - - for (i = 0, decal = cl.decals;i < cl.num_decals;i++, decal++) - { - if (!decal->typeindex) - continue; - - if (killsequence > decal->decalsequence) - goto killdecal; - - if (cl.time > decal->time2 + cl_decals_time.value) - { - decal->alpha -= decalfade; - if (decal->alpha <= 0) - goto killdecal; - } - - if (decal->owner) - { - if (cl.entities[decal->owner].render.model == decal->ownermodel) - { - Matrix4x4_Transform(&cl.entities[decal->owner].render.matrix, decal->relativeorigin, decal->org); - Matrix4x4_Transform3x3(&cl.entities[decal->owner].render.matrix, decal->relativenormal, decal->normal); - } - else - goto killdecal; - } - - if(cl_decals_visculling.integer && decal->clusterindex > -1000 && !CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, decal->clusterindex)) - continue; - - if (!drawdecals) - continue; - - if (!r_refdef.view.useperspective || (DotProduct(r_refdef.view.origin, decal->normal) > DotProduct(decal->org, decal->normal) && VectorDistance2(decal->org, r_refdef.view.origin) < drawdist2 * (decal->size * decal->size))) - R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, decal->org, R_DrawDecal_TransparentCallback, NULL, i, NULL); - continue; -killdecal: - decal->typeindex = 0; - if (cl.free_decal > i) - cl.free_decal = i; - } - - // reduce cl.num_decals if possible - while (cl.num_decals > 0 && cl.decals[cl.num_decals - 1].typeindex == 0) - cl.num_decals--; - - if (cl.num_decals == cl.max_decals && cl.max_decals < MAX_DECALS) - { - decal_t *olddecals = cl.decals; - cl.max_decals = min(cl.max_decals * 2, MAX_DECALS); - cl.decals = (decal_t *) Mem_Alloc(cls.levelmempool, cl.max_decals * sizeof(decal_t)); - memcpy(cl.decals, olddecals, cl.num_decals * sizeof(decal_t)); - Mem_Free(olddecals); - } - - r_refdef.stats[r_stat_totaldecals] = cl.num_decals; -} - static void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist) { vec3_t vecorg, vecvel, baseright, baseup; @@ -2862,6 +2659,13 @@ static void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const t2f[6] = v[1];t2f[7] = tex->t1; break; } + if (r_showparticleedges.integer) + { + R_DebugLine(v3f, v3f + 3); + R_DebugLine(v3f + 3, v3f + 6); + R_DebugLine(v3f + 6, v3f + 9); + R_DebugLine(v3f + 9, v3f); + } } // now render batches of particles based on blendmode and texture @@ -2877,7 +2681,7 @@ static void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const if (texture != particletexture[p->texnum].texture) { texture = particletexture[p->texnum].texture; - R_SetupShader_Generic(texture, NULL, GL_MODULATE, 1, false, false, false); + R_SetupShader_Generic(texture, false, false, false); } if (p->blendmode == PBLEND_INVMOD) @@ -2928,7 +2732,7 @@ void R_DrawParticles (void) frametime = bound(0, cl.time - cl.particles_updatetime, 1); cl.particles_updatetime = bound(cl.time - 1, cl.particles_updatetime + frametime, cl.time + 1); - // LordHavoc: early out conditions + // LadyHavoc: early out conditions if (!cl.num_particles) return;