X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=cl_particles.c;h=3d129b61f4081ff6f3663e67d23445f1458d8112;hb=87a99dafc0a80dd138a8bddef2664a497c970a9a;hp=c185062e58a7a3d8b4978267b925599c82ec9d69;hpb=db37e0dbe94491a5d182ad2bed1938611e43b7ef;p=xonotic%2Fdarkplaces.git diff --git a/cl_particles.c b/cl_particles.c index c185062e..3d129b61 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -180,7 +180,7 @@ float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int typedef enum { - pt_dead, pt_static, pt_rain, pt_bubble, pt_blood, pt_grow, pt_decal, pt_decalfade, pt_ember + pt_dead, pt_static, pt_rain, pt_bubble, pt_blood, pt_grow, pt_decal, pt_ember } ptype_t; @@ -327,6 +327,7 @@ void CL_Particles_Init (void) { int i; +// COMMANDLINEOPTION: Client: -particles changes maximum number of particles at once, default 32768 i = COM_CheckParm ("-particles"); if (i && i < com_argc - 1) @@ -370,6 +371,15 @@ void CL_Particles_Init (void) CL_Particles_Clear(); } +void CL_Particles_Shutdown (void) +{ +#ifdef WORKINGLQUAKE + // No clue what to do here... +#else + Mem_FreePool (&cl_part_mempool); +#endif +} + // list of all 26 parameters: // ptype - any of the pt_ enum values (pt_static, pt_blood, etc), see ptype_t near the top of this file // porientation - PARTICLE_ enum values (PARTICLE_BILLBOARD, PARTICLE_SPARK, etc) @@ -781,46 +791,53 @@ void CL_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count) CL_SparkShower =============== */ -void CL_SparkShower (vec3_t org, vec3_t dir, int count) +void CL_SparkShower (vec3_t org, vec3_t dir, int count, vec_t gravityscale) { - vec3_t org2, org3; int k; - if (cl_stainmaps.integer) - R_Stain(org, 32, 96, 96, 96, 24, 128, 128, 128, 24); - CL_SpawnDecalParticleForPoint(org, 6, 3, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF); - if (!cl_particles.integer) return; - if (cl_particles_bulletimpacts.integer) + if (cl_particles_sparks.integer) { - // smoke puff - if (cl_particles_smoke.integer) + // sparks + count *= cl_particles_quality.value; + while(count--) { - k = count * 0.25 * cl_particles_quality.value; - while(k--) - { - org2[0] = org[0] + 0.125f * lhrandom(-count, count); - org2[1] = org[1] + 0.125f * lhrandom(-count, count); - org2[2] = org[2] + 0.125f * lhrandom(-count, count); - CL_TraceLine(org, org2, org3, NULL, true, NULL, SUPERCONTENTS_SOLID); - particle(pt_grow, PARTICLE_BILLBOARD, 0x101010, 0x202020, tex_smoke[rand()&7], true, PBLEND_ADD, 3, 3, (1.0f / cl_particles_quality.value) * 255, (1.0f / cl_particles_quality.value) * 1024, 9999, -0.2, 0, org3[0], org3[1], org3[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(0, 16), 15, 0, 0, 0, 0.2, 0); - } + k = particlepalette[0x68 + (rand() & 7)]; + particle(pt_static, PARTICLE_SPARK, k, k, tex_particle, false, PBLEND_ADD, 0.4f, 0.015f, (1.0f / cl_particles_quality.value) * lhrandom(64, 255), (1.0f / cl_particles_quality.value) * 512, 9999, gravityscale, 0, org[0], org[1], org[2], lhrandom(-64, 64) + dir[0], lhrandom(-64, 64) + dir[1], lhrandom(0, 128) + dir[2], 0, 0, 0, 0, 0, 0); } + } +} + +void CL_Smoke (vec3_t org, vec3_t dir, int count) +{ + vec3_t org2, org3; + int k; + + if (!cl_particles.integer) return; - if (cl_particles_sparks.integer) + // smoke puff + if (cl_particles_smoke.integer) + { + k = count * 0.25 * cl_particles_quality.value; + while(k--) { - // sparks - count *= cl_particles_quality.value; - while(count--) - { - k = particlepalette[0x68 + (rand() & 7)]; - particle(pt_static, PARTICLE_SPARK, k, k, tex_particle, false, PBLEND_ADD, 0.4f, 0.015f, (1.0f / cl_particles_quality.value) * lhrandom(64, 255), (1.0f / cl_particles_quality.value) * 512, 9999, 1, 0, org[0], org[1], org[2], lhrandom(-64, 64) + dir[0], lhrandom(-64, 64) + dir[1], lhrandom(0, 128) + dir[2], 0, 0, 0, 0, 0.2, 0); - } + org2[0] = org[0] + 0.125f * lhrandom(-count, count); + org2[1] = org[1] + 0.125f * lhrandom(-count, count); + org2[2] = org[2] + 0.125f * lhrandom(-count, count); + CL_TraceLine(org, org2, org3, NULL, true, NULL, SUPERCONTENTS_SOLID); + particle(pt_grow, PARTICLE_BILLBOARD, 0x101010, 0x202020, tex_smoke[rand()&7], true, PBLEND_ADD, 3, 3, (1.0f / cl_particles_quality.value) * 255, (1.0f / cl_particles_quality.value) * 1024, 9999, 0, 0, org3[0], org3[1], org3[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(-8, 8), 15, 0, 0, 0, 0, 0); } } } +void CL_BulletMark (vec3_t org) +{ + if (cl_stainmaps.integer) + R_Stain(org, 32, 96, 96, 96, 24, 128, 128, 128, 24); + CL_SpawnDecalParticleForPoint(org, 6, 3, 255, tex_bulletdecal[rand()&7], 0xFFFFFF, 0xFFFFFF); +} + void CL_PlasmaBurn (vec3_t org) { if (cl_stainmaps.integer) @@ -1124,6 +1141,7 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, int color, entity_t *en if (speed) speed = 1.0f / speed; VectorSubtract(ent->state_current.origin, ent->state_previous.origin, vel); + color = particlepalette[color]; #endif VectorScale(vel, speed, vel); @@ -1340,8 +1358,8 @@ void CL_MoveParticles (void) Matrix4x4_Transform3x3(&hitent->inversematrix, normal, p->relativedirection); VectorAdd(p->relativeorigin, p->relativedirection, p->relativeorigin); #endif - p->time2 = cl.time + cl_decals_time.value; - p->die = p->time2 + cl_decals_fadetime.value; + p->time2 = cl.time; + p->die = p->time2 + cl_decals_time.value + cl_decals_fadetime.value; p->alphafade = 0; VectorCopy(normal, p->vel2); VectorClear(p->vel); @@ -1434,22 +1452,7 @@ void CL_MoveParticles (void) p->scaley += frametime * p->time2; break; case pt_decal: -#ifndef WORKINGLQUAKE - if (p->owner->model == p->ownermodel) - { - Matrix4x4_Transform(&p->owner->matrix, p->relativeorigin, p->org); - Matrix4x4_Transform3x3(&p->owner->matrix, p->relativedirection, p->vel2); - if (cl.time > p->time2) - { - p->alphafade = p->alpha / (p->die - cl.time); - p->type = pt_decalfade; - } - } - else - p->type = pt_dead; -#endif - break; - case pt_decalfade: + p->alphafade = cl.time > (p->time2 + cl_decals_time.value) ? (p->alpha / cl_decals_fadetime.value) : 0; #ifndef WORKINGLQUAKE if (p->owner->model == p->ownermodel) { @@ -1497,7 +1500,7 @@ static particletexture_t particletexture[MAX_PARTICLETEXTURES]; static cvar_t r_drawparticles = {0, "r_drawparticles", "1"}; -#define PARTICLETEXTURESIZE 32 +#define PARTICLETEXTURESIZE 64 #define PARTICLEFONTSIZE (PARTICLETEXTURESIZE*8) static qbyte shadebubble(float dx, float dy, vec3_t light) @@ -1626,10 +1629,10 @@ static void R_InitParticleTexture (void) m = 0; for (y = 0;y < PARTICLETEXTURESIZE;y++) { - dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); for (x = 0;x < PARTICLETEXTURESIZE;x++) { - dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); d = (noise2[y][x] - 128) * 3 + 192; if (d > 0) d = d * (1-(dx*dx+dy*dy)); @@ -1653,10 +1656,10 @@ static void R_InitParticleTexture (void) f2 = 255.0f * ((15.0f - i) / 15.0f); for (y = 0;y < PARTICLETEXTURESIZE;y++) { - dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); for (x = 0;x < PARTICLETEXTURESIZE;x++) { - dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); f = f2 * (1.0 - 4.0f * fabs(radius - sqrt(dx*dx+dy*dy))); data[y][x][3] = (int) (bound(0.0f, f, 255.0f)); } @@ -1668,10 +1671,10 @@ static void R_InitParticleTexture (void) memset(&data[0][0][0], 255, sizeof(data)); for (y = 0;y < PARTICLETEXTURESIZE;y++) { - dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); for (x = 0;x < PARTICLETEXTURESIZE;x++) { - dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); d = 256 * (1 - (dx*dx+dy*dy)); d = bound(0, d, 255); data[y][x][3] = (qbyte) d; @@ -1685,7 +1688,7 @@ static void R_InitParticleTexture (void) VectorNormalize(light); for (y = 0;y < PARTICLETEXTURESIZE;y++) { - dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); // stretch upper half of bubble by +50% and shrink lower half by -50% // (this gives an elongated teardrop shape) if (dy > 0.5f) @@ -1694,7 +1697,7 @@ static void R_InitParticleTexture (void) dy = (dy - 0.5f) / 1.5f; for (x = 0;x < PARTICLETEXTURESIZE;x++) { - dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); // shrink bubble width to half dx *= 2.0f; data[y][x][3] = shadebubble(dx, dy, light); @@ -1708,10 +1711,10 @@ static void R_InitParticleTexture (void) VectorNormalize(light); for (y = 0;y < PARTICLETEXTURESIZE;y++) { - dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); for (x = 0;x < PARTICLETEXTURESIZE;x++) { - dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f+1); + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); data[y][x][3] = shadebubble(dx, dy, light); } } @@ -1759,6 +1762,11 @@ static void R_InitParticleTexture (void) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); #else + +#if 0 + Image_WriteTGARGBA ("particles/particlefont.tga", PARTICLEFONTSIZE, PARTICLEFONTSIZE, particletexturedata); +#endif + particlefonttexture = loadtextureimage(particletexturepool, "particles/particlefont.tga", 0, 0, false, TEXF_ALPHA | TEXF_PRECACHE); if (!particlefonttexture) particlefonttexture = R_LoadTexture2D(particletexturepool, "particlefont", PARTICLEFONTSIZE, PARTICLEFONTSIZE, particletexturedata, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL); @@ -1770,16 +1778,20 @@ static void R_InitParticleTexture (void) m = 0; for (y = 0;y < 64;y++) { - dy = (y - 0.5f*64) / (64*0.5f+1); + dy = (y - 0.5f*64) / (64*0.5f-1); for (x = 0;x < 16;x++) { - dx = (x - 0.5f*16) / (16*0.5f+1); - d = (1 - (dx*dx)) * noise3[y][x]; + dx = (x - 0.5f*16) / (16*0.5f-2); + d = (1 - sqrt(fabs(dx))) * noise3[y][x]; data2[y][x][0] = data2[y][x][1] = data2[y][x][2] = (qbyte) bound(0, d, 255); data2[y][x][3] = 255; } } +#if 0 + Image_WriteTGARGBA ("particles/nexbeam.tga", 64, 64, &data2[0][0][0]); +#endif + particletexture[tex_beam].texture = loadtextureimage(particletexturepool, "particles/nexbeam.tga", 0, 0, false, TEXF_ALPHA | TEXF_PRECACHE); if (!particletexture[tex_beam].texture) particletexture[tex_beam].texture = R_LoadTexture2D(particletexturepool, "nexbeam", 16, 64, &data2[0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE, NULL); @@ -1946,8 +1958,8 @@ void R_DrawParticleCallback(const void *calldata1, int calldata2) R_CalcBeam_Vertex3f(particle_vertex3f, p->org, p->vel2, p->scalex); VectorSubtract(p->vel2, p->org, up); VectorNormalizeFast(up); - v[0] = DotProduct(p->org, up) * (1.0f / 64.0f) - cl.time * 0.25; - v[1] = DotProduct(p->vel2, up) * (1.0f / 64.0f) - cl.time * 0.25; + v[0] = DotProduct(p->org, up) * (1.0f / 64.0f); + v[1] = DotProduct(p->vel2, up) * (1.0f / 64.0f); particle_texcoord2f[0] = 1;particle_texcoord2f[1] = v[0]; particle_texcoord2f[2] = 0;particle_texcoord2f[3] = v[0]; particle_texcoord2f[4] = 0;particle_texcoord2f[5] = v[1]; @@ -2011,7 +2023,12 @@ void R_DrawParticles (void) { c_particles++; if (DotProduct(p->org, r_viewforward) >= minparticledist || p->orientation == PARTICLE_BEAM) - R_MeshQueue_AddTransparent(p->org, R_DrawParticleCallback, p, 0); + { + if (p->type == pt_decal) + R_DrawParticleCallback(p, 0); + else + R_MeshQueue_AddTransparent(p->org, R_DrawParticleCallback, p, 0); + } } } #endif