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"};
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);
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);
}
}
*/
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;
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);
}
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);
}
}
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);
+ }
}
/*
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);
}
/*
*/
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);
}
/*
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)
// 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);
}
}
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;
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]);
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);
}
}
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);
//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);
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)
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);
}
}
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];
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)
{
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)
{
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;
}
}
}
+ 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)
{
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);
{
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;
p->die = -1;
break;
case pt_fade:
- p->alpha -= frametime * 384;
+ p->alpha -= frametime * p->time2;
if (p->alpha < 1)
p->die = -1;
break;
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;
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);
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];
{
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);
*/
void SCR_EndLoadingPlaque (void)
{
+ /*
if (!scr_drawloading)
return;
// scr_disabled_for_loading = false;
scr_drawloading = false;
Con_ClearNotify ();
+ */
}
//=============================================================================
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();
ui_draw();
- /*
if (scr_drawloading)
{
+ scr_drawloading = false;
SCR_DrawLoading();
- if (
}
- */
R_TimeReport("2d");
{
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;
}
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)
{
}
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);
// 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
}
}
}
- 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;
#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)
{
}
*/
+/*
rtexturepool_t *chrometexturepool;
+rtexture_t *chrometexture;
// currently unused reflection effect texture
void makechrometexture(void)
chrometexture = R_LoadTexture (chrometexturepool, "chrometexture", 64, 64, &data[0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_PRECACHE);
}
+*/
mempool_t *gl_models_mempool;
{
// 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);
}
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);
}
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--;
}
}
}
}
-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];
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;
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)
}
}
-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);
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++)
{
}
}
-void R_DrawZymoticModel (void)
+void R_DrawZymoticModel (float fog)
{
zymtype1header_t *m;
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
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);
}
static void R_BlendView(void)
{
rmeshinfo_t m;
- float tvxyz[3][4];
+ float tvxyz[3][4], r;
if (!r_render.integer)
return;
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);
/*
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;
{"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
};
+extern int gl_backend_rebindtextures;
+
static void GL_TextureMode_f (void)
{
int i;
}
}
}
+ gl_backend_rebindtextures = true;
}
static int R_CalcTexelDataSize (gltexture_t *glt)
/*
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);
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;
glBindTexture(GL_TEXTURE_2D, glt->image->texnum);
CHECKGLERROR
+ gl_backend_rebindtextures = true;
+
glt->flags &= ~GLTEXF_UPLOAD;
if (glt->flags & TEXF_FRAGMENT)
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;
}
}
{
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);
isdown = true;
// keep Con_Printf from trying to update the screen
- scr_disabled_for_loading = true;
+// scr_disabled_for_loading = true;
Host_WriteConfiguration ();
}
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");
+ }
+}
+#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
key_linepos = 1;
// force an update, because the command may take some time
if (cls.state == ca_disconnected)
+ {
+ CL_UpdateScreen ();
CL_UpdateScreen ();
+ }
return;
}
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++)
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();
}
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)
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;
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
{
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
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;
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);
}
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;
//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)
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;
//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++;
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);
#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);
}
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);
int VID_SetMode (int modenum)
{
- int original_mode, temp;
+ int original_mode
+ //int temp;
qboolean stat = 0;
MSG msg;
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 ();
VID_UpdateWindowStatus ();
CDAudio_Resume ();
- scr_disabled_for_loading = temp;
+// scr_disabled_for_loading = temp;
if (!stat)
Sys_Error ("Couldn't set video mode");