#include "image.h"
#include "r_shadow.h"
-#define ABSOLUTE_MAX_PARTICLES 1<<24 // upper limit on cl.max_particles
-#define ABSOLUTE_MAX_DECALS 1<<24 // upper limit on cl.max_decals
-
// must match ptype_t values
particletype_t particletype[pt_total] =
{
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"};
+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_RegisterVariable (&cl_particles_quake);
Cvar_RegisterVariable (&cl_particles_blood);
Cvar_RegisterVariable (&cl_particles_blood_alpha);
+ Cvar_RegisterVariable (&cl_particles_blood_decal_alpha);
+ Cvar_RegisterVariable (&cl_particles_blood_decal_scalemin);
+ Cvar_RegisterVariable (&cl_particles_blood_decal_scalemax);
Cvar_RegisterVariable (&cl_particles_blood_bloodhack);
Cvar_RegisterVariable (&cl_particles_explosions_sparks);
Cvar_RegisterVariable (&cl_particles_explosions_shell);
// (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);
- GL_LockArrays(0, numsurfaces*4);
R_Mesh_Draw(0, numsurfaces * 4, 0, numsurfaces * 2, NULL, particle_elements, 0, 0);
- GL_LockArrays(0, 0);
}
void R_DrawDecals (void)
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 < ABSOLUTE_MAX_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, ABSOLUTE_MAX_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);
// now render batches of particles based on blendmode and texture
blendmode = PBLEND_INVALID;
texture = NULL;
- GL_LockArrays(0, numsurfaces*4);
batchstart = 0;
batchcount = 0;
for (surfacelistindex = 0;surfacelistindex < numsurfaces;)
batchcount = surfacelistindex - batchstart;
R_Mesh_Draw(batchstart * 4, batchcount * 4, batchstart * 2, batchcount * 2, NULL, particle_elements, 0, 0);
}
- GL_LockArrays(0, 0);
}
void R_DrawParticles (void)
if (cl_decals.integer)
{
// create a decal for the blood splat
- CL_SpawnDecalParticleForSurface(hitent, p->org, trace.plane.normal, p->color[0] * 65536 + p->color[1] * 256 + p->color[2], p->color[0] * 65536 + p->color[1] * 256 + p->color[2], tex_blooddecal[rand()&7], p->size * 2, p->alpha);
+ CL_SpawnDecalParticleForSurface(hitent, p->org, trace.plane.normal, p->color[0] * 65536 + p->color[1] * 256 + p->color[2], p->color[0] * 65536 + p->color[1] * 256 + p->color[2], tex_blooddecal[rand()&7], p->size * lhrandom(cl_particles_blood_decal_scalemin.value, cl_particles_blood_decal_scalemax.value), cl_particles_blood_decal_alpha.value * 768);
}
}
goto killparticle;
while (cl.num_particles > 0 && cl.particles[cl.num_particles - 1].typeindex == 0)
cl.num_particles--;
- if (cl.num_particles == cl.max_particles && cl.max_particles < ABSOLUTE_MAX_PARTICLES)
+ if (cl.num_particles == cl.max_particles && cl.max_particles < MAX_PARTICLES)
{
particle_t *oldparticles = cl.particles;
- cl.max_particles = min(cl.max_particles * 2, ABSOLUTE_MAX_PARTICLES);
+ cl.max_particles = min(cl.max_particles * 2, MAX_PARTICLES);
cl.particles = (particle_t *) Mem_Alloc(cls.levelmempool, cl.max_particles * sizeof(particle_t));
memcpy(cl.particles, oldparticles, cl.num_particles * sizeof(particle_t));
Mem_Free(oldparticles);