From: lordhavoc Date: Tue, 12 Mar 2002 16:57:26 +0000 (+0000) Subject: added cl_particles_blood_size_min, cl_particles_blood_size_max, and cl_particles_bloo... X-Git-Tag: RELEASE_0_2_0_RC1~591 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=63e01393ed618f8561aee961acfc8a25bb30eb7f added cl_particles_blood_size_min, cl_particles_blood_size_max, and cl_particles_blood_alpha cvars changed trails back to quake-style (spawn over distance, not over time) pt_fade now takes a fade rate (in p->time2) many tweaks to particle effets loading screens work correctly now cleaned up backend code a bit, now does not freak out if a texture upload occurs during rendering added r_quickmodels (default: on) which makes single-pass models (the vast majority of models) store vertex data directly into the backend arrays (using R_Mesh_Draw_GetBuffer) model vertex transforms are now applied *after* lighting, this avoids transforming the normals, and prepares for someday adding transforms to the backend fixed view blend in gl_rmain.c to work correctly with fov values above 90 moved image resampling and mipmapping from gl_textures.c to image.c now updates screen twice while connecting to a server (so it displays the 'trying...' messages) improved directional shading of explosions disabled r_lightmodelhardness since the default was nearly 1.0 anyway, 1.0 is a special quick case R_LightModel now tints the model and can accept vertices/normals in either model or world coordinates (previously required world coordinates) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@1631 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_particles.c b/cl_particles.c index 823c68bf..cca5a5b6 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -109,6 +109,9 @@ static cvar_t cl_particles = {CVAR_SAVE, "cl_particles", "1"}; static cvar_t cl_particles_size = {CVAR_SAVE, "cl_particles_size", "1"}; static cvar_t cl_particles_bloodshowers = {CVAR_SAVE, "cl_particles_bloodshowers", "1"}; static cvar_t cl_particles_blood = {CVAR_SAVE, "cl_particles_blood", "1"}; +static cvar_t cl_particles_blood_size_min = {CVAR_SAVE, "cl_particles_blood_size_min", "3"}; +static cvar_t cl_particles_blood_size_max = {CVAR_SAVE, "cl_particles_blood_size_max", "15"}; +static cvar_t cl_particles_blood_alpha = {CVAR_SAVE, "cl_particles_blood_alpha", "1"}; static cvar_t cl_particles_smoke = {CVAR_SAVE, "cl_particles_smoke", "1"}; static cvar_t cl_particles_sparks = {CVAR_SAVE, "cl_particles_sparks", "1"}; static cvar_t cl_particles_bubbles = {CVAR_SAVE, "cl_particles_bubbles", "1"}; @@ -148,6 +151,9 @@ void CL_Particles_Init (void) Cvar_RegisterVariable (&cl_particles_size); Cvar_RegisterVariable (&cl_particles_bloodshowers); Cvar_RegisterVariable (&cl_particles_blood); + Cvar_RegisterVariable (&cl_particles_blood_size_min); + Cvar_RegisterVariable (&cl_particles_blood_size_max); + Cvar_RegisterVariable (&cl_particles_blood_alpha); Cvar_RegisterVariable (&cl_particles_smoke); Cvar_RegisterVariable (&cl_particles_sparks); Cvar_RegisterVariable (&cl_particles_bubbles); @@ -234,7 +240,7 @@ void CL_EntityParticles (entity_t *ent) forward[1] = cp*sy; forward[2] = -sp; - particle(pt_oneframe, PARTICLE_BILLBOARD, particlepalette[0x6f], tex_particle, false, true, 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); + particle(pt_oneframe, PARTICLE_BILLBOARD, particlepalette[0x6f], tex_particle, false, 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); } } @@ -320,6 +326,7 @@ CL_ParticleExplosion */ void CL_ParticleExplosion (vec3_t org, int smoke) { + R_Stain(org, 96, 80, 80, 80, 128, 176, 176, 176, 128); if (cl_particles.integer && cl_particles_explosions.integer) { int i, j; @@ -349,7 +356,7 @@ 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, PARTICLE_BILLBOARD, noise2[j*32+i] * 0x010101, tex_smoke[rand()&7], false, 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); + particle(pt_underwaterspark, PARTICLE_BILLBOARD, noise2[j*32+i] * 0x010101, tex_smoke[rand()&7], false, true, 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, PARTICLE_BILLBOARD, explosparkramp[(noise2[j*32+i] >> 5)], tex_particle, false, true, 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); } @@ -372,7 +379,7 @@ 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, PARTICLE_BILLBOARD, noise2[j*32+i] * 0x010101, tex_smoke[rand()&7], false, 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); + particle(pt_spark, PARTICLE_BILLBOARD, noise2[j*32+i] * 0x010101, tex_smoke[rand()&7], false, true, 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, PARTICLE_BILLBOARD, explosparkramp[(noise2[j*32+i] >> 5)], tex_particle, false, true, 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); @@ -383,8 +390,23 @@ void CL_ParticleExplosion (vec3_t org, int smoke) } } else + { + /* + int i; + vec3_t v; + for (i = 0;i < 256;i++) + { + do + { + VectorRandom(v); + } + while(DotProduct(v,v) < 0.75); + VectorScale(v, 512, v); + particle(pt_spark, PARTICLE_BILLBOARD, explosparkramp[rand()&7], tex_particle, false, true, 4, 4, 255, 9999, 1.5, org[0], org[1], org[2], v[0], v[1], v[2] + 160.0f, 512.0f, 0, 0, 0, 2, 0); + } + */ R_NewExplosion(org); - R_Stain(org, 96, 80, 80, 80, 128, 176, 176, 176, 128); + } } /* @@ -399,7 +421,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, PARTICLE_BILLBOARD, particlepalette[colorStart + (i % colorLength)], tex_particle, false, 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, 1, 0); + particle(pt_fade, PARTICLE_BILLBOARD, particlepalette[colorStart + (i % colorLength)], tex_particle, false, 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), 384, 0, 0, 0, 1, 0); } /* @@ -410,14 +432,18 @@ CL_BlobExplosion */ void CL_BlobExplosion (vec3_t org) { - int i; + //int i; if (!cl_particles.integer) return; - R_Stain(org, 96, 96, 64, 96, 128, 160, 128, 160, 128); - for (i = 0;i < 256;i++) - particle(pt_blob , PARTICLE_BILLBOARD, particlepalette[ 66+(rand()%6)], tex_particle, false, true, 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, PARTICLE_BILLBOARD, particlepalette[150+(rand()%6)], tex_particle, false, true, 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); + R_Stain(org, 96, 80, 80, 80, 128, 176, 176, 176, 128); + //R_Stain(org, 96, 96, 64, 96, 128, 160, 128, 160, 128); + + R_NewExplosion(org); + + //for (i = 0;i < 256;i++) + // particle(pt_blob , PARTICLE_BILLBOARD, particlepalette[ 66+(rand()%6)], tex_particle, false, true, 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, PARTICLE_BILLBOARD, particlepalette[150+(rand()%6)], tex_particle, false, true, 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); } /* @@ -436,7 +462,7 @@ void CL_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count) return; } while (count--) - particle(pt_fade, PARTICLE_BILLBOARD, particlepalette[color + (rand()&7)], tex_particle, false, 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); + particle(pt_fade, PARTICLE_BILLBOARD, particlepalette[color + (rand()&7)], tex_particle, false, 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), 384, 0, 0, 0, 0, 0); } // LordHavoc: added this for spawning sparks/dust (which have strong gravity) @@ -453,13 +479,13 @@ void CL_SparkShower (vec3_t org, vec3_t dir, int count) // smoke puff if (cl_particles_smoke.integer) - particle(pt_bulletsmoke, PARTICLE_BILLBOARD, 0xFFFFFF /*0xA0A0A0*/, tex_smoke[rand()&7], true, 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); + particle(pt_bulletsmoke, PARTICLE_BILLBOARD, 0xFFFFFF /*0xA0A0A0*/, tex_smoke[rand()&7], true, true, 2, 2, 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, PARTICLE_BILLBOARD, particlepalette[0x68 + (rand() & 7)], tex_particle, false, true, 1, 1, lhrandom(0, 255), 9999, 1.5, org[0], org[1], org[2], lhrandom(-64, 64) + dir[0], lhrandom(-64, 64) + dir[1], lhrandom(0, 128) + dir[2], 512, 0, 0, 0, 1, 0); + particle(pt_spark, PARTICLE_BILLBOARD, particlepalette[0x68 + (rand() & 7)], tex_particle, false, true, 1, 1, lhrandom(64, 128), 9999, 0, org[0], org[1], org[2], lhrandom(-64, 64) + dir[0], lhrandom(-64, 64) + dir[1], lhrandom(0, 128) + dir[2], 480, 0, 0, 0, 1, 0); } } @@ -472,23 +498,29 @@ void CL_PlasmaBurn (vec3_t org) void CL_BloodPuff (vec3_t org, vec3_t vel, int count) { + float r, s; // bloodcount is used to accumulate counts too small to cause a blood particle static int bloodcount = 0; if (!cl_particles.integer) return; if (!cl_particles_blood.integer) return; - if (count > 100) - count = 100; + s = count + 32.0f; + count *= 5.0f; + if (count > 1000) + count = 1000; bloodcount += count; - while(bloodcount >= 10) + while(bloodcount > 0) { - particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, false, 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, 0); - bloodcount -= 10; + r = lhrandom(cl_particles_blood_size_min.value, cl_particles_blood_size_max.value); + particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, false, r, r, cl_particles_blood_alpha.value * 255, 9999, -1, org[0], org[1], org[2], vel[0] + lhrandom(-s, s), vel[1] + lhrandom(-s, s), vel[2] + lhrandom(-s, s), 0, 0, 0, 0, 1, 0); + bloodcount -= r; } } void CL_BloodShower (vec3_t mins, vec3_t maxs, float velspeed, int count) { + float c; + float r; vec3_t diff, center, velscale; if (!cl_particles.integer) return; if (!cl_particles_bloodshowers.integer) return; @@ -503,7 +535,8 @@ void CL_BloodShower (vec3_t mins, vec3_t maxs, float velspeed, int count) velscale[1] = velspeed * 2.0 / diff[1]; velscale[2] = velspeed * 2.0 / diff[2]; - while (count--) + c = count * 5; + while (c > 0) { vec3_t org, vel; org[0] = lhrandom(mins[0], maxs[0]); @@ -512,7 +545,9 @@ 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, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, false, 24, 24, 255, 9999, -1, org[0], org[1], org[2], vel[0], vel[1], vel[2], 0, 0, 0, 0, 1, 0); + r = lhrandom(cl_particles_blood_size_min.value, cl_particles_blood_size_max.value); + c -= r; + particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, false, r, r, cl_particles_blood_alpha.value * 255, 9999, -1, org[0], org[1], org[2], vel[0], vel[1], vel[2], 0, 0, 0, 0, 1, 0); } } @@ -641,16 +676,15 @@ 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, PARTICLE_BILLBOARD, 0xFFFFFF, tex_particle, false, true, 1.5, 1.5, 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, 1, 0); - particle(pt_spark, PARTICLE_BILLBOARD, 0xFFFFFF, tex_particle, false, true, 2, 2, lhrandom(64, 255), 9999, 0, org[0] + i + lhrandom(0, 8), org[1] + j + lhrandom(0, 8), org[2] + k + lhrandom(0, 8), lhrandom(-64, 64), lhrandom(-64, 64), lhrandom(0, 512), 512.0f, 0, 0, 0, 1, 0); + //particle(pt_fade, PARTICLE_BILLBOARD, 0xFFFFFF, tex_particle, false, true, 1.5, 1.5, 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), 384.0f, 0, 0, 0, 1, 0); + particle(pt_fade, PARTICLE_BILLBOARD, 0xFFFFFF, tex_particle, false, true, 10, 10, lhrandom(64, 128), 9999, 0, org[0] + i + lhrandom(0, 8), org[1] + j + lhrandom(0, 8), org[2] + k + lhrandom(0, 8), lhrandom(-64, 64), lhrandom(-64, 64), lhrandom(-256, 256), 256.0f, 0, 0, 0, 1, 0); } void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) { vec3_t vec, dir, vel, pos; - float len, dec = 0, speed; - int contents, bubbles; - double t; + float len, dec, speed; + int contents, bubbles/*, c*/; if (!cl_particles.integer) return; VectorSubtract(end, start, dir); @@ -659,57 +693,53 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) //if (type == 0 && host_frametime != 0) // rocket glow // particle(pt_oneframe, PARTICLE_BILLBOARD, 0xFFFFFF, tex_rocketglow, false, true, 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) - return; // no particles to spawn this frame (sparse trail) - - if (t < cl.oldtime) - t = cl.oldtime; - VectorSubtract (end, start, vec); len = VectorNormalizeLength (vec); - if (len <= 0.01f) - { - // advance the trail time - ent->persistent.trail_time = cl.time; + dec = -ent->persistent.trail_time; + ent->persistent.trail_time += len; + if (ent->persistent.trail_time < 0.01f) return; - } - speed = len / (cl.time - cl.oldtime); - VectorScale(vec, speed, vel); + + speed = 1.0f / (ent->state_current.time - ent->state_previous.time); + VectorSubtract(ent->state_current.origin, ent->state_previous.origin, vel); + VectorScale(vel, speed, vel); // advance into this frame to reach the first puff location - dec = t - cl.oldtime; - dec *= speed; VectorMA(start, dec, vec, pos); + len -= dec; + + // if we skip out, leave it reset + ent->persistent.trail_time = 0.0f; contents = Mod_PointInLeaf(pos, cl.worldmodel)->contents; if (contents == CONTENTS_SKY || contents == CONTENTS_LAVA) - { - // advance the trail time - ent->persistent.trail_time = cl.time; return; - } bubbles = (contents == CONTENTS_WATER || contents == CONTENTS_SLIME); - while (t < cl.time) + while (len >= 0) { switch (type) { case 0: // rocket trail if (!cl_particles_smoke.integer) - dec = cl.time - t; - else if (bubbles && cl_particles_bubbles.integer) + return; + //dec = 5; + //particle(pt_fade, PARTICLE_BILLBOARD, 0x707070, tex_particle, true, false, dec, dec, 128, 9999, 0, pos[0], pos[1], pos[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(-8, 8), 256.0f, 0, 0, 0, 0, 0); + dec = 6; + particle(pt_fade, PARTICLE_BILLBOARD, 0x707070, tex_smoke[rand()&7], true, true, dec, dec, 128, 9999, 0, pos[0], pos[1], pos[2], lhrandom(-5, 5), lhrandom(-5, 5), lhrandom(-5, 5), 256.0f, 0, 0, 0, 0, 0); + //particle(pt_fade, PARTICLE_BILLBOARD, 0x707070, tex_smoke[rand()&7], false, true, dec, dec, 128, 9999, 0, pos[0], pos[1], pos[2], lhrandom(-10, 10), lhrandom(-10, 10), lhrandom(-10, 10), 128.0f, 0, 0, 0, 0, 0); + //dec = 10; + //particle(pt_smoke, PARTICLE_BILLBOARD, 0x707070, tex_smoke[rand()&7], false, true, 2, 2, 160, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + if (bubbles && cl_particles_bubbles.integer) { - dec = 0.005f; particle(pt_bubble, PARTICLE_BILLBOARD, 0xFFFFFF, tex_bubble, false, true, 2, 2, 255, 9999, 1.5, pos[0], pos[1], pos[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, true, 2, 2, 255, 9999, 1.5, pos[0], pos[1], pos[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, false, 2, 2, 160, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + //particle(pt_bubble, PARTICLE_BILLBOARD, 0xFFFFFF, tex_bubble, false, true, 2, 2, 255, 9999, 1.5, pos[0], pos[1], pos[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16), 0, 0, 0, 0, 0, 0); } else { - dec = 0.005f; - particle(pt_smoke, PARTICLE_BILLBOARD, 0xC0C0C0, tex_smoke[rand()&7], true, false, 2, 2, 160, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + //particle(pt_spark, PARTICLE_BILLBOARD, particlepalette[0x68 + (rand() & 7)], tex_particle, false, true, 2, 2, lhrandom(128, 255), 9999, 1.5, pos[0], pos[1], pos[2], lhrandom(-64, 64), lhrandom(-64, 64), lhrandom(-64, 64), 512.0f, 0, 0, 0, 1, 0); + //particle(pt_spark, PARTICLE_BILLBOARD, particlepalette[0x68 + (rand() & 7)], tex_particle, false, true, 2, 2, lhrandom(128, 255), 9999, 1.5, pos[0], pos[1], pos[2], lhrandom(-64, 64), lhrandom(-64, 64), lhrandom(-64, 64), 512.0f, 0, 0, 0, 1, 0); //particle(pt_spark, PARTICLE_BILLBOARD, particlepalette[0x68 + (rand() & 7)], tex_particle, false, true, 1, 1, lhrandom(128, 255), 9999, 1.5, pos[0], pos[1], pos[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, 1, 0); //particle(pt_spark, PARTICLE_BILLBOARD, particlepalette[0x68 + (rand() & 7)], tex_particle, false, true, 1, 1, lhrandom(128, 255), 9999, 1.5, pos[0], pos[1], pos[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, 1, 0); //particle(pt_spark, PARTICLE_BILLBOARD, particlepalette[0x68 + (rand() & 7)], tex_particle, false, true, 1, 1, lhrandom(128, 255), 9999, 1.5, pos[0], pos[1], pos[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, 1, 0); @@ -720,74 +750,71 @@ void CL_RocketTrail (vec3_t start, vec3_t end, int type, entity_t *ent) case 1: // grenade trail // FIXME: make it gradually stop smoking if (!cl_particles_smoke.integer) - dec = cl.time - t; - else if (bubbles && cl_particles_bubbles.integer) + return; + //dec = 5; + //particle(pt_fade, PARTICLE_BILLBOARD, 0x707070, tex_particle, true, false, dec, dec, 128, 9999, 0, pos[0], pos[1], pos[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(-8, 8), 256.0f, 0, 0, 0, 0, 0); + dec = 6; + particle(pt_fade, PARTICLE_BILLBOARD, 0x404040, tex_smoke[rand()&7], true, true, dec, dec, 128, 9999, 0, pos[0], pos[1], pos[2], lhrandom(-5, 5), lhrandom(-5, 5), lhrandom(-5, 5), 256.0f, 0, 0, 0, 0, 0); + //particle(pt_smoke, PARTICLE_BILLBOARD, 0x404040, tex_smoke[rand()&7], false, true, 2, 2, 160, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + if (bubbles && cl_particles_bubbles.integer) { - dec = 0.02f; - particle(pt_bubble, PARTICLE_BILLBOARD, 0xFFFFFF, tex_bubble, false, true, 2, 2, 255, 9999, 1.5, pos[0], pos[1], pos[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, true, 2, 2, 255, 9999, 1.5, pos[0], pos[1], pos[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, false, 2, 2, 160, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); - } - else - { - dec = 0.02f; - particle(pt_smoke, PARTICLE_BILLBOARD, 0x808080, tex_smoke[rand()&7], true, false, 2, 2, 160, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + //particle(pt_bubble, PARTICLE_BILLBOARD, 0xFFFFFF, tex_bubble, false, true, 2, 2, 255, 9999, 1.5, pos[0], pos[1], pos[2], lhrandom(-16, 16), lhrandom(-16, 16), lhrandom(-16, 16), 0, 0, 0, 0, 0, 0); } break; case 2: // blood if (!cl_particles_blood.integer) - dec = cl.time - t; - else - { - dec = 0.1f; - particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, false, 24, 24, 255, 9999, -1, pos[0], pos[1], pos[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64), 0, 0, 0, 0, 1, 0); - } + return; + dec = lhrandom(cl_particles_blood_size_min.value, cl_particles_blood_size_max.value); + //particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, false, dec, dec, cl_particles_blood_alpha.value * 255.0f, 9999, -1, pos[0], pos[1], pos[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64), 0, 0, 0, 0, 1, 0); + particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, false, dec, dec, cl_particles_blood_alpha.value * 255.0f, 9999, -1, pos[0], pos[1], pos[2], lhrandom(-64, 64), lhrandom(-64, 64), lhrandom(-64, 64), 0, 0, 0, 0, 1, 0); + //c = ((rand() & 15) + 16) << 16; + //particle(pt_blood, PARTICLE_BILLBOARD, c, tex_particle, true, false, dec, dec, cl_particles_blood_alpha.value * 255.0f, 9999, -1, pos[0], pos[1], pos[2], lhrandom(-64, 64), lhrandom(-64, 64), lhrandom(-64, 64), 0, 0, 0, 0, 1, 0); break; case 4: // slight blood if (!cl_particles_blood.integer) - dec = cl.time - t; - else - { - dec = 0.15f; - particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, false, 24, 24, 255, 9999, -1, pos[0], pos[1], pos[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64), 0, 0, 0, 0, 1, 0); - } + return; + dec = lhrandom(cl_particles_blood_size_min.value, cl_particles_blood_size_max.value); + //particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, false, dec, dec, cl_particles_blood_alpha.value * 128.0f, 9999, -1, pos[0], pos[1], pos[2], vel[0] + lhrandom(-64, 64), vel[1] + lhrandom(-64, 64), vel[2] + lhrandom(-64, 64), 0, 0, 0, 0, 1, 0); + particle(pt_blood, PARTICLE_BILLBOARD, 0x300000, tex_smoke[rand()&7], true, false, dec, dec, cl_particles_blood_alpha.value * 128.0f, 9999, -1, pos[0], pos[1], pos[2], lhrandom(-64, 64), lhrandom(-64, 64), lhrandom(-64, 64), 0, 0, 0, 0, 1, 0); + //c = ((rand() & 15) + 16) << 16; + //particle(pt_blood, PARTICLE_BILLBOARD, c, tex_particle, true, false, dec, dec, cl_particles_blood_alpha.value * 128.0f, 9999, -1, pos[0], pos[1], pos[2], lhrandom(-64, 64), lhrandom(-64, 64), lhrandom(-64, 64), 0, 0, 0, 0, 1, 0); break; case 3: // green tracer - dec = 0.02f; - particle(pt_fade, PARTICLE_BILLBOARD, 0x373707, tex_smoke[rand()&7], false, false, 4, 4, 255, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + dec = 6; + //particle(pt_fade, PARTICLE_BILLBOARD, 0x373707, tex_particle, false, true, dec, dec, 255, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 384.0f, 0, 0, 0, 0, 0); + particle(pt_fade, PARTICLE_BILLBOARD, 0x373707, tex_particle, false, true, dec, dec, 255, 9999, 0, pos[0], pos[1], pos[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(-8, 8), 384.0f, 0, 0, 0, 0, 0); break; case 5: // flame tracer - dec = 0.02f; - particle(pt_fade, PARTICLE_BILLBOARD, 0xCF632B, tex_smoke[rand()&7], false, false, 4, 4, 255, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + dec = 6; + //particle(pt_fade, PARTICLE_BILLBOARD, 0xCF632B, tex_particle, false, true, dec, dec, 255, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 384.0f, 0, 0, 0, 0, 0); + particle(pt_fade, PARTICLE_BILLBOARD, 0xCF632B, tex_particle, false, true, dec, dec, 255, 9999, 0, pos[0], pos[1], pos[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(-8, 8), 384.0f, 0, 0, 0, 0, 0); break; case 6: // voor trail - dec = 0.05f; // sparse trail - particle(pt_fade, PARTICLE_BILLBOARD, 0x47232B, tex_smoke[rand()&7], false, false, 4, 4, 255, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + dec = 6; + //particle(pt_fade, PARTICLE_BILLBOARD, 0x47232B, tex_particle, false, true, dec, dec, 255, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 384.0f, 0, 0, 0, 0, 0); + particle(pt_fade, PARTICLE_BILLBOARD, 0x47232B, tex_particle, false, true, dec, dec, 255, 9999, 0, pos[0], pos[1], pos[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(-8, 8), 384.0f, 0, 0, 0, 0, 0); break; case 7: // Nehahra smoke tracer if (!cl_particles_smoke.integer) - dec = cl.time - t; - else - { - dec = 0.14f; - particle(pt_smoke, PARTICLE_BILLBOARD, 0xC0C0C0, tex_smoke[rand()&7], true, false, 10, 10, 64, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); - } + return; + dec = 10; + particle(pt_smoke, PARTICLE_BILLBOARD, 0xC0C0C0, tex_smoke[rand()&7], true, false, dec, dec, 64, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); break; } // advance to next time and position - t += dec; - dec *= speed; + len -= dec; VectorMA (pos, dec, vec, pos); } - ent->persistent.trail_time = t; + ent->persistent.trail_time = len; } void CL_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent) @@ -804,7 +831,7 @@ void CL_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent) color = particlepalette[color]; while (len--) { - particle(pt_smoke, PARTICLE_BILLBOARD, color, tex_particle, false, false, 8, 8, 192, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); + particle(pt_smoke, PARTICLE_BILLBOARD, color, tex_particle, false, false, 5, 5, 128, 9999, 0, pos[0], pos[1], pos[2], 0, 0, 0, 0, 0, 0, 0, 0, 0); VectorAdd (pos, vec, pos); } } @@ -818,7 +845,7 @@ CL_MoveParticles void CL_MoveParticles (void) { particle_t *p; - renderparticle_t *r; + renderparticle_t *r, *rend; int i, activeparticles, maxparticle, j, a, pressureused = false, content; float gravity, dvel, frametime, f, dist, normal[3], v[3], org[3]; @@ -838,7 +865,7 @@ void CL_MoveParticles (void) activeparticles = 0; maxparticle = -1; j = 0; - for (i = 0, p = particles, r = r_refdef.particles;i < cl_numparticles;i++, p++) + for (i = 0, p = particles, r = r_refdef.particles, rend = r + cl_maxparticles;i < cl_numparticles;i++, p++) { if (p->die < cl.time) { @@ -849,16 +876,6 @@ void CL_MoveParticles (void) content = 0; VectorCopy(p->org, p->oldorg); VectorMA(p->org, frametime, p->vel, p->org); - if (p->friction) - { - f = p->friction * frametime; - if (!content) - content = Mod_PointInLeaf(p->org, cl.worldmodel)->contents; - if (content != CONTENTS_EMPTY) - f *= 4; - f = 1.0f - f; - VectorScale(p->vel, f, p->vel); - } VectorCopy(p->org, org); if (p->bounce) { @@ -868,7 +885,7 @@ void CL_MoveParticles (void) if (p->bounce < 0) { // assume it's blood (lame, but...) - R_Stain(v, 48, 64, 24, 24, 48, 192, 48, 48, 48); + R_Stain(v, 48, 64, 24, 24, p->alpha * p->scalex * p->scaley * (1.0f / 2048.0f), 192, 48, 48, p->alpha * p->scalex * p->scaley * (1.0f / 2048.0f)); p->die = -1; freeparticles[j++] = p; continue; @@ -882,6 +899,16 @@ void CL_MoveParticles (void) } } } + if (p->friction) + { + f = p->friction * frametime; + if (!content) + content = Mod_PointInLeaf(p->org, cl.worldmodel)->contents; + if (content != CONTENTS_EMPTY) + f *= 4; + f = 1.0f - f; + VectorScale(p->vel, f, p->vel); + } switch (p->type) { @@ -954,6 +981,7 @@ void CL_MoveParticles (void) p->tex = tex_smoke[rand()&7]; p->orientation = PARTICLE_BILLBOARD; p->type = pt_fade; + p->time2 = 384.0f; p->scalex = 5; p->scaley = 5; VectorClear(p->vel); @@ -971,22 +999,19 @@ void CL_MoveParticles (void) { if (a == CONTENTS_WATER || a == CONTENTS_SLIME) { - p->friction = 5; - p->scalex += frametime * 32.0f; - p->scaley += frametime * 32.0f; - p->alpha -= frametime * 128.0f; - p->vel[2] += gravity * 0.125f; + //p->friction = 5; + p->scalex += frametime * (cl_particles_blood_size_min.value + cl_particles_blood_size_max.value); + p->scaley += frametime * (cl_particles_blood_size_min.value + cl_particles_blood_size_max.value); + p->alpha -= frametime * max(cl_particles_blood_alpha.value, 0.01f) * 128.0f; + //p->vel[2] += gravity * 0.25f; if (p->alpha < 1) p->die = -1; - break; } else - { p->die = -1; - break; - } } - p->vel[2] -= gravity * 0.5; + else + p->vel[2] -= gravity; break; case pt_spark: p->alpha -= frametime * p->time2; @@ -1013,7 +1038,7 @@ void CL_MoveParticles (void) p->die = -1; break; case pt_fade: - p->alpha -= frametime * 384; + p->alpha -= frametime * p->time2; if (p->alpha < 1) p->die = -1; break; @@ -1048,15 +1073,15 @@ void CL_MoveParticles (void) p->scalex += frametime * 16; p->scaley += frametime * 16; p->alpha -= frametime * 1024; - p->vel[2] += gravity * 0.1; + p->vel[2] += gravity * 0.2; if (p->alpha < 1) p->die = -1; break; case pt_smoke: - p->scalex += frametime * 24; - p->scaley += frametime * 24; - p->alpha -= frametime * 256; - p->vel[2] += gravity * 0.1; + p->scalex += frametime * 16; + p->scaley += frametime * 16; + p->alpha -= frametime * 320; + //p->vel[2] += gravity * 0.2; if (p->alpha < 1) p->die = -1; break; @@ -1173,8 +1198,8 @@ void CL_MoveParticles (void) r->org[1] = p->org[1]; r->org[2] = p->org[2]; r->tex = p->tex; - r->scalex = p->scalex * 0.5f * cl_particles_size.value; - r->scaley = p->scaley * 0.5f * cl_particles_size.value; + r->scalex = p->scalex * cl_particles_size.value; + r->scaley = p->scaley * 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); diff --git a/cl_screen.c b/cl_screen.c index 174f320d..b8922b2b 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -19,8 +19,8 @@ float scr_conlines; // lines of console to display int clearconsole; int clearnotify; -qboolean scr_disabled_for_loading; -qboolean scr_drawloading; +//qboolean scr_disabled_for_loading; +qboolean scr_drawloading = false; //float scr_disabled_time; static qbyte menuplyr_pixels[4096]; @@ -227,8 +227,8 @@ void SCR_DrawLoading (void) { cachepic_t *pic; - if (!scr_drawloading) - return; + //if (!scr_drawloading) + // return; pic = Draw_CachePic ("gfx/loading.lmp"); DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/loading.lmp", 0, 0, 1, 1, 1, 1, 0); @@ -336,12 +336,14 @@ SCR_EndLoadingPlaque */ void SCR_EndLoadingPlaque (void) { + /* if (!scr_drawloading) return; // scr_disabled_for_loading = false; scr_drawloading = false; Con_ClearNotify (); + */ } //============================================================================= @@ -1003,16 +1005,6 @@ void CL_UpdateScreen(void) R_TimeReport("setup"); - if (scr_drawloading) - { - scr_drawloading = false; - scr_con_current = vid.conheight; - DrawQ_Clear(); - SCR_DrawLoading(); - SCR_UpdateScreen(); - return; - } - SCR_DrawRam(); SCR_DrawNet(); SCR_DrawTurtle(); @@ -1025,13 +1017,11 @@ void CL_UpdateScreen(void) ui_draw(); - /* if (scr_drawloading) { + scr_drawloading = false; SCR_DrawLoading(); - if ( } - */ R_TimeReport("2d"); diff --git a/console.c b/console.c index e6382e98..5d424f66 100644 --- a/console.c +++ b/console.c @@ -469,16 +469,16 @@ void Con_SafePrintf (char *fmt, ...) { va_list argptr; char msg[1024]; - int temp; + //int temp; va_start (argptr,fmt); vsprintf (msg,fmt,argptr); va_end (argptr); - temp = scr_disabled_for_loading; - scr_disabled_for_loading = true; + //temp = scr_disabled_for_loading; + //scr_disabled_for_loading = true; Con_Printf ("%s", msg); - scr_disabled_for_loading = temp; + //scr_disabled_for_loading = temp; } diff --git a/gl_backend.c b/gl_backend.c index 562c447a..d5f605a0 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -386,6 +386,71 @@ static int mesh_clientunit; static int mesh_texture[MAX_TEXTUREUNITS]; static float mesh_texturergbscale[MAX_TEXTUREUNITS]; +void GL_SetupTextureState(void) +{ + int i; + if (backendunits > 1) + { + for (i = 0;i < backendunits;i++) + { + qglActiveTexture(GL_TEXTURE0_ARB + (mesh_unit = i));CHECKGLERROR + glBindTexture(GL_TEXTURE_2D, mesh_texture[i]);CHECKGLERROR + if (gl_combine.integer) + { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_CONSTANT_ARB);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_CONSTANT_ARB);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, mesh_texturergbscale[i]);CHECKGLERROR + glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0f);CHECKGLERROR + } + else + { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR + } + qglClientActiveTexture(GL_TEXTURE0_ARB + (mesh_clientunit = i));CHECKGLERROR + glTexCoordPointer(2, GL_FLOAT, sizeof(buf_texcoord_t), buf_texcoord[i]);CHECKGLERROR + if (mesh_texture[i]) + { + glEnable(GL_TEXTURE_2D);CHECKGLERROR + glEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + else + { + glDisable(GL_TEXTURE_2D);CHECKGLERROR + glDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + } + } + else + { + glBindTexture(GL_TEXTURE_2D, mesh_texture[0]);CHECKGLERROR + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR + glTexCoordPointer(2, GL_FLOAT, sizeof(buf_texcoord_t), buf_texcoord[0]);CHECKGLERROR + if (mesh_texture[0]) + { + glEnable(GL_TEXTURE_2D);CHECKGLERROR + glEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + else + { + glDisable(GL_TEXTURE_2D);CHECKGLERROR + glDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + } +} + // called at beginning of frame void R_Mesh_Start(void) { @@ -451,82 +516,18 @@ void R_Mesh_Start(void) } glEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR - if (backendunits > 1) - { - for (i = 0;i < backendunits;i++) - { - qglActiveTexture(GL_TEXTURE0_ARB + (mesh_unit = i));CHECKGLERROR - glBindTexture(GL_TEXTURE_2D, mesh_texture[i]);CHECKGLERROR - glDisable(GL_TEXTURE_2D);CHECKGLERROR - if (gl_combine.integer) - { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_CONSTANT_ARB);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_CONSTANT_ARB);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR - glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, mesh_texturergbscale[i]);CHECKGLERROR - glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0f);CHECKGLERROR - } - else - { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR - } - - qglClientActiveTexture(GL_TEXTURE0_ARB + (mesh_clientunit = i));CHECKGLERROR - glTexCoordPointer(2, GL_FLOAT, sizeof(buf_texcoord_t), buf_texcoord[i]);CHECKGLERROR - glEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR - } - } - else - { - glBindTexture(GL_TEXTURE_2D, (mesh_texture[0] = 0));CHECKGLERROR - glDisable(GL_TEXTURE_2D);CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR - - glTexCoordPointer(2, GL_FLOAT, sizeof(buf_texcoord_t), buf_texcoord[0]);CHECKGLERROR - glEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR - } + GL_SetupTextureState(); } -// renders mesh buffers, called to flush buffers when full -void R_Mesh_Render(void) +int gl_backend_rebindtextures; + +void GL_UpdateFarclip(void) { int i; - int k; - int firsttriangle; - int endtriangle; - int indexcount; - int firstvert; - int endvert; float farclip; - buf_mesh_t *mesh; - unsigned int *index; - // float to byte color conversion - int *icolor; - float *fcolor; - qbyte *bcolor; - - if (!backendactive) - Sys_Error("R_Mesh_Render: called when backend is not active\n"); - - if (!currentmesh) - return; - - CHECKGLERROR // push out farclip based on vertices - // FIXME: wouldn't this be a little slow when using matrix transforms? + // FIXME: wouldn't this be slow when using matrix transforms? for (i = 0;i < currentvertex;i++) { farclip = DotProduct(buf_vertex[i].v, vpn); @@ -539,115 +540,109 @@ void R_Mesh_Render(void) // push out farclip for next frame if (farclip > r_newfarclip) r_newfarclip = ceil((farclip + 255) / 256) * 256 + 256; +} - if (!gl_mesh_floatcolors.integer) +void GL_ConvertColorsFloatToByte(void) +{ + int i, k, *icolor; + float *fcolor; + qbyte *bcolor; + + // shift float to have 8bit fraction at base of number + for (i = 0, fcolor = &buf_fcolor->c[0];i < currentvertex;i++) { - // shift float to have 8bit fraction at base of number - for (i = 0, fcolor = &buf_fcolor->c[0];i < currentvertex;i++) - { - *fcolor++ += 32768.0f; - *fcolor++ += 32768.0f; - *fcolor++ += 32768.0f; - *fcolor++ += 32768.0f; - } - // then read as integer and kill float bits... - for (i = 0, icolor = (int *)&buf_fcolor->c[0], bcolor = &buf_bcolor->c[0];i < currentvertex;i++) - { - k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; - k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; - k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; - k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; - } + *fcolor++ += 32768.0f; + *fcolor++ += 32768.0f; + *fcolor++ += 32768.0f; + *fcolor++ += 32768.0f; } + // then read as integer and kill float bits... + for (i = 0, icolor = (int *)&buf_fcolor->c[0], bcolor = &buf_bcolor->c[0];i < currentvertex;i++) + { + k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; + k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; + k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; + k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; + } +} - // lock the arrays now that they will have no further modifications - //GL_LockArray(0, currentvertex);CHECKGLERROR - - for (k = 0, mesh = buf_mesh;k < currentmesh;k++, mesh++) +void GL_MeshState(buf_mesh_t *mesh) +{ + int i; + if (backendunits > 1) { - if (backendunits > 1) + for (i = 0;i < backendunits;i++) { - for (i = 0;i < backendunits;i++) + if (mesh_texture[i] != mesh->textures[i]) { - if (mesh_texture[i] != mesh->textures[i]) + if (mesh_unit != i) { - if (mesh_unit != i) - { - qglActiveTexture(GL_TEXTURE0_ARB + (mesh_unit = i));CHECKGLERROR - } - if (mesh_texture[i] == 0) - { - glEnable(GL_TEXTURE_2D);CHECKGLERROR - // have to disable texcoord array on disabled texture - // units due to NVIDIA driver bug with - // compiled_vertex_array - if (mesh_clientunit != i) - { - qglClientActiveTexture(GL_TEXTURE0_ARB + (mesh_clientunit = i));CHECKGLERROR - } - glEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR - } - glBindTexture(GL_TEXTURE_2D, (mesh_texture[i] = mesh->textures[i]));CHECKGLERROR - if (mesh_texture[i] == 0) + qglActiveTexture(GL_TEXTURE0_ARB + (mesh_unit = i));CHECKGLERROR + } + if (mesh_texture[i] == 0) + { + glEnable(GL_TEXTURE_2D);CHECKGLERROR + // have to disable texcoord array on disabled texture + // units due to NVIDIA driver bug with + // compiled_vertex_array + if (mesh_clientunit != i) { - glDisable(GL_TEXTURE_2D);CHECKGLERROR - // have to disable texcoord array on disabled texture - // units due to NVIDIA driver bug with - // compiled_vertex_array - if (mesh_clientunit != i) - { - qglClientActiveTexture(GL_TEXTURE0_ARB + (mesh_clientunit = i));CHECKGLERROR - } - glDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + qglClientActiveTexture(GL_TEXTURE0_ARB + (mesh_clientunit = i));CHECKGLERROR } + glEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR } - if (mesh_texturergbscale[i] != mesh->texturergbscale[i]) + glBindTexture(GL_TEXTURE_2D, (mesh_texture[i] = mesh->textures[i]));CHECKGLERROR + if (mesh_texture[i] == 0) { - if (mesh_unit != i) + glDisable(GL_TEXTURE_2D);CHECKGLERROR + // have to disable texcoord array on disabled texture + // units due to NVIDIA driver bug with + // compiled_vertex_array + if (mesh_clientunit != i) { - qglActiveTexture(GL_TEXTURE0_ARB + (mesh_unit = i));CHECKGLERROR + qglClientActiveTexture(GL_TEXTURE0_ARB + (mesh_clientunit = i));CHECKGLERROR } - glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (mesh_texturergbscale[i] = mesh->texturergbscale[i]));CHECKGLERROR + glDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR } } - } - else - { - if (mesh_texture[0] != mesh->textures[0]) + if (mesh_texturergbscale[i] != mesh->texturergbscale[i]) { - if (mesh_texture[0] == 0) + if (mesh_unit != i) { - glEnable(GL_TEXTURE_2D);CHECKGLERROR - glEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR - } - glBindTexture(GL_TEXTURE_2D, (mesh_texture[0] = mesh->textures[0]));CHECKGLERROR - if (mesh_texture[0] == 0) - { - glDisable(GL_TEXTURE_2D);CHECKGLERROR - glDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + qglActiveTexture(GL_TEXTURE0_ARB + (mesh_unit = i));CHECKGLERROR } + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (mesh_texturergbscale[i] = mesh->texturergbscale[i]));CHECKGLERROR } } - if (mesh_blendfunc1 != mesh->blendfunc1 || mesh_blendfunc2 != mesh->blendfunc2) + } + else + { + if (mesh_texture[0] != mesh->textures[0]) { - glBlendFunc(mesh_blendfunc1 = mesh->blendfunc1, mesh_blendfunc2 = mesh->blendfunc2);CHECKGLERROR - if (mesh_blendfunc2 == GL_ZERO) + if (mesh_texture[0] == 0) { - if (mesh_blendfunc1 == GL_ONE) - { - if (mesh_blend) - { - mesh_blend = 0; - glDisable(GL_BLEND);CHECKGLERROR - } - } - else + glEnable(GL_TEXTURE_2D);CHECKGLERROR + glEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + glBindTexture(GL_TEXTURE_2D, (mesh_texture[0] = mesh->textures[0]));CHECKGLERROR + if (mesh_texture[0] == 0) + { + glDisable(GL_TEXTURE_2D);CHECKGLERROR + glDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + } + } + if (mesh_blendfunc1 != mesh->blendfunc1 || mesh_blendfunc2 != mesh->blendfunc2) + { + glBlendFunc(mesh_blendfunc1 = mesh->blendfunc1, mesh_blendfunc2 = mesh->blendfunc2);CHECKGLERROR + if (mesh_blendfunc2 == GL_ZERO) + { + if (mesh_blendfunc1 == GL_ONE) + { + if (mesh_blend) { - if (!mesh_blend) - { - mesh_blend = 1; - glEnable(GL_BLEND);CHECKGLERROR - } + mesh_blend = 0; + glDisable(GL_BLEND);CHECKGLERROR } } else @@ -659,41 +654,91 @@ void R_Mesh_Render(void) } } } - if (mesh_depthtest != mesh->depthtest) - { - mesh_depthtest = mesh->depthtest; - if (mesh_depthtest) - glEnable(GL_DEPTH_TEST); - else - glDisable(GL_DEPTH_TEST); - } - if (mesh_depthmask != mesh->depthmask) + else { - glDepthMask(mesh_depthmask = mesh->depthmask);CHECKGLERROR + if (!mesh_blend) + { + mesh_blend = 1; + glEnable(GL_BLEND);CHECKGLERROR + } } + } + if (mesh_depthtest != mesh->depthtest) + { + mesh_depthtest = mesh->depthtest; + if (mesh_depthtest) + glEnable(GL_DEPTH_TEST); + else + glDisable(GL_DEPTH_TEST); + } + if (mesh_depthmask != mesh->depthmask) + { + glDepthMask(mesh_depthmask = mesh->depthmask);CHECKGLERROR + } +} - firsttriangle = mesh->firsttriangle; - firstvert = mesh->firstvert; - endtriangle = firsttriangle + mesh->triangles; - endvert = firstvert + mesh->verts; +// renders mesh buffers, called to flush buffers when full +void R_Mesh_Render(void) +{ + int i; + int k; + int indexcount; + int firstvert; + buf_mesh_t *mesh; + unsigned int *index; + + if (!backendactive) + Sys_Error("R_Mesh_Render: called when backend is not active\n"); - indexcount = (endtriangle - firsttriangle) * 3; - index = (unsigned int *)&buf_tri[firsttriangle].index[0]; + if (!currentmesh) + return; - // if not using batching, skip the index adjustment - if (firstvert != 0) - for (i = 0;i < indexcount;i++) - index[i] += firstvert; + CHECKGLERROR - // lock arrays (this is ignored if already locked) - CHECKGLERROR - GL_LockArray(0, currentvertex); -#ifdef WIN32 - // FIXME: dynamic link to GL so we can get DrawRangeElements on WIN32 - glDrawElements(GL_TRIANGLES, indexcount, GL_UNSIGNED_INT, index);CHECKGLERROR -#else - glDrawRangeElements(GL_TRIANGLES, firstvert, endvert, indexcount, GL_UNSIGNED_INT, index);CHECKGLERROR -#endif + GL_UpdateFarclip(); + + if (!gl_mesh_floatcolors.integer) + GL_ConvertColorsFloatToByte(); + + // lock the arrays now that they will have no further modifications + //GL_LockArray(0, currentvertex);CHECKGLERROR + if (gl_backend_rebindtextures) + { + gl_backend_rebindtextures = false; + GL_SetupTextureState(); + } + + GL_MeshState(buf_mesh); + GL_LockArray(0, currentvertex); + #ifdef WIN32 + // FIXME: dynamic link to GL so we can get DrawRangeElements on WIN32 + glDrawElements(GL_TRIANGLES, buf_mesh->triangles * 3, GL_UNSIGNED_INT, (unsigned int *)&buf_tri[buf_mesh->firsttriangle].index[0]);CHECKGLERROR + #else + glDrawRangeElements(GL_TRIANGLES, buf_mesh->firstvert, buf_mesh->firstvert + buf_mesh->verts, buf_mesh->triangles * 3, GL_UNSIGNED_INT, (unsigned int *)&buf_tri[buf_mesh->firsttriangle].index[0]);CHECKGLERROR + #endif + + if (currentmesh >= 2) + { + for (k = 1, mesh = buf_mesh + k;k < currentmesh;k++, mesh++) + { + GL_MeshState(mesh); + + firstvert = mesh->firstvert; + indexcount = mesh->triangles * 3; + index = (unsigned int *)&buf_tri[mesh->firsttriangle].index[0]; + + // if not using batching, skip the index adjustment + if (firstvert != 0) + for (i = 0;i < indexcount;i++) + index[i] += firstvert; + + #ifdef WIN32 + // FIXME: dynamic link to GL so we can get DrawRangeElements on WIN32 + glDrawElements(GL_TRIANGLES, indexcount, GL_UNSIGNED_INT, index);CHECKGLERROR + #else + glDrawRangeElements(GL_TRIANGLES, firstvert, firstvert + mesh->verts, indexcount, GL_UNSIGNED_INT, index);CHECKGLERROR + #endif + } } currentmesh = 0; diff --git a/gl_models.c b/gl_models.c index 3c83354b..815ddb48 100644 --- a/gl_models.c +++ b/gl_models.c @@ -2,24 +2,27 @@ #include "quakedef.h" //cvar_t gl_transform = {0, "gl_transform", "1"}; +cvar_t r_quickmodels = {0, "r_quickmodels", "1"}; typedef struct { float m[3][4]; } zymbonematrix; -// LordHavoc: vertex array -float *aliasvert; -float *aliasvertnorm; -float *aliasvertcolor; +// LordHavoc: vertex arrays + +float *aliasvertbuf; +float *aliasvertcolorbuf; +float *aliasvert; // this may point at aliasvertbuf or at vertex arrays in the mesh backend +float *aliasvertcolor; // this may point at aliasvertcolorbuf or at vertex arrays in the mesh backend + float *aliasvertcolor2; -zymbonematrix *zymbonepose; +float *aliasvertnorm; int *aliasvertusage; +zymbonematrix *zymbonepose; rmeshinfo_t aliasmeshinfo; -rtexture_t *chrometexture; - /* void GL_SetupModelTransform (vec3_t origin, vec3_t angles, vec_t scale) { @@ -36,7 +39,9 @@ void GL_SetupModelTransform (vec3_t origin, vec3_t angles, vec_t scale) } */ +/* rtexturepool_t *chrometexturepool; +rtexture_t *chrometexture; // currently unused reflection effect texture void makechrometexture(void) @@ -56,6 +61,7 @@ void makechrometexture(void) chrometexture = R_LoadTexture (chrometexturepool, "chrometexture", 64, 64, &data[0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_PRECACHE); } +*/ mempool_t *gl_models_mempool; @@ -63,19 +69,19 @@ void gl_models_start(void) { // allocate vertex processing arrays gl_models_mempool = Mem_AllocPool("GL_Models"); - aliasvert = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); + aliasvert = aliasvertbuf = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); + aliasvertcolor = aliasvertcolorbuf = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); aliasvertnorm = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][3])); - aliasvertcolor = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); aliasvertcolor2 = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); // used temporarily for tinted coloring zymbonepose = Mem_Alloc(gl_models_mempool, sizeof(zymbonematrix[256])); aliasvertusage = Mem_Alloc(gl_models_mempool, sizeof(int[MD2MAX_VERTS])); - chrometexturepool = R_AllocTexturePool(); - makechrometexture(); + //chrometexturepool = R_AllocTexturePool(); + //makechrometexture(); } void gl_models_shutdown(void) { - R_FreeTexturePool(&chrometexturepool); + //R_FreeTexturePool(&chrometexturepool); Mem_FreePool(&gl_models_mempool); } @@ -86,6 +92,7 @@ void gl_models_newmap(void) void GL_Models_Init(void) { // Cvar_RegisterVariable(&gl_transform); + Cvar_RegisterVariable(&r_quickmodels); R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown, gl_models_newmap); } @@ -93,25 +100,26 @@ void GL_Models_Init(void) void R_AliasTransformVerts(int vertcount) { vec3_t point; - float *av, *avn; + float *av; +// float *avn; av = aliasvert; - avn = aliasvertnorm; +// avn = aliasvertnorm; while (vertcount >= 4) { VectorCopy(av, point);softwaretransform(point, av);av += 4; VectorCopy(av, point);softwaretransform(point, av);av += 4; VectorCopy(av, point);softwaretransform(point, av);av += 4; VectorCopy(av, point);softwaretransform(point, av);av += 4; - VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3; - VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3; - VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3; - VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3; +// VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3; +// VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3; +// VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3; +// VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3; vertcount -= 4; } while(vertcount > 0) { VectorCopy(av, point);softwaretransform(point, av);av += 4; - VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3; +// VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3; vertcount--; } } @@ -278,18 +286,22 @@ void R_TintModel(float *in, float *out, int verts, float r, float g, float b) } } -void R_SetupMDLMD2Frames(skinframe_t **skinframe) +skinframe_t *R_FetchSkinFrame(void) +{ + model_t *model = currentrenderentity->model; + if (model->skinscenes[currentrenderentity->skinnum].framecount > 1) + return &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe + (int) (cl.time * 10) % model->skinscenes[currentrenderentity->skinnum].framecount]; + else + return &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe]; +} + +void R_SetupMDLMD2Frames(float colorr, float colorg, float colorb) { md2frame_t *frame1, *frame2, *frame3, *frame4; trivertx_t *frame1verts, *frame2verts, *frame3verts, *frame4verts; model_t *model; model = currentrenderentity->model; - if (model->skinscenes[currentrenderentity->skinnum].framecount > 1) - *skinframe = &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe + (int) (cl.time * 10) % model->skinscenes[currentrenderentity->skinnum].framecount]; - else - *skinframe = &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe]; - frame1 = &model->mdlmd2data_frames[currentrenderentity->frameblend[0].frame]; frame2 = &model->mdlmd2data_frames[currentrenderentity->frameblend[1].frame]; frame3 = &model->mdlmd2data_frames[currentrenderentity->frameblend[2].frame]; @@ -303,124 +315,103 @@ void R_SetupMDLMD2Frames(skinframe_t **skinframe) currentrenderentity->frameblend[1].lerp, frame2verts, frame2->scale, frame2->translate, currentrenderentity->frameblend[2].lerp, frame3verts, frame3->scale, frame3->translate, currentrenderentity->frameblend[3].lerp, frame4verts, frame4->scale, frame4->translate); - R_AliasTransformVerts(model->numverts); - R_LightModel(model->numverts); + R_LightModel(model->numverts, colorr, colorg, colorb, false); + + R_AliasTransformVerts(model->numverts); } -void R_DrawQ1Q2AliasModel (void) +void R_DrawQ1Q2AliasModel (float fog) { - float fog; - vec3_t diff; model_t *model; skinframe_t *skinframe; model = currentrenderentity->model; - R_SetupMDLMD2Frames(&skinframe); - - memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo)); - - aliasmeshinfo.vertex = aliasvert; - aliasmeshinfo.vertexstep = sizeof(float[4]); - aliasmeshinfo.numverts = model->numverts; - aliasmeshinfo.numtriangles = model->numtris; - aliasmeshinfo.index = model->mdlmd2data_indices; - aliasmeshinfo.colorstep = sizeof(float[4]); - aliasmeshinfo.texcoords[0] = model->mdlmd2data_texcoords; - aliasmeshinfo.texcoordstep[0] = sizeof(float[2]); - - fog = 0; - if (fogenabled) + skinframe = R_FetchSkinFrame(); + if (fog && !(currentrenderentity->effects & EF_ADDITIVE)) { - VectorSubtract(currentrenderentity->origin, r_origin, diff); - fog = DotProduct(diff,diff); - if (fog < 0.01f) - fog = 0.01f; - fog = exp(fogdensity/fog); - if (fog > 1) - fog = 1; - if (fog < 0.01f) - fog = 0; - // fog method: darken, additive fog - // 1. render model as normal, scaled by inverse of fog alpha (darkens it) - // 2. render fog as additive - } + R_SetupMDLMD2Frames(1 - fog, 1 - fog, 1 - fog); - if (currentrenderentity->effects & EF_ADDITIVE) - { - aliasmeshinfo.transparent = true; - aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA; - aliasmeshinfo.blendfunc2 = GL_ONE; - } - else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL) - { - aliasmeshinfo.transparent = true; - aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA; - aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; - } - else - { - aliasmeshinfo.transparent = false; - aliasmeshinfo.blendfunc1 = GL_ONE; - aliasmeshinfo.blendfunc2 = GL_ZERO; - } + memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo)); - // darken source - if (fog) - R_TintModel(aliasvertcolor, aliasvertcolor, model->numverts, 1 - fog, 1 - fog, 1 - fog); + aliasmeshinfo.vertex = aliasvert; + aliasmeshinfo.vertexstep = sizeof(float[4]); + aliasmeshinfo.numverts = model->numverts; + aliasmeshinfo.numtriangles = model->numtris; + aliasmeshinfo.index = model->mdlmd2data_indices; + aliasmeshinfo.colorstep = sizeof(float[4]); + aliasmeshinfo.texcoords[0] = model->mdlmd2data_texcoords; + aliasmeshinfo.texcoordstep[0] = sizeof(float[2]); - if (skinframe->base || skinframe->pants || skinframe->shirt || skinframe->glow || skinframe->merged) - { - if (currentrenderentity->colormap >= 0 && (skinframe->base || skinframe->pants || skinframe->shirt)) + if (currentrenderentity->effects & EF_ADDITIVE) { - int c; - qbyte *color; - if (skinframe->base) - R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0); - if (skinframe->pants) + aliasmeshinfo.transparent = true; + aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA; + aliasmeshinfo.blendfunc2 = GL_ONE; + } + else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL) + { + aliasmeshinfo.transparent = true; + aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA; + aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; + } + else + { + aliasmeshinfo.transparent = false; + aliasmeshinfo.blendfunc1 = GL_ONE; + aliasmeshinfo.blendfunc2 = GL_ZERO; + } + + if (skinframe->base || skinframe->pants || skinframe->shirt || skinframe->glow || skinframe->merged) + { + if (currentrenderentity->colormap >= 0 && (skinframe->base || skinframe->pants || skinframe->shirt)) { - c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges - color = (qbyte *) (&d_8to24table[c]); - if (c >= 224) // fullbright ranges - R_DrawModelMesh(skinframe->pants, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f)); - else + int c; + qbyte *color; + if (skinframe->base) + R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0); + if (skinframe->pants) + { + c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges + color = (qbyte *) (&d_8to24table[c]); + if (c >= 224) // fullbright ranges + R_DrawModelMesh(skinframe->pants, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f)); + else + { + R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f)); + R_DrawModelMesh(skinframe->pants, aliasvertcolor2, 0, 0, 0); + } + } + if (skinframe->shirt) { - R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f)); - R_DrawModelMesh(skinframe->pants, aliasvertcolor2, 0, 0, 0); + c = currentrenderentity->colormap & 0xF0 ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges + color = (qbyte *) (&d_8to24table[c]); + if (c >= 224) // fullbright ranges + R_DrawModelMesh(skinframe->shirt, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f)); + else + { + R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f)); + R_DrawModelMesh(skinframe->shirt, aliasvertcolor2, 0, 0, 0); + } } } - if (skinframe->shirt) + else { - c = currentrenderentity->colormap & 0xF0 ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges - color = (qbyte *) (&d_8to24table[c]); - if (c >= 224) // fullbright ranges - R_DrawModelMesh(skinframe->shirt, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f)); + if (skinframe->merged) + R_DrawModelMesh(skinframe->merged, aliasvertcolor, 0, 0, 0); else { - R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f)); - R_DrawModelMesh(skinframe->shirt, aliasvertcolor2, 0, 0, 0); + if (skinframe->base) R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0); + if (skinframe->pants) R_DrawModelMesh(skinframe->pants, aliasvertcolor, 0, 0, 0); + if (skinframe->shirt) R_DrawModelMesh(skinframe->shirt, aliasvertcolor, 0, 0, 0); } } + if (skinframe->glow) R_DrawModelMesh(skinframe->glow, NULL, 1 - fog, 1 - fog, 1 - fog); } else - { - if (skinframe->merged) - R_DrawModelMesh(skinframe->merged, aliasvertcolor, 0, 0, 0); - else - { - if (skinframe->base) R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0); - if (skinframe->pants) R_DrawModelMesh(skinframe->pants, aliasvertcolor, 0, 0, 0); - if (skinframe->shirt) R_DrawModelMesh(skinframe->shirt, aliasvertcolor, 0, 0, 0); - } - } - if (skinframe->glow) R_DrawModelMesh(skinframe->glow, NULL, 1 - fog, 1 - fog, 1 - fog); - } - else - R_DrawModelMesh(0, NULL, 1 - fog, 1 - fog, 1 - fog); + R_DrawModelMesh(0, NULL, 1 - fog, 1 - fog, 1 - fog); - if (fog && !(currentrenderentity->effects & EF_ADDITIVE)) - { aliasmeshinfo.tex[0] = R_GetTexture(skinframe->fog); aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA; aliasmeshinfo.blendfunc2 = GL_ONE; @@ -434,6 +425,128 @@ void R_DrawQ1Q2AliasModel (void) c_alias_polys += aliasmeshinfo.numtriangles; R_Mesh_Draw(&aliasmeshinfo); } + else if (currentrenderentity->colormap >= 0 || !skinframe->merged || skinframe->glow || !r_quickmodels.integer) + { + R_SetupMDLMD2Frames(1 - fog, 1 - fog, 1 - fog); + + memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo)); + + aliasmeshinfo.vertex = aliasvert; + aliasmeshinfo.vertexstep = sizeof(float[4]); + aliasmeshinfo.numverts = model->numverts; + aliasmeshinfo.numtriangles = model->numtris; + aliasmeshinfo.index = model->mdlmd2data_indices; + aliasmeshinfo.colorstep = sizeof(float[4]); + aliasmeshinfo.texcoords[0] = model->mdlmd2data_texcoords; + aliasmeshinfo.texcoordstep[0] = sizeof(float[2]); + + if (currentrenderentity->effects & EF_ADDITIVE) + { + aliasmeshinfo.transparent = true; + aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA; + aliasmeshinfo.blendfunc2 = GL_ONE; + } + else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL) + { + aliasmeshinfo.transparent = true; + aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA; + aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; + } + else + { + aliasmeshinfo.transparent = false; + aliasmeshinfo.blendfunc1 = GL_ONE; + aliasmeshinfo.blendfunc2 = GL_ZERO; + } + + if (skinframe->base || skinframe->pants || skinframe->shirt || skinframe->glow || skinframe->merged) + { + if (currentrenderentity->colormap >= 0 && (skinframe->base || skinframe->pants || skinframe->shirt)) + { + int c; + qbyte *color; + if (skinframe->base) + R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0); + if (skinframe->pants) + { + c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges + color = (qbyte *) (&d_8to24table[c]); + if (c >= 224) // fullbright ranges + R_DrawModelMesh(skinframe->pants, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f)); + else + { + R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f)); + R_DrawModelMesh(skinframe->pants, aliasvertcolor2, 0, 0, 0); + } + } + if (skinframe->shirt) + { + c = currentrenderentity->colormap & 0xF0 ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges + color = (qbyte *) (&d_8to24table[c]); + if (c >= 224) // fullbright ranges + R_DrawModelMesh(skinframe->shirt, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f)); + else + { + R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f)); + R_DrawModelMesh(skinframe->shirt, aliasvertcolor2, 0, 0, 0); + } + } + } + else + { + if (skinframe->merged) + R_DrawModelMesh(skinframe->merged, aliasvertcolor, 0, 0, 0); + else + { + if (skinframe->base) R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0); + if (skinframe->pants) R_DrawModelMesh(skinframe->pants, aliasvertcolor, 0, 0, 0); + if (skinframe->shirt) R_DrawModelMesh(skinframe->shirt, aliasvertcolor, 0, 0, 0); + } + } + if (skinframe->glow) R_DrawModelMesh(skinframe->glow, NULL, 1 - fog, 1 - fog, 1 - fog); + } + else + R_DrawModelMesh(0, NULL, 1 - fog, 1 - fog, 1 - fog); + } + else + { + rmeshbufferinfo_t bufmesh; + memset(&bufmesh, 0, sizeof(bufmesh)); + if (currentrenderentity->effects & EF_ADDITIVE) + { + bufmesh.transparent = true; + bufmesh.blendfunc1 = GL_SRC_ALPHA; + bufmesh.blendfunc2 = GL_ONE; + } + else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL) + { + bufmesh.transparent = true; + bufmesh.blendfunc1 = GL_SRC_ALPHA; + bufmesh.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; + } + else + { + bufmesh.transparent = false; + bufmesh.blendfunc1 = GL_ONE; + bufmesh.blendfunc2 = GL_ZERO; + } + bufmesh.numtriangles = model->numtris; + bufmesh.numverts = model->numverts; + bufmesh.tex[0] = R_GetTexture(skinframe->merged); + + R_Mesh_Draw_GetBuffer(&bufmesh); + + aliasvert = bufmesh.vertex; + aliasvertcolor = bufmesh.color; + memcpy(bufmesh.index, model->mdlmd2data_indices, bufmesh.numtriangles * sizeof(int[3])); + memcpy(bufmesh.texcoords[0], model->mdlmd2data_texcoords, bufmesh.numverts * sizeof(float[2])); + + fog = bufmesh.colorscale * (1 - fog); + R_SetupMDLMD2Frames(fog, fog, fog); + + aliasvert = aliasvertbuf; + aliasvertcolor = aliasvertcolorbuf; + } } int ZymoticLerpBones(int count, zymbonematrix *bonebase, frameblend_t *blend, zymbone_t *bone) @@ -757,10 +870,9 @@ void R_DrawZymoticModelMesh(zymtype1header_t *m) } } -void R_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m) +void R_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m, float fog) { int i, *renderlist; - vec3_t diff; // FIXME: do better fog renderlist = (int *)(m->lump_render.start + (int) m); @@ -769,11 +881,10 @@ void R_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m) aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA; aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; - VectorSubtract(org, r_origin, diff); aliasmeshinfo.cr = fogcolor[0]; aliasmeshinfo.cg = fogcolor[1]; aliasmeshinfo.cb = fogcolor[2]; - aliasmeshinfo.ca = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff)); + aliasmeshinfo.ca = currentrenderentity->alpha * fog; for (i = 0;i < m->numshaders;i++) { @@ -785,7 +896,7 @@ void R_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m) } } -void R_DrawZymoticModel (void) +void R_DrawZymoticModel (float fog) { zymtype1header_t *m; @@ -795,19 +906,22 @@ void R_DrawZymoticModel (void) ZymoticTransformVerts(m->numverts, (int *)(m->lump_vertbonecounts.start + (int) m), (zymvertex_t *)(m->lump_verts.start + (int) m)); ZymoticCalcNormals(m->numverts, m->numshaders, (int *)(m->lump_render.start + (int) m)); - R_LightModel(m->numverts); + R_LightModel(m->numverts, 1 - fog, 1 - fog, 1 - fog, true); memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo)); aliasmeshinfo.numverts = m->numverts; R_DrawZymoticModelMesh(m); - if (fogenabled) - R_DrawZymoticModelMeshFog(currentrenderentity->origin, m); + if (fog) + R_DrawZymoticModelMeshFog(currentrenderentity->origin, m, fog); } void R_DrawAliasModel (void) { + float fog; + vec3_t diff; + if (currentrenderentity->alpha < (1.0f / 64.0f)) return; // basically completely transparent @@ -815,8 +929,25 @@ void R_DrawAliasModel (void) softwaretransformforentity(currentrenderentity); + fog = 0; + if (fogenabled) + { + VectorSubtract(currentrenderentity->origin, r_origin, diff); + fog = DotProduct(diff,diff); + if (fog < 0.01f) + fog = 0.01f; + fog = exp(fogdensity/fog); + if (fog > 1) + fog = 1; + if (fog < 0.01f) + fog = 0; + // fog method: darken, additive fog + // 1. render model as normal, scaled by inverse of fog alpha (darkens it) + // 2. render fog as additive + } + if (currentrenderentity->model->aliastype == ALIASTYPE_ZYM) - R_DrawZymoticModel(); + R_DrawZymoticModel(fog); else - R_DrawQ1Q2AliasModel(); + R_DrawQ1Q2AliasModel(fog); } diff --git a/gl_rmain.c b/gl_rmain.c index 845c87f7..ceae807b 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -543,7 +543,7 @@ static int blendviewpolyindex[3] = {0, 1, 2}; static void R_BlendView(void) { rmeshinfo_t m; - float tvxyz[3][4]; + float tvxyz[3][4], r; if (!r_render.integer) return; @@ -565,15 +565,17 @@ static void R_BlendView(void) m.cg = r_refdef.viewblend[1]; m.cb = r_refdef.viewblend[2]; m.ca = r_refdef.viewblend[3]; - tvxyz[0][0] = r_origin[0] + vpn[0] * 8 - vright[0] * 16 - vup[0] * 16; - tvxyz[0][1] = r_origin[1] + vpn[1] * 8 - vright[1] * 16 - vup[1] * 16; - tvxyz[0][2] = r_origin[2] + vpn[2] * 8 - vright[2] * 16 - vup[2] * 16; - tvxyz[1][0] = tvxyz[0][0] + vup[0] * 48; - tvxyz[1][1] = tvxyz[0][1] + vup[1] * 48; - tvxyz[1][2] = tvxyz[0][2] + vup[2] * 48; - tvxyz[2][0] = tvxyz[0][0] + vright[0] * 48; - tvxyz[2][1] = tvxyz[0][1] + vright[1] * 48; - tvxyz[2][2] = tvxyz[0][2] + vright[2] * 48; + r = 64000; + tvxyz[0][0] = r_origin[0] + vpn[0] * 1.5 - vright[0] * r - vup[0] * r; + tvxyz[0][1] = r_origin[1] + vpn[1] * 1.5 - vright[1] * r - vup[1] * r; + tvxyz[0][2] = r_origin[2] + vpn[2] * 1.5 - vright[2] * r - vup[2] * r; + r *= 3; + tvxyz[1][0] = tvxyz[0][0] + vup[0] * r; + tvxyz[1][1] = tvxyz[0][1] + vup[1] * r; + tvxyz[1][2] = tvxyz[0][2] + vup[2] * r; + tvxyz[2][0] = tvxyz[0][0] + vright[0] * r; + tvxyz[2][1] = tvxyz[0][1] + vright[1] * r; + tvxyz[2][2] = tvxyz[0][2] + vright[2] * r; R_Mesh_Draw(&m); /* diff --git a/gl_textures.c b/gl_textures.c index 2ef38e93..7c1d44c3 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -118,8 +118,6 @@ gltexturepool_t; static gltexturepool_t *gltexturepoolchain = NULL; -static qbyte *resamplerow1 = NULL, *resamplerow2 = NULL; -static int resamplerowsize = 0; static qbyte *resizebuffer = NULL, *colorconvertbuffer; static int resizebuffersize = 0; static qbyte *texturebuffer; @@ -319,6 +317,8 @@ static glmode_t modes[] = {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR} }; +extern int gl_backend_rebindtextures; + static void GL_TextureMode_f (void) { int i; @@ -369,6 +369,7 @@ static void GL_TextureMode_f (void) } } } + gl_backend_rebindtextures = true; } static int R_CalcTexelDataSize (gltexture_t *glt) @@ -486,18 +487,13 @@ static void r_textures_shutdown(void) /* if (resizebuffer) Mem_Free(resizebuffer);resizebuffer = NULL; if (colorconvertbuffer) Mem_Free(colorconvertbuffer);colorconvertbuffer = NULL; - if (resamplerow1) Mem_Free(resamplerow1);resamplerow1 = NULL; - if (resamplerow2) Mem_Free(resamplerow2);resamplerow2 = NULL; if (texturebuffer) Mem_Free(texturebuffer);texturebuffer = NULL; if (gltexnuminuse) Mem_Free(gltexnuminuse);gltexnuminuse = NULL; */ resizebuffersize = 0; - resamplerowsize = 0; texturebuffersize = 0; resizebuffer = NULL; colorconvertbuffer = NULL; - resamplerow1 = NULL; - resamplerow2 = NULL; texturebuffer = NULL; gltexnuminuse = NULL; Mem_FreePool(&texturemempool); @@ -523,476 +519,6 @@ void R_Textures_Init (void) R_RegisterModule("R_Textures", r_textures_start, r_textures_shutdown, r_textures_newmap); } -static void R_ResampleTextureLerpLine (qbyte *in, qbyte *out, int inwidth, int outwidth, int bytesperpixel) -{ - int j, xi, oldx = 0, f, fstep, endx, lerp; - fstep = (int) (inwidth*65536.0f/outwidth); - endx = (inwidth-1); - if (bytesperpixel == 4) - { - for (j = 0,f = 0;j < outwidth;j++, f += fstep) - { - xi = f >> 16; - if (xi != oldx) - { - in += (xi - oldx) * 4; - oldx = xi; - } - if (xi < endx) - { - lerp = f & 0xFFFF; - *out++ = (qbyte) ((((in[4] - in[0]) * lerp) >> 16) + in[0]); - *out++ = (qbyte) ((((in[5] - in[1]) * lerp) >> 16) + in[1]); - *out++ = (qbyte) ((((in[6] - in[2]) * lerp) >> 16) + in[2]); - *out++ = (qbyte) ((((in[7] - in[3]) * lerp) >> 16) + in[3]); - } - else // last pixel of the line has no pixel to lerp to - { - *out++ = in[0]; - *out++ = in[1]; - *out++ = in[2]; - *out++ = in[3]; - } - } - } - else if (bytesperpixel == 3) - { - for (j = 0,f = 0;j < outwidth;j++, f += fstep) - { - xi = f >> 16; - if (xi != oldx) - { - in += (xi - oldx) * 3; - oldx = xi; - } - if (xi < endx) - { - lerp = f & 0xFFFF; - *out++ = (qbyte) ((((in[3] - in[0]) * lerp) >> 16) + in[0]); - *out++ = (qbyte) ((((in[4] - in[1]) * lerp) >> 16) + in[1]); - *out++ = (qbyte) ((((in[5] - in[2]) * lerp) >> 16) + in[2]); - } - else // last pixel of the line has no pixel to lerp to - { - *out++ = in[0]; - *out++ = in[1]; - *out++ = in[2]; - } - } - } - else - Sys_Error("R_ResampleTextureLerpLine: unsupported bytesperpixel %i\n", bytesperpixel); -} - -/* -================ -R_ResampleTexture -================ -*/ -static void R_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight, int bytesperpixel) -{ - if (resamplerowsize < outwidth*4) - { - if (resamplerow1) - Mem_Free(resamplerow1); - if (resamplerow2) - Mem_Free(resamplerow2); - resamplerowsize = outwidth*4; - resamplerow1 = Mem_Alloc(textureprocessingmempool, resamplerowsize); - resamplerow2 = Mem_Alloc(textureprocessingmempool, resamplerowsize); - } -#define row1 resamplerow1 -#define row2 resamplerow2 - if (bytesperpixel == 4) - { - if (r_lerpimages.integer) - { - int i, j, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth4 = inwidth*4, outwidth4 = outwidth*4; - qbyte *inrow, *out; - out = outdata; - fstep = (int) (inheight*65536.0f/outheight); - - inrow = indata; - oldy = 0; - R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel); - R_ResampleTextureLerpLine (inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel); - for (i = 0, f = 0;i < outheight;i++,f += fstep) - { - yi = f >> 16; - if (yi < endy) - { - lerp = f & 0xFFFF; - if (yi != oldy) - { - inrow = (qbyte *)indata + inwidth4*yi; - if (yi == oldy+1) - memcpy(row1, row2, outwidth4); - else - R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel); - R_ResampleTextureLerpLine (inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel); - oldy = yi; - } - j = outwidth - 4; - while(j >= 0) - { -#define LERPBYTE(i) out[i] = (qbyte) ((((row2[i] - row1[i]) * lerp) >> 16) + row1[i]) - LERPBYTE( 0); - LERPBYTE( 1); - LERPBYTE( 2); - LERPBYTE( 3); - LERPBYTE( 4); - LERPBYTE( 5); - LERPBYTE( 6); - LERPBYTE( 7); - LERPBYTE( 8); - LERPBYTE( 9); - LERPBYTE(10); - LERPBYTE(11); - LERPBYTE(12); - LERPBYTE(13); - LERPBYTE(14); - LERPBYTE(15); - out += 16; - row1 += 16; - row2 += 16; - j -= 4; - } - if (j & 2) - { - LERPBYTE( 0); - LERPBYTE( 1); - LERPBYTE( 2); - LERPBYTE( 3); - LERPBYTE( 4); - LERPBYTE( 5); - LERPBYTE( 6); - LERPBYTE( 7); - out += 8; - row1 += 8; - row2 += 8; - } - if (j & 1) - { - LERPBYTE( 0); - LERPBYTE( 1); - LERPBYTE( 2); - LERPBYTE( 3); - out += 4; - row1 += 4; - row2 += 4; - } - row1 -= outwidth4; - row2 -= outwidth4; - } - else - { - if (yi != oldy) - { - inrow = (qbyte *)indata + inwidth4*yi; - if (yi == oldy+1) - memcpy(row1, row2, outwidth4); - else - R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel); - oldy = yi; - } - memcpy(out, row1, outwidth4); - } - } - } - else - { - int i, j; - unsigned frac, fracstep; - // relies on int being 4 bytes - int *inrow, *out; - out = outdata; - - fracstep = inwidth*0x10000/outwidth; - for (i = 0;i < outheight;i++) - { - inrow = (int *)indata + inwidth*(i*inheight/outheight); - frac = fracstep >> 1; - j = outwidth - 4; - while (j >= 0) - { - out[0] = inrow[frac >> 16];frac += fracstep; - out[1] = inrow[frac >> 16];frac += fracstep; - out[2] = inrow[frac >> 16];frac += fracstep; - out[3] = inrow[frac >> 16];frac += fracstep; - out += 4; - j -= 4; - } - if (j & 2) - { - out[0] = inrow[frac >> 16];frac += fracstep; - out[1] = inrow[frac >> 16];frac += fracstep; - out += 2; - } - if (j & 1) - { - out[0] = inrow[frac >> 16];frac += fracstep; - out += 1; - } - } - } - } - else if (bytesperpixel == 3) - { - if (r_lerpimages.integer) - { - int i, j, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth3 = inwidth * 3, outwidth3 = outwidth * 3; - qbyte *inrow, *out; - out = outdata; - fstep = (int) (inheight*65536.0f/outheight); - - inrow = indata; - oldy = 0; - R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel); - R_ResampleTextureLerpLine (inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel); - for (i = 0, f = 0;i < outheight;i++,f += fstep) - { - yi = f >> 16; - if (yi < endy) - { - lerp = f & 0xFFFF; - if (yi != oldy) - { - inrow = (qbyte *)indata + inwidth3*yi; - if (yi == oldy+1) - memcpy(row1, row2, outwidth3); - else - R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel); - R_ResampleTextureLerpLine (inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel); - oldy = yi; - } - j = outwidth - 4; - while(j >= 0) - { -#define LERPBYTE(i) out[i] = (qbyte) ((((row2[i] - row1[i]) * lerp) >> 16) + row1[i]) - LERPBYTE( 0); - LERPBYTE( 1); - LERPBYTE( 2); - LERPBYTE( 3); - LERPBYTE( 4); - LERPBYTE( 5); - LERPBYTE( 6); - LERPBYTE( 7); - LERPBYTE( 8); - LERPBYTE( 9); - LERPBYTE(10); - LERPBYTE(11); - out += 12; - row1 += 12; - row2 += 12; - j -= 4; - } - if (j & 2) - { - LERPBYTE( 0); - LERPBYTE( 1); - LERPBYTE( 2); - LERPBYTE( 3); - LERPBYTE( 4); - LERPBYTE( 5); - out += 6; - row1 += 6; - row2 += 6; - } - if (j & 1) - { - LERPBYTE( 0); - LERPBYTE( 1); - LERPBYTE( 2); - out += 3; - row1 += 3; - row2 += 3; - } - row1 -= outwidth3; - row2 -= outwidth3; - } - else - { - if (yi != oldy) - { - inrow = (qbyte *)indata + inwidth3*yi; - if (yi == oldy+1) - memcpy(row1, row2, outwidth3); - else - R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel); - oldy = yi; - } - memcpy(out, row1, outwidth3); - } - } - } - else - { - int i, j, f, inwidth3 = inwidth * 3; - unsigned frac, fracstep; - qbyte *inrow, *out; - out = outdata; - - fracstep = inwidth*0x10000/outwidth; - for (i = 0;i < outheight;i++) - { - inrow = (qbyte *)indata + inwidth3*(i*inheight/outheight); - frac = fracstep >> 1; - j = outwidth - 4; - while (j >= 0) - { - f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; - f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; - f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; - f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; - j -= 4; - } - if (j & 2) - { - f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; - f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; - out += 2; - } - if (j & 1) - { - f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; - out += 1; - } - } - } - } - else - Sys_Error("R_ResampleTexture: unsupported bytesperpixel %i\n", bytesperpixel); -#undef row1 -#undef row2 -} - -// in can be the same as out -static void R_MipReduce(qbyte *in, qbyte *out, int *width, int *height, int destwidth, int destheight, int bytesperpixel) -{ - int x, y, nextrow; - nextrow = *width * bytesperpixel; - if (*width > destwidth) - { - *width >>= 1; - if (*height > destheight) - { - // reduce both - *height >>= 1; - if (bytesperpixel == 4) - { - for (y = 0;y < *height;y++) - { - for (x = 0;x < *width;x++) - { - out[0] = (qbyte) ((in[0] + in[4] + in[nextrow ] + in[nextrow+4]) >> 2); - out[1] = (qbyte) ((in[1] + in[5] + in[nextrow+1] + in[nextrow+5]) >> 2); - out[2] = (qbyte) ((in[2] + in[6] + in[nextrow+2] + in[nextrow+6]) >> 2); - out[3] = (qbyte) ((in[3] + in[7] + in[nextrow+3] + in[nextrow+7]) >> 2); - out += 4; - in += 8; - } - in += nextrow; // skip a line - } - } - else if (bytesperpixel == 3) - { - for (y = 0;y < *height;y++) - { - for (x = 0;x < *width;x++) - { - out[0] = (qbyte) ((in[0] + in[3] + in[nextrow ] + in[nextrow+3]) >> 2); - out[1] = (qbyte) ((in[1] + in[4] + in[nextrow+1] + in[nextrow+4]) >> 2); - out[2] = (qbyte) ((in[2] + in[5] + in[nextrow+2] + in[nextrow+5]) >> 2); - out += 3; - in += 6; - } - in += nextrow; // skip a line - } - } - else - Sys_Error("R_MipReduce: unsupported bytesperpixel %i\n", bytesperpixel); - } - else - { - // reduce width - if (bytesperpixel == 4) - { - for (y = 0;y < *height;y++) - { - for (x = 0;x < *width;x++) - { - out[0] = (qbyte) ((in[0] + in[4]) >> 1); - out[1] = (qbyte) ((in[1] + in[5]) >> 1); - out[2] = (qbyte) ((in[2] + in[6]) >> 1); - out[3] = (qbyte) ((in[3] + in[7]) >> 1); - out += 4; - in += 8; - } - } - } - else if (bytesperpixel == 3) - { - for (y = 0;y < *height;y++) - { - for (x = 0;x < *width;x++) - { - out[0] = (qbyte) ((in[0] + in[3]) >> 1); - out[1] = (qbyte) ((in[1] + in[4]) >> 1); - out[2] = (qbyte) ((in[2] + in[5]) >> 1); - out += 3; - in += 6; - } - } - } - else - Sys_Error("R_MipReduce: unsupported bytesperpixel %i\n", bytesperpixel); - } - } - else - { - if (*height > destheight) - { - // reduce height - *height >>= 1; - if (bytesperpixel == 4) - { - for (y = 0;y < *height;y++) - { - for (x = 0;x < *width;x++) - { - out[0] = (qbyte) ((in[0] + in[nextrow ]) >> 1); - out[1] = (qbyte) ((in[1] + in[nextrow+1]) >> 1); - out[2] = (qbyte) ((in[2] + in[nextrow+2]) >> 1); - out[3] = (qbyte) ((in[3] + in[nextrow+3]) >> 1); - out += 4; - in += 4; - } - in += nextrow; // skip a line - } - } - else if (bytesperpixel == 3) - { - for (y = 0;y < *height;y++) - { - for (x = 0;x < *width;x++) - { - out[0] = (qbyte) ((in[0] + in[nextrow ]) >> 1); - out[1] = (qbyte) ((in[1] + in[nextrow+1]) >> 1); - out[2] = (qbyte) ((in[2] + in[nextrow+2]) >> 1); - out += 3; - in += 3; - } - in += nextrow; // skip a line - } - } - else - Sys_Error("R_MipReduce: unsupported bytesperpixel %i\n", bytesperpixel); - } - else - Sys_Error("R_MipReduce: desired size already achieved\n"); - } -} - static void R_Upload(gltexture_t *glt, qbyte *data) { int mip, width, height, internalformat; @@ -1002,6 +528,8 @@ static void R_Upload(gltexture_t *glt, qbyte *data) glBindTexture(GL_TEXTURE_2D, glt->image->texnum); CHECKGLERROR + gl_backend_rebindtextures = true; + glt->flags &= ~GLTEXF_UPLOAD; if (glt->flags & TEXF_FRAGMENT) @@ -1088,14 +616,14 @@ static void R_Upload(gltexture_t *glt, qbyte *data) if (glt->width != width || glt->height != height) { - R_ResampleTexture(prevbuffer, glt->width, glt->height, resizebuffer, width, height, glt->image->bytesperpixel); + Image_Resample(prevbuffer, glt->width, glt->height, resizebuffer, width, height, glt->image->bytesperpixel, r_lerpimages.integer); prevbuffer = resizebuffer; } // apply picmip/max_size limitations while (width > glt->image->width || height > glt->image->height) { - R_MipReduce(prevbuffer, resizebuffer, &width, &height, glt->image->width, glt->image->height, glt->image->bytesperpixel); + Image_MipReduce(prevbuffer, resizebuffer, &width, &height, glt->image->width, glt->image->height, glt->image->bytesperpixel); prevbuffer = resizebuffer; } } @@ -1112,7 +640,7 @@ static void R_Upload(gltexture_t *glt, qbyte *data) { while (width > 1 || height > 1) { - R_MipReduce(prevbuffer, resizebuffer, &width, &height, 1, 1, glt->image->bytesperpixel); + Image_MipReduce(prevbuffer, resizebuffer, &width, &height, 1, 1, glt->image->bytesperpixel); prevbuffer = resizebuffer; glTexImage2D(GL_TEXTURE_2D, mip++, internalformat, width, height, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer); diff --git a/host.c b/host.c index 88ef16a6..c9f500f3 100644 --- a/host.c +++ b/host.c @@ -868,7 +868,7 @@ void Host_Shutdown(void) isdown = true; // keep Con_Printf from trying to update the screen - scr_disabled_for_loading = true; +// scr_disabled_for_loading = true; Host_WriteConfiguration (); diff --git a/image.c b/image.c index bcd2bc77..1c414dd7 100644 --- a/image.c +++ b/image.c @@ -702,3 +702,484 @@ qboolean Image_CheckAlpha(qbyte *data, int size, qboolean rgba) } return 0; } + +static void Image_Resample32LerpLine (qbyte *in, qbyte *out, int inwidth, int outwidth) +{ + int j, xi, oldx = 0, f, fstep, endx, lerp; + fstep = (int) (inwidth*65536.0f/outwidth); + endx = (inwidth-1); + for (j = 0,f = 0;j < outwidth;j++, f += fstep) + { + xi = f >> 16; + if (xi != oldx) + { + in += (xi - oldx) * 4; + oldx = xi; + } + if (xi < endx) + { + lerp = f & 0xFFFF; + *out++ = (qbyte) ((((in[4] - in[0]) * lerp) >> 16) + in[0]); + *out++ = (qbyte) ((((in[5] - in[1]) * lerp) >> 16) + in[1]); + *out++ = (qbyte) ((((in[6] - in[2]) * lerp) >> 16) + in[2]); + *out++ = (qbyte) ((((in[7] - in[3]) * lerp) >> 16) + in[3]); + } + else // last pixel of the line has no pixel to lerp to + { + *out++ = in[0]; + *out++ = in[1]; + *out++ = in[2]; + *out++ = in[3]; + } + } +} + +static void Image_Resample24LerpLine (qbyte *in, qbyte *out, int inwidth, int outwidth) +{ + int j, xi, oldx = 0, f, fstep, endx, lerp; + fstep = (int) (inwidth*65536.0f/outwidth); + endx = (inwidth-1); + for (j = 0,f = 0;j < outwidth;j++, f += fstep) + { + xi = f >> 16; + if (xi != oldx) + { + in += (xi - oldx) * 3; + oldx = xi; + } + if (xi < endx) + { + lerp = f & 0xFFFF; + *out++ = (qbyte) ((((in[3] - in[0]) * lerp) >> 16) + in[0]); + *out++ = (qbyte) ((((in[4] - in[1]) * lerp) >> 16) + in[1]); + *out++ = (qbyte) ((((in[5] - in[2]) * lerp) >> 16) + in[2]); + } + else // last pixel of the line has no pixel to lerp to + { + *out++ = in[0]; + *out++ = in[1]; + *out++ = in[2]; + } + } +} + +int resamplerowsize = 0; +qbyte *resamplerow1 = NULL; +qbyte *resamplerow2 = NULL; +mempool_t *resamplemempool = NULL; + +#define LERPBYTE(i) r = resamplerow1[i];out[i] = (qbyte) ((((resamplerow2[i] - r) * lerp) >> 16) + r) +void Image_Resample32Lerp(void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight) +{ + int i, j, r, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth4 = inwidth*4, outwidth4 = outwidth*4; + qbyte *inrow, *out; + out = outdata; + fstep = (int) (inheight*65536.0f/outheight); + + inrow = indata; + oldy = 0; + Image_Resample32LerpLine (inrow, resamplerow1, inwidth, outwidth); + Image_Resample32LerpLine (inrow + inwidth4, resamplerow2, inwidth, outwidth); + for (i = 0, f = 0;i < outheight;i++,f += fstep) + { + yi = f >> 16; + if (yi < endy) + { + lerp = f & 0xFFFF; + if (yi != oldy) + { + inrow = (qbyte *)indata + inwidth4*yi; + if (yi == oldy+1) + memcpy(resamplerow1, resamplerow2, outwidth4); + else + Image_Resample32LerpLine (inrow, resamplerow1, inwidth, outwidth); + Image_Resample32LerpLine (inrow + inwidth4, resamplerow2, inwidth, outwidth); + oldy = yi; + } + j = outwidth - 4; + while(j >= 0) + { + LERPBYTE( 0); + LERPBYTE( 1); + LERPBYTE( 2); + LERPBYTE( 3); + LERPBYTE( 4); + LERPBYTE( 5); + LERPBYTE( 6); + LERPBYTE( 7); + LERPBYTE( 8); + LERPBYTE( 9); + LERPBYTE(10); + LERPBYTE(11); + LERPBYTE(12); + LERPBYTE(13); + LERPBYTE(14); + LERPBYTE(15); + out += 16; + resamplerow1 += 16; + resamplerow2 += 16; + j -= 4; + } + if (j & 2) + { + LERPBYTE( 0); + LERPBYTE( 1); + LERPBYTE( 2); + LERPBYTE( 3); + LERPBYTE( 4); + LERPBYTE( 5); + LERPBYTE( 6); + LERPBYTE( 7); + out += 8; + resamplerow1 += 8; + resamplerow2 += 8; + } + if (j & 1) + { + LERPBYTE( 0); + LERPBYTE( 1); + LERPBYTE( 2); + LERPBYTE( 3); + out += 4; + resamplerow1 += 4; + resamplerow2 += 4; + } + resamplerow1 -= outwidth4; + resamplerow2 -= outwidth4; + } + else + { + if (yi != oldy) + { + inrow = (qbyte *)indata + inwidth4*yi; + if (yi == oldy+1) + memcpy(resamplerow1, resamplerow2, outwidth4); + else + Image_Resample32LerpLine (inrow, resamplerow1, inwidth, outwidth); + oldy = yi; + } + memcpy(out, resamplerow1, outwidth4); + } + } +} + +void Image_Resample32Nearest(void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight) +{ + int i, j; + unsigned frac, fracstep; + // relies on int being 4 bytes + int *inrow, *out; + out = outdata; + + fracstep = inwidth*0x10000/outwidth; + for (i = 0;i < outheight;i++) + { + inrow = (int *)indata + inwidth*(i*inheight/outheight); + frac = fracstep >> 1; + j = outwidth - 4; + while (j >= 0) + { + out[0] = inrow[frac >> 16];frac += fracstep; + out[1] = inrow[frac >> 16];frac += fracstep; + out[2] = inrow[frac >> 16];frac += fracstep; + out[3] = inrow[frac >> 16];frac += fracstep; + out += 4; + j -= 4; + } + if (j & 2) + { + out[0] = inrow[frac >> 16];frac += fracstep; + out[1] = inrow[frac >> 16];frac += fracstep; + out += 2; + } + if (j & 1) + { + out[0] = inrow[frac >> 16];frac += fracstep; + out += 1; + } + } +} + +void Image_Resample24Lerp(void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight) +{ + int i, j, r, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth3 = inwidth * 3, outwidth3 = outwidth * 3; + qbyte *inrow, *out; + out = outdata; + fstep = (int) (inheight*65536.0f/outheight); + + inrow = indata; + oldy = 0; + Image_Resample24LerpLine (inrow, resamplerow1, inwidth, outwidth); + Image_Resample24LerpLine (inrow + inwidth3, resamplerow2, inwidth, outwidth); + for (i = 0, f = 0;i < outheight;i++,f += fstep) + { + yi = f >> 16; + if (yi < endy) + { + lerp = f & 0xFFFF; + if (yi != oldy) + { + inrow = (qbyte *)indata + inwidth3*yi; + if (yi == oldy+1) + memcpy(resamplerow1, resamplerow2, outwidth3); + else + Image_Resample24LerpLine (inrow, resamplerow1, inwidth, outwidth); + Image_Resample24LerpLine (inrow + inwidth3, resamplerow2, inwidth, outwidth); + oldy = yi; + } + j = outwidth - 4; + while(j >= 0) + { + LERPBYTE( 0); + LERPBYTE( 1); + LERPBYTE( 2); + LERPBYTE( 3); + LERPBYTE( 4); + LERPBYTE( 5); + LERPBYTE( 6); + LERPBYTE( 7); + LERPBYTE( 8); + LERPBYTE( 9); + LERPBYTE(10); + LERPBYTE(11); + out += 12; + resamplerow1 += 12; + resamplerow2 += 12; + j -= 4; + } + if (j & 2) + { + LERPBYTE( 0); + LERPBYTE( 1); + LERPBYTE( 2); + LERPBYTE( 3); + LERPBYTE( 4); + LERPBYTE( 5); + out += 6; + resamplerow1 += 6; + resamplerow2 += 6; + } + if (j & 1) + { + LERPBYTE( 0); + LERPBYTE( 1); + LERPBYTE( 2); + out += 3; + resamplerow1 += 3; + resamplerow2 += 3; + } + resamplerow1 -= outwidth3; + resamplerow2 -= outwidth3; + } + else + { + if (yi != oldy) + { + inrow = (qbyte *)indata + inwidth3*yi; + if (yi == oldy+1) + memcpy(resamplerow1, resamplerow2, outwidth3); + else + Image_Resample24LerpLine (inrow, resamplerow1, inwidth, outwidth); + oldy = yi; + } + memcpy(out, resamplerow1, outwidth3); + } + } +} + +void Image_Resample24Nolerp(void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight) +{ + int i, j, f, inwidth3 = inwidth * 3; + unsigned frac, fracstep; + qbyte *inrow, *out; + out = outdata; + + fracstep = inwidth*0x10000/outwidth; + for (i = 0;i < outheight;i++) + { + inrow = (qbyte *)indata + inwidth3*(i*inheight/outheight); + frac = fracstep >> 1; + j = outwidth - 4; + while (j >= 0) + { + f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; + f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; + f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; + f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; + j -= 4; + } + if (j & 2) + { + f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; + f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; + out += 2; + } + if (j & 1) + { + f = (frac >> 16)*3;*out++ = inrow[f+0];*out++ = inrow[f+1];*out++ = inrow[f+2];frac += fracstep; + out += 1; + } + } +} + +/* +================ +Image_Resample +================ +*/ +void Image_Resample (void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight, int bytesperpixel, int quality) +{ + if (resamplerowsize < outwidth*4) + { + if (resamplerow1) + Mem_Free(resamplerow1); + resamplerowsize = outwidth*4; + if (!resamplemempool) + resamplemempool = Mem_AllocPool("Image Scaling Buffer"); + resamplerow1 = Mem_Alloc(resamplemempool, resamplerowsize*2); + resamplerow2 = resamplerow1 + resamplerowsize; + } + if (bytesperpixel == 4) + { + if (quality) + Image_Resample32Lerp(indata, inwidth, inheight, outdata, outwidth, outheight); + else + Image_Resample32Nearest(indata, inwidth, inheight, outdata, outwidth, outheight); + } + else if (bytesperpixel == 3) + { + if (quality) + Image_Resample24Lerp(indata, inwidth, inheight, outdata, outwidth, outheight); + else + Image_Resample24Nolerp(indata, inwidth, inheight, outdata, outwidth, outheight); + } + else + Sys_Error("Image_Resample: unsupported bytesperpixel %i\n", bytesperpixel); +} + +// in can be the same as out +void Image_MipReduce(qbyte *in, qbyte *out, int *width, int *height, int destwidth, int destheight, int bytesperpixel) +{ + int x, y, nextrow; + nextrow = *width * bytesperpixel; + if (*width > destwidth) + { + *width >>= 1; + if (*height > destheight) + { + // reduce both + *height >>= 1; + if (bytesperpixel == 4) + { + for (y = 0;y < *height;y++) + { + for (x = 0;x < *width;x++) + { + out[0] = (qbyte) ((in[0] + in[4] + in[nextrow ] + in[nextrow+4]) >> 2); + out[1] = (qbyte) ((in[1] + in[5] + in[nextrow+1] + in[nextrow+5]) >> 2); + out[2] = (qbyte) ((in[2] + in[6] + in[nextrow+2] + in[nextrow+6]) >> 2); + out[3] = (qbyte) ((in[3] + in[7] + in[nextrow+3] + in[nextrow+7]) >> 2); + out += 4; + in += 8; + } + in += nextrow; // skip a line + } + } + else if (bytesperpixel == 3) + { + for (y = 0;y < *height;y++) + { + for (x = 0;x < *width;x++) + { + out[0] = (qbyte) ((in[0] + in[3] + in[nextrow ] + in[nextrow+3]) >> 2); + out[1] = (qbyte) ((in[1] + in[4] + in[nextrow+1] + in[nextrow+4]) >> 2); + out[2] = (qbyte) ((in[2] + in[5] + in[nextrow+2] + in[nextrow+5]) >> 2); + out += 3; + in += 6; + } + in += nextrow; // skip a line + } + } + else + Sys_Error("Image_MipReduce: unsupported bytesperpixel %i\n", bytesperpixel); + } + else + { + // reduce width + if (bytesperpixel == 4) + { + for (y = 0;y < *height;y++) + { + for (x = 0;x < *width;x++) + { + out[0] = (qbyte) ((in[0] + in[4]) >> 1); + out[1] = (qbyte) ((in[1] + in[5]) >> 1); + out[2] = (qbyte) ((in[2] + in[6]) >> 1); + out[3] = (qbyte) ((in[3] + in[7]) >> 1); + out += 4; + in += 8; + } + } + } + else if (bytesperpixel == 3) + { + for (y = 0;y < *height;y++) + { + for (x = 0;x < *width;x++) + { + out[0] = (qbyte) ((in[0] + in[3]) >> 1); + out[1] = (qbyte) ((in[1] + in[4]) >> 1); + out[2] = (qbyte) ((in[2] + in[5]) >> 1); + out += 3; + in += 6; + } + } + } + else + Sys_Error("Image_MipReduce: unsupported bytesperpixel %i\n", bytesperpixel); + } + } + else + { + if (*height > destheight) + { + // reduce height + *height >>= 1; + if (bytesperpixel == 4) + { + for (y = 0;y < *height;y++) + { + for (x = 0;x < *width;x++) + { + out[0] = (qbyte) ((in[0] + in[nextrow ]) >> 1); + out[1] = (qbyte) ((in[1] + in[nextrow+1]) >> 1); + out[2] = (qbyte) ((in[2] + in[nextrow+2]) >> 1); + out[3] = (qbyte) ((in[3] + in[nextrow+3]) >> 1); + out += 4; + in += 4; + } + in += nextrow; // skip a line + } + } + else if (bytesperpixel == 3) + { + for (y = 0;y < *height;y++) + { + for (x = 0;x < *width;x++) + { + out[0] = (qbyte) ((in[0] + in[nextrow ]) >> 1); + out[1] = (qbyte) ((in[1] + in[nextrow+1]) >> 1); + out[2] = (qbyte) ((in[2] + in[nextrow+2]) >> 1); + out += 3; + in += 3; + } + in += nextrow; // skip a line + } + } + else + Sys_Error("Image_MipReduce: unsupported bytesperpixel %i\n", bytesperpixel); + } + else + Sys_Error("Image_MipReduce: desired size already achieved\n"); + } +} diff --git a/image.h b/image.h index f8d4608c..bf3e76f1 100644 --- a/image.h +++ b/image.h @@ -1,14 +1,48 @@ +#ifndef IMAGE_H +#define IMAGE_H + +// applies gamma correction to RGB pixels, in can be the same as out void Image_GammaRemapRGB(qbyte *in, qbyte *out, int pixels, qbyte *gammar, qbyte *gammag, qbyte *gammab); + +// converts 8bit image data to RGBA, in can not be the same as out void Image_Copy8bitRGBA(qbyte *in, qbyte *out, int pixels, int *pal); + +// makes a RGBA mask from RGBA input, in can be the same as out int image_makemask (qbyte *in, qbyte *out, int size); + +// loads a texture, as pixel data qbyte *loadimagepixels (char* filename, qboolean complain, int matchwidth, int matchheight); + +// loads a texture, as a texture rtexture_t *loadtextureimage (rtexturepool_t *pool, char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache); + +// loads a texture's alpha mask, as pixel data qbyte *loadimagepixelsmask (char* filename, qboolean complain, int matchwidth, int matchheight); + +// loads a texture's alpha mask, as a texture rtexture_t *loadtextureimagemask (rtexturepool_t *pool, char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache); + +// loads a texture and it's alpha mask at once (NULL if it has no translucent pixels) rtexture_t *image_masktex; rtexture_t *loadtextureimagewithmask (rtexturepool_t *pool, char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache); + +// writes a RGB TGA that is already upside down (which TGA wants) void Image_WriteTGARGB_preflipped (char *filename, int width, int height, qbyte *data); + +// writes a RGB TGA void Image_WriteTGARGB (char *filename, int width, int height, qbyte *data); + +// writes a RGBA TGA void Image_WriteTGARGBA (char *filename, int width, int height, qbyte *data); + +// returns true if the image has some translucent pixels qboolean Image_CheckAlpha(qbyte *data, int size, qboolean rgba); + +// resizes the image (in can not be the same as out) +void Image_Resample (void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight, int bytesperpixel, int quality); + +// scales the image down by a power of 2 (in can be the same as out) +void Image_MipReduce(qbyte *in, qbyte *out, int *width, int *height, int destwidth, int destheight, int bytesperpixel); + +#endif diff --git a/keys.c b/keys.c index 4cd6d4b3..133da90c 100644 --- a/keys.c +++ b/keys.c @@ -171,7 +171,10 @@ void Key_Console (int key) key_linepos = 1; // force an update, because the command may take some time if (cls.state == ca_disconnected) + { + CL_UpdateScreen (); CL_UpdateScreen (); + } return; } diff --git a/net_dgrm.c b/net_dgrm.c index db5f46bc..ac8cfa6c 100644 --- a/net_dgrm.c +++ b/net_dgrm.c @@ -1242,7 +1242,7 @@ static qsocket_t *_Datagram_Connect (char *host) goto ErrorReturn; // send the connection request - Con_Printf("trying...\n"); CL_UpdateScreen (); + Con_Printf("trying...\n");CL_UpdateScreen();CL_UpdateScreen(); start_time = net_time; for (reps = 0; reps < 3; reps++) @@ -1306,7 +1306,7 @@ static qsocket_t *_Datagram_Connect (char *host) while (ret == 0 && (SetNetTime() - start_time) < 2.5); if (ret) break; - Con_Printf("still trying...\n"); CL_UpdateScreen (); + Con_Printf("still trying...\n");CL_UpdateScreen();CL_UpdateScreen(); start_time = SetNetTime(); } diff --git a/r_explosion.c b/r_explosion.c index a8644ffc..8bac758f 100644 --- a/r_explosion.c +++ b/r_explosion.c @@ -172,7 +172,7 @@ void R_NewExplosion(vec3_t org) int i, j; float dist; qbyte noise[EXPLOSIONGRID*EXPLOSIONGRID]; - fractalnoisequick(noise, EXPLOSIONGRID, 4); + fractalnoisequick(noise, EXPLOSIONGRID, 4); // adjust noise grid size according to explosion for (i = 0;i < MAX_EXPLOSIONS;i++) { if (explosion[i].alpha <= 0.01f) @@ -221,7 +221,7 @@ void R_NewExplosion(vec3_t org) void R_DrawExplosion(explosion_t *e) { int i; - float c[EXPLOSIONVERTS][4], diff[3], /*fog, */ifog, alpha, dist, centerdist, size, scale; + float c[EXPLOSIONVERTS][4], diff[3], centerdir[3], /*fog, */ifog, alpha, dist/*, centerdist, size, scale*/; rmeshinfo_t m; memset(&m, 0, sizeof(m)); m.transparent = true; @@ -233,28 +233,35 @@ void R_DrawExplosion(explosion_t *e) m.vertex = &e->vert[0][0]; m.vertexstep = sizeof(float[3]); alpha = e->alpha; - if (alpha > 1) - alpha = 1; + //if (alpha > 1) + // alpha = 1; m.cr = 1; m.cg = 1; m.cb = 1; - m.ca = alpha; + m.ca = 1; //alpha; m.color = &c[0][0]; m.colorstep = sizeof(float[4]); - centerdist = DotProduct(e->origin, vpn); + VectorSubtract(r_origin, e->origin, centerdir); + VectorNormalizeFast(centerdir); + /* + centerdist = DotProduct(e->origin, centerdir); size = 0; for (i = 0;i < EXPLOSIONVERTS;i++) { - dist = DotProduct(e->vert[i], vpn) - centerdist; - if (size > dist) + dist = DotProduct(e->vert[i], centerdir) - centerdist; + if (size < dist) size = dist; } - scale = 1.0f / size; + scale = 4.0f / size; + */ if (fogenabled) { for (i = 0;i < EXPLOSIONVERTS;i++) { - dist = (DotProduct(e->vert[i], vpn) - centerdist) * scale; + //dist = (DotProduct(e->vert[i], centerdir) - centerdist) * scale - 2.0f; + VectorSubtract(e->vert[i], e->origin, diff); + VectorNormalizeFast(diff); + dist = DotProduct(diff, centerdir) * 6.0f - 4.0f; if (dist > 0) { // use inverse fog alpha as color @@ -273,7 +280,10 @@ void R_DrawExplosion(explosion_t *e) { for (i = 0;i < EXPLOSIONVERTS;i++) { - dist = (DotProduct(e->vert[i], vpn) - centerdist) * scale; + //dist = (DotProduct(e->vert[i], centerdir) - centerdist) * scale - 2.0f; + VectorSubtract(e->vert[i], e->origin, diff); + VectorNormalizeFast(diff); + dist = DotProduct(diff, centerdir) * 6.0f - 4.0f; if (dist > 0) c[i][0] = c[i][1] = c[i][2] = dist * alpha; else diff --git a/r_light.c b/r_light.c index aa35da8e..4264ea65 100644 --- a/r_light.c +++ b/r_light.c @@ -26,7 +26,7 @@ int r_numdlights = 0; cvar_t r_lightmodels = {CVAR_SAVE, "r_lightmodels", "1"}; cvar_t r_vismarklights = {0, "r_vismarklights", "1"}; -cvar_t r_lightmodelhardness = {CVAR_SAVE, "r_lightmodelhardness", "0.9"}; +//cvar_t r_lightmodelhardness = {CVAR_SAVE, "r_lightmodelhardness", "1"}; static rtexture_t *lightcorona; static rtexturepool_t *lighttexturepool; @@ -67,7 +67,7 @@ void r_light_newmap(void) void R_Light_Init(void) { Cvar_RegisterVariable(&r_lightmodels); - Cvar_RegisterVariable(&r_lightmodelhardness); + //Cvar_RegisterVariable(&r_lightmodelhardness); Cvar_RegisterVariable(&r_vismarklights); R_RegisterModule("R_Light", r_light_start, r_light_shutdown, r_light_newmap); } @@ -804,10 +804,10 @@ void R_ModelLightPoint (vec3_t color, vec3_t p, int *dlightbits) dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0; } -void R_LightModel(int numverts) +void R_LightModel(int numverts, float colorr, float colorg, float colorb, int worldcoords) { int i, j, nearlights = 0; - float color[3], basecolor[3], v[3], t, *av, *avn, *avc, a, number, f, hardness, hardnessoffset, dist2; + float color[3], basecolor[3], v[3], t, *av, *avn, *avc, a, number, f/*, hardness, hardnessoffset*/, dist2; struct { vec3_t origin; @@ -820,7 +820,11 @@ void R_LightModel(int numverts) //staticlight_t *sl; a = currentrenderentity->alpha; if (currentrenderentity->effects & EF_FULLBRIGHT) - basecolor[0] = basecolor[1] = basecolor[2] = 1; + { + basecolor[0] = colorr; + basecolor[1] = colorg; + basecolor[2] = colorb; + } else { if (r_lightmodels.integer) @@ -837,7 +841,11 @@ void R_LightModel(int numverts) nl->fadetype = sl->fadetype; nl->distancescale = sl->distancescale; nl->radius = sl->radius; - VectorCopy(sl->origin, nl->origin); + // transform the light into the model's coordinate system + if (worldcoords) + VectorCopy(sl->origin, nl->origin); + else + softwareuntransform(sl->origin, nl->origin); VectorCopy(sl->color, nl->light); nl->cullradius2 = 99999999; nl->lightsubtract = 0; @@ -862,12 +870,14 @@ void R_LightModel(int numverts) //if (TraceLine(currentrenderentity->origin, r_dlight[i].origin, NULL, NULL, 0) == 1) { // transform the light into the model's coordinate system - //if (gl_transform.integer) - // softwareuntransform(r_dlight[i].origin, nl->origin); - //else + if (worldcoords) VectorCopy(r_dlight[i].origin, nl->origin); + else + softwareuntransform(r_dlight[i].origin, nl->origin); nl->cullradius2 = r_dlight[i].cullradius2; - VectorCopy(r_dlight[i].light, nl->light); + nl->light[0] = r_dlight[i].light[0] * colorr; + nl->light[1] = r_dlight[i].light[1] * colorg; + nl->light[2] = r_dlight[i].light[2] * colorb; nl->lightsubtract = r_dlight[i].lightsubtract; nl++; nearlights++; @@ -878,13 +888,16 @@ void R_LightModel(int numverts) else R_CompleteLightPoint (basecolor, currentrenderentity->origin, true, NULL); } + basecolor[0] *= colorr; + basecolor[1] *= colorg; + basecolor[2] *= colorb; avc = aliasvertcolor; if (nearlights) { av = aliasvert; avn = aliasvertnorm; - hardness = r_lightmodelhardness.value; - hardnessoffset = (1.0f - hardness); + //hardness = r_lightmodelhardness.value; + //hardnessoffset = (1.0f - hardness); for (i = 0;i < numverts;i++) { VectorCopy(basecolor, color); @@ -908,7 +921,7 @@ void R_LightModel(int numverts) #endif // DotProduct(avn,v) * t is dotproduct with a normalized v, // the hardness variables are for backlighting/shinyness - f *= DotProduct(avn,v) * t * hardness + hardnessoffset; + f *= DotProduct(avn,v) * t;// * hardness + hardnessoffset; if (f > 0) VectorMA(color, f, nl->light, color); } diff --git a/r_light.h b/r_light.h index 9a264c94..c3899f45 100644 --- a/r_light.h +++ b/r_light.h @@ -18,4 +18,4 @@ void R_AnimateLight(void); void R_MarkLights(void); void R_DrawCoronas(void); void R_CompleteLightPoint(vec3_t color, vec3_t p, int dynamic, mleaf_t *leaf); -void R_LightModel(int numverts); +void R_LightModel(int numverts, float colorr, float colorg, float colorb, int worldcoords); diff --git a/vid_wgl.c b/vid_wgl.c index efefc6ea..c6ea4233 100644 --- a/vid_wgl.c +++ b/vid_wgl.c @@ -249,7 +249,8 @@ qboolean VID_SetFullDIBMode (int modenum) int VID_SetMode (int modenum) { - int original_mode, temp; + int original_mode + //int temp; qboolean stat = 0; MSG msg; @@ -257,8 +258,8 @@ int VID_SetMode (int modenum) Sys_Error ("Bad video mode\n"); // so Con_Printfs don't mess us up by forcing vid and snd updates - temp = scr_disabled_for_loading; - scr_disabled_for_loading = true; +// temp = scr_disabled_for_loading; +// scr_disabled_for_loading = true; CDAudio_Pause (); @@ -301,7 +302,7 @@ int VID_SetMode (int modenum) VID_UpdateWindowStatus (); CDAudio_Resume (); - scr_disabled_for_loading = temp; +// scr_disabled_for_loading = temp; if (!stat) Sys_Error ("Couldn't set video mode");