added cl_particles_blood_size_min, cl_particles_blood_size_max, and cl_particles_bloo...
authorlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 12 Mar 2002 16:57:26 +0000 (16:57 +0000)
committerlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 12 Mar 2002 16:57:26 +0000 (16:57 +0000)
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

16 files changed:
cl_particles.c
cl_screen.c
console.c
gl_backend.c
gl_models.c
gl_rmain.c
gl_textures.c
host.c
image.c
image.h
keys.c
net_dgrm.c
r_explosion.c
r_light.c
r_light.h
vid_wgl.c

index 823c68b..cca5a5b 100644 (file)
@@ -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);
index 174f320..b8922b2 100644 (file)
@@ -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");
 
index e6382e9..5d424f6 100644 (file)
--- 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;
 }
 
 
index 562c447..d5f605a 100644 (file)
@@ -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;
index 3c83354..815ddb4 100644 (file)
@@ -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);
 }
index 845c87f..ceae807 100644 (file)
@@ -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);
 
        /*
index 2ef38e9..7c1d44c 100644 (file)
@@ -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 88ef16a..c9f500f 100644 (file)
--- 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 bcd2bc7..1c414dd 100644 (file)
--- 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 f8d4608..bf3e76f 100644 (file)
--- 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 4cd6d4b..133da90 100644 (file)
--- 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;
        }
 
index db5f46b..ac8cfa6 100644 (file)
@@ -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();
        }
 
index a8644ff..8bac758 100644 (file)
@@ -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
index aa35da8..4264ea6 100644 (file)
--- 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);
                                        }
index 9a264c9..c3899f4 100644 (file)
--- 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);
index efefc6e..c6ea423 100644 (file)
--- 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");