+++ /dev/null
-/*
-Copyright (C) 1996-1997 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-*/
-{-0.525731, 0.000000, 0.850651},
-{-0.442863, 0.238856, 0.864188},
-{-0.295242, 0.000000, 0.955423},
-{-0.309017, 0.500000, 0.809017},
-{-0.162460, 0.262866, 0.951056},
-{0.000000, 0.000000, 1.000000},
-{0.000000, 0.850651, 0.525731},
-{-0.147621, 0.716567, 0.681718},
-{0.147621, 0.716567, 0.681718},
-{0.000000, 0.525731, 0.850651},
-{0.309017, 0.500000, 0.809017},
-{0.525731, 0.000000, 0.850651},
-{0.295242, 0.000000, 0.955423},
-{0.442863, 0.238856, 0.864188},
-{0.162460, 0.262866, 0.951056},
-{-0.681718, 0.147621, 0.716567},
-{-0.809017, 0.309017, 0.500000},
-{-0.587785, 0.425325, 0.688191},
-{-0.850651, 0.525731, 0.000000},
-{-0.864188, 0.442863, 0.238856},
-{-0.716567, 0.681718, 0.147621},
-{-0.688191, 0.587785, 0.425325},
-{-0.500000, 0.809017, 0.309017},
-{-0.238856, 0.864188, 0.442863},
-{-0.425325, 0.688191, 0.587785},
-{-0.716567, 0.681718, -0.147621},
-{-0.500000, 0.809017, -0.309017},
-{-0.525731, 0.850651, 0.000000},
-{0.000000, 0.850651, -0.525731},
-{-0.238856, 0.864188, -0.442863},
-{0.000000, 0.955423, -0.295242},
-{-0.262866, 0.951056, -0.162460},
-{0.000000, 1.000000, 0.000000},
-{0.000000, 0.955423, 0.295242},
-{-0.262866, 0.951056, 0.162460},
-{0.238856, 0.864188, 0.442863},
-{0.262866, 0.951056, 0.162460},
-{0.500000, 0.809017, 0.309017},
-{0.238856, 0.864188, -0.442863},
-{0.262866, 0.951056, -0.162460},
-{0.500000, 0.809017, -0.309017},
-{0.850651, 0.525731, 0.000000},
-{0.716567, 0.681718, 0.147621},
-{0.716567, 0.681718, -0.147621},
-{0.525731, 0.850651, 0.000000},
-{0.425325, 0.688191, 0.587785},
-{0.864188, 0.442863, 0.238856},
-{0.688191, 0.587785, 0.425325},
-{0.809017, 0.309017, 0.500000},
-{0.681718, 0.147621, 0.716567},
-{0.587785, 0.425325, 0.688191},
-{0.955423, 0.295242, 0.000000},
-{1.000000, 0.000000, 0.000000},
-{0.951056, 0.162460, 0.262866},
-{0.850651, -0.525731, 0.000000},
-{0.955423, -0.295242, 0.000000},
-{0.864188, -0.442863, 0.238856},
-{0.951056, -0.162460, 0.262866},
-{0.809017, -0.309017, 0.500000},
-{0.681718, -0.147621, 0.716567},
-{0.850651, 0.000000, 0.525731},
-{0.864188, 0.442863, -0.238856},
-{0.809017, 0.309017, -0.500000},
-{0.951056, 0.162460, -0.262866},
-{0.525731, 0.000000, -0.850651},
-{0.681718, 0.147621, -0.716567},
-{0.681718, -0.147621, -0.716567},
-{0.850651, 0.000000, -0.525731},
-{0.809017, -0.309017, -0.500000},
-{0.864188, -0.442863, -0.238856},
-{0.951056, -0.162460, -0.262866},
-{0.147621, 0.716567, -0.681718},
-{0.309017, 0.500000, -0.809017},
-{0.425325, 0.688191, -0.587785},
-{0.442863, 0.238856, -0.864188},
-{0.587785, 0.425325, -0.688191},
-{0.688191, 0.587785, -0.425325},
-{-0.147621, 0.716567, -0.681718},
-{-0.309017, 0.500000, -0.809017},
-{0.000000, 0.525731, -0.850651},
-{-0.525731, 0.000000, -0.850651},
-{-0.442863, 0.238856, -0.864188},
-{-0.295242, 0.000000, -0.955423},
-{-0.162460, 0.262866, -0.951056},
-{0.000000, 0.000000, -1.000000},
-{0.295242, 0.000000, -0.955423},
-{0.162460, 0.262866, -0.951056},
-{-0.442863, -0.238856, -0.864188},
-{-0.309017, -0.500000, -0.809017},
-{-0.162460, -0.262866, -0.951056},
-{0.000000, -0.850651, -0.525731},
-{-0.147621, -0.716567, -0.681718},
-{0.147621, -0.716567, -0.681718},
-{0.000000, -0.525731, -0.850651},
-{0.309017, -0.500000, -0.809017},
-{0.442863, -0.238856, -0.864188},
-{0.162460, -0.262866, -0.951056},
-{0.238856, -0.864188, -0.442863},
-{0.500000, -0.809017, -0.309017},
-{0.425325, -0.688191, -0.587785},
-{0.716567, -0.681718, -0.147621},
-{0.688191, -0.587785, -0.425325},
-{0.587785, -0.425325, -0.688191},
-{0.000000, -0.955423, -0.295242},
-{0.000000, -1.000000, 0.000000},
-{0.262866, -0.951056, -0.162460},
-{0.000000, -0.850651, 0.525731},
-{0.000000, -0.955423, 0.295242},
-{0.238856, -0.864188, 0.442863},
-{0.262866, -0.951056, 0.162460},
-{0.500000, -0.809017, 0.309017},
-{0.716567, -0.681718, 0.147621},
-{0.525731, -0.850651, 0.000000},
-{-0.238856, -0.864188, -0.442863},
-{-0.500000, -0.809017, -0.309017},
-{-0.262866, -0.951056, -0.162460},
-{-0.850651, -0.525731, 0.000000},
-{-0.716567, -0.681718, -0.147621},
-{-0.716567, -0.681718, 0.147621},
-{-0.525731, -0.850651, 0.000000},
-{-0.500000, -0.809017, 0.309017},
-{-0.238856, -0.864188, 0.442863},
-{-0.262866, -0.951056, 0.162460},
-{-0.864188, -0.442863, 0.238856},
-{-0.809017, -0.309017, 0.500000},
-{-0.688191, -0.587785, 0.425325},
-{-0.681718, -0.147621, 0.716567},
-{-0.442863, -0.238856, 0.864188},
-{-0.587785, -0.425325, 0.688191},
-{-0.309017, -0.500000, 0.809017},
-{-0.147621, -0.716567, 0.681718},
-{-0.425325, -0.688191, 0.587785},
-{-0.162460, -0.262866, 0.951056},
-{0.442863, -0.238856, 0.864188},
-{0.162460, -0.262866, 0.951056},
-{0.309017, -0.500000, 0.809017},
-{0.147621, -0.716567, 0.681718},
-{0.000000, -0.525731, 0.850651},
-{0.425325, -0.688191, 0.587785},
-{0.587785, -0.425325, 0.688191},
-{0.688191, -0.587785, 0.425325},
-{-0.955423, 0.295242, 0.000000},
-{-0.951056, 0.162460, 0.262866},
-{-1.000000, 0.000000, 0.000000},
-{-0.850651, 0.000000, 0.525731},
-{-0.955423, -0.295242, 0.000000},
-{-0.951056, -0.162460, 0.262866},
-{-0.864188, 0.442863, -0.238856},
-{-0.951056, 0.162460, -0.262866},
-{-0.809017, 0.309017, -0.500000},
-{-0.864188, -0.442863, -0.238856},
-{-0.951056, -0.162460, -0.262866},
-{-0.809017, -0.309017, -0.500000},
-{-0.681718, 0.147621, -0.716567},
-{-0.681718, -0.147621, -0.716567},
-{-0.850651, 0.000000, -0.525731},
-{-0.688191, 0.587785, -0.425325},
-{-0.587785, 0.425325, -0.688191},
-{-0.425325, 0.688191, -0.587785},
-{-0.425325, -0.688191, -0.587785},
-{-0.587785, -0.425325, -0.688191},
-{-0.688191, -0.587785, -0.425325},
void Chase_Update (void)
{
- vec3_t forward, up, right, stop, chase_dest, normal;
+ vec3_t forward, stop, chase_dest, normal;
float dist;
chase_back.value = bound(0, chase_back.value, 128);
chase_up.value = bound(-64, chase_up.value, 64);
- AngleVectors (cl.viewangles, forward, right, up);
+ AngleVectors (cl.viewangles, forward, NULL, NULL);
dist = -chase_back.value - 8;
chase_dest[0] = r_refdef.vieworg[0] + forward[0] * dist;
return 0;
// decide if it is time to grab the next message
- if (cls.signon == SIGNONS) // allways grab until fully connected
+ if (cls.signon == SIGNONS) // always grab until fully connected
{
if (cls.timedemo)
{
if (host_framecount == cls.td_lastframe)
- return 0; // allready read this frame's message
+ return 0; // already read this frame's message
cls.td_lastframe = host_framecount;
// if this is the second frame, grab the real td_starttime
// so the bogus time on the first frame doesn't count
float up, down;
if (in_speed.state & 1)
- speed = host_frametime * cl_anglespeedkey.value;
+ speed = cl.frametime * cl_anglespeedkey.value;
else
- speed = host_frametime;
+ speed = cl.frametime;
if (!(in_strafe.state & 1))
{
return;
//
-// allways dump the first two message, because it may contain leftover inputs
-// from the last level
+// always dump the first two messages, because they may contain leftover inputs from the last level
//
if (++cl.movemessages <= 2)
return;
cls.signon = 0; // need all the signon messages before playing
}
-extern int numgltextures;
-extern int texels;
-
/*
=====================
CL_SignonReply
case 4:
SCR_EndLoadingPlaque (); // allow normal screen updates
- // LordHavoc: debugging purposes
- Con_DPrintf("Texture slots in use: %i : %i : %i texels\n", texture_extension_number, numgltextures, texels);
break;
}
}
Con_Printf ("EMPTY\n");
continue;
}
- Con_Printf ("%s:%2i (%5.1f,%5.1f,%5.1f) [%5.1f %5.1f %5.1f]\n"
- ,ent->model->name,ent->frame, ent->origin[0], ent->origin[1], ent->origin[2], ent->angles[0], ent->angles[1], ent->angles[2]);
+ Con_Printf ("%s:%2i (%5.1f,%5.1f,%5.1f) [%5.1f %5.1f %5.1f]\n", ent->model->name, ent->frame, ent->origin[0], ent->origin[1], ent->origin[2], ent->angles[0], ent->angles[1], ent->angles[2]);
}
}
float f, frac;
f = cl.mtime[0] - cl.mtime[1];
-
- if (!f || cl_nolerp.value || cls.timedemo || sv.active)
+
+ // LordHavoc: lerp in listen games as the server is being capped below the client (usually)
+ if (!f || cl_nolerp.value || cls.timedemo || (sv.active && svs.maxclients == 1))
{
cl.time = cl.mtime[0];
return 1;
{
if (!ent->model)
{ // empty slot
- if (ent->forcelink)
- R_RemoveEfrags (ent); // just became empty
+// if (ent->forcelink)
+// R_RemoveEfrags (ent); // just became empty
continue;
}
{
ent->model = NULL;
// LordHavoc: free on the same frame, not the next
- if (ent->forcelink)
- R_RemoveEfrags (ent); // just became empty
+// if (ent->forcelink)
+// R_RemoveEfrags (ent); // just became empty
continue;
}
- // LordHavoc: animation interpolation, note: framegroups partially override this in the renderer
- /*
- if (ent->model != ent->lerp_model || ent->lerp_time > cl.time)
- {
- ent->lerp_frame1 = ent->lerp_frame2 = ent->frame;
- ent->lerp_time = cl.time;
- ent->lerp = 0;
- }
- else if (ent->frame != ent->lerp_frame2)
- {
- ent->lerp_frame1 = ent->lerpframe2;
- ent->lerp_frame2 = ent->frame;
- ent->lerp_time = cl.time;
- ent->lerp = 0;
- }
- else
- ent->lerp = bound(0, (cl.time - ent->lerp_time) * 10.0f, 1);
- */
-
VectorCopy (ent->origin, oldorg);
if (ent->forcelink)
R_EntityParticles (ent);
if (ent->effects & EF_MUZZLEFLASH)
{
- vec3_t fv, rv, uv;
+ vec3_t fv;
dl = CL_AllocDlight (i);
VectorCopy (ent->origin, dl->origin);
dl->origin[2] += 16;
- AngleVectors (ent->angles, fv, rv, uv);
+ AngleVectors (ent->angles, fv, NULL, NULL);
VectorMA (dl->origin, 18, fv, dl->origin);
dl->radius = 100 + (rand()&31);
dl->die = cl.time + 0.001;
dl->color[0] = 0.05;dl->color[1] = 0.05;dl->color[2] = 0.8;
}
+ else if (ent->effects & EF_FLAME)
+ {
+ if (ent->model)
+ {
+ vec3_t mins, maxs;
+ int temp;
+ VectorAdd(ent->origin, ent->model->mins, mins);
+ VectorAdd(ent->origin, ent->model->maxs, maxs);
+ // how many flames to make
+ temp = (int) (cl.time * 30) - (int) (cl.oldtime * 30);
+ R_FlameCube(mins, maxs, temp);
+ }
+ dl = CL_AllocDlight (i);
+ VectorCopy (ent->origin, dl->origin);
+ dl->radius = 200 + (rand()&31);
+ dl->die = cl.time + 0.25;
+ dl->decay = dl->radius * 4;
+ dl->color[0] = 1.0;dl->color[1] = 0.7;dl->color[2] = 0.3;
+ }
if (ent->model->flags) // LordHavoc: if the model has no flags, don't check each
{
if (!ent->model || ent->effects & EF_NODRAW)
continue;
if (cl_numvisedicts < MAX_VISEDICTS)
- {
- cl_visedicts[cl_numvisedicts] = ent;
- cl_numvisedicts++;
- }
+ cl_visedicts[cl_numvisedicts++] = ent;
}
}
int ret;
cl.oldtime = cl.time;
- cl.time += host_frametime;
+ cl.time += cl.frametime;
do
{
CL_RelinkEntities ();
CL_UpdateTEnts ();
+ CL_DoEffects ();
//
// bring the links up to date
// send the unreliable message
CL_SendMove (&cmd);
-
}
if (cls.demoplayback)
"svc_cdtrack", // [byte] track [byte] looptrack
"svc_sellscreen",
"svc_cutscene",
- "svc_showlmp", // [string] iconlabel [string] lmpfile [byte] x [byte] y
+ "svc_showlmp", // [string] iconlabel [string] lmpfile [short] x [short] y
"svc_hidelmp", // [string] iconlabel
- "svc_skybox", // [string] skyname
- "?", // 38
- "?", // 39
- "?", // 40
- "?", // 41
- "?", // 42
- "?", // 43
- "?", // 44
- "?", // 45
- "?", // 46
- "?", // 47
- "?", // 48
- "?", // 49
- "svc_farclip", // [coord] size
- "svc_fog", // [byte] enable <optional past this point, only included if enable is true> [short] density*4096 [byte] red [byte] green [byte] blue
- "svc_playerposition" // [float] x [float] y [float] z
+ "", // 37
+ "", // 38
+ "", // 39
+ "", // 40
+ "", // 41
+ "", // 42
+ "", // 43
+ "", // 44
+ "", // 45
+ "", // 46
+ "", // 47
+ "", // 48
+ "", // 49
+ "", // 50
+ "svc_fog", // 51
+ "svc_effect", // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
+ "svc_effect2", // [vector] org [short] modelindex [byte] startframe [byte] framecount [byte] framerate
};
//=============================================================================
CL_ParseStartSoundPacket
==================
*/
-void CL_ParseStartSoundPacket(void)
+void CL_ParseStartSoundPacket(int largesoundindex)
{
vec3_t pos;
int channel, ent;
int sound_num;
int volume;
int field_mask;
- float attenuation;
+ float attenuation;
int i;
field_mask = MSG_ReadByte();
attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
channel = MSG_ReadShort ();
- sound_num = MSG_ReadByte ();
+ if (largesoundindex)
+ sound_num = (unsigned short) MSG_ReadShort ();
+ else
+ sound_num = MSG_ReadByte ();
+
+ if (sound_num >= MAX_SOUNDS)
+ Host_Error("CL_ParseStartSoundPacket: sound_num (%i) >= MAX_SOUNDS (%i)\n", sound_num, MAX_SOUNDS);
ent = channel >> 3;
channel &= 7;
*/
void CL_ParseUpdate (int bits)
{
- int i, modnum, num, alpha, scale, glowsize, glowcolor, colormod;
+ int i, modnum, num, alpha, scale, glowsize, glowcolor, colormod, frame;
model_t *model;
qboolean forcelink;
entity_t *ent;
modnum = bits & U_MODEL ? MSG_ReadByte() : baseline->modelindex;
if (modnum >= MAX_MODELS)
Host_Error ("CL_ParseModel: bad modnum");
- ent->deltabaseline.modelindex = modnum;
-
- model = cl.model_precache[modnum];
- if (model != ent->model)
- {
- ent->model = model;
- // automatic animation (torches, etc) can be either all together
- // or randomized
- if (model)
- ent->syncbase = model->synctype == ST_RAND ? (float)(rand()&0x7fff) / 0x7fff : 0.0;
- else
- forcelink = true; // hack to make null model players work
- }
- ent->frame = ((bits & U_FRAME) ? MSG_ReadByte() : (baseline->frame & 0xFF));
+ frame = ((bits & U_FRAME) ? MSG_ReadByte() : (baseline->frame & 0xFF));
i = bits & U_COLORMAP ? MSG_ReadByte() : baseline->colormap;
ent->deltabaseline.colormap = i;
glowsize = bits & U_GLOWSIZE ? MSG_ReadByte() : baseline->glowsize;
glowcolor = bits & U_GLOWCOLOR ? MSG_ReadByte() : baseline->glowcolor;
colormod = bits & U_COLORMOD ? MSG_ReadByte() : baseline->colormod;
- ent->frame |= ((bits & U_FRAME2) ? (MSG_ReadByte() << 8) : (baseline->frame & 0xFF00));
+ modnum |= ((bits & U_MODEL2) ? (MSG_ReadByte() << 8) : (baseline->modelindex & 0xFF00));
+ frame |= ((bits & U_FRAME2) ? (MSG_ReadByte() << 8) : (baseline->frame & 0xFF00));
+
+ if (modnum >= MAX_MODELS)
+ Host_Error("modnum (%i) >= MAX_MODELS (%i)\n", modnum, MAX_MODELS);
+
+ model = cl.model_precache[modnum];
+ if (model != ent->model)
+ {
+ ent->model = model;
+ // automatic animation (torches, etc) can be either all together
+ // or randomized
+ if (model)
+ ent->syncbase = model->synctype == ST_RAND ? (float)(rand()&0x7fff) / 0x7fff : 0.0;
+ else
+ forcelink = true; // hack to make null model players work
+ }
+
+ ent->frame = frame;
+ if (model && (unsigned) frame >= model->numframes)
+ Con_DPrintf("CL_ParseUpdate: no such frame %i in \"%s\"\n", frame, model->name);
+
ent->deltabaseline.alpha = alpha;
ent->deltabaseline.scale = scale;
ent->deltabaseline.effects = ent->effects;
ent->deltabaseline.glowsize = glowsize;
ent->deltabaseline.glowcolor = glowcolor;
ent->deltabaseline.colormod = colormod;
- ent->deltabaseline.frame = ent->frame;
+ ent->deltabaseline.modelindex = modnum;
+ ent->deltabaseline.frame = frame;
ent->alpha = (float) alpha * (1.0 / 255.0);
ent->scale = (float) scale * (1.0 / 16.0);
ent->glowsize = glowsize * 4.0;
ent->colormod[0] = (float) ((colormod >> 5) & 7) * (1.0 / 7.0);
ent->colormod[1] = (float) ((colormod >> 2) & 7) * (1.0 / 7.0);
ent->colormod[2] = (float) (colormod & 3) * (1.0 / 3.0);
- if (bits & U_EXTEND1 && Nehahrademcompatibility) // LordHavoc: to allow playback of the early Nehahra movie segments
+ if (bits & U_EXTEND1 && Nehahrademcompatibility) // LordHavoc: to allow playback of the Nehahra movie
{
i = MSG_ReadFloat();
ent->alpha = MSG_ReadFloat();
CL_ParseBaseline
==================
*/
-void CL_ParseBaseline (entity_t *ent)
+void CL_ParseBaseline (entity_t *ent, int largemodelindex)
{
int i;
-
- ent->baseline.modelindex = MSG_ReadByte ();
+
+ if (largemodelindex)
+ ent->baseline.modelindex = (unsigned short) MSG_ReadShort ();
+ else
+ ent->baseline.modelindex = MSG_ReadByte ();
ent->baseline.frame = MSG_ReadByte ();
ent->baseline.colormap = MSG_ReadByte();
ent->baseline.skin = MSG_ReadByte();
ent->baseline.glowsize = 0;
ent->baseline.glowcolor = 254;
ent->baseline.colormod = 255;
+
+ if (ent->baseline.modelindex >= MAX_MODELS)
+ Host_Error("CL_ParseBaseline: modelindex (%i) >= MAX_MODELS (%i)\n", ent->baseline.modelindex, MAX_MODELS);
}
void CL_ParseClientdata (int bits)
{
int i, j;
-
+
+ bits &= 0xFFFF;
+ if (bits & SU_EXTEND1)
+ bits |= (MSG_ReadByte() << 16);
+ if (bits & SU_EXTEND2)
+ bits |= (MSG_ReadByte() << 24);
+
if (bits & SU_VIEWHEIGHT)
cl.viewheight = MSG_ReadChar ();
else
for (i=0 ; i<3 ; i++)
{
if (bits & (SU_PUNCH1<<i) )
- cl.punchangle[i] = MSG_ReadChar();
+ {
+ if (dpprotocol)
+ cl.punchangle[i] = MSG_ReadPreciseAngle();
+ else
+ cl.punchangle[i] = MSG_ReadChar();
+ }
else
cl.punchangle[i] = 0;
+ if (bits & (SU_PUNCHVEC1<<i))
+ cl.punchvector[i] = MSG_ReadFloatCoord();
+ else
+ cl.punchvector[i] = 0;
if (bits & (SU_VELOCITY1<<i) )
cl.mvelocity[0][i] = MSG_ReadChar()*16;
else
CL_ParseStatic
=====================
*/
-void CL_ParseStatic (void)
+void CL_ParseStatic (int largemodelindex)
{
entity_t *ent;
int i;
Host_Error ("Too many static entities");
ent = &cl_static_entities[i];
cl.num_statics++;
- CL_ParseBaseline (ent);
+ CL_ParseBaseline (ent, largemodelindex);
// copy it to the current state
ent->model = cl.model_precache[ent->baseline.modelindex];
- ent->frame = ent->baseline.frame;
+ ent->frame = ent->frame1 = ent->frame2 = ent->baseline.frame;
+ ent->framelerp = 0;
+ ent->lerp_starttime = -1;
+ // make torchs play out of sync
+ ent->frame1start = ent->frame2start = -(rand() & 32767);
ent->colormap = -1; // no special coloring
ent->skinnum = ent->baseline.skin;
ent->effects = ent->baseline.effects;
{
vec3_t org;
int sound_num, vol, atten;
- int i;
-
- for (i=0 ; i<3 ; i++)
- org[i] = MSG_ReadCoord ();
+
+ MSG_ReadVector(org);
sound_num = MSG_ReadByte ();
vol = MSG_ReadByte ();
atten = MSG_ReadByte ();
S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
}
+void CL_ParseEffect (void)
+{
+ vec3_t org;
+ int modelindex, startframe, framecount, framerate;
+
+ MSG_ReadVector(org);
+ modelindex = MSG_ReadByte ();
+ startframe = MSG_ReadByte ();
+ framecount = MSG_ReadByte ();
+ framerate = MSG_ReadByte ();
+
+ CL_Effect(org, modelindex, startframe, framecount, framerate);
+}
+
+void CL_ParseEffect2 (void)
+{
+ vec3_t org;
+ int modelindex, startframe, framecount, framerate;
+
+ MSG_ReadVector(org);
+ modelindex = MSG_ReadShort ();
+ startframe = MSG_ReadByte ();
+ framecount = MSG_ReadByte ();
+ framerate = MSG_ReadByte ();
+
+ CL_Effect(org, modelindex, startframe, framecount, framerate);
+}
+
#define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
break;
case svc_sound:
- CL_ParseStartSoundPacket();
+ CL_ParseStartSoundPacket(false);
break;
-
+
+ case svc_sound2:
+ CL_ParseStartSoundPacket(true);
+ break;
+
case svc_stopsound:
i = MSG_ReadShort();
S_StopSound(i>>3, i&7);
R_ParseParticleEffect ();
break;
+ case svc_effect:
+ CL_ParseEffect ();
+ break;
+
+ case svc_effect2:
+ CL_ParseEffect2 ();
+ break;
+
case svc_spawnbaseline:
i = MSG_ReadShort ();
// must use CL_EntityNum() to force cl.num_entities up
- CL_ParseBaseline (CL_EntityNum(i));
+ CL_ParseBaseline (CL_EntityNum(i), false);
+ break;
+ case svc_spawnbaseline2:
+ i = MSG_ReadShort ();
+ // must use CL_EntityNum() to force cl.num_entities up
+ CL_ParseBaseline (CL_EntityNum(i), false);
break;
case svc_spawnstatic:
- CL_ParseStatic ();
- break;
+ CL_ParseStatic (false);
+ break;
+ case svc_spawnstatic2:
+ CL_ParseStatic (true);
+ break;
case svc_temp_entity:
CL_ParseTEnt ();
break;
case svc_showlmp:
SHOWLMP_decodeshow();
break;
- // LordHavoc: extra worldspawn fields (fog, sky, farclip)
- case svc_skybox:
- R_SetSkyBox(MSG_ReadString());
- break;
- case svc_farclip:
- r_farclip.value = MSG_ReadCoord();
- break;
- case svc_fog:
- if (MSG_ReadByte())
- {
- fog_density = MSG_ReadShort() * (1.0f / 4096.0f);
- fog_red = MSG_ReadByte() * (1.0 / 255.0);
- fog_green = MSG_ReadByte() * (1.0 / 255.0);
- fog_blue = MSG_ReadByte() * (1.0 / 255.0);
- }
- else
- fog_density = 0.0f;
- break;
}
}
}
#include "quakedef.h"
-#define MSG_ReadVector(v) {(v)[0] = MSG_ReadCoord();(v)[1] = MSG_ReadCoord();(v)[2] = MSG_ReadCoord();}
-
cvar_t r_glowinglightning = {"r_glowinglightning", "1", true};
int num_temp_entities;
dir[1] = MSG_ReadChar ();
dir[2] = MSG_ReadChar ();
count = MSG_ReadByte (); // amount of particles
- R_BloodPuff(pos);
+ R_BloodPuff(pos, dir, count);
break;
case TE_BLOOD2: // blood puff
MSG_ReadVector(pos);
- R_BloodPuff(pos);
+ R_BloodPuff(pos, vec3_origin, 10);
break;
case TE_SPARK: // spark shower
MSG_ReadVector(pos);
S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
break;
+ case TE_SMALLFLASH:
+ MSG_ReadVector(pos);
+ FindNonSolidLocation(pos);
+ dl = CL_AllocDlight (0);
+ VectorCopy (pos, dl->origin);
+ dl->radius = 200;
+ dl->die = cl.time + 0.2;
+ dl->decay = 1000;
+ dl->color[0] = dl->color[1] = dl->color[2] = 1;
+ break;
+
+ case TE_CUSTOMFLASH:
+ MSG_ReadVector(pos);
+ FindNonSolidLocation(pos);
+ dl = CL_AllocDlight (0);
+ VectorCopy (pos, dl->origin);
+ dl->radius = MSG_ReadByte() * 8;
+ velspeed = (MSG_ReadByte() + 1) * (1.0 / 256.0);
+ dl->die = cl.time + velspeed;
+ dl->decay = dl->radius / velspeed;
+ dl->color[0] = MSG_ReadByte() * (1.0 / 255.0);dl->color[1] = MSG_ReadByte() * (1.0 / 255.0);dl->color[2] = MSG_ReadByte() * (1.0 / 255.0);
+ break;
+
+ case TE_FLAMEJET:
+ MSG_ReadVector(pos);
+ MSG_ReadVector(dir);
+ count = MSG_ReadByte();
+ R_Flames(pos, dir, count);
+ break;
+
case TE_LIGHTNING1: // lightning bolts
CL_ParseBeam (Mod_ForName("progs/bolt.mdl", true));
break;
{
entity_t *ent;
- if (cl_numvisedicts == MAX_VISEDICTS)
+ if (cl_numvisedicts >= MAX_VISEDICTS)
return NULL;
- if (num_temp_entities == MAX_TEMP_ENTITIES)
+ if (num_temp_entities >= MAX_TEMP_ENTITIES)
return NULL;
- ent = &cl_temp_entities[num_temp_entities];
+ ent = &cl_temp_entities[num_temp_entities++];
memset (ent, 0, sizeof(*ent));
- num_temp_entities++;
- cl_visedicts[cl_numvisedicts] = ent;
- cl_numvisedicts++;
+ cl_visedicts[cl_numvisedicts++] = ent;
ent->colormap = -1; // no special coloring
ent->scale = 1;
VectorCopy (ent->origin, dl->origin);
dl->radius = 100 + (rand()&31);
dl->die = cl.time + 0.001;
- dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 1;
+ dl->color[0] = dl->color[1] = dl->color[2] = r_glowinglightning.value * 0.25f;
}
VectorMA(org, 30, dist, org);
vec3_t velocity; // lerped between mvelocity[0] and [1]
vec3_t punchangle; // temporary offset
+ vec3_t punchvector; // LordHavoc: origin view kick
// pitch drifting vars
float idealpitch;
// a lerp point for other data
double oldtime; // previous cl.time, time-oldtime is used
// to decay light values and smooth step ups
+
+ double frametime;
float last_received_message; // (realtime) for net trouble icon
extern cvar_t m_side;
-#define MAX_TEMP_ENTITIES 64 // lightning bolts, etc
-#define MAX_STATIC_ENTITIES 128 // torches, etc
+// LordHavoc: raised these from 64 and 128 to 512 and 256
+#define MAX_TEMP_ENTITIES 512 // lightning bolts, effects, etc
+#define MAX_STATIC_ENTITIES 256 // torches, etc
extern client_state_t cl;
void CL_Disconnect_f (void);
void CL_NextDemo (void);
-#define MAX_VISEDICTS 256
+// LordHavoc: raised this from 256 to the maximum possible number of entities visible
+#define MAX_VISEDICTS (MAX_EDICTS + MAX_STATIC_ENTITIES + MAX_TEMP_ENTITIES)
extern int cl_numvisedicts;
extern entity_t *cl_visedicts[MAX_VISEDICTS];
void CL_ParseTEnt (void);
void CL_UpdateTEnts (void);
+void CL_DoEffects (void);
+
+entity_t *CL_NewTempEntity (void);
+
+void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float framerate);
void CL_ClearState (void);
return;
}
- // if the alias allready exists, reuse it
+ // if the alias already exists, reuse it
for (a = cmd_alias ; a ; a=a->next)
{
if (!strcmp(s, a->name))
char *Cmd_Args (void);
// The functions that execute commands get their parameters with these
// functions. Cmd_Argv () will return an empty string, not a NULL
-// if arg > argc, so string operations are allways safe.
+// if arg > argc, so string operations are always safe.
int Cmd_CheckParm (char *parm);
// Returns the position (1 to argc-1) in the command's argument list
}
}
+/*
+============
+COM_CreatePath
+
+LordHavoc: Previously only used for CopyFile, now also used for COM_WriteFile.
+============
+*/
+void COM_CreatePath (char *path)
+{
+ char *ofs, save;
+
+ for (ofs = path+1 ; *ofs ; ofs++)
+ {
+ if (*ofs == '/' || *ofs == '\\' || *ofs == ':')
+ { // create the directory
+ save = *ofs;
+ *ofs = 0;
+ Sys_mkdir (path);
+ *ofs = save;
+ }
+ }
+}
+
+
/*
============
COM_WriteFile
sprintf (name, "%s/%s", com_gamedir, filename);
+ // LordHavoc: added this
+ COM_CreatePath (name); // create directories up to the file
+
handle = Sys_FileOpenWrite (name);
if (handle == -1)
{
}
-/*
-============
-COM_CreatePath
-
-Only used for CopyFile
-============
-*/
-void COM_CreatePath (char *path)
-{
- char *ofs;
-
- for (ofs = path+1 ; *ofs ; ofs++)
- {
- if (*ofs == '/')
- { // create the directory
- *ofs = 0;
- Sys_mkdir (path);
- *ofs = '/';
- }
- }
-}
-
-
/*
===========
COM_CopyFile
COM_LoadFile
Filename are reletive to the quake directory.
-Allways appends a 0 byte.
+Always appends a 0 byte.
============
*/
cache_user_t *loadcache;
#define MSG_ReadAngle() (MSG_ReadByte() * (360.0f / 256.0f))
#define MSG_ReadPreciseAngle() (MSG_ReadShort() * (360.0f / 65536.0f))
+#define MSG_ReadVector(v) {(v)[0] = MSG_ReadCoord();(v)[1] = MSG_ReadCoord();(v)[2] = MSG_ReadCoord();}
+
extern qboolean dpprotocol;
//============================================================================
+++ /dev/null
-
-#include "quakedef.h"
-
-/*
-===============
-Mod_PointInLeaf
-===============
-*/
-mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
-{
- mnode_t *node;
-
-// if (!model || !model->nodes)
-// Sys_Error ("Mod_PointInLeaf: bad model");
-
- node = model->nodes;
- if (node->contents < 0)
- return (mleaf_t *)node;
- while (1)
- {
- node = node->children[(node->plane->type < 3 ? p[node->plane->type] : DotProduct (p,node->plane->normal)) < node->plane->dist];
- if (node->contents < 0)
- return (mleaf_t *)node;
- }
-
- return NULL; // never reached
-}
-/*
-mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
-{
- mnode_t *node;
- float d;
- mplane_t *plane;
-
- if (!model || !model->nodes)
- Sys_Error ("Mod_PointInLeaf: bad model");
-
- node = model->nodes;
- while (1)
- {
- if (node->contents < 0)
- return (mleaf_t *)node;
- plane = node->plane;
- d = DotProduct (p,plane->normal) - plane->dist;
- if (d > 0)
- node = node->children[0];
- else
- node = node->children[1];
- }
-
- return NULL; // never reached
-}
-*/
-
-/*
-==================
-SV_HullPointContents
-
-==================
-*/
-int SV_HullPointContents (hull_t *hull, int num, vec3_t p)
-{
- while (num >= 0)
- num = hull->clipnodes[num].children[(hull->planes[hull->clipnodes[num].planenum].type < 3 ? p[hull->planes[hull->clipnodes[num].planenum].type] : DotProduct (hull->planes[hull->clipnodes[num].planenum].normal, p)) < hull->planes[hull->clipnodes[num].planenum].dist];
-
- return num;
-}
+++ /dev/null
-nasmw -fwin32 cpu_x86.nasm
+++ /dev/null
- BITS 32
- GLOBAL _Mod_PointInLeaf
- GLOBAL _SV_HullPointContents
- SECTION .text
-_Mod_PointInLeaf
-
-;{
-
- mov eax, dword [esp+12-4] ; model
- sub esp, 4
- push ebx
- push esi
-
-; mnode_t *node;
-; node = model->nodes;
-
- mov esi, dword [eax+200] ; model->nodes
-
-; if (node->contents < 0)
-
- cmp dword [esi], 0 ; node->contents
- jge .firstvalid
-
-; return (mleaf_t *)node;
-
- mov eax, esi
- pop esi
- pop ebx
- add esp, 4
- ret 0
-.firstvalid
- mov edx, dword [esp+8+8] ; p
-.loop
-
-; while (1)
-
- xor ecx, ecx
- mov eax, dword [esi+76] ; node->plane
- mov cl, byte [eax+16] ; node->plane->type
-
-; {
-; node = node->children[(node->plane->type < 3 ? p[node->plane->type] : DotProduct (p,node->plane->normal)) < node->plane->dist];
-
- cmp cl, 3
- jb .axisplane
- fld dword [eax+4] ; node->plane->normal[1]
- fmul dword [edx+4] ; p[1]
- fld dword [eax+8] ; node->plane->normal[2]
- fmul dword [edx+8] ; p[2]
- fld dword [eax] ; node->plane->normal[0]
- fmul dword [edx] ; p[0]
- faddp st1, st0
- faddp st1, st0
- fld dword [eax+12] ; node->plane->dist
- fcompp
- fnstsw ax
- test ah, 65 ; 00000041H
- sete cl
- mov esi, dword [esi+ecx*4+80] ; node = node->children[condition]
-
-; if (node->contents < 0)
-
- cmp dword [esi], 0
- jge .loop
-
-; return (mleaf_t *)node;
-
- mov eax, esi
-
-; }
-; return NULL; // never reached
-;}
-
- pop esi
- pop ebx
- add esp, 4
- ret 0
-.axisplane:
- fld dword [edx+ecx*4]
- fld dword [eax+12]
- fcompp
- fnstsw ax
- test ah, 65 ; 00000041H
- sete cl
- mov esi, dword [esi+ecx*4+80] ; node = node->children[condition]
-
-; if (node->contents < 0)
-
- cmp dword [esi], 0
- jge .loop
-
-; return (mleaf_t *)node;
-
- mov eax, esi
-
-; }
-; return NULL; // never reached
-;}
-
- pop esi
- pop ebx
- add esp, 4
- ret 0
-
-
-_SV_HullPointContents
-
-;{
- mov ecx, [esp+12-4] ; num
- sub esp, 4
- test ecx, ecx
- nop ; padding
- push ebx
- push esi
- push edi
- push ebp
-
-; while (num >= 0)
-
- jge .firstvalid
-; return num;
- mov eax, ecx
- pop ebp
-;}
- pop edi
- pop esi
- pop ebx
- add esp, 4
- ret 0
-.firstvalid
- mov eax, [esp+8+16] ; hull
- mov edx, [esp+16+16] ; p
- mov esi, [eax]
- mov edi, [eax+4]
-.loop
- mov eax, [esi+ecx*8]
- lea ebx, [eax+eax*2]
- xor eax, eax
- mov al, [edi+ebx*8+16]
- lea ebp, [edi+ebx*8]
-
-; num = hull->clipnodes[num].children[(hull->planes[hull->clipnodes[num].planenum].type < 3 ? p[hull->planes[hull->clipnodes[num].planenum].type] : DotProduct (hull->planes[hull->clipnodes[num].planenum].normal, p)) < hull->planes[hull->clipnodes[num].planenum].dist];
-
- cmp al, 3
- jb .axisplane
- fld dword [edx+8]
- fmul dword [ebp+8]
- fld dword [edx+4]
- fmul dword [ebp+4]
- fld dword [edx]
- fmul dword [ebp]
- faddp st1, st0
- faddp st1, st0
- fstp dword [esp-4+20]
-
- fld dword [ebp+12]
- fcomp dword [esp-4+20]
- xor ebx, ebx
- fnstsw ax
- test ah, 65 ; 00000041H
- sete bl
- lea eax, [ebx+ecx*4]
- movsx ecx, word [esi+eax*2+4]
- test ecx, ecx
- jge .loop
-; return num;
- mov eax, ecx
- pop ebp
-;}
- pop edi
- pop esi
- pop ebx
- add esp, 4
- ret 0
-
-.axisplane
- mov eax, [edx+eax*4]
- mov [esp-4+20], eax
-
- fld dword [ebp+12]
- fcomp dword [esp-4+20]
- xor ebx, ebx
- fnstsw ax
- test ah, 65 ; 00000041H
- sete bl
- lea eax, [ebx+ecx*4]
- movsx ecx, word [esi+eax*2+4]
- test ecx, ecx
- jge .loop
-; return num;
- mov eax, ecx
- pop ebp
-;}
- pop edi
- pop esi
- pop ebx
- add esp, 4
- ret 0
{
char *oldstr;
-// first check to see if it has allready been defined
+// first check to see if it has already been defined
if (Cvar_FindVar (variable->name))
{
Con_Printf ("Can't register variable %s, already defined\n", variable->name);
} cvar_t;
void Cvar_RegisterVariable (cvar_t *variable);
-// registers a cvar that allready has the name, string, and optionally the
+// registers a cvar that already has the name, string, and optionally the
// archive elements set.
void Cvar_Set (char *var_name, char *value);
void Draw_Init (void);
void Draw_Character (int x, int y, int num);
-void Draw_GenericPic (int texnum, float red, float green, float blue, float alpha, int x, int y, int width, int height);
+void Draw_GenericPic (rtexture_t *tex, float red, float green, float blue, float alpha, int x, int y, int width, int height);
void Draw_Pic (int x, int y, qpic_t *pic);
void Draw_PicTranslate (int x, int y, qpic_t *pic, byte *translation);
void Draw_ConsoleBackground (int lines);
#include "quakedef.h"
-void fractalnoise(unsigned char *noise, int size, int startgrid)
+void fractalnoise(byte *noise, int size, int startgrid)
{
- int x, y, g, g2, amplitude, min, max, size1 = size - 1;
+ int x, y, g, g2, amplitude, min, max, size1 = size - 1, sizepower, gridpower;
int *noisebuf;
#define n(x,y) noisebuf[((y)&size1)*size+((x)&size1)]
- if (startgrid > size)
- startgrid = size;
+
+ for (sizepower = 0;(1 << sizepower) < size;sizepower++);
+ if (size != (1 << sizepower))
+ Sys_Error("fractalnoise: size must be power of 2\n");
+
+ for (gridpower = 0;(1 << gridpower) < startgrid;gridpower++);
+ if (startgrid != (1 << gridpower))
+ Sys_Error("fractalnoise: grid must be power of 2\n");
+
+ startgrid = bound(0, startgrid, size);
+
+ amplitude = 32767;
noisebuf = qmalloc(size*size*sizeof(int));
memset(noisebuf, 0, size*size*sizeof(int));
- amplitude = 32767;
- // quick 1x1 case which the rest of the code can't handle
- if (startgrid < 2)
- {
- for (x = 0;x < size*size;x++)
- *noise++ = (rand()&255);
- return;
- }
- g2 = startgrid;
- // clear the starting grid (the rest does not need to be cleared, it will simply be overwritten)
- for (y = 0;y < size;y += g2)
- for (x = 0;x < size;x += g2)
- n(x,y) = 0;
- for (;(g = g2 >> 1) >= 1;g2 >>= 1)
+ for (g2 = startgrid;g2;g2 >>= 1)
{
- // subdivide, diamond-square algorythm (really this has little to do with squares)
- // diamond
- for (y = 0;y < size;y += g2)
- for (x = 0;x < size;x += g2)
- n(x+g,y+g) = (n(x,y) + n(x+g2,y) + n(x,y+g2) + n(x+g2,y+g2)) >> 2;
- // square
+ // brownian motion (at every smaller level there is random behavior)
+ amplitude >>= 1;
for (y = 0;y < size;y += g2)
for (x = 0;x < size;x += g2)
- {
- n(x+g,y) = (n(x,y) + n(x+g2,y) + n(x+g,y-g) + n(x+g,y+g)) >> 2;
- n(x,y+g) = (n(x,y) + n(x,y+g2) + n(x-g,y+g) + n(x+g,y+g)) >> 2;
- }
- // brownian motion theory
- amplitude >>= 1;
- for (y = 0;y < size;y += g)
- for (x = 0;x < size;x += g)
n(x,y) += (rand()&litude);
+
+ g = g2 >> 1;
+ if (g)
+ {
+ // subdivide, diamond-square algorythm (really this has little to do with squares)
+ // diamond
+ for (y = 0;y < size;y += g2)
+ for (x = 0;x < size;x += g2)
+ n(x+g,y+g) = (n(x,y) + n(x+g2,y) + n(x,y+g2) + n(x+g2,y+g2)) >> 2;
+ // square
+ for (y = 0;y < size;y += g2)
+ for (x = 0;x < size;x += g2)
+ {
+ n(x+g,y) = (n(x,y) + n(x+g2,y) + n(x+g,y-g) + n(x+g,y+g)) >> 2;
+ n(x,y+g) = (n(x,y) + n(x,y+g2) + n(x-g,y+g) + n(x+g,y+g)) >> 2;
+ }
+ }
}
// find range of noise values
min = max = 0;
*noise++ = (n(x,y) - min) * 255 / max;
qfree(noisebuf);
#undef n
-}
\ No newline at end of file
+}
//#define GL_COLOR_INDEX8_EXT 0x80E5
-cvar_t qsg_version = {"qsg_version", "1"};
cvar_t scr_conalpha = {"scr_conalpha", "1"};
byte *draw_chars; // 8*8 graphic characters
qpic_t *draw_disc;
-int char_texture;
+rtexture_t *char_texture;
typedef struct
{
- int texnum;
+ rtexture_t *tex;
} glpic_t;
-int conbacktexnum;
+rtexture_t *conbacktex;
//=============================================================================
/* Support Routines */
p = W_GetLumpName (name);
gl = (glpic_t *)p->data;
- gl->texnum = GL_LoadTexture (name, p->width, p->height, p->data, false, true, 1);
+ gl->tex = R_LoadTexture (name, p->width, p->height, p->data, TEXF_ALPHA | TEXF_PRECACHE);
return p;
}
pic->pic.height = dat->height;
gl = (glpic_t *)pic->pic.data;
- gl->texnum = loadtextureimage(path, 0, 0, false, false);
- if (!gl->texnum)
- gl->texnum = GL_LoadTexture (path, dat->width, dat->height, dat->data, false, true, 1);
+ gl->tex = loadtextureimage(path, 0, 0, false, false, true);
+ if (!gl->tex)
+ gl->tex = R_LoadTexture (path, dat->width, dat->height, dat->data, TEXF_ALPHA | TEXF_PRECACHE);
qfree(dat);
{
int i;
- char_texture = loadtextureimage ("conchars", 0, 0, false, false);
+ char_texture = loadtextureimage ("conchars", 0, 0, false, false, true);
if (!char_texture)
{
draw_chars = W_GetLumpName ("conchars");
draw_chars[i] = 255; // proper transparent color
// now turn them into textures
- char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true, 1);
+ char_texture = R_LoadTexture ("charset", 128, 128, draw_chars, TEXF_ALPHA | TEXF_PRECACHE);
}
- conbacktexnum = loadtextureimage("gfx/conback", 0, 0, false, false);
+ conbacktex = loadtextureimage("gfx/conback", 0, 0, false, false, true);
// get the other pics we need
draw_disc = Draw_PicFromWad ("disc");
char engineversion[40];
int engineversionx, engineversiony;
-extern void GL_Textures_Init();
+extern void R_Textures_Init();
void GL_Draw_Init (void)
{
int i;
- Cvar_RegisterVariable (&qsg_version);
Cvar_RegisterVariable (&scr_conalpha);
Cmd_AddCommand ("loadsky", &LoadSky_f);
engineversionx = vid.width - strlen(engineversion) * 8 - 8;
engineversiony = vid.height - 8;
- GL_Textures_Init();
+ R_Textures_Init();
R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown);
}
if (!r_render.value)
return;
- glBindTexture(GL_TEXTURE_2D, char_texture);
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(char_texture));
// LordHavoc: NEAREST mode on text if not scaling up
- if (glwidth < (int) vid.width)
+ if (glwidth <= (int) vid.width)
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
+ else
+ {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
glColor3f(1,1,1);
glBegin (GL_QUADS);
glEnd ();
// LordHavoc: revert to LINEAR mode
- if (glwidth < (int) vid.width)
- {
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }
+// if (glwidth < (int) vid.width)
+// {
+// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+// }
}
/*
maxlen = strlen(str);
else if (maxlen > (int) strlen(str))
maxlen = strlen(str);
- glBindTexture(GL_TEXTURE_2D, char_texture);
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(char_texture));
// LordHavoc: NEAREST mode on text if not scaling up
- if (glwidth < (int) vid.width)
+ if (glwidth <= (int) vid.width)
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
+ else
+ {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
glColor3f(1,1,1);
glBegin (GL_QUADS);
glEnd ();
// LordHavoc: revert to LINEAR mode
- if (glwidth < (int) vid.width)
- {
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }
+// if (glwidth < (int) vid.width)
+// {
+// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+// }
}
-void Draw_GenericPic (int texnum, float red, float green, float blue, float alpha, int x, int y, int width, int height)
+void Draw_GenericPic (rtexture_t *tex, float red, float green, float blue, float alpha, int x, int y, int width, int height)
{
if (!r_render.value)
return;
glColor4f(red,green,blue,alpha);
- glBindTexture(GL_TEXTURE_2D, texnum);
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(tex));
glBegin (GL_QUADS);
glTexCoord2f (0, 0);glVertex2f (x, y);
glTexCoord2f (1, 0);glVertex2f (x+width, y);
*/
void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha)
{
- Draw_GenericPic(((glpic_t *)pic->data)->texnum, 1,1,1,alpha, x,y,pic->width, pic->height);
+ Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,alpha, x,y,pic->width, pic->height);
}
*/
void Draw_Pic (int x, int y, qpic_t *pic)
{
- Draw_GenericPic(((glpic_t *)pic->data)->texnum, 1,1,1,1, x,y,pic->width, pic->height);
+ Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,1, x,y,pic->width, pic->height);
}
{
int i, c;
byte *trans, *src, *dest;
+ rtexture_t *rt;
c = pic->width * pic->height;
src = menuplyr_pixels;
for (i = 0;i < c;i++)
*dest++ = translation[*src++];
- c = GL_LoadTexture ("translatedplayerpic", pic->width, pic->height, trans, false, true, 1);
+ rt = R_LoadTexture ("translatedplayerpic", pic->width, pic->height, trans, TEXF_ALPHA | TEXF_PRECACHE);
qfree(trans);
if (!r_render.value)
return;
- Draw_GenericPic (c, 1,1,1,1, x, y, pic->width, pic->height);
+ Draw_GenericPic (rt, 1,1,1,1, x, y, pic->width, pic->height);
}
*/
void Draw_ConsoleBackground (int lines)
{
- Draw_GenericPic (conbacktexnum, 1,1,1,scr_conalpha.value*lines/vid.height, 0, lines - vid.height, vid.width, vid.height);
+ Draw_GenericPic (conbacktex, 1,1,1,scr_conalpha.value*lines/vid.height, 0, lines - vid.height, vid.width, vid.height);
// LordHavoc: draw version
Draw_String(engineversionx, lines - vid.height + engineversiony, engineversion, 9999);
}
float x, y;
strcpy(lmplabel,MSG_ReadString());
strcpy(picname, MSG_ReadString());
- x = MSG_ReadByte();
- y = MSG_ReadByte();
+ if (nehahra) // LordHavoc: nasty old legacy junk
+ {
+ x = MSG_ReadByte();
+ y = MSG_ReadByte();
+ }
+ else
+ {
+ x = MSG_ReadShort();
+ y = MSG_ReadShort();
+ }
k = -1;
for (i = 0;i < SHOWLMP_MAXLABELS;i++)
if (showlmp[i].isactive)
#include "quakedef.h"
+cvar_t gl_transform = {"gl_transform", "1"};
+cvar_t gl_lockarrays = {"gl_lockarrays", "1"};
+
typedef struct
{
float m[3][4];
// LordHavoc: vertex array
float *aliasvert;
-float *modelaliasvert;
float *aliasvertnorm;
byte *aliasvertcolor;
byte *aliasvertcolor2;
zymbonematrix *zymbonepose;
int *aliasvertusage;
-int chrometexture;
+rtexture_t *chrometexture;
+
+int arraylocked = false;
+void GL_LockArray(int first, int count)
+{
+ if (gl_supportslockarrays && gl_lockarrays.value)
+ {
+ qglLockArraysEXT(first, count);
+ arraylocked = true;
+ }
+}
+
+void GL_UnlockArray()
+{
+ if (arraylocked)
+ {
+ qglUnlockArraysEXT();
+ arraylocked = false;
+ }
+}
+
+void GL_SetupModelTransform (vec3_t origin, vec3_t angles, vec_t scale)
+{
+ glTranslatef (origin[0], origin[1], origin[2]);
+
+ if (scale != 1)
+ glScalef (scale, scale, scale);
+ if (angles[1])
+ glRotatef (angles[1], 0, 0, 1);
+ if (angles[0])
+ glRotatef (-angles[0], 0, 1, 0);
+ if (angles[2])
+ glRotatef (angles[2], 1, 0, 0);
+}
void makechrometexture()
{
byte noise[64*64];
byte data[64*64][4];
- fractalnoise(noise, 64, 16);
+ fractalnoise(noise, 64, 8);
// convert to RGBA data
for (i = 0;i < 64*64;i++)
data[i][3] = 255;
}
- chrometexture = GL_LoadTexture ("chrometexture", 64, 64, &data[0][0], true, false, 4);
+ chrometexture = R_LoadTexture ("chrometexture", 64, 64, &data[0][0], TEXF_MIPMAP | TEXF_RGBA | TEXF_PRECACHE);
}
void gl_models_start()
{
// allocate vertex processing arrays
aliasvert = qmalloc(sizeof(float[MD2MAX_VERTS][3]));
- modelaliasvert = qmalloc(sizeof(float[MD2MAX_VERTS][3]));
aliasvertnorm = qmalloc(sizeof(float[MD2MAX_VERTS][3]));
aliasvertcolor = qmalloc(sizeof(byte[MD2MAX_VERTS][4]));
aliasvertcolor2 = qmalloc(sizeof(byte[MD2MAX_VERTS][4])); // used temporarily for tinted coloring
void GL_Models_Init()
{
+ Cvar_RegisterVariable(&gl_transform);
+ Cvar_RegisterVariable(&gl_lockarrays);
+
R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown);
}
extern vec3_t softwaretransform_z;
extern vec_t softwaretransform_scale;
extern vec3_t softwaretransform_offset;
-extern cvar_t r_modelsdonttransformnormals;
-void R_AliasLerpVerts(int vertcount, float lerp, trivert2 *verts1, vec3_t scale1, vec3_t translate1, trivert2 *verts2, vec3_t scale2, vec3_t translate2)
+void R_AliasTransformVerts(int vertcount)
{
int i;
vec3_t point, matrix_x, matrix_y, matrix_z;
float *av, *avn;
av = aliasvert;
avn = aliasvertnorm;
- VectorScale(softwaretransform_x, softwaretransform_scale, matrix_x);
- VectorScale(softwaretransform_y, softwaretransform_scale, matrix_y);
- VectorScale(softwaretransform_z, softwaretransform_scale, matrix_z);
- if (lerp < 0) lerp = 0;
- if (lerp > 1) lerp = 1;
- if (lerp != 0)
+ matrix_x[0] = softwaretransform_x[0] * softwaretransform_scale;
+ matrix_x[1] = softwaretransform_y[0] * softwaretransform_scale;
+ matrix_x[2] = softwaretransform_z[0] * softwaretransform_scale;
+ matrix_y[0] = softwaretransform_x[1] * softwaretransform_scale;
+ matrix_y[1] = softwaretransform_y[1] * softwaretransform_scale;
+ matrix_y[2] = softwaretransform_z[1] * softwaretransform_scale;
+ matrix_z[0] = softwaretransform_x[2] * softwaretransform_scale;
+ matrix_z[1] = softwaretransform_y[2] * softwaretransform_scale;
+ matrix_z[2] = softwaretransform_z[2] * softwaretransform_scale;
+ for (i = 0;i < vertcount;i++)
+ {
+ // rotate, scale, and translate the vertex locations
+ VectorCopy(av, point);
+ av[0] = DotProduct(point, matrix_x) + softwaretransform_offset[0];
+ av[1] = DotProduct(point, matrix_y) + softwaretransform_offset[1];
+ av[2] = DotProduct(point, matrix_z) + softwaretransform_offset[2];
+ // rotate the normals
+ VectorCopy(avn, point);
+ avn[0] = point[0] * softwaretransform_x[0] + point[1] * softwaretransform_y[0] + point[2] * softwaretransform_z[0];
+ avn[1] = point[0] * softwaretransform_x[1] + point[1] * softwaretransform_y[1] + point[2] * softwaretransform_z[1];
+ avn[2] = point[0] * softwaretransform_x[2] + point[1] * softwaretransform_y[2] + point[2] * softwaretransform_z[2];
+ av += 3;
+ avn += 3;
+ }
+}
+
+void R_AliasLerpVerts(int vertcount,
+ float lerp1, trivertx_t *verts1, vec3_t fscale1, vec3_t translate1,
+ float lerp2, trivertx_t *verts2, vec3_t fscale2, vec3_t translate2,
+ float lerp3, trivertx_t *verts3, vec3_t fscale3, vec3_t translate3,
+ float lerp4, trivertx_t *verts4, vec3_t fscale4, vec3_t translate4)
+{
+ int i;
+ vec3_t scale1, scale2, scale3, scale4, translate;
+ float *n1, *n2, *n3, *n4;
+ float *av, *avn;
+ av = aliasvert;
+ avn = aliasvertnorm;
+ VectorScaleQuick(fscale1, lerp1, scale1);
+ if (lerp2)
{
- float ilerp, ilerp127, lerp127, scalex1, scalex2, translatex, scaley1, scaley2, translatey, scalez1, scalez2, translatez;
- ilerp = 1 - lerp;
- ilerp127 = ilerp * (1.0 / 127.0);
- lerp127 = lerp * (1.0 / 127.0);
- // calculate combined interpolation variables
- scalex1 = scale1[0] * ilerp;scalex2 = scale2[0] * lerp;translatex = translate1[0] * ilerp + translate2[0] * lerp;
- scaley1 = scale1[1] * ilerp;scaley2 = scale2[1] * lerp;translatey = translate1[1] * ilerp + translate2[1] * lerp;
- scalez1 = scale1[2] * ilerp;scalez2 = scale2[2] * lerp;translatez = translate1[2] * ilerp + translate2[2] * lerp;
- // generate vertices
- if (r_modelsdonttransformnormals.value)
+ VectorScaleQuick(fscale2, lerp2, scale2);
+ if (lerp3)
{
- float *modelav = modelaliasvert;
- for (i = 0;i < vertcount;i++)
+ VectorScaleQuick(fscale3, lerp3, scale3);
+ if (lerp4)
{
- // rotate, scale, and translate the vertex locations
- point[0] = verts1->v[0] * scalex1 + verts2->v[0] * scalex2 + translatex;
- point[1] = verts1->v[1] * scaley1 + verts2->v[1] * scaley2 + translatey;
- point[2] = verts1->v[2] * scalez1 + verts2->v[2] * scalez2 + translatez;
- // save mostly un-transformed copy for lighting
- modelav[0] = point[0] * softwaretransform_scale;
- modelav[1] = point[1] * softwaretransform_scale;
- modelav[2] = point[2] * softwaretransform_scale;
- av[0] = point[0] * matrix_x[0] + point[1] * matrix_y[0] + point[2] * matrix_z[0] + softwaretransform_offset[0];
- av[1] = point[0] * matrix_x[1] + point[1] * matrix_y[1] + point[2] * matrix_z[1] + softwaretransform_offset[1];
- av[2] = point[0] * matrix_x[2] + point[1] * matrix_y[2] + point[2] * matrix_z[2] + softwaretransform_offset[2];
- // decompress but do not transform the normals
- avn[0] = verts1->n[0] * ilerp127 + verts2->n[0] * lerp127;
- avn[1] = verts1->n[1] * ilerp127 + verts2->n[1] * lerp127;
- avn[2] = verts1->n[2] * ilerp127 + verts2->n[2] * lerp127;
- modelav += 3;
- av += 3;
- avn += 3;
- verts1++;verts2++;
+ VectorScaleQuick(fscale4, lerp4, scale4);
+ translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2 + translate3[0] * lerp3 + translate4[0] * lerp4;
+ translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2 + translate3[1] * lerp3 + translate4[1] * lerp4;
+ translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2 + translate3[2] * lerp3 + translate4[2] * lerp4;
+ // generate vertices
+ for (i = 0;i < vertcount;i++)
+ {
+ av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + verts3->v[0] * scale3[0] + verts4->v[0] * scale4[0] + translate[0];
+ av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + verts3->v[1] * scale3[1] + verts4->v[1] * scale4[1] + translate[1];
+ av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + verts3->v[2] * scale3[2] + verts4->v[2] * scale4[2] + translate[2];
+ n1 = m_bytenormals[verts1->lightnormalindex];
+ n2 = m_bytenormals[verts2->lightnormalindex];
+ n3 = m_bytenormals[verts3->lightnormalindex];
+ n4 = m_bytenormals[verts4->lightnormalindex];
+ avn[0] = n1[0] * lerp1 + n2[0] * lerp2 + n3[0] * lerp3 + n4[0] * lerp4;
+ avn[1] = n1[1] * lerp1 + n2[1] * lerp2 + n3[1] * lerp3 + n4[1] * lerp4;
+ avn[2] = n1[2] * lerp1 + n2[2] * lerp2 + n3[2] * lerp3 + n4[2] * lerp4;
+ av += 3;
+ avn += 3;
+ verts1++;verts2++;verts3++;verts4++;
+ }
+ }
+ else
+ {
+ translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2 + translate3[0] * lerp3;
+ translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2 + translate3[1] * lerp3;
+ translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2 + translate3[2] * lerp3;
+ // generate vertices
+ for (i = 0;i < vertcount;i++)
+ {
+ av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + verts3->v[0] * scale3[0] + translate[0];
+ av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + verts3->v[1] * scale3[1] + translate[1];
+ av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + verts3->v[2] * scale3[2] + translate[2];
+ n1 = m_bytenormals[verts1->lightnormalindex];
+ n2 = m_bytenormals[verts2->lightnormalindex];
+ n3 = m_bytenormals[verts3->lightnormalindex];
+ avn[0] = n1[0] * lerp1 + n2[0] * lerp2 + n3[0] * lerp3;
+ avn[1] = n1[1] * lerp1 + n2[1] * lerp2 + n3[1] * lerp3;
+ avn[2] = n1[2] * lerp1 + n2[2] * lerp2 + n3[2] * lerp3;
+ av += 3;
+ avn += 3;
+ verts1++;verts2++;verts3++;
+ }
}
}
else
{
+ translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2;
+ translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2;
+ translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2;
+ // generate vertices
for (i = 0;i < vertcount;i++)
{
- // rotate, scale, and translate the vertex locations
- point[0] = verts1->v[0] * scalex1 + verts2->v[0] * scalex2 + translatex;
- point[1] = verts1->v[1] * scaley1 + verts2->v[1] * scaley2 + translatey;
- point[2] = verts1->v[2] * scalez1 + verts2->v[2] * scalez2 + translatez;
- av[0] = point[0] * matrix_x[0] + point[1] * matrix_y[0] + point[2] * matrix_z[0] + softwaretransform_offset[0];
- av[1] = point[0] * matrix_x[1] + point[1] * matrix_y[1] + point[2] * matrix_z[1] + softwaretransform_offset[1];
- av[2] = point[0] * matrix_x[2] + point[1] * matrix_y[2] + point[2] * matrix_z[2] + softwaretransform_offset[2];
- // rotate the normals
- point[0] = verts1->n[0] * ilerp127 + verts2->n[0] * lerp127;
- point[1] = verts1->n[1] * ilerp127 + verts2->n[1] * lerp127;
- point[2] = verts1->n[2] * ilerp127 + verts2->n[2] * lerp127;
- avn[0] = point[0] * softwaretransform_x[0] + point[1] * softwaretransform_y[0] + point[2] * softwaretransform_z[0];
- avn[1] = point[0] * softwaretransform_x[1] + point[1] * softwaretransform_y[1] + point[2] * softwaretransform_z[1];
- avn[2] = point[0] * softwaretransform_x[2] + point[1] * softwaretransform_y[2] + point[2] * softwaretransform_z[2];
+ av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + translate[0];
+ av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + translate[1];
+ av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + translate[2];
+ n1 = m_bytenormals[verts1->lightnormalindex];
+ n2 = m_bytenormals[verts2->lightnormalindex];
+ avn[0] = n1[0] * lerp1 + n2[0] * lerp2;
+ avn[1] = n1[1] * lerp1 + n2[1] * lerp2;
+ avn[2] = n1[2] * lerp1 + n2[2] * lerp2;
av += 3;
avn += 3;
verts1++;verts2++;
}
else
{
+ translate[0] = translate1[0] * lerp1;
+ translate[1] = translate1[1] * lerp1;
+ translate[2] = translate1[2] * lerp1;
// generate vertices
- if (r_modelsdonttransformnormals.value)
+ if (lerp1 != 1)
{
- float *modelav = modelaliasvert;
+ // general but almost never used case
for (i = 0;i < vertcount;i++)
{
- // rotate, scale, and translate the vertex locations
- point[0] = verts1->v[0] * scale1[0] + translate1[0];
- point[1] = verts1->v[1] * scale1[1] + translate1[1];
- point[2] = verts1->v[2] * scale1[2] + translate1[2];
- // save mostly un-transformed copy for lighting
- modelav[0] = point[0] * softwaretransform_scale;
- modelav[1] = point[1] * softwaretransform_scale;
- modelav[2] = point[2] * softwaretransform_scale;
- av[0] = point[0] * matrix_x[0] + point[1] * matrix_y[0] + point[2] * matrix_z[0] + softwaretransform_offset[0];
- av[1] = point[0] * matrix_x[1] + point[1] * matrix_y[1] + point[2] * matrix_z[1] + softwaretransform_offset[1];
- av[2] = point[0] * matrix_x[2] + point[1] * matrix_y[2] + point[2] * matrix_z[2] + softwaretransform_offset[2];
- // decompress normal but do not rotate it
- avn[0] = verts1->n[0] * (1.0f / 127.0f);
- avn[1] = verts1->n[1] * (1.0f / 127.0f);
- avn[2] = verts1->n[2] * (1.0f / 127.0f);
- modelav += 3;
+ av[0] = verts1->v[0] * scale1[0] + translate[0];
+ av[1] = verts1->v[1] * scale1[1] + translate[1];
+ av[2] = verts1->v[2] * scale1[2] + translate[2];
+ n1 = m_bytenormals[verts1->lightnormalindex];
+ avn[0] = n1[0] * lerp1;
+ avn[1] = n1[1] * lerp1;
+ avn[2] = n1[2] * lerp1;
av += 3;
avn += 3;
verts1++;
}
else
{
+ // fast normal case
for (i = 0;i < vertcount;i++)
{
- // rotate, scale, and translate the vertex locations
- point[0] = verts1->v[0] * scale1[0] + translate1[0];
- point[1] = verts1->v[1] * scale1[1] + translate1[1];
- point[2] = verts1->v[2] * scale1[2] + translate1[2];
- av[0] = point[0] * matrix_x[0] + point[1] * matrix_y[0] + point[2] * matrix_z[0] + softwaretransform_offset[0];
- av[1] = point[0] * matrix_x[1] + point[1] * matrix_y[1] + point[2] * matrix_z[1] + softwaretransform_offset[1];
- av[2] = point[0] * matrix_x[2] + point[1] * matrix_y[2] + point[2] * matrix_z[2] + softwaretransform_offset[2];
- // rotate the normals
- point[0] = verts1->n[0] * (1.0f / 127.0f);
- point[1] = verts1->n[1] * (1.0f / 127.0f);
- point[2] = verts1->n[2] * (1.0f / 127.0f);
- avn[0] = point[0] * softwaretransform_x[0] + point[1] * softwaretransform_y[0] + point[2] * softwaretransform_z[0];
- avn[1] = point[0] * softwaretransform_x[1] + point[1] * softwaretransform_y[1] + point[2] * softwaretransform_z[1];
- avn[2] = point[0] * softwaretransform_x[2] + point[1] * softwaretransform_y[2] + point[2] * softwaretransform_z[2];
+ av[0] = verts1->v[0] * scale1[0] + translate[0];
+ av[1] = verts1->v[1] * scale1[1] + translate[1];
+ av[2] = verts1->v[2] * scale1[2] + translate[2];
+ VectorCopy(m_bytenormals[verts1->lightnormalindex], avn);
av += 3;
avn += 3;
verts1++;
}
}
-float R_CalcAnimLerp(entity_t *ent, int pose, float lerpscale)
-{
- if (ent->draw_lastmodel == ent->model && ent->draw_lerpstart <= cl.time)
- {
- if (pose != ent->draw_pose)
- {
- ent->draw_lastpose = ent->draw_pose;
- ent->draw_pose = pose;
- ent->draw_lerpstart = cl.time;
- return 0;
- }
- else
- return ((cl.time - ent->draw_lerpstart) * lerpscale);
- }
- else // uninitialized
- {
- ent->draw_lastmodel = ent->model;
- ent->draw_lastpose = ent->draw_pose = pose;
- ent->draw_lerpstart = cl.time;
- return 0;
- }
-}
-
-void GL_DrawModelMesh(int skin, byte *colors, maliashdr_t *maliashdr)
+void GL_DrawModelMesh(rtexture_t *skin, byte *colors, maliashdr_t *maliashdr)
{
- int i;
if (!r_render.value)
return;
- glBindTexture(GL_TEXTURE_2D, skin);
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(skin));
if (!colors)
{
if (lighthalf)
else
glColor3f(1.0f, 1.0f, 1.0f);
}
- if (gl_vertexarrays.value)
+ if (colors)
{
- if (colors)
- {
- qglColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
- glEnableClientState(GL_COLOR_ARRAY);
- }
-
- qglTexCoordPointer(2, GL_FLOAT, 0, (void *)((int) maliashdr->texdata + (int) maliashdr));
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- qglDrawElements(GL_TRIANGLES, maliashdr->numtris * 3, GL_UNSIGNED_SHORT, (void *)((int) maliashdr + maliashdr->tridata));
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
+ glEnableClientState(GL_COLOR_ARRAY);
+ }
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDrawElements(GL_TRIANGLES, maliashdr->numtris * 3, GL_UNSIGNED_SHORT, (void *)((int) maliashdr + maliashdr->tridata));
- if (colors)
- glDisableClientState(GL_COLOR_ARRAY);
- }
- else
- {
- unsigned short *in, index;
- float *tex;
- in = (void *)((int) maliashdr + maliashdr->tridata);
- glBegin(GL_TRIANGLES);
- tex = (void *)((int) maliashdr + maliashdr->texdata);
- for (i = 0;i < maliashdr->numtris * 3;i++)
- {
- index = *in++;
- glTexCoord2f(tex[index*2], tex[index*2+1]);
- if (colors)
- glColor4f(colors[index*4] * (1.0f / 255.0f), colors[index*4+1] * (1.0f / 255.0f), colors[index*4+2] * (1.0f / 255.0f), colors[index*4+3] * (1.0f / 255.0f));
- glVertex3fv(&aliasvert[index*3]);
- }
- glEnd();
- }
+ if (colors)
+ glDisableClientState(GL_COLOR_ARRAY);
// leave it in a state for additional passes
glDepthMask(0);
glEnable(GL_BLEND);
*/
extern vec3_t lightspot;
void R_LightModel(int numverts, vec3_t center, vec3_t basecolor);
-void R_DrawAliasFrame (maliashdr_t *maliashdr, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, vec3_t angles, int frame, int *skin, int colormap, int effects, int flags)
+void R_DrawAliasFrame (maliashdr_t *maliashdr, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, vec3_t angles, vec_t scale, frameblend_t *blend, rtexture_t **skin, int colormap, int effects, int flags)
{
- int i, pose;
- float lerpscale, lerp;
- maliasframe_t *frameinfo;
-
- softwaretransformforentity(ent);
-
- if ((frame >= maliashdr->numframes) || (frame < 0))
- {
- Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
- frame = 0;
- }
-
- frameinfo = ((maliasframe_t *)((int) maliashdr + maliashdr->framedata)) + frame;
- pose = frameinfo->start;
-
- if (frameinfo->length > 1)
+ if (gl_transform.value)
{
- lerpscale = frameinfo->rate;
- pose += (int)(cl.time * frameinfo->rate) % frameinfo->length;
+ if (r_render.value)
+ {
+ glPushMatrix();
+ GL_SetupModelTransform(org, angles, scale);
+ }
}
- else
- lerpscale = 10.0f;
-
- lerp = R_CalcAnimLerp(ent, pose, lerpscale);
+ // always needed, for model lighting
+ softwaretransformforentity(ent);
- R_AliasLerpVerts(maliashdr->numverts, lerp, (trivert2 *)((int) maliashdr + maliashdr->posedata) + ent->draw_lastpose * maliashdr->numverts, maliashdr->scale, maliashdr->scale_origin, (trivert2 *)((int) maliashdr + maliashdr->posedata) + ent->draw_pose * maliashdr->numverts, maliashdr->scale, maliashdr->scale_origin);
+ R_AliasLerpVerts(maliashdr->numverts,
+ blend[0].lerp, ((trivertx_t *)((int) maliashdr + maliashdr->posedata)) + blend[0].frame * maliashdr->numverts, maliashdr->scale, maliashdr->scale_origin,
+ blend[1].lerp, ((trivertx_t *)((int) maliashdr + maliashdr->posedata)) + blend[1].frame * maliashdr->numverts, maliashdr->scale, maliashdr->scale_origin,
+ blend[2].lerp, ((trivertx_t *)((int) maliashdr + maliashdr->posedata)) + blend[2].frame * maliashdr->numverts, maliashdr->scale, maliashdr->scale_origin,
+ blend[3].lerp, ((trivertx_t *)((int) maliashdr + maliashdr->posedata)) + blend[3].frame * maliashdr->numverts, maliashdr->scale, maliashdr->scale_origin);
+ if (!gl_transform.value)
+ R_AliasTransformVerts(maliashdr->numverts);
// prep the vertex array as early as possible
if (r_render.value)
{
- if (gl_vertexarrays.value)
- {
- qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
- glEnableClientState(GL_VERTEX_ARRAY);
- }
+ glVertexPointer(3, GL_FLOAT, 0, aliasvert);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, 0, (void *)((int) maliashdr->texdata + (int) maliashdr));
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ GL_LockArray(0, maliashdr->numverts);
}
R_LightModel(maliashdr->numverts, org, color);
VectorSubtract(org, r_refdef.vieworg, diff);
glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
- if (gl_vertexarrays.value)
- {
- qglDrawElements(GL_TRIANGLES, maliashdr->numtris * 3, GL_UNSIGNED_SHORT, (void *)((int) maliashdr + maliashdr->tridata));
- }
- else
- {
- unsigned short *in;
- in = (void *)((int) maliashdr + maliashdr->tridata);
- glBegin(GL_TRIANGLES);
- for (i = 0;i < maliashdr->numtris * 3;i++)
- glVertex3fv(&aliasvert[*in++ * 3]);
- glEnd();
- }
-
- glEnable (GL_TEXTURE_2D);
- glColor3f (1,1,1);
- }
- if (gl_vertexarrays.value)
- glDisableClientState(GL_VERTEX_ARRAY);
-
- if (!fogenabled && r_shadows.value && !(effects & EF_ADDITIVE) && shadow)
- {
- // flatten it to make a shadow
- float *av = aliasvert + 2, l = lightspot[2] + 0.125;
- av = aliasvert + 2;
- for (i = 0;i < maliashdr->numverts;i++, av+=3)
- if (*av > l)
- *av = l;
- glDisable (GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable (GL_BLEND);
- glDepthMask(0); // disable zbuffer updates
- glColor4f (0,0,0,0.5 * alpha);
-
- if (gl_vertexarrays.value)
- {
- qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
- glEnableClientState(GL_VERTEX_ARRAY);
- qglDrawElements(GL_TRIANGLES, maliashdr->numtris * 3, GL_UNSIGNED_SHORT, (void *)((int) maliashdr + maliashdr->tridata));
- glDisableClientState(GL_VERTEX_ARRAY);
- }
- else
- {
- unsigned short *in;
- in = (void *)((int) maliashdr + maliashdr->tridata);
- glBegin(GL_TRIANGLES);
- for (i = 0;i < maliashdr->numtris * 3;i++)
- glVertex3fv(&aliasvert[*in++ * 3]);
- glEnd();
- }
+ glDrawElements(GL_TRIANGLES, maliashdr->numtris * 3, GL_UNSIGNED_SHORT, (void *)((int) maliashdr + maliashdr->tridata));
glEnable (GL_TEXTURE_2D);
glColor3f (1,1,1);
}
+ GL_UnlockArray();
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_BLEND);
glDepthMask(1);
+
+ glPopMatrix();
}
/*
=================
*/
-void R_DrawQ2AliasFrame (md2mem_t *pheader, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, vec3_t angles, int frame, int skin, int effects, int flags)
+void R_DrawQ2AliasFrame (md2mem_t *pheader, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, vec3_t angles, vec_t scale, frameblend_t *blend, rtexture_t *skin, int effects, int flags)
{
int *order, count;
- float lerp;
- md2memframe_t *frame1, *frame2;
+ md2frame_t *frame1, *frame2, *frame3, *frame4;
if (r_render.value)
- glBindTexture(GL_TEXTURE_2D, skin);
-
- softwaretransformforentity(ent);
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(skin));
- if ((frame >= pheader->num_frames) || (frame < 0))
+ if (gl_transform.value)
{
- Con_DPrintf ("R_SetupQ2AliasFrame: no such frame %d\n", frame);
- frame = 0;
+ if (r_render.value)
+ {
+ glPushMatrix();
+ GL_SetupModelTransform(org, angles, scale);
+ }
}
+ // always needed, for model lighting
+ softwaretransformforentity(ent);
- lerp = R_CalcAnimLerp(ent, frame, 10);
-
- frame1 = (void *)((int) pheader + pheader->ofs_frames + (pheader->framesize * ent->draw_lastpose));
- frame2 = (void *)((int) pheader + pheader->ofs_frames + (pheader->framesize * ent->draw_pose));
- R_AliasLerpVerts(pheader->num_xyz, lerp, frame1->verts, frame1->scale, frame1->translate, frame2->verts, frame2->scale, frame2->translate);
+ frame1 = (void *)((int) pheader + pheader->ofs_frames + (pheader->framesize * blend[0].frame));
+ frame2 = (void *)((int) pheader + pheader->ofs_frames + (pheader->framesize * blend[1].frame));
+ frame3 = (void *)((int) pheader + pheader->ofs_frames + (pheader->framesize * blend[2].frame));
+ frame4 = (void *)((int) pheader + pheader->ofs_frames + (pheader->framesize * blend[3].frame));
+ R_AliasLerpVerts(pheader->num_xyz,
+ blend[0].lerp, frame1->verts, frame1->scale, frame1->translate,
+ blend[1].lerp, frame2->verts, frame2->scale, frame2->translate,
+ blend[2].lerp, frame3->verts, frame3->scale, frame3->translate,
+ blend[3].lerp, frame4->verts, frame4->scale, frame4->translate);
+ if (!gl_transform.value)
+ R_AliasTransformVerts(pheader->num_xyz);
R_LightModel(pheader->num_xyz, org, color);
if (!r_render.value)
return;
- if (gl_vertexarrays.value)
+ // LordHavoc: big mess...
+ // using vertex arrays only slightly, although it is enough to prevent duplicates
+ // (saving half the transforms)
+ glVertexPointer(3, GL_FLOAT, 0, aliasvert);
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, aliasvertcolor);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ order = (int *)((int)pheader + pheader->ofs_glcmds);
+ while(1)
+ {
+ if (!(count = *order++))
+ break;
+ if (count > 0)
+ glBegin(GL_TRIANGLE_STRIP);
+ else
+ {
+ glBegin(GL_TRIANGLE_FAN);
+ count = -count;
+ }
+ do
+ {
+ glTexCoord2f(((float *)order)[0], ((float *)order)[1]);
+ glArrayElement(order[2]);
+ order += 3;
+ }
+ while (count--);
+ }
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
+
+ if (fogenabled)
{
+ glDisable (GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable (GL_BLEND);
+ glDepthMask(0); // disable zbuffer updates
+ {
+ vec3_t diff;
+ VectorSubtract(org, r_refdef.vieworg, diff);
+ glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
+ }
+
// LordHavoc: big mess...
- // using arrays only slightly, although it is enough to prevent duplicates
+ // using vertex arrays only slightly, although it is enough to prevent duplicates
// (saving half the transforms)
- qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
- qglColorPointer(4, GL_UNSIGNED_BYTE, 0, aliasvertcolor);
+ glVertexPointer(3, GL_FLOAT, 0, aliasvert);
glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
order = (int *)((int)pheader + pheader->ofs_glcmds);
while(1)
}
do
{
- glTexCoord2f(((float *)order)[0], ((float *)order)[1]);
- qglArrayElement(order[2]);
+ glArrayElement(order[2]);
order += 3;
}
while (count--);
}
- glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
- }
- else
- {
- order = (int *)((int)pheader + pheader->ofs_glcmds);
- while(1)
- {
- if (!(count = *order++))
- break;
- if (count > 0)
- glBegin(GL_TRIANGLE_STRIP);
- else
- {
- glBegin(GL_TRIANGLE_FAN);
- count = -count;
- }
- do
- {
- glTexCoord2f(((float *)order)[0], ((float *)order)[1]);
- glColor4f(aliasvertcolor[order[2] * 4] * (1.0f / 255.0f), aliasvertcolor[order[2] * 4 + 1] * (1.0f / 255.0f), aliasvertcolor[order[2] * 4 + 2] * (1.0f / 255.0f), aliasvertcolor[order[2] * 4 + 3] * (1.0f / 255.0f));
- glVertex3fv(&aliasvert[order[2] * 3]);
- order += 3;
- }
- while (count--);
- }
+
+ glEnable (GL_TEXTURE_2D);
+ glColor3f (1,1,1);
}
- if (fogenabled)
- {
- glDisable (GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable (GL_BLEND);
- glDepthMask(0); // disable zbuffer updates
- {
- vec3_t diff;
- VectorSubtract(org, r_refdef.vieworg, diff);
- glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
- }
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable (GL_BLEND);
+ glDepthMask(1);
+
+ if (gl_transform.value)
+ glPopMatrix();
+}
- if (gl_vertexarrays.value)
+void ZymoticLerpBones(int count, zymbonematrix *bonebase, frameblend_t *blend, zymbone_t *bone, float rootorigin[3], float rootangles[3], float rootscale)
+{
+ float lerp1, lerp2, lerp3, lerp4;
+ zymbonematrix *out, rootmatrix, m, *bone1, *bone2, *bone3, *bone4;
+ lerp1 = 1 - lerp2;
+ out = zymbonepose;
+ AngleVectors(rootangles, rootmatrix.m[0], rootmatrix.m[1], rootmatrix.m[2]);
+ VectorScale(rootmatrix.m[0], rootscale, rootmatrix.m[0]);
+ VectorScale(rootmatrix.m[1], rootscale, rootmatrix.m[1]);
+ VectorScale(rootmatrix.m[2], rootscale, rootmatrix.m[2]);
+ rootmatrix.m[0][3] = rootorigin[0];
+ rootmatrix.m[1][3] = rootorigin[1];
+ rootmatrix.m[2][3] = rootorigin[2];
+ bone1 = bonebase + blend[0].frame * count;
+ lerp1 = blend[0].lerp;
+ if (blend[1].lerp)
+ {
+ bone2 = bonebase + blend[1].frame * count;
+ lerp2 = blend[1].lerp;
+ if (blend[2].lerp)
{
- // LordHavoc: big mess...
- // using arrays only slightly, although it is enough to prevent duplicates
- // (saving half the transforms)
- qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
- glEnableClientState(GL_VERTEX_ARRAY);
-
- order = (int *)((int)pheader + pheader->ofs_glcmds);
- while(1)
+ bone3 = bonebase + blend[2].frame * count;
+ lerp3 = blend[2].lerp;
+ if (blend[3].lerp)
{
- if (!(count = *order++))
- break;
- if (count > 0)
- glBegin(GL_TRIANGLE_STRIP);
- else
+ // 4 poses
+ bone4 = bonebase + blend[3].frame * count;
+ lerp4 = blend[3].lerp;
+ while(count--)
{
- glBegin(GL_TRIANGLE_FAN);
- count = -count;
+ // interpolate matrices
+ m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3 + bone4->m[0][0] * lerp4;
+ m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3 + bone4->m[0][1] * lerp4;
+ m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3 + bone4->m[0][2] * lerp4;
+ m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3 + bone4->m[0][3] * lerp4;
+ m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3 + bone4->m[1][0] * lerp4;
+ m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3 + bone4->m[1][1] * lerp4;
+ m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3 + bone4->m[1][2] * lerp4;
+ m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3 + bone4->m[1][3] * lerp4;
+ m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3 + bone4->m[2][0] * lerp4;
+ m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3 + bone4->m[2][1] * lerp4;
+ m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3 + bone4->m[2][2] * lerp4;
+ m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3 + bone4->m[2][3] * lerp4;
+ if (bone->parent >= 0)
+ R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
+ else
+ R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
+ bone1++;
+ bone2++;
+ bone3++;
+ bone4++;
+ bone++;
+ out++;
}
- do
+ }
+ else
+ {
+ // 3 poses
+ while(count--)
{
- qglArrayElement(order[2]);
- order += 3;
+ // interpolate matrices
+ m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3;
+ m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3;
+ m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3;
+ m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3;
+ m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3;
+ m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3;
+ m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3;
+ m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3;
+ m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3;
+ m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3;
+ m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3;
+ m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3;
+ if (bone->parent >= 0)
+ R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
+ else
+ R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
+ bone1++;
+ bone2++;
+ bone3++;
+ bone++;
+ out++;
}
- while (count--);
}
-
- glDisableClientState(GL_VERTEX_ARRAY);
}
else
{
- order = (int *)((int)pheader + pheader->ofs_glcmds);
- while(1)
+ // 2 poses
+ while(count--)
{
- if (!(count = *order++))
- break;
- if (count > 0)
- glBegin(GL_TRIANGLE_STRIP);
+ // interpolate matrices
+ m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2;
+ m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2;
+ m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2;
+ m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2;
+ m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2;
+ m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2;
+ m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2;
+ m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2;
+ m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2;
+ m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2;
+ m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2;
+ m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2;
+ if (bone->parent >= 0)
+ R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
else
- {
- glBegin(GL_TRIANGLE_FAN);
- count = -count;
- }
- do
- {
- glVertex3fv(&aliasvert[order[2] * 3]);
- order += 3;
- }
- while (count--);
+ R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
+ bone1++;
+ bone2++;
+ bone++;
+ out++;
}
}
-
- glEnable (GL_TEXTURE_2D);
- glColor3f (1,1,1);
}
-
- if (!fogenabled && r_shadows.value && !(effects & EF_ADDITIVE) && shadow)
+ else
{
- int i;
- float *av = aliasvert + 2, l = lightspot[2] + 0.125;
- av = aliasvert + 2;
- for (i = 0;i < pheader->num_xyz;i++, av+=3)
- if (*av > l)
- *av = l;
- glDisable (GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable (GL_BLEND);
- glDepthMask(0); // disable zbuffer updates
- glColor4f (0,0,0,0.5 * alpha);
-
- if (gl_vertexarrays.value)
+ // 1 pose
+ if (lerp1 != 1)
{
- qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
- glEnableClientState(GL_VERTEX_ARRAY);
-
- while(1)
+ // lerp != 1.0
+ while(count--)
{
- if (!(count = *order++))
- break;
- if (count > 0)
- glBegin(GL_TRIANGLE_STRIP);
+ // interpolate matrices
+ m.m[0][0] = bone1->m[0][0] * lerp1;
+ m.m[0][1] = bone1->m[0][1] * lerp1;
+ m.m[0][2] = bone1->m[0][2] * lerp1;
+ m.m[0][3] = bone1->m[0][3] * lerp1;
+ m.m[1][0] = bone1->m[1][0] * lerp1;
+ m.m[1][1] = bone1->m[1][1] * lerp1;
+ m.m[1][2] = bone1->m[1][2] * lerp1;
+ m.m[1][3] = bone1->m[1][3] * lerp1;
+ m.m[2][0] = bone1->m[2][0] * lerp1;
+ m.m[2][1] = bone1->m[2][1] * lerp1;
+ m.m[2][2] = bone1->m[2][2] * lerp1;
+ m.m[2][3] = bone1->m[2][3] * lerp1;
+ if (bone->parent >= 0)
+ R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
else
- {
- glBegin(GL_TRIANGLE_FAN);
- count = -count;
- }
- do
- {
- qglArrayElement(order[2]);
- order += 3;
- }
- while (count--);
+ R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
+ bone1++;
+ bone++;
+ out++;
}
-
- glDisableClientState(GL_VERTEX_ARRAY);
}
else
{
- while(1)
+ // lerp == 1.0
+ while(count--)
{
- if (!(count = *order++))
- break;
- if (count > 0)
- glBegin(GL_TRIANGLE_STRIP);
+ if (bone->parent >= 0)
+ R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &bone1->m[0], &out->m[0]);
else
- {
- glBegin(GL_TRIANGLE_FAN);
- count = -count;
- }
- do
- {
- glVertex3fv(&aliasvert[order[2] * 3]);
- order += 3;
- }
- while (count--);
+ R_ConcatTransforms(&rootmatrix.m[0], &bone1->m[0], &out->m[0]);
+ bone1++;
+ bone++;
+ out++;
}
}
-
- glEnable (GL_TEXTURE_2D);
- glColor3f (1,1,1);
- }
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable (GL_BLEND);
- glDepthMask(1);
-}
-
-void ZymoticLerpBones(int count, float lerp2, zymbonematrix *bone1, zymbonematrix *bone2, zymbone_t *bone, float rootorigin[3], float rootangles[3])
-{
- float lerp1;
- zymbonematrix *out, rootmatrix, m;
- lerp1 = 1 - lerp2;
- out = zymbonepose;
- AngleVectors(rootangles, rootmatrix.m[0], rootmatrix.m[1], rootmatrix.m[2]);
- rootmatrix.m[0][3] = rootorigin[0];
- rootmatrix.m[1][3] = rootorigin[1];
- rootmatrix.m[2][3] = rootorigin[2];
- if (lerp1 != 1) // interpolation
- {
- while(count--)
- {
- // interpolate matrices
- m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2;
- m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2;
- m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2;
- m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2;
- m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2;
- m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2;
- m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2;
- m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2;
- m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2;
- m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2;
- m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2;
- m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2;
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
- bone1++;
- bone2++;
- bone++;
- out++;
- }
- }
- else // no interpolation
- {
- while(count--)
- {
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &bone1->m[0], &out->m[0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0], &bone1->m[0], &out->m[0]);
- bone1++;
- bone++;
- out++;
- }
}
}
void GL_DrawZymoticModelMesh(byte *colors, zymtype1header_t *m)
{
- int i, c, *renderlist, *texturenum;
+ int i, c, *renderlist;
+ rtexture_t **texture;
if (!r_render.value)
return;
renderlist = (int *)(m->lump_render.start + (int) m);
- texturenum = (int *)(m->lump_shaders.start + (int) m);
- if (gl_vertexarrays.value)
- {
- qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
- glEnableClientState(GL_VERTEX_ARRAY);
-
- qglColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
- glEnableClientState(GL_COLOR_ARRAY);
+ texture = (rtexture_t **)(m->lump_shaders.start + (int) m);
+ glVertexPointer(3, GL_FLOAT, 0, aliasvert);
+ glEnableClientState(GL_VERTEX_ARRAY);
- qglTexCoordPointer(2, GL_FLOAT, 0, (float *)(m->lump_texcoords.start + (int) m));
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
+ glEnableClientState(GL_COLOR_ARRAY);
- for (i = 0;i < m->numshaders;i++)
- {
- c = (*renderlist++) * 3;
- glBindTexture(GL_TEXTURE_2D, *texturenum++);
- qglDrawElements(GL_TRIANGLES, c, GL_UNSIGNED_INT, renderlist);
- renderlist += c;
- }
+ glTexCoordPointer(2, GL_FLOAT, 0, (float *)(m->lump_texcoords.start + (int) m));
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ for (i = 0;i < m->numshaders;i++)
+ {
+ c = (*renderlist++) * 3;
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(*texture));
+ texture++;
+ glDrawElements(GL_TRIANGLES, c, GL_UNSIGNED_INT, renderlist);
+ renderlist += c;
+ }
- glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
- }
- else
- {
- int index;
- float *tex;
- tex = (float *)(m->lump_texcoords.start + (int) m);
+ glDisableClientState(GL_COLOR_ARRAY);
- for (i = 0;i < m->numshaders;i++)
- {
- c = *renderlist++;
- glBindTexture(GL_TEXTURE_2D, *texturenum++);
- glBegin(GL_TRIANGLES);
- while (c--)
- {
- index = *renderlist++;
- glTexCoord2fv(tex + index*2);
- glColor4ubv(colors + index*4);
- glVertex3fv(aliasvert + index*3);
- index = *renderlist++;
- glTexCoord2fv(tex + index*2);
- glColor4ubv(colors + index*4);
- glVertex3fv(aliasvert + index*3);
- index = *renderlist++;
- glTexCoord2fv(tex + index*2);
- glColor4ubv(colors + index*4);
- glVertex3fv(aliasvert + index*3);
- }
- glEnd();
- }
- }
+ glDisableClientState(GL_VERTEX_ARRAY);
}
void GL_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m)
VectorSubtract(org, r_refdef.vieworg, diff);
glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
- if (gl_vertexarrays.value)
- {
- qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
- glEnableClientState(GL_VERTEX_ARRAY);
- for (i = 0;i < m->numshaders;i++)
- {
- c = (*renderlist++) * 3;
- qglDrawElements(GL_TRIANGLES, c, GL_UNSIGNED_INT, renderlist);
- renderlist += c;
- }
+ glVertexPointer(3, GL_FLOAT, 0, aliasvert);
+ glEnableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
- }
- else
+ for (i = 0;i < m->numshaders;i++)
{
- int index;
- float *tex;
- tex = (float *)(m->lump_texcoords.start + (int) m);
-
- glBegin(GL_TRIANGLES);
- for (i = 0;i < m->numshaders;i++)
- {
- c = *renderlist++;
- while (c--)
- {
- index = *renderlist++;
- glVertex3fv(aliasvert + index*3);
- index = *renderlist++;
- glVertex3fv(aliasvert + index*3);
- index = *renderlist++;
- glVertex3fv(aliasvert + index*3);
- }
- }
- glEnd();
+ c = (*renderlist++) * 3;
+ glDrawElements(GL_TRIANGLES, c, GL_UNSIGNED_INT, renderlist);
+ renderlist += c;
}
- glEnable(GL_TEXTURE_2D);
- glColor3f (1,1,1);
-}
-
-void GL_DrawZymoticModelMeshShadow(zymtype1header_t *m)
-{
- int i, c, *renderlist;
- float *av, l;
- if (!r_render.value)
- return;
-
- // flatten it to make a shadow
- av = aliasvert + 2;
- l = lightspot[2] + 0.125;
- for (i = 0;i < m->numverts;i++, av+=3)
- if (*av > l)
- *av = l;
-
- renderlist = (int *)(m->lump_render.start + (int) m);
- glDisable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable (GL_BLEND);
- glDepthMask(0); // disable zbuffer updates
-
- glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
- if (gl_vertexarrays.value)
- {
- qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
- glEnableClientState(GL_VERTEX_ARRAY);
- for (i = 0;i < m->numshaders;i++)
- {
- c = (*renderlist++) * 3;
- qglDrawElements(GL_TRIANGLES, c, GL_UNSIGNED_INT, renderlist);
- renderlist += c;
- }
-
- glDisableClientState(GL_VERTEX_ARRAY);
- }
- else
- {
- int index;
- float *tex;
- tex = (float *)(m->lump_texcoords.start + (int) m);
+ glDisableClientState(GL_VERTEX_ARRAY);
- glBegin(GL_TRIANGLES);
- for (i = 0;i < m->numshaders;i++)
- {
- c = *renderlist++;
- while (c--)
- {
- index = *renderlist++;
- glVertex3fv(aliasvert + index*3);
- index = *renderlist++;
- glVertex3fv(aliasvert + index*3);
- index = *renderlist++;
- glVertex3fv(aliasvert + index*3);
- }
- }
- glEnd();
- }
glEnable(GL_TEXTURE_2D);
glColor3f (1,1,1);
}
R_DrawZymoticFrame
=================
*/
-void R_DrawZymoticFrame (zymtype1header_t *m, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, vec3_t angles, int frame, int skinblah, int effects, int flags)
+void R_DrawZymoticFrame (zymtype1header_t *m, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, vec3_t angles, vec_t scale, frameblend_t *blend, int skinblah, int effects, int flags)
{
- zymscene_t *scene;
- float scenetime, scenefrac;
- int sceneframe1, sceneframe2;
- zymbonematrix *basebonepose;
- if ((frame >= m->numscenes) || (frame < 0))
- {
- Con_DPrintf ("R_ZymoticSetupFrame: no such frame %d\n", frame);
- frame = 0;
- }
-
- scene = (zymscene_t *)(m->lump_scenes.start + (int) m) + frame;
- if (ent->draw_lastmodel != ent->model || ent->draw_pose != frame || ent->draw_lerpstart >= cl.time)
- {
- ent->draw_lastmodel = ent->model;
- ent->draw_lastpose = -1;
- ent->draw_pose = frame;
- ent->draw_lerpstart = cl.time;
- }
- scenetime = (cl.time - ent->draw_lerpstart) * scene->framerate;
- sceneframe1 = (int) scenetime;
- sceneframe2 = sceneframe1 + 1;
- scenefrac = scenetime - sceneframe1;
- if (scene->flags & ZYMSCENEFLAG_NOLOOP)
- {
- if (sceneframe1 > (scene->length - 1))
- sceneframe1 = (scene->length - 1);
- if (sceneframe2 > (scene->length - 1))
- sceneframe2 = (scene->length - 1);
- }
- else
- {
- sceneframe1 %= scene->length;
- sceneframe2 %= scene->length;
- }
- if (sceneframe2 == sceneframe1)
- scenefrac = 0;
-
- basebonepose = (zymbonematrix *)(m->lump_poses.start + (int) m);
- ZymoticLerpBones(m->numbones, scenefrac, basebonepose + sceneframe1 * m->numbones, basebonepose + sceneframe2 * m->numbones, (zymbone_t *)(m->lump_bones.start + (int) m), org, angles);
+ ZymoticLerpBones(m->numbones, (zymbonematrix *)(m->lump_poses.start + (int) m), blend, (zymbone_t *)(m->lump_bones.start + (int) m), org, angles, scale);
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));
if (fogenabled)
GL_DrawZymoticModelMeshFog(org, m);
- if (!fogenabled && r_shadows.value && !(effects & EF_ADDITIVE) && shadow)
- GL_DrawZymoticModelMeshShadow(m);
-
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_BLEND);
glDepthMask(1);
}
-int modeldlightbits[8];
extern int r_dlightframecount;
/*
=================
*/
-void R_DrawAliasModel (entity_t *ent, int cull, float alpha, model_t *clmodel, int frame, int skin, vec3_t org, vec3_t angles, int effects, int flags, int colormap)
+void R_DrawAliasModel (entity_t *ent, int cull, float alpha, model_t *clmodel, frameblend_t *blend, int skin, vec3_t org, vec3_t angles, vec_t scale, int effects, int flags, int colormap)
{
int i;
vec3_t mins, maxs, color;
- mleaf_t *leaf;
void *modelheader;
- int *skinset;
+ rtexture_t **skinset;
if (alpha < (1.0 / 64.0))
return; // basically completely transparent
c_models++;
- leaf = Mod_PointInLeaf (org, cl.worldmodel);
- if (leaf->dlightframe == r_dlightframecount)
- for (i = 0;i < 8;i++)
- modeldlightbits[i] = leaf->dlightbits[i];
- else
- for (i = 0;i < 8;i++)
- modeldlightbits[i] = 0;
-
- // get lighting information
-
- if ((flags & EF_FULLBRIGHT) || (effects & EF_FULLBRIGHT))
- color[0] = color[1] = color[2] = 256;
- else
- R_LightPoint (color, org);
-
- if (r_render.value)
- glDisable(GL_ALPHA_TEST);
-
- if (frame < 0 || frame >= clmodel->numframes)
- {
- frame = 0;
- Con_DPrintf("invalid skin number %d for model %s\n", frame, clmodel->name);
- }
-
if (skin < 0 || skin >= clmodel->numskins)
{
skin = 0;
// int *skinanimrange = (int *) (clmodel->skinanimrange + (int) modelheader) + skin * 2;
// int *skinanim = (int *) (clmodel->skinanim + (int) modelheader);
int *skinanimrange = clmodel->skinanimrange + skin * 2;
- int *skinanim = clmodel->skinanim;
+ rtexture_t **skinanim = clmodel->skinanim;
i = skinanimrange[0];
if (skinanimrange[1] > 1) // animated
i += ((int) (cl.time * 10) % skinanimrange[1]);
c_alias_polys += clmodel->numtris;
if (clmodel->aliastype == ALIASTYPE_ZYM)
- R_DrawZymoticFrame (modelheader, alpha, color, ent, ent != &cl.viewent, org, angles, frame, 0, effects, flags);
+ R_DrawZymoticFrame (modelheader, alpha, color, ent, ent != &cl.viewent, org, angles, scale, blend, 0 , effects, flags);
else if (clmodel->aliastype == ALIASTYPE_MD2)
- R_DrawQ2AliasFrame (modelheader, alpha, color, ent, ent != &cl.viewent, org, angles, frame, skinset[0], effects, flags);
+ R_DrawQ2AliasFrame (modelheader, alpha, color, ent, ent != &cl.viewent, org, angles, scale, blend, skinset[0] , effects, flags);
else
- R_DrawAliasFrame (modelheader, alpha, color, ent, ent != &cl.viewent, org, angles, frame, skinset, colormap, effects, flags);
+ R_DrawAliasFrame (modelheader, alpha, color, ent, ent != &cl.viewent, org, angles, scale, blend, skinset , colormap, effects, flags);
}
transpoly_t *transpoly;
unsigned short *transpolyindex;
wallvert_t *wallvert;
+wallvertcolor_t *wallvertcolor;
wallpoly_t *wallpoly;
skyvert_t *skyvert;
skypoly_t *skypoly;
-unsigned short currenttranspoly;
-unsigned short currenttransvert;
-unsigned short currentwallpoly;
-unsigned short currentwallvert;
-unsigned short currentskypoly;
-unsigned short currentskyvert;
+int currenttranspoly;
+int currenttransvert;
+int currentwallpoly;
+int currentwallvert;
+int currentskypoly;
+int currentskyvert;
cvar_t gl_multitexture = {"gl_multitexture", "1"};
-cvar_t gl_vertexarrays = {"gl_vertexarrays", "1"};
typedef struct translistitem_s
{
transpoly = qmalloc(MAX_TRANSPOLYS * sizeof(transpoly_t));
transpolyindex = qmalloc(MAX_TRANSPOLYS * sizeof(unsigned short));
wallvert = qmalloc(MAX_WALLVERTS * sizeof(wallvert_t));
+ wallvertcolor = qmalloc(MAX_WALLVERTS * sizeof(wallvertcolor_t));
wallpoly = qmalloc(MAX_WALLPOLYS * sizeof(wallpoly_t));
skyvert = qmalloc(MAX_SKYVERTS * sizeof(skyvert_t));
skypoly = qmalloc(MAX_SKYPOLYS * sizeof(skypoly_t));
qfree(transpoly);
qfree(transpolyindex);
qfree(wallvert);
+ qfree(wallvertcolor);
qfree(wallpoly);
qfree(skyvert);
qfree(skypoly);
void GL_Poly_Init()
{
Cvar_RegisterVariable (&gl_multitexture);
- Cvar_RegisterVariable (&gl_vertexarrays);
R_RegisterModule("GL_Poly", gl_poly_start, gl_poly_shutdown);
}
glEnable(GL_BLEND);
glShadeModel(GL_SMOOTH);
glDepthMask(0); // disable zbuffer updates
- if (isG200) // Matrox G200 cards can't handle per pixel alpha
- glEnable(GL_ALPHA_TEST);
- else
- glDisable(GL_ALPHA_TEST);
+ glDisable(GL_ALPHA_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
tpolytype = TPOLYTYPE_ALPHA;
texnum = -1;
if (gl_vertexarrays.value)
{
// set up the vertex array
- qglInterleavedArrays(GL_T2F_C4UB_V3F, 0, transvert);
+ glInterleavedArrays(GL_T2F_C4UB_V3F, 0, transvert);
for (i = 0;i < transpolyindices;i++)
{
p = &transpoly[transpolyindex[i]];
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
}
- qglDrawArrays(GL_POLYGON, p->firstvert, p->verts);
+ glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
if (p->glowtexnum)
{
texnum = p->glowtexnum; // highly unlikely to match next poly, but...
glBindTexture(GL_TEXTURE_2D, texnum);
tpolytype = TPOLYTYPE_ADD; // might match next poly
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- qglDrawArrays(GL_POLYGON, p->firstvert, p->verts);
+ glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
}
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glEnd();
if (isG200)
{
- if (p->fogtexnum) // alpha
+ // LordHavoc: Matrox G200 cards can't handle per pixel alpha
+ if (p->fogtexnum)
glEnable(GL_ALPHA_TEST);
else
glDisable(GL_ALPHA_TEST);
int i, j, texnum, lighttexnum;
wallpoly_t *p;
wallvert_t *vert;
+ wallvertcolor_t *vertcolor;
if (!r_render.value)
return;
if (currentwallpoly < 1)
glShadeModel(GL_FLAT);
// make sure zbuffer is enabled
glEnable(GL_DEPTH_TEST);
- glDisable(GL_ALPHA_TEST);
+// glDisable(GL_ALPHA_TEST);
glDepthMask(1);
glColor3f(1,1,1);
if (r_fullbright.value) // LordHavoc: easy to do fullbright...
glBegin(GL_POLYGON);
for (j=0 ; j<p->numverts ; j++, vert++)
{
- glTexCoord2f (vert->s, vert->t);
+ glTexCoord2f (vert->vert[3], vert->vert[4]);
glVertex3fv (vert->vert);
}
glEnd ();
glBegin(GL_POLYGON);
for (j=0 ; j<p->numverts ; j++, vert++)
{
- qglMTexCoord2f(gl_mtex_enum, vert->s, vert->t); // texture
- qglMTexCoord2f((gl_mtex_enum+1), vert->u, vert->v); // lightmap
+ qglMTexCoord2f(gl_mtex_enum, vert->vert[3], vert->vert[4]); // texture
+ qglMTexCoord2f((gl_mtex_enum+1), vert->vert[5], vert->vert[6]); // lightmap
glVertex3fv (vert->vert);
}
glEnd ();
glBegin(GL_POLYGON);
for (j=0 ; j<p->numverts ; j++, vert++)
{
- glTexCoord2f (vert->s, vert->t);
+ glTexCoord2f (vert->vert[3], vert->vert[4]);
glVertex3fv (vert->vert);
}
glEnd ();
glBegin(GL_POLYGON);
for (j=0 ; j<p->numverts ; j++, vert++)
{
- glTexCoord2f (vert->u, vert->v);
+ glTexCoord2f (vert->vert[5], vert->vert[6]);
glVertex3fv (vert->vert);
}
glEnd ();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_BLEND);
- glDisable(GL_ALPHA_TEST);
+// glDisable(GL_ALPHA_TEST);
glShadeModel(GL_SMOOTH);
// render vertex lit overlays ontop
texnum = -1;
{
if (!p->lit)
continue;
- for (j = 0,vert = &wallvert[p->firstvert];j < p->numverts;j++, vert++)
- if (vert->r || vert->g || vert->b)
+ for (j = 0,vertcolor = &wallvertcolor[p->firstvert];j < p->numverts;j++, vertcolor++)
+ if (vertcolor->r || vertcolor->g || vertcolor->b)
goto lit;
continue;
lit:
glBindTexture(GL_TEXTURE_2D, texnum);
}
glBegin(GL_POLYGON);
- for (j = 0,vert = &wallvert[p->firstvert];j < p->numverts;j++, vert++)
+ for (j = 0,vert = &wallvert[p->firstvert], vertcolor = &wallvertcolor[p->firstvert];j < p->numverts;j++, vert++, vertcolor++)
{
// would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
- glTexCoord2f(vert->s, vert->t);
+ glTexCoord2f(vert->vert[3], vert->vert[4]);
// again, vector version isn't supported I think
- glColor3ub(vert->r, vert->g, vert->b);
+ glColor3ub(vertcolor->r, vertcolor->g, vertcolor->b);
glVertex3fv(vert->vert);
}
glEnd();
glBegin(GL_POLYGON);
for (j=0 ; j<p->numverts ; j++, vert++)
{
- glTexCoord2f (vert->s, vert->t);
+ glTexCoord2f (vert->vert[3], vert->vert[4]);
glVertex3fv (vert->vert);
}
glEnd();
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glDisable(GL_ALPHA_TEST);
+// glDisable(GL_ALPHA_TEST);
glShadeModel(GL_SMOOTH);
glDisable(GL_BLEND);
glDepthMask(1);
}
extern char skyname[];
-extern int solidskytexture, alphaskytexture;
+extern rtexture_t *solidskytexture, *alphaskytexture;
void skypolyrender()
{
- int i, j;
+ int i, j, numskyverts;
skypoly_t *p;
skyvert_t *vert;
float length, speedscale;
return;
// testing
// Con_DPrintf("skypolyrender: %i polys %i vertices\n", currentskypoly, currentskyvert);
- glDisable(GL_ALPHA_TEST);
+// glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
// make sure zbuffer is enabled
glEnable(GL_DEPTH_TEST);
glDepthMask(1);
if (!fogenabled && !skyname[0]) // normal quake sky
{
+ glInterleavedArrays(GL_T2F_V3F, 0, skyvert);
+// glTexCoordPointer(2, GL_FLOAT, sizeof(skyvert_t) - sizeof(float) * 2, &skyvert[0].tex[0]);
+// glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+// glVertexPointer(3, GL_FLOAT, sizeof(skyvert_t) - sizeof(float) * 3, &skyvert[0].v[0]);
+// glEnableClientState(GL_VERTEX_ARRAY);
if(lighthalf)
glColor3f(0.5f, 0.5f, 0.5f);
else
glEnable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, solidskytexture); // upper clouds
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(solidskytexture)); // upper clouds
speedscale = cl.time*8;
speedscale -= (int)speedscale & ~127 ;
- for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++)
+ numskyverts = 0;
+ for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
{
- vert = &skyvert[p->firstvert];
- glBegin(GL_POLYGON);
- for (j=0 ; j<p->verts ; j++, vert++)
+ vert = skyvert + p->firstvert;
+ for (j = 0;j < p->verts;j++, vert++)
{
VectorSubtract (vert->v, r_origin, dir);
dir[2] *= 3; // flatten the sphere
length = sqrt (length);
length = 6*63/length;
- glTexCoord2f ((speedscale + dir[0] * length) * (1.0/128), (speedscale + dir[1] * length) * (1.0/128));
- glVertex3fv (vert->v);
+ vert->tex[0] = (speedscale + dir[0] * length) * (1.0/128);
+ vert->tex[1] = (speedscale + dir[1] * length) * (1.0/128);
}
- glEnd ();
+ numskyverts += p->verts;
}
+ GL_LockArray(0, numskyverts);
+ for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
+ glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
+ GL_UnlockArray();
glEnable(GL_BLEND);
glDepthMask(0);
- glBindTexture(GL_TEXTURE_2D, alphaskytexture); // lower clouds
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(alphaskytexture)); // lower clouds
speedscale = cl.time*16;
speedscale -= (int)speedscale & ~127 ;
- for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++)
+ for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
{
- vert = &skyvert[p->firstvert];
- glBegin(GL_POLYGON);
- for (j=0 ; j<p->verts ; j++, vert++)
+ vert = skyvert + p->firstvert;
+ for (j = 0;j < p->verts;j++, vert++)
{
VectorSubtract (vert->v, r_origin, dir);
dir[2] *= 3; // flatten the sphere
length = sqrt (length);
length = 6*63/length;
- glTexCoord2f ((speedscale + dir[0] * length) * (1.0/128), (speedscale + dir[1] * length) * (1.0/128));
- glVertex3fv (vert->v);
+ vert->tex[0] = (speedscale + dir[0] * length) * (1.0/128);
+ vert->tex[1] = (speedscale + dir[1] * length) * (1.0/128);
}
- glEnd ();
}
+ GL_LockArray(0, numskyverts);
+ for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
+ glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
+ GL_UnlockArray();
glDisable(GL_BLEND);
glColor3f(1,1,1);
glDepthMask(1);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
}
else
{
+ glVertexPointer(3, GL_FLOAT, sizeof(skyvert_t) - sizeof(float) * 3, &skyvert[0].v[0]);
+ glEnableClientState(GL_VERTEX_ARRAY);
glDisable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor3fv(fogcolor); // note: gets rendered over by skybox if fog is not enabled
- for (i = 0,p = &skypoly[0];i < currentskypoly;i++, p++)
- {
- vert = &skyvert[p->firstvert];
- glBegin(GL_POLYGON);
- for (j=0 ; j<p->verts ; j++, vert++)
- glVertex3fv (vert->v);
- glEnd ();
- }
+ numskyverts = 0;
+ for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
+ numskyverts += p->verts;
+ GL_LockArray(0, numskyverts);
+ for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
+ glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
+ GL_UnlockArray();
glColor3f(1,1,1);
glEnable(GL_TEXTURE_2D);
+ glDisableClientState(GL_VERTEX_ARRAY);
}
}
vec_t s, t;
byte r,g,b,a;
vec3_t v;
-} transvert_t;
+}
+transvert_t;
typedef struct
{
unsigned short firstvert;
unsigned short verts;
unsigned short transpolytype;
-} transpoly_t;
+}
+transpoly_t;
+
+// note: must match format of glpoly_t vertices due to a memcpy used in RSurf_DrawWall
+typedef struct
+{
+ vec_t vert[VERTEXSIZE]; // xyz st uv
+}
+wallvert_t;
typedef struct
{
- vec3_t vert;
- vec_t s, t, u, v;
byte r,g,b,a;
-} wallvert_t;
+}
+wallvertcolor_t;
typedef struct
{
unsigned short firstvert;
unsigned short numverts;
unsigned short lit; // doesn't need to be an unsigned short, but to keep the structure consistent...
-} wallpoly_t;
+}
+wallpoly_t;
typedef struct
{
+ // the order and type of these is crucial to the vertex array based rendering
+ vec2_t tex;
vec3_t v;
-} skyvert_t;
+}
+skyvert_t;
typedef struct
{
unsigned short firstvert;
unsigned short verts;
-} skypoly_t;
+}
+skypoly_t;
extern transvert_t *transvert;
extern transpoly_t *transpoly;
extern unsigned short *transpolyindex;
extern wallvert_t *wallvert;
+extern wallvertcolor_t *wallvertcolor;
extern wallpoly_t *wallpoly;
extern skyvert_t *skyvert;
extern skypoly_t *skypoly;
-extern unsigned short currenttranspoly;
-extern unsigned short currenttransvert;
-extern unsigned short currentwallpoly;
-extern unsigned short currentwallvert;
-extern unsigned short currentskypoly;
-extern unsigned short currentskyvert;
+extern int currenttranspoly;
+extern int currenttransvert;
+extern int currentwallpoly;
+extern int currentwallvert;
+extern int currentskypoly;
+extern int currentskyvert;
#define transpolybegin(ttexnum, tglowtexnum, tfogtexnum, ttranspolytype)\
{\
transpoly[currenttranspoly].verts++;\
}\
}
+
+#define transpolyvertub(vx,vy,vz,vs,vt,vr,vg,vb,va) \
+{\
+ if (currenttranspoly < MAX_TRANSPOLYS && currenttransvert < MAX_TRANSVERTS)\
+ {\
+ transvert[currenttransvert].s = (vs);\
+ transvert[currenttransvert].t = (vt);\
+ if (lighthalf)\
+ {\
+ transvert[currenttransvert].r = (vr) >> 1;\
+ transvert[currenttransvert].g = (vg) >> 1;\
+ transvert[currenttransvert].b = (vb) >> 1;\
+ }\
+ else\
+ {\
+ transvert[currenttransvert].r = (vr);\
+ transvert[currenttransvert].g = (vg);\
+ transvert[currenttransvert].b = (vb);\
+ }\
+ transvert[currenttransvert].a = (va);\
+ transvert[currenttransvert].v[0] = (vx);\
+ transvert[currenttransvert].v[1] = (vy);\
+ transvert[currenttransvert].v[2] = (vz);\
+ currenttransvert++;\
+ transpoly[currenttranspoly].verts++;\
+ }\
+}
cvar_t r_speeds2 = {"r_speeds2","0"};
cvar_t r_fullbright = {"r_fullbright","0"};
//cvar_t r_lightmap = {"r_lightmap","0"};
-cvar_t r_shadows = {"r_shadows","0"};
cvar_t r_wateralpha = {"r_wateralpha","1"};
cvar_t r_dynamic = {"r_dynamic","1"};
cvar_t r_novis = {"r_novis","0"};
FOG_registercvars();
Cvar_RegisterVariable (&r_drawentities);
Cvar_RegisterVariable (&r_drawviewmodel);
- Cvar_RegisterVariable (&r_shadows);
Cvar_RegisterVariable (&r_speeds);
Cvar_RegisterVariable (&r_speeds2);
Cvar_RegisterVariable (&contrast);
extern void R_Light_Init();
extern void R_Particles_Init();
extern void R_Explosion_Init();
+extern void CL_Effects_Init();
void Render_Init()
{
R_Light_Init();
R_Particles_Init();
R_Explosion_Init();
+ CL_Effects_Init();
R_StartModules();
}
GL_Init
===============
*/
-extern char *QSG_EXTENSIONS;
+extern char *ENGINE_EXTENSIONS;
void GL_Init (void)
{
gl_vendor = glGetString (GL_VENDOR);
// Con_Printf ("%s %s\n", gl_renderer, gl_version);
VID_CheckMultitexture();
- VID_CheckVertexArrays();
+ VID_CheckCVA();
// LordHavoc: report supported extensions
- Con_Printf ("\nQSG extensions: %s\n", QSG_EXTENSIONS);
+ Con_Printf ("\nengine extensions: %s\n", ENGINE_EXTENSIONS);
glCullFace(GL_FRONT);
glEnable(GL_TEXTURE_2D);
}
*/
-// LordHavoc: if not for the fact BRIGHTFIELD particles require this, it would be removed...
-#define NUMVERTEXNORMALS 162
-
-float r_avertexnormals[NUMVERTEXNORMALS][3] = {
-#include "anorms.h"
-};
-
// LordHavoc: shading stuff
vec3_t shadevector;
vec3_t shadecolor;
//==================================================================================
void R_DrawBrushModel (entity_t *e);
-void R_DrawSpriteModel (entity_t *e);
+void R_DrawSpriteModel (entity_t *e, frameblend_t *blend);
+
+void R_LerpUpdate(entity_t *ent)
+{
+ int frame;
+ frame = ent->frame;
+ if (ent->model && ent->frame >= ent->model->numframes)
+ {
+ Con_Printf("R_LerpUpdate: no such frame%6i in \"%s\"\n", ent->frame, ent->model->name);
+ frame = 0;
+ }
+
+ if (ent->lerp_model != ent->model)
+ {
+ // reset all interpolation information
+ ent->lerp_model = ent->model;
+ ent->frame1 = ent->frame2 = frame;
+ ent->frame1start = ent->frame2start = cl.time;
+ ent->framelerp = 1;
+ ent->lerp_starttime = 0;
+ }
+ else if (ent->frame2 != frame)
+ {
+ // transition to new frame
+ ent->frame1 = ent->frame2;
+ ent->frame1start = ent->frame2start;
+ ent->frame2 = frame;
+ ent->frame2start = cl.time;
+ ent->framelerp = 0;
+ ent->lerp_starttime = cl.time;
+ }
+ else
+ {
+ // lerp_starttime < 0 is used to prevent changing of framelerp
+ if (ent->lerp_starttime >= 0)
+ {
+ // update transition
+ ent->framelerp = (cl.time - ent->lerp_starttime) * 10;
+ ent->framelerp = bound(0, ent->framelerp, 1);
+ }
+ }
+}
+
/*
=============
void R_DrawEntitiesOnList2 (void)
{
int i;
+ frameblend_t blend[4];
if (!r_drawentities.value)
return;
switch (currententity->model->type)
{
case mod_alias:
- R_DrawAliasModel (currententity, true, modelalpha, currententity->model, currententity->frame, currententity->skinnum, currententity->origin, currententity->angles, currententity->effects, currententity->model->flags, currententity->colormap);
+ if (!strcmp(currententity->model->name, "progs/flame2.mdl"))
+ blend[0].frame = 0;
+
+ R_LerpUpdate(currententity);
+ R_LerpAnimation(currententity->model, currententity->frame1, currententity->frame2, currententity->frame1start, currententity->frame2start, currententity->framelerp, blend);
+ R_DrawAliasModel (currententity, true, modelalpha, currententity->model, blend, currententity->skinnum, currententity->origin, currententity->angles, currententity->scale, currententity->effects, currententity->model->flags, currententity->colormap);
break;
case mod_sprite:
- R_DrawSpriteModel (currententity);
+ R_LerpUpdate(currententity);
+ R_LerpAnimation(currententity->model, currententity->frame1, currententity->frame2, currententity->frame1start, currententity->frame2start, currententity->framelerp, blend);
+ R_DrawSpriteModel (currententity, blend);
break;
default:
*/
void R_DrawViewModel (void)
{
+ frameblend_t blend[4];
+
if (!r_drawviewmodel.value || chase_active.value || envmap || !r_drawentities.value || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.model)
return;
currententity->scale = 1;
VectorCopy(cl_entities[cl.viewentity].colormod, currententity->colormod);
+ R_LerpUpdate(currententity);
+ R_LerpAnimation(currententity->model, currententity->frame1, currententity->frame2, currententity->frame1start, currententity->frame2start, currententity->framelerp, blend);
+
// hack the depth range to prevent view model from poking into walls
glDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
- R_DrawAliasModel (currententity, false, modelalpha, currententity->model, currententity->frame, currententity->skinnum, currententity->origin, currententity->angles, currententity->effects, currententity->model->flags, currententity->colormap);
+ R_DrawAliasModel (currententity, false, modelalpha, currententity->model, blend, currententity->skinnum, currententity->origin, currententity->angles, currententity->scale, currententity->effects, currententity->model->flags, currententity->colormap);
glDepthRange (gldepthmin, gldepthmax);
}
else
starttime = currtime = 0;
R_Clear();
- skypolyclear();
- wallpolyclear();
- transpolyclear();
skyisvisible = false;
TIMEREPORT(time_clear)
R_SetupFrame ();
R_SetFrustum ();
R_SetupGL ();
+
+ skypolyclear();
+ wallpolyclear();
+ transpolyclear();
+
TIMEREPORT(time_setup)
R_MarkLeaves (); // done here so we know if we're in water
wallpolyrender();
TIMEREPORT(time_wall)
-// if (!intimerefresh)
-// S_ExtraUpdate (); // don't let sound get messed up if going slow
+ if (!intimerefresh && !r_speeds2.value)
+ S_ExtraUpdate (); // don't let sound get messed up if going slow
R_DrawEntitiesOnList2 (); // other models
// R_RenderDlights ();
qboolean lightmaprgba, nosubimagefragments, nosubimage, skyisvisible;
int lightmapbytes;
-extern qboolean gl_arrays;
-
extern int r_dlightframecount;
void gl_surf_start()
Cvar_RegisterVariable(&r_newworldnode);
Cvar_RegisterVariable(&r_oldclip);
Cvar_RegisterVariable(&r_dlightmap);
- // check if it's the glquake minigl driver
- if (strncasecmp(gl_vendor,"3Dfx",4)==0)
- if (!gl_arrays)
- {
-// Cvar_SetValue("gl_nosubimagefragments", 1);
-// Cvar_SetValue("gl_nosubimage", 1);
- Cvar_SetValue("gl_lightmode", 0);
- }
R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown);
}
*/
int R_AddDynamicLights (msurface_t *surf)
{
- int sdtable[18], lnum, td, maxdist, maxdist2, maxdist3, i, j, s, t, smax, tmax, red, green, blue, lit, dist2, impacts, impactt;
+ int sdtable[18], lnum, td, maxdist, maxdist2, maxdist3, i, s, t, smax, tmax, red, green, blue, lit, dist2, impacts, impactt;
unsigned int *bl;
float dist;
vec3_t impact, local;
// LordHavoc: use 64bit integer... shame it's not very standardized...
-//#if _MSC_VER || __BORLANDC__
-// __int64 k;
-//#else
-// long long k;
-//#endif
-
- // LordHavoc: later note: MSVC and hopefully all other C compilers use a 64bit result for 32bit*32bit multiply, so that was not necessary
- int k;
+#if _MSC_VER || __BORLANDC__
+ __int64 k;
+#else
+ long long k;
+#endif
lit = false;
dist = DotProduct (local, surf->plane->normal) - surf->plane->dist;
// for comparisons to minimum acceptable light
- maxdist = (int) ((cl_dlights[lnum].radius * cl_dlights[lnum].radius) * LIGHTSCALE);
+ maxdist = (int) ((cl_dlights[lnum].radius * cl_dlights[lnum].radius));
// clamp radius to avoid exceeding 32768 entry division table
if (maxdist > 4194304)
// reduce calculations
for (s = 0, i = impacts; s < smax; s++, i -= 16)
- sdtable[s] = i * i + dist2;
+ sdtable[s] = i * i + dist2 + LIGHTOFFSET;
maxdist3 = maxdist - (int) (dist * dist);
if (sdtable[s] < maxdist2)
{
k = dlightdivtable[(sdtable[s] + td) >> 7];
- j = (red * k) >> 9;bl[0] += j;
- j = (green * k) >> 9;bl[1] += j;
- j = (blue * k) >> 9;bl[2] += j;
+ bl[0] += (red * k) >> 9;
+ bl[1] += (green * k) >> 9;
+ bl[2] += (blue * k) >> 9;
lit = true;
}
bl += 3;
}
+void R_ConvertLightmap (int *in, byte *out, int width, int height, int stride)
+{
+ int i, j;
+ stride -= (width*lightmapbytes);
+ if (lighthalf)
+ {
+ // LordHavoc: I shift down by 8 unlike GLQuake's 7,
+ // the image is brightened as a processing pass
+ if (lightmaprgba)
+ {
+ for (i = 0;i < height;i++, out += stride)
+ {
+ for (j = 0;j < width;j++, in += 3, out += 4)
+ {
+ out[0] = min(in[0] >> 8, 255);
+ out[1] = min(in[1] >> 8, 255);
+ out[2] = min(in[2] >> 8, 255);
+ out[3] = 255;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0;i < height;i++, out += stride)
+ {
+ for (j = 0;j < width;j++, in += 3, out += 3)
+ {
+ out[0] = min(in[0] >> 8, 255);
+ out[1] = min(in[1] >> 8, 255);
+ out[2] = min(in[2] >> 8, 255);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (lightmaprgba)
+ {
+ for (i = 0;i < height;i++, out += stride)
+ {
+ for (j = 0;j < width;j++, in += 3, out += 4)
+ {
+ out[0] = min(in[0] >> 7, 255);
+ out[1] = min(in[1] >> 7, 255);
+ out[2] = min(in[2] >> 7, 255);
+ out[3] = 255;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0;i < height;i++, out += stride)
+ {
+ for (j = 0;j < width;j++, in += 3, out += 3)
+ {
+ out[0] = min(in[0] >> 7, 255);
+ out[1] = min(in[1] >> 7, 255);
+ out[2] = min(in[2] >> 7, 255);
+ }
+ }
+ }
+ }
+}
+
/*
===============
R_BuildLightMap
lightmap = surf->samples;
// set to full bright if no light data
- if (currententity->effects & EF_FULLBRIGHT || !cl.worldmodel->lightdata)
+ if (currententity && currententity->effects & EF_FULLBRIGHT || !cl.worldmodel->lightdata)
{
bl = blocklights;
for (i=0 ; i<size ; i++)
if ((surf->cached_dlight = R_AddDynamicLights(surf)))
c_light_polys++;
}
- stride -= (smax*lightmapbytes);
- bl = blocklights;
- if (lighthalf)
- {
- // LordHavoc: I shift down by 8 unlike GLQuake's 7,
- // the image is brightened as a processing pass
- if (lightmaprgba)
- {
- for (i = 0;i < tmax;i++, dest += stride)
- {
- for (j = 0;j < smax;j++, bl += 3, dest += 4)
- {
- dest[0] = min(bl[0] >> 8, 255);
- dest[1] = min(bl[1] >> 8, 255);
- dest[2] = min(bl[2] >> 8, 255);
- dest[3] = 255;
- }
- }
- }
- else
- {
- for (i = 0;i < tmax;i++, dest += stride)
- {
- for (j = 0;j < smax;j++, bl += 3, dest += 3)
- {
- dest[0] = min(bl[0] >> 8, 255);
- dest[1] = min(bl[1] >> 8, 255);
- dest[2] = min(bl[2] >> 8, 255);
- }
- }
- }
- }
- else
- {
- if (lightmaprgba)
- {
- for (i = 0;i < tmax;i++, dest += stride)
- {
- for (j = 0;j < smax;j++, bl += 3, dest += 4)
- {
- dest[0] = min(bl[0] >> 7, 255);
- dest[1] = min(bl[1] >> 7, 255);
- dest[2] = min(bl[2] >> 7, 255);
- dest[3] = 255;
- }
- }
- }
- else
- {
- for (i = 0;i < tmax;i++, dest += stride)
- {
- for (j = 0;j < smax;j++, bl += 3, dest += 3)
- {
- dest[0] = min(bl[0] >> 7, 255);
- dest[1] = min(bl[1] >> 7, 255);
- dest[2] = min(bl[2] >> 7, 255);
- }
- }
- }
- }
+ R_ConvertLightmap(blocklights, dest, smax, tmax, stride);
}
byte templight[BLOCK_WIDTH*BLOCK_HEIGHT*4];
extern char skyname[];
-void R_DynamicLightPoint(vec3_t color, vec3_t org, int *dlightbits);
float turbsin[256] =
{
#include "gl_warp_sin.h"
{
for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
{
- skyvert[currentskyvert].v[0] = v[0];
- skyvert[currentskyvert].v[1] = v[1];
- skyvert[currentskyvert++].v[2] = v[2];
+ VectorCopy(v, skyvert[currentskyvert].v);
+ currentskyvert++;
}
}
}
cr = light->color[0];
cg = light->color[1];
cb = light->color[2];
- radius = light->radius*light->radius*LIGHTSCALE;
- radius2 = radius * (256.0f / LIGHTSCALE2);
+ radius = light->radius*light->radius;
+ radius2 = radius * 256.0f;
wv = wvert;
for (p = polys;p;p = p->next)
{
int i;
float os = turbsin[(int)(realtime * TURBSCALE) & 255], ot = turbsin[(int)(cl.time * TURBSCALE + 96.0) & 255];
glpoly_t *p;
- float *wv, *v;
- wv = wvert;
- for (p = s->polys;p;p = p->next)
+ float *v;
+ // FIXME: make fog texture if water texture is transparent?
+
+ if (s->dlightframe != r_dlightframecount)
{
- for (i = 0, v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+ vec3_t temp;
+ // LordHavoc: fast path for no vertex lighting cases
+ if (transform)
{
- if (transform)
- softwaretransform(v, wv);
+ if (r_waterripple.value)
+ {
+ for (p=s->polys ; p ; p=p->next)
+ {
+ transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, TPOLYTYPE_ALPHA);
+ for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+ {
+ softwaretransform(v, temp);
+ transpolyvert(temp[0], temp[1], temp[2] + r_waterripple.value * turbsin[(int)((temp[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((temp[1]*(1.0f/32.0f)+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f), (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), 128, 128, 128, alpha);
+ }
+ transpolyend();
+ }
+ }
else
- VectorCopy(v, wv);
+ {
+ for (p=s->polys ; p ; p=p->next)
+ {
+ transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, TPOLYTYPE_ALPHA);
+ for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+ {
+ softwaretransform(v, temp);
+ transpolyvert(temp[0], temp[1], temp[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), 128, 128, 128, alpha);
+ }
+ transpolyend();
+ }
+ }
+ }
+ else
+ {
if (r_waterripple.value)
- wv[2] += r_waterripple.value * turbsin[(int)((wv[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((wv[1]*(1.0f/32.0f)+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f);
- wv[3] = wv[4] = wv[5] = 128.0f;
- wv += 6;
+ {
+ for (p=s->polys ; p ; p=p->next)
+ {
+ transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, TPOLYTYPE_ALPHA);
+ for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+ transpolyvert(v[0], v[1], v[2] + r_waterripple.value * turbsin[(int)((v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v[1]*(1.0f/32.0f)+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f), (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), 128, 128, 128, alpha);
+ transpolyend();
+ }
+ }
+ else
+ {
+ for (p=s->polys ; p ; p=p->next)
+ {
+ transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, TPOLYTYPE_ALPHA);
+ for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+ transpolyvert(v[0], v[1], v[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), 128, 128, 128, alpha);
+ transpolyend();
+ }
+ }
}
}
- if (s->dlightframe == r_dlightframecount)
- RSurf_Light(s->dlightbits, s->polys);
- wv = wvert;
- // FIXME: make fog texture if water texture is transparent?
- for (p=s->polys ; p ; p=p->next)
+ else
{
- transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA);
- for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6)
- transpolyvert(wv[0], wv[1], wv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), wv[3], wv[4], wv[5], alpha);
- transpolyend();
+ float *wv;
+ wv = wvert;
+ for (p = s->polys;p;p = p->next)
+ {
+ for (i = 0, v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+ {
+ if (transform)
+ softwaretransform(v, wv);
+ else
+ VectorCopy(v, wv);
+ if (r_waterripple.value)
+ wv[2] += r_waterripple.value * turbsin[(int)((wv[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((wv[1]*(1.0f/32.0f)+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f);
+ wv[3] = wv[4] = wv[5] = 128.0f;
+ wv += 6;
+ }
+ }
+ if (s->dlightframe == r_dlightframecount)
+ RSurf_Light(s->dlightbits, s->polys);
+ wv = wvert;
+ for (p=s->polys ; p ; p=p->next)
+ {
+ transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, TPOLYTYPE_ALPHA);
+ for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6)
+ transpolyvert(wv[0], wv[1], wv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), wv[3], wv[4], wv[5], alpha);
+ transpolyend();
+ }
}
}
void RSurf_DrawWall(msurface_t *s, texture_t *t, int transform)
{
int i, lit = false, polys = 0, verts = 0;
- float *v, *wv;
+ float *v;
glpoly_t *p;
wallpoly_t *wp;
wallvert_t *out;
+ wallvertcolor_t *outcolor;
// check for lightmap modification
- if (r_dynamic.value)
+ if (s->cached_dlight
+ || (r_dynamic.value && r_dlightmap.value && s->dlightframe == r_dlightframecount)
+ || r_ambient.value != s->cached_ambient
+ || lighthalf != s->cached_lighthalf
+ || (r_dynamic.value
+ && (s->styles[0] != 255 && d_lightstylevalue[s->styles[0]] != s->cached_light[0])
+ || (s->styles[1] != 255 && d_lightstylevalue[s->styles[1]] != s->cached_light[1])
+ || (s->styles[2] != 255 && d_lightstylevalue[s->styles[2]] != s->cached_light[2])
+ || (s->styles[3] != 255 && d_lightstylevalue[s->styles[3]] != s->cached_light[3])))
+ R_UpdateLightmap(s, s->lightmaptexturenum);
+ if (r_dlightmap.value || s->dlightframe != r_dlightframecount)
{
- if (s->cached_dlight
- || (r_dlightmap.value && s->dlightframe == r_dlightframecount)
- || r_ambient.value != s->cached_ambient
- || lighthalf != s->cached_lighthalf
- || (s->styles[0] != 255 && d_lightstylevalue[s->styles[0]] != s->cached_light[0])
- || (s->styles[1] != 255 && d_lightstylevalue[s->styles[1]] != s->cached_light[1])
- || (s->styles[2] != 255 && d_lightstylevalue[s->styles[2]] != s->cached_light[2])
- || (s->styles[3] != 255 && d_lightstylevalue[s->styles[3]] != s->cached_light[3]))
- R_UpdateLightmap(s, s->lightmaptexturenum);
- }
- wv = wvert;
- for (p = s->polys;p;p = p->next)
- {
- for (i = 0, v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
+ // LordHavoc: fast path version for no vertex lighting cases
+ wp = &wallpoly[currentwallpoly];
+ out = &wallvert[currentwallvert];
+ for (p = s->polys;p;p = p->next)
{
+ if ((currentwallpoly >= MAX_WALLPOLYS) || (currentwallvert+p->numverts > MAX_WALLVERTS))
+ return;
+ wp->texnum = (unsigned short) R_GetTexture(t->texture);
+ wp->lighttexnum = (unsigned short) (lightmap_textures + s->lightmaptexturenum);
+ wp->glowtexnum = (unsigned short) R_GetTexture(t->glowtexture);
+ wp->firstvert = currentwallvert;
+ wp->numverts = p->numverts;
+ wp->lit = lit;
+ wp++;
+ currentwallpoly++;
+ currentwallvert += p->numverts;
+ v = p->verts[0];
if (transform)
- softwaretransform(v, wv);
+ {
+ for (i = 0;i < p->numverts;i++, v += VERTEXSIZE, out++)
+ {
+ softwaretransform(v, out->vert);
+ out->vert[3] = v[3];
+ out->vert[4] = v[4];
+ out->vert[5] = v[5];
+ out->vert[6] = v[6];
+ }
+ }
else
- VectorCopy(v, wv);
- wv[3] = wv[4] = wv[5] = 0.0f;
- wv += 6;
+ {
+ /*
+ for (i = 0;i < p->numverts;i++, v += VERTEXSIZE, out++)
+ {
+ VectorCopy(v, out->vert);
+ out->vert[3] = v[3];
+ out->vert[4] = v[4];
+ out->vert[5] = v[5];
+ out->vert[6] = v[6];
+ }
+ */
+ memcpy(out, v, sizeof(vec_t) * VERTEXSIZE * p->numverts);
+ out += p->numverts;
+ }
}
- verts += p->numverts;
- polys++;
}
- if ((currentwallpoly + polys > MAX_WALLPOLYS) || (currentwallvert+verts > MAX_WALLVERTS))
- return;
- if ((!r_dlightmap.value) && s->dlightframe == r_dlightframecount)
- lit = RSurf_Light(s->dlightbits, s->polys);
- wv = wvert;
- wp = &wallpoly[currentwallpoly];
- out = &wallvert[currentwallvert];
- currentwallpoly += polys;
- for (p = s->polys;p;p = p->next)
+ else
{
- v = p->verts[0];
- wp->texnum = (unsigned short) t->gl_texturenum;
- wp->lighttexnum = (unsigned short) (lightmap_textures + s->lightmaptexturenum);
- wp->glowtexnum = (unsigned short) t->gl_glowtexturenum;
- wp->firstvert = currentwallvert;
- wp->numverts = p->numverts;
- wp->lit = lit;
- wp++;
- currentwallvert += p->numverts;
- for (i = 0;i < p->numverts;i++, v += VERTEXSIZE, wv += 6, out++)
+ float *wv;
+ wv = wvert;
+ for (p = s->polys;p;p = p->next)
{
- if (lit)
+ for (i = 0, v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE)
{
- if (lighthalf)
- {
- out->r = (byte) (bound(0, (int) wv[3] >> 1, 255));
- out->g = (byte) (bound(0, (int) wv[4] >> 1, 255));
- out->b = (byte) (bound(0, (int) wv[5] >> 1, 255));
- out->a = 255;
- }
+ if (transform)
+ softwaretransform(v, wv);
else
+ VectorCopy(v, wv);
+ wv[3] = wv[4] = wv[5] = 0.0f;
+ wv += 6;
+ }
+ verts += p->numverts;
+ polys++;
+ }
+ if ((currentwallpoly + polys > MAX_WALLPOLYS) || (currentwallvert+verts > MAX_WALLVERTS))
+ return;
+ if ((!r_dlightmap.value) && s->dlightframe == r_dlightframecount)
+ lit = RSurf_Light(s->dlightbits, s->polys);
+ wv = wvert;
+ wp = &wallpoly[currentwallpoly];
+ out = &wallvert[currentwallvert];
+ outcolor = &wallvertcolor[currentwallvert];
+ currentwallpoly += polys;
+ for (p = s->polys;p;p = p->next)
+ {
+ v = p->verts[0];
+ wp->texnum = (unsigned short) R_GetTexture(t->texture);
+ wp->lighttexnum = (unsigned short) (lightmap_textures + s->lightmaptexturenum);
+ wp->glowtexnum = (unsigned short) R_GetTexture(t->glowtexture);
+ wp->firstvert = currentwallvert;
+ wp->numverts = p->numverts;
+ wp->lit = lit;
+ wp++;
+ currentwallvert += p->numverts;
+ for (i = 0;i < p->numverts;i++, v += VERTEXSIZE, wv += 6, out++, outcolor++)
+ {
+ if (lit)
{
- out->r = (byte) (bound(0, (int) wv[3], 255));
- out->g = (byte) (bound(0, (int) wv[4], 255));
- out->b = (byte) (bound(0, (int) wv[5], 255));
- out->a = 255;
+ if (lighthalf)
+ {
+ outcolor->r = (byte) (bound(0, (int) wv[3] >> 1, 255));
+ outcolor->g = (byte) (bound(0, (int) wv[4] >> 1, 255));
+ outcolor->b = (byte) (bound(0, (int) wv[5] >> 1, 255));
+ outcolor->a = 255;
+ }
+ else
+ {
+ outcolor->r = (byte) (bound(0, (int) wv[3], 255));
+ outcolor->g = (byte) (bound(0, (int) wv[4], 255));
+ outcolor->b = (byte) (bound(0, (int) wv[5], 255));
+ outcolor->a = 255;
+ }
}
+ out->vert[0] = wv[0];
+ out->vert[1] = wv[1];
+ out->vert[2] = wv[2];
+ out->vert[3] = v[3];
+ out->vert[4] = v[4];
+ out->vert[5] = v[5];
+ out->vert[6] = v[6];
}
- out->vert[0] = wv[0];
- out->vert[1] = wv[1];
- out->vert[2] = wv[2];
- out->s = v[3];
- out->t = v[4];
- out->u = v[5];
- out->v = v[6];
}
}
}
for (p = s->polys;p;p = p->next)
{
v = p->verts[0];
- transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
+ transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6)
transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], wv[3] * currententity->colormod[0], wv[4] * currententity->colormod[1], wv[5] * currententity->colormod[2], alpha);
transpolyend();
for (p = s->polys;p;p = p->next)
{
v = p->verts[0];
- transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
+ transpolybegin(R_GetTexture(t->texture), R_GetTexture(t->glowtexture), 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6)
transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], wv[3], wv[4], wv[5], alpha);
transpolyend();
}
if (!lightmap_textures)
- {
- lightmap_textures = texture_extension_number;
- texture_extension_number += MAX_LIGHTMAPS;
- }
+ lightmap_textures = R_GetTextureSlots(MAX_LIGHTMAPS);
for (j=1 ; j<MAX_MODELS ; j++)
{
net
turn off messages option
-the refresh is allways rendered, unless the console is full screen
+the refresh is always rendered, unless the console is full screen
console is:
if (!scr_showturtle.value)
return;
- if (host_frametime < 0.1)
+ if (cl.frametime < 0.1)
{
count = 0;
return;
LordHavoc: due to my rewrite of R_WorldNode, it no longer takes 256k of stack space :)
==================
*/
-extern cvar_t gl_vertexarrays;
-extern qboolean gl_arrays;
void GL_Finish();
void SCR_UpdateScreen (void)
{
if (r_speeds.value)
time1 = Sys_FloatTime ();
- if (!gl_arrays)
- gl_vertexarrays.value = 0;
-
scr_copytop = 0;
scr_copyeverything = 0;
#include "quakedef.h"
-cvar_t gl_max_size = {"gl_max_size", "2048"};
-cvar_t gl_picmip = {"gl_picmip", "0"};
-cvar_t gl_lerpimages = {"gl_lerpimages", "1"};
+cvar_t r_max_size = {"r_max_size", "2048"};
+cvar_t r_picmip = {"r_picmip", "0"};
+cvar_t r_lerpimages = {"r_lerpimages", "1"};
cvar_t r_upload = {"r_upload", "1"};
+cvar_t r_precachetextures = {"r_precachetextures", "1", true};
int gl_filter_min = GL_LINEAR_MIPMAP_LINEAR; //NEAREST;
int gl_filter_max = GL_LINEAR;
// 65536x65536
#define MAXMIPS 16
+#define GLTEXF_LERPED 1
+#define GLTEXF_UPLOADED 2
+
typedef struct
{
char identifier[64];
- int texnum;
- int texeldatasize;
- byte *texels[MAXMIPS];
- unsigned short texelsize[MAXMIPS][2];
+ int texnum; // GL texture slot number
+ int texeldatasize; // computed memory usage of this texture (including mipmaps, expansion to 32bit, etc)
+ byte *inputtexels; // copy of the original texture supplied to the upload function, for re-uploading or deferred uploads (non-precached)
+ int inputtexeldatasize; // size of the original texture
unsigned short width, height;
// LordHavoc: CRC to identify cache mismatchs
unsigned short crc;
- char mipmap;
- char alpha;
- char bytesperpixel;
- char lerped; // whether this texture was uploaded with or without interpolation
- char inuse; // cleared during texture purge when loading new level
- char pad; // unused
+ int flags; // the requested flags when the texture was supplied to the upload function
+ int internalflags; // internal notes (lerped, etc)
} gltexture_t;
#define MAX_GLTEXTURES 4096
gltexture_t *gltextures;
-int numgltextures;
+unsigned int numgltextures = 0, gl_texture_number = 1;
+
+void GL_UploadTexture(gltexture_t *t);
+
+int R_GetTexture(rtexture_t *rt)
+{
+ gltexture_t *glt;
+ if (!rt)
+ return 0;
+ glt = (gltexture_t *)rt;
+ if (!(glt->internalflags & GLTEXF_UPLOADED))
+ {
+ GL_UploadTexture(glt);
+ if (!(glt->internalflags & GLTEXF_UPLOADED))
+ Host_Error("R_GetTexture: unable to upload texture\n");
+ }
+ return glt->texnum;
+}
typedef struct
{
int minimize, maximize;
} glmode_t;
-glmode_t modes[] = {
+glmode_t modes[] =
+{
{"GL_NEAREST", GL_NEAREST, GL_NEAREST},
{"GL_LINEAR", GL_LINEAR, GL_LINEAR},
{"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
// change all the existing mipmap texture objects
for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
{
- if (glt->mipmap)
+ if (glt->flags & TEXF_MIPMAP)
{
glBindTexture(GL_TEXTURE_2D, glt->texnum);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
}
}
-void GL_TextureStats_Print(char *name, int total, int crc, int mip, int alpha)
+void GL_TextureStats_Print(char *name, int total, int total2, int loaded, int crc, int mip, int alpha, int total2valid)
{
- char n[64];
- int c = 0;
if (!name[0])
name = "<unnamed>";
- while (name[c] && c < 28)
- n[c++] = name[c];
- // no need to pad since the name was moved to last
-// while (c < 28)
-// n[c++] = ' ';
- n[c] = 0;
- Con_Printf("%5i %04X %s %s %s\n", total, crc, mip ? "yes" : "no ", alpha ? "yes " : "no ", n);
+ Con_Printf("%5iK %c%5iK%c %04X %s %s %s %s\n", total, total2valid ? ' ' : '(', total2, total2valid ? ' ' : ')', crc, loaded ? "loaded" : " ", mip ? "mip" : " ", alpha ? "alpha" : " ", name);
}
-void GL_TextureStats_f(void)
+void GL_TextureStats_PrintTotal(void)
{
- int i, s = 0, sc = 0, t = 0;
+ int i, t = 0, p = 0, loaded = 0, loadedt = 0, loadedp = 0;
gltexture_t *glt;
- Con_Printf("kbytes crc mip alpha name\n");
for (i = 0, glt = gltextures;i < numgltextures;i++, glt++)
{
- GL_TextureStats_Print(glt->identifier, (glt->texeldatasize + 512) >> 10, glt->crc, glt->mipmap, glt->alpha);
t += glt->texeldatasize;
- if (glt->identifier[0] == '&')
+ p += glt->inputtexeldatasize;
+ if (glt->internalflags & GLTEXF_UPLOADED)
{
- sc++;
- s += glt->texeldatasize;
+ loaded++;
+ loadedt += glt->texeldatasize;
+ loadedp += glt->inputtexeldatasize;
}
}
- Con_Printf("%i textures, totalling %.3fMB, %i are (usually) unnecessary model skins totalling %.3fMB\n", numgltextures, t / 1048576.0, sc, s / 1048576.0);
+ Con_Printf("total: %i (%.3fMB, %.3fMB original), uploaded %i (%.3fMB, %.3fMB original), upload on demand %i (%.3fMB, %.3fMB original)\n", numgltextures, t / 1048576.0, p / 1048576.0, loaded, loadedt / 1048576.0, loadedp / 1048576.0, numgltextures - loaded, (t - loadedt) / 1048576.0, (p - loadedp) / 1048576.0);
}
-void GL_TextureStats_PrintTotal(void)
+void GL_TextureStats_f(void)
{
- int i, s = 0, sc = 0, t = 0;
+ int i;
gltexture_t *glt;
+ Con_Printf("kbytes original crc loaded mip alpha name\n");
for (i = 0, glt = gltextures;i < numgltextures;i++, glt++)
- {
- t += glt->texeldatasize;
- if (glt->identifier[0] == '&')
- {
- sc++;
- s += glt->texeldatasize;
- }
- }
- Con_Printf("%i textures, totalling %.3fMB, %i are (usually) unnecessary model skins totalling %.3fMB\n", numgltextures, t / 1048576.0, sc, s / 1048576.0);
+ GL_TextureStats_Print(glt->identifier, (glt->texeldatasize + 1023) / 1024, (glt->inputtexeldatasize + 1023) / 1024, glt->internalflags & GLTEXF_UPLOADED, glt->crc, glt->flags & TEXF_MIPMAP, glt->flags & TEXF_ALPHA, glt->inputtexels != NULL);
+ GL_TextureStats_PrintTotal();
}
char engineversion[40];
//void GL_UploadTexture (gltexture_t *glt);
-void gl_textures_start()
+void r_textures_start()
{
// int i;
// gltexture_t *glt;
// GL_UploadTexture(glt);
}
-void gl_textures_shutdown()
+void r_textures_shutdown()
{
}
-void GL_Textures_Init (void)
+void R_Textures_Init (void)
{
Cmd_AddCommand("r_texturestats", GL_TextureStats_f);
- Cvar_RegisterVariable (&gl_max_size);
- Cvar_RegisterVariable (&gl_picmip);
- Cvar_RegisterVariable (&gl_lerpimages);
+ Cvar_RegisterVariable (&r_max_size);
+ Cvar_RegisterVariable (&r_picmip);
+ Cvar_RegisterVariable (&r_lerpimages);
Cvar_RegisterVariable (&r_upload);
+ Cvar_RegisterVariable (&r_precachetextures);
#ifdef NORENDER
r_upload.value = 0;
#endif
// 3dfx can only handle 256 wide textures
if (!Q_strncasecmp ((char *)gl_renderer, "3dfx",4) || strstr((char *)gl_renderer, "Glide"))
- Cvar_Set ("gl_max_size", "256");
+ Cvar_Set ("r_max_size", "256");
gltextures = qmalloc(sizeof(gltexture_t) * MAX_GLTEXTURES);
memset(gltextures, 0, sizeof(gltexture_t) * MAX_GLTEXTURES);
Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_f);
- R_RegisterModule("GL_Textures", gl_textures_start, gl_textures_shutdown);
+ R_RegisterModule("R_Textures", r_textures_start, r_textures_shutdown);
}
/*
================
-GL_FindTexture
+R_FindTexture
================
*/
-int GL_FindTexture (char *identifier)
+int R_FindTexture (char *identifier)
{
int i;
gltexture_t *glt;
return -1;
}
-void GL_ResampleTextureLerpLine (byte *in, byte *out, int inwidth, int outwidth)
+void R_ResampleTextureLerpLine (byte *in, byte *out, int inwidth, int outwidth)
{
int j, xi, oldx = 0, f, fstep, l1, l2, endx;
fstep = (int) (inwidth*65536.0f/outwidth);
/*
================
-GL_ResampleTexture
+R_ResampleTexture
================
*/
-void GL_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
+void R_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
{
- if (gl_lerpimages.value)
+ if (r_lerpimages.value)
{
int i, j, yi, oldy, f, fstep, l1, l2, endy = (inheight-1);
byte *inrow, *out, *row1, *row2;
row2 = qmalloc(outwidth*4);
inrow = indata;
oldy = 0;
- GL_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth);
- GL_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth);
+ R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth);
+ R_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth);
for (i = 0, f = 0;i < outheight;i++,f += fstep)
{
yi = f >> 16;
if (yi == oldy+1)
memcpy(row1, row2, outwidth*4);
else
- GL_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth);
+ R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth);
if (yi < endy)
- GL_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth);
+ R_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth);
else
memcpy(row2, row1, outwidth*4);
oldy = yi;
}
}
-void GL_FreeTexels(gltexture_t *glt)
-{
- if (glt->texels[0])
- qfree(glt->texels[0]);
- glt->texels[0] = 0;
-}
-
-void GL_AllocTexels(gltexture_t *glt, int width, int height, int mipmapped)
-{
- int i, w, h, size;
- if (glt->texels[0])
- GL_FreeTexels(glt);
- glt->texelsize[0][0] = width;
- glt->texelsize[0][1] = height;
- if (mipmapped)
- {
- size = 0;
- w = width;h = height;
- i = 0;
- while (i < MAXMIPS)
- {
- glt->texelsize[i][0] = w;
- glt->texelsize[i][1] = h;
- glt->texels[i++] = (void *)size;
- size += w*h*4;
- if (w > 1)
- {
- w >>= 1;
- if (h > 1)
- h >>= 1;
- }
- else if (h > 1)
- h >>= 1;
- else
- break;
- }
- glt->texeldatasize = size;
- while (i < MAXMIPS)
- glt->texels[i++] = NULL;
- glt->texels[0] = qmalloc(size);
- for (i = 1;i < MAXMIPS && glt->texels[i];i++)
- glt->texels[i] += (int) glt->texels[0];
- }
- else
- {
- size = width*height*4;
- glt->texeldatasize = size;
- glt->texels[0] = qmalloc(size);
- for (i = 1;i < MAXMIPS;i++)
- glt->texels[i] = NULL;
- }
- if (!glt->texels[0])
- Sys_Error("GL_AllocTexels: out of memory\n");
-}
-
// in can be the same as out
void GL_MipReduce(byte *in, byte *out, int width, int height, int destwidth, int destheight)
{
}
}
-void GL_UploadTexture (gltexture_t *glt)
+void GL_Upload32(int glslot, byte *data, int width, int height, int flags)
{
- int mip, width, height;
+ int mip, width2, height2, width3, height3, internalformat;
+ byte *gammadata, *buffer;
+
if (!r_upload.value)
return;
- glBindTexture(GL_TEXTURE_2D, glt->texnum);
- width = glt->width;
- height = glt->height;
- for (mip = 0;mip < MAXMIPS && glt->texels[mip];mip++)
- glTexImage2D(GL_TEXTURE_2D, mip, glt->alpha ? 4 : 3, glt->texelsize[mip][0], glt->texelsize[mip][1], 0, GL_RGBA, GL_UNSIGNED_BYTE, glt->texels[mip]);
- if (glt->mipmap)
+
+ // 3 and 4 are converted by the driver to it's preferred format for the current display mode
+ internalformat = 3;
+ if (flags & TEXF_ALPHA)
+ internalformat = 4;
+
+ // calculate power of 2 size
+ width2 = 1;while (width2 < width) width2 <<= 1;
+ height2 = 1;while (height2 < height) height2 <<= 1;
+ // calculate final size (mipmapped downward to this)
+ width3 = width2 >> (int) r_picmip.value;
+ height3 = height2 >> (int) r_picmip.value;
+ while (width3 > (int) r_max_size.value) width3 >>= 1;
+ while (height3 > (int) r_max_size.value) height3 >>= 1;
+ if (width3 < 1) width3 = 1;
+ if (height3 < 1) height3 = 1;
+
+ gammadata = qmalloc(width*height*4);
+ buffer = qmalloc(width2*height2*4);
+ if (!gammadata || !buffer)
+ Host_Error("GL_Upload32: out of memory\n");
+
+ Image_CopyRGBAGamma(data, gammadata, width*height);
+
+ R_ResampleTexture(gammadata, width, height, buffer, width2, height2);
+
+ qfree(gammadata);
+
+ while (width2 > width3 || height2 > height3)
{
+ GL_MipReduce(buffer, buffer, width2, height2, width3, height3);
+
+ if (width2 > width3)
+ width2 >>= 1;
+ if (height2 > height3)
+ height2 >>= 1;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, glslot);
+ mip = 0;
+ glTexImage2D(GL_TEXTURE_2D, mip++, internalformat, width2, height2, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+ if (flags & TEXF_MIPMAP)
+ {
+ while (width2 > 1 || height2 > 1)
+ {
+ GL_MipReduce(buffer, buffer, width2, height2, 1, 1);
+
+ if (width2 > 1)
+ width2 >>= 1;
+ if (height2 > 1)
+ height2 >>= 1;
+
+ glTexImage2D(GL_TEXTURE_2D, mip++, internalformat, width2, height2, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+ }
+
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ qfree(buffer);
+}
+
+void GL_Upload8 (int glslot, byte *data, int width, int height, int flags)
+{
+ byte *data32;
+ data32 = qmalloc(width*height*4);
+ Image_Copy8bitRGBA(data, data32, width*height, d_8to24table);
+ GL_Upload32(glslot, data32, width, height, flags);
+ qfree(data32);
+}
+
+void GL_UploadTexture (gltexture_t *glt)
+{
+ if (glt->inputtexels == NULL)
+ return;
+ if (glt->flags & TEXF_RGBA)
+ GL_Upload32(glt->texnum, glt->inputtexels, glt->width, glt->height, glt->flags);
+ else // 8bit
+ GL_Upload8(glt->texnum, glt->inputtexels, glt->width, glt->height, glt->flags);
+ glt->internalflags |= GLTEXF_UPLOADED;
+ qfree(glt->inputtexels);
+ glt->inputtexels = NULL;
+}
+
+int R_CalcTexelDataSize (int width, int height, int mipmapped)
+{
+ int width2, height2, size;
+ width2 = 1;while (width2 < width) width2 <<= 1;
+ height2 = 1;while (height2 < height) height2 <<= 1;
+ // calculate final size (mipmapped downward to this)
+ width2 >>= (int) r_picmip.value;
+ height2 >>= (int) r_picmip.value;
+ while (width2 > (int) r_max_size.value) width2 >>= 1;
+ while (height2 > (int) r_max_size.value) height2 >>= 1;
+ if (width2 < 1) width2 = 1;
+ if (height2 < 1) height2 = 1;
+
+ size = 0;
+ if (mipmapped)
+ {
+ while (width2 > 1 || height2 > 1)
+ {
+ size += width2 * height2;
+ if (width2 > 1)
+ width2 >>= 1;
+ if (height2 > 1)
+ height2 >>= 1;
+ }
+ size++; // count the last 1x1 mipmap
+ }
+ else
+ size = width2*height2;
+
+ size *= 4; // RGBA
+
+ return size;
}
/*
GL_LoadTexture
================
*/
-int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha, int bytesperpixel)
+rtexture_t *R_LoadTexture (char *identifier, int width, int height, byte *data, int flags)
{
+ int i, bytesperpixel, internalflags, precache;
+ gltexture_t *glt;
unsigned short crc;
- int i, width2, height2, width3, height3, w, h, mip;
- gltexture_t *glt, *freeglt;
- // LordHavoc: texture caching, turned out to be a waste of time (and immense waste of diskspace)
- //char cachefilename[1024], *cachefile;
if (isDedicated)
- return 1;
+ return NULL;
- freeglt = NULL;
+ if (!identifier[0])
+ Host_Error("R_LoadTexture: no identifier\n");
- // LordHavoc: do a CRC to confirm the data really is the same as previous occurances.
- crc = CRC_Block(data, width*height*bytesperpixel);
- // see if the texture is already present
- if (identifier[0])
+ // clear the alpha flag if the texture has no transparent pixels
+ if (flags & TEXF_ALPHA)
{
- for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
+ int alpha = false;
+ if (flags & TEXF_RGBA)
{
- if (glt->inuse)
+ for (i = 0;i < width * height;i++)
{
- if (!strcmp (identifier, glt->identifier))
+ if (data[i * 4 + 3] < 255)
{
- // LordHavoc: everyone hates cache mismatchs, so I fixed it
- if (crc != glt->crc || width != glt->width || height != glt->height)
- {
- Con_DPrintf("GL_LoadTexture: cache mismatch, replacing old texture\n");
- goto GL_LoadTexture_setup; // drop out with glt pointing to the texture to replace
- }
- if ((gl_lerpimages.value != 0) != glt->lerped)
- goto GL_LoadTexture_setup; // drop out with glt pointing to the texture to replace
- return glt->texnum;
+ alpha = true;
+ break;
}
}
- else
- freeglt = glt;
}
+ else
+ {
+ for (i = 0;i < width * height;i++)
+ {
+ if (data[i] == 255)
+ {
+ alpha = true;
+ break;
+ }
+ }
+ }
+ if (!alpha)
+ flags &= ~TEXF_ALPHA;
}
+
+ if (flags & TEXF_RGBA)
+ bytesperpixel = 4;
else
- i = 0;
- // LordHavoc: although this could be an else condition as it was in the original id code,
- // it is more clear this way
+ bytesperpixel = 1;
+
+ internalflags = 0;
+ if (r_lerpimages.value != 0)
+ internalflags |= GLTEXF_LERPED;
+
+ // LordHavoc: do a CRC to confirm the data really is the same as previous occurances.
+ crc = CRC_Block(data, width*height*bytesperpixel);
+ // see if the texture is already present
+ for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
+ {
+ if (!strcmp (identifier, glt->identifier))
+ {
+ // LordHavoc: everyone hates cache mismatchs, so I fixed it
+ if (crc != glt->crc || width != glt->width || height != glt->height || flags != glt->flags)
+ {
+ Con_DPrintf("GL_LoadTexture: cache mismatch, replacing old texture\n");
+ goto GL_LoadTexture_setup; // drop out with glt pointing to the texture to replace
+ }
+ if (internalflags != glt->internalflags)
+ goto GL_LoadTexture_setup; // drop out with glt pointing to the texture to replace
+ return (rtexture_t *)glt;
+ }
+ }
+
+/*
if (freeglt)
{
glt = freeglt;
}
else
{
+*/
// LordHavoc: check if there are still slots available
if (numgltextures >= MAX_GLTEXTURES)
Sys_Error ("GL_LoadTexture: ran out of texture slots (%d)\n", MAX_GLTEXTURES);
glt = &gltextures[numgltextures++];
- glt->texnum = texture_extension_number;
- texture_extension_number++;
+ glt->texnum = gl_texture_number++;
strcpy (glt->identifier, identifier);
- }
+// }
// LordHavoc: label to drop out of the loop into the setup code
GL_LoadTexture_setup:
- // calculate power of 2 size
- width2 = 1;while (width2 < width) width2 <<= 1;
- height2 = 1;while (height2 < height) height2 <<= 1;
- // calculate final size (mipmapped downward to this)
- width3 = width2 >> (int) gl_picmip.value;
- height3 = height2 >> (int) gl_picmip.value;
- while (width3 > (int) gl_max_size.value) width3 >>= 1;
- while (height3 > (int) gl_max_size.value) height3 >>= 1;
- if (width3 < 1) width3 = 1;
- if (height3 < 1) height3 = 1;
-
- // final storage
- GL_AllocTexels(glt, width3, height3, mipmap);
glt->crc = crc; // LordHavoc: used to verify textures are identical
glt->width = width;
glt->height = height;
- glt->mipmap = mipmap;
- glt->bytesperpixel = bytesperpixel;
- glt->lerped = gl_lerpimages.value != 0;
- glt->alpha = false; // updated later
- glt->inuse = true;
- /*
- // LordHavoc: texture caching, turned out to be a waste of time (and immense waste of diskspace)
- sprintf(cachefilename, "%s%x%x%x.texels", identifier, width3, height3, crc);
- for (i = 0;cachefilename[i];i++)
- {
- if (cachefilename[i] <= ' ' || cachefilename[i] >= 127 || cachefilename[i] == '/' || cachefilename[i] == '\\' || cachefilename[i] == ':' || cachefilename[i] == '*' || cachefilename[i] == '?')
- cachefilename[i] = '@';
- if (cachefilename[i] >= 'A' && cachefilename[i] <= 'Z')
- cachefilename[i] += 'a' - 'A';
- }
- cachefile = COM_LoadMallocFile(cachefilename, true);
- if (cachefile)
- {
- if (cachefile[0] == 'D' && cachefile[1] == 'P' && cachefile[2] == 'C' && cachefile[3] == 'T')
- {
- memcpy(glt->texels[0], cachefile + 4, width3*height3*4);
- qfree(cachefile);
-// Con_Printf("loaded cache texture %s\n", cachefilename);
- goto cacheloaded;
- }
- else
- qfree(cachefile);
- }
- */
- if (width == width3 && height == height3) // perfect match
- {
- if (bytesperpixel == 1) // 8bit
- Image_Copy8bitRGBA(data, glt->texels[0], width*height, d_8to24table);
- else
- Image_CopyRGBAGamma(data, glt->texels[0], width*height);
- }
- else if (width == width2 && height == height2) // perfect match for top level, but needs to be reduced
- {
- byte *temptexels2;
- temptexels2 = qmalloc(width2*height2*4); // scaleup buffer
- if (bytesperpixel == 1) // 8bit
- Image_Copy8bitRGBA(data, temptexels2, width*height, d_8to24table);
- else
- Image_CopyRGBAGamma(data, temptexels2, width*height);
- while (width2 > width3 || height2 > height3)
- {
- w = width2;h = height2;
- if (width2 > width3) width2 >>= 1;
- if (height2 > height3) height2 >>= 1;
- if (width2 <= width3 && height2 <= height3) // size achieved
- GL_MipReduce(temptexels2, glt->texels[0], w, h, width3, height3);
- else
- GL_MipReduce(temptexels2, temptexels2, w, h, width3, height3);
- }
- qfree(temptexels2);
- }
- else // scaling...
- {
- byte *temptexels;
- // pre-scaleup buffer
- temptexels = qmalloc(width*height*4);
- if (bytesperpixel == 1) // 8bit
- Image_Copy8bitRGBA(data, temptexels, width*height, d_8to24table);
- else
- Image_CopyRGBAGamma(data, temptexels, width*height);
- if (width2 != width3 || height2 != height3) // reduced by gl_pic_mip or gl_max_size
- {
- byte *temptexels2;
- temptexels2 = qmalloc(width2*height2*4); // scaleup buffer
- GL_ResampleTexture(temptexels, width, height, temptexels2, width2, height2);
- while (width2 > width3 || height2 > height3)
- {
- w = width2;h = height2;
- if (width2 > width3) width2 >>= 1;
- if (height2 > height3) height2 >>= 1;
- if (width2 <= width3 && height2 <= height3) // size achieved
- GL_MipReduce(temptexels2, glt->texels[0], w, h, width3, height3);
- else
- GL_MipReduce(temptexels2, temptexels2, w, h, width3, height3);
- }
- qfree(temptexels2);
- }
- else // copy directly
- GL_ResampleTexture(temptexels, width, height, glt->texels[0], width2, height2);
- qfree(temptexels);
- }
- /*
- // LordHavoc: texture caching, turned out to be a waste of time (and immense waste of diskspace)
- Con_Printf("writing cache texture %s\n", cachefilename);
- cachefile = qmalloc(width3*height3*4 + 4);
- cachefile[0] = 'D';
- cachefile[1] = 'P';
- cachefile[2] = 'C';
- cachefile[3] = 'T';
- memcpy(cachefile + 4, glt->texels[0], width3*height3*4);
- COM_WriteFile(cachefilename, cachefile, width3*height3*4 + 4);
- qfree(cachefile);
-cacheloaded:
- */
- if (alpha)
+ glt->flags = flags;
+ glt->internalflags = internalflags;
+
+ if (glt->inputtexels)
+ qfree(glt->inputtexels);
+ glt->inputtexeldatasize = width*height*bytesperpixel;
+ glt->inputtexels = qmalloc(glt->inputtexeldatasize);
+
+ memcpy(glt->inputtexels, data, glt->inputtexeldatasize);
+
+ glt->texeldatasize = R_CalcTexelDataSize(width, height, flags & TEXF_MIPMAP);
+
+ precache = false;
+ if (r_precachetextures.value >= 1)
{
- byte *in = glt->texels[0] + 3;
- for (i = 0;i < width*height;i++, in += 4)
- if (*in < 255)
- {
- glt->alpha = true;
- break;
- }
+ if (flags & TEXF_PRECACHE)
+ precache = true;
+ if (r_precachetextures.value >= 2)
+ precache = true;
}
- // this loop is skipped if there are no mipmaps to generate
- for (mip = 1;mip < MAXMIPS && glt->texels[mip];mip++)
- GL_MipReduce(glt->texels[mip-1], glt->texels[mip], glt->texelsize[mip-1][0], glt->texelsize[mip-1][1], 1, 1);
- GL_UploadTexture(glt);
- GL_FreeTexels(glt);
-// if (bytesperpixel == 1) // 8bit
-// GL_Upload8 (data, width, height, mipmap, alpha);
-// else // 32bit
-// GL_Upload32 (data, width, height, mipmap, true);
+ if (precache)
+ GL_UploadTexture(glt);
- return glt->texnum;
+ return (rtexture_t *)glt;
+}
+
+// only used for lightmaps
+int R_GetTextureSlots(int count)
+{
+ int i;
+ i = gl_texture_number;
+ gl_texture_number += count;
+ return i;
}
int skytexturenum;
-int solidskytexture;
-int alphaskytexture;
+rtexture_t *solidskytexture;
+rtexture_t *alphaskytexture;
float speedscale; // for top sky and bottom sky
msurface_t *warpface;
-int skyboxside[6];
+rtexture_t *skyboxside[6];
char skyname[256];
continue;
}
}
- skyboxside[i] = GL_LoadTexture(va("skyboxside%d", i), image_width, image_height, image_rgba, false, false, 4);
+ skyboxside[i] = R_LoadTexture(va("skyboxside%d", i), image_width, image_height, image_rgba, TEXF_RGBA | TEXF_PRECACHE);
qfree(image_rgba);
}
}
glColor3f(0.5,0.5,0.5);
else
glColor3f(1,1,1);
- glBindTexture(GL_TEXTURE_2D, skyboxside[3]); // front
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(skyboxside[3])); // front
glBegin(GL_QUADS);
R_SkyBoxPolyVec(1, 0, 1, -1, 1);
R_SkyBoxPolyVec(1, 1, 1, -1, -1);
R_SkyBoxPolyVec(0, 1, 1, 1, -1);
R_SkyBoxPolyVec(0, 0, 1, 1, 1);
glEnd();
- glBindTexture(GL_TEXTURE_2D, skyboxside[1]); // back
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(skyboxside[1])); // back
glBegin(GL_QUADS);
R_SkyBoxPolyVec(1, 0, -1, 1, 1);
R_SkyBoxPolyVec(1, 1, -1, 1, -1);
R_SkyBoxPolyVec(0, 1, -1, -1, -1);
R_SkyBoxPolyVec(0, 0, -1, -1, 1);
glEnd();
- glBindTexture(GL_TEXTURE_2D, skyboxside[0]); // right
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(skyboxside[0])); // right
glBegin(GL_QUADS);
R_SkyBoxPolyVec(1, 0, 1, 1, 1);
R_SkyBoxPolyVec(1, 1, 1, 1, -1);
R_SkyBoxPolyVec(0, 1, -1, 1, -1);
R_SkyBoxPolyVec(0, 0, -1, 1, 1);
glEnd();
- glBindTexture(GL_TEXTURE_2D, skyboxside[2]); // left
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(skyboxside[2])); // left
glBegin(GL_QUADS);
R_SkyBoxPolyVec(1, 0, -1, -1, 1);
R_SkyBoxPolyVec(1, 1, -1, -1, -1);
R_SkyBoxPolyVec(0, 1, 1, -1, -1);
R_SkyBoxPolyVec(0, 0, 1, -1, 1);
glEnd();
- glBindTexture(GL_TEXTURE_2D, skyboxside[4]); // up
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(skyboxside[4])); // up
glBegin(GL_QUADS);
R_SkyBoxPolyVec(1, 0, 1, -1, 1);
R_SkyBoxPolyVec(1, 1, 1, 1, 1);
R_SkyBoxPolyVec(0, 1, -1, 1, 1);
R_SkyBoxPolyVec(0, 0, -1, -1, 1);
glEnd();
- glBindTexture(GL_TEXTURE_2D, skyboxside[5]); // down
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(skyboxside[5])); // down
glBegin(GL_QUADS);
R_SkyBoxPolyVec(1, 0, 1, 1, -1);
R_SkyBoxPolyVec(1, 1, 1, -1, -1);
}
}
-extern cvar_t gl_vertexarrays;
void skydome(float *source, float s, float texscale)
{
vec_t vert[33*33][3], tex[33*33][2], *v, *t;
*v++ = *source++ + r_refdef.vieworg[1];
*v++ = *source++ + r_refdef.vieworg[2];
}
- if (gl_vertexarrays.value)
- {
- qglTexCoordPointer(2, GL_FLOAT, 0, tex);
- qglVertexPointer(3, GL_FLOAT, 0, vert);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glEnableClientState(GL_VERTEX_ARRAY);
-// qglInterleavedArrays(GL_T2F_V3F, 0, vert);
- for (i = 0;i < (32*66);i+=66)
- qglDrawElements(GL_TRIANGLE_STRIP, 66, GL_UNSIGNED_SHORT, &skydomeindices[i]);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- else
- {
- index = skydomeindices;
- for (i = 0;i < (32*66);i+=66)
- {
- glBegin(GL_TRIANGLE_STRIP);
- for (j = 0;j < 66;j++)
- {
- // Matrox G200 (and possibly G400) drivers don't support TexCoord2fv...
- glTexCoord2f(tex[*index][0], tex[*index][1]);
- glVertex3fv(&vert[*index++][0]);
- }
- glEnd();
- }
- }
+ glTexCoordPointer(2, GL_FLOAT, 0, tex);
+ glVertexPointer(3, GL_FLOAT, 0, vert);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_VERTEX_ARRAY);
+// glInterleavedArrays(GL_T2F_V3F, 0, vert);
+ for (i = 0;i < (32*66);i+=66)
+ glDrawElements(GL_TRIANGLE_STRIP, 66, GL_UNSIGNED_SHORT, &skydomeindices[i]);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void R_SkyDome()
((byte *)&transpix)[3] = 0;
}
- solidskytexture = GL_LoadTexture ("sky_solidtexture", 128, 128, (byte *) trans, false, false, 4);
+ solidskytexture = R_LoadTexture ("sky_solidtexture", 128, 128, (byte *) trans, TEXF_RGBA | TEXF_PRECACHE);
if (bytesperpixel == 4)
{
}
}
- alphaskytexture = GL_LoadTexture ("sky_alphatexture", 128, 128, (byte *) trans, false, true, 4);
+ alphaskytexture = R_LoadTexture ("sky_alphatexture", 128, 128, (byte *) trans, TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE);
}
#include <GL/gl.h>
//#include <GL/glu.h>
+extern qboolean isG200;
+extern qboolean isRagePro;
+extern qboolean gl_mtexable;
+extern qboolean gl_supportslockarrays;
+
extern void GL_BeginRendering (int *x, int *y, int *width, int *height);
extern void GL_EndRendering (void);
-extern int texture_extension_number;
-
extern float gldepthmin, gldepthmax;
-extern void GL_Upload32 (void *data, int width, int height, qboolean mipmap, qboolean alpha);
-extern void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha);
-extern int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha, int bytesperpixel);
-extern int GL_FindTexture (char *identifier);
-
typedef struct
{
float x, y, z;
extern cvar_t r_drawviewmodel;
extern cvar_t r_speeds;
extern cvar_t r_fullbright;
-extern cvar_t r_shadows;
extern cvar_t r_wateralpha;
extern cvar_t r_dynamic;
extern cvar_t r_novis;
extern cvar_t r_waterripple;
-extern cvar_t gl_max_size;
-
extern float r_world_matrix[16];
extern const char *gl_vendor;
#define APIENTRY /* */
#endif
-extern qboolean gl_mtexable;
-
// LordHavoc: ARB multitexure support
extern int gl_mtex_enum;
#define GLAPIENTRY APIENTRY
#endif
-// Micro$oft dropped GL support beyond 1.1, so...
-#ifdef WIN32
+// multitexture
+extern void (GLAPIENTRY *qglMTexCoord2f) (GLenum, GLfloat, GLfloat);
+extern void (GLAPIENTRY *qglSelectTexture) (GLenum);
+extern void (GLAPIENTRY *qglLockArraysEXT) (GLint first, GLint count);
+extern void (GLAPIENTRY *qglUnlockArraysEXT) (void);
-//#define GL_POLYGON_OFFSET_POINT 0x2A01
-//#define GL_POLYGON_OFFSET_LINE 0x2A02
-//#define GL_POLYGON_OFFSET_FILL 0x8037
+#ifndef GL_ACTIVE_TEXTURE_ARB
+// multitexture
#define GL_ACTIVE_TEXTURE_ARB 0x84E0
#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
#define GL_MAX_TEXTURES_UNITS_ARB 0x84E2
#define GL_TEXTURE2_ARB 0x84C2
#define GL_TEXTURE3_ARB 0x84C3
// LordHavoc: ARB supports 32+ texture units, but hey I only use 2 anyway...
+#endif
-// LordHavoc: vertex array defines
-#define GL_VERTEX_ARRAY 0x8074
-#define GL_NORMAL_ARRAY 0x8075
-#define GL_COLOR_ARRAY 0x8076
-#define GL_TEXTURE_COORD_ARRAY 0x8078
-
-//extern void (GLAPIENTRY *qglPolygonOffset)(GLfloat factor, GLfloat units);
-extern void (GLAPIENTRY *qglVertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
-//extern void (GLAPIENTRY *qglNormalPointer)(GLenum type, GLsizei stride, const GLvoid *ptr);
-extern void (GLAPIENTRY *qglColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
-extern void (GLAPIENTRY *qglTexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
-extern void (GLAPIENTRY *qglArrayElement)(GLint i);
-//extern void (GLAPIENTRY *qglDrawArrays)(GLenum mode, GLint first, GLsizei count);
-extern void (GLAPIENTRY *qglDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
-
-extern void (GLAPIENTRY *qglMTexCoord2f) (GLenum, GLfloat, GLfloat);
-extern void (GLAPIENTRY *qglSelectTexture) (GLenum);
-//extern void (GLAPIENTRY *glColorTableEXT)(int, int, int, int, int, const void*);
-
+#ifdef WIN32
#else
-
-//#define qglPolygonOffset glPolygonOffset
-#define qglVertexPointer glVertexPointer
-//#define qglNormalPointer glNormalPointer
-#define qglColorPointer glColorPointer
-#define qglTexCoordPointer glTexCoordPointer
-#define qglArrayElement glArrayElement
-//#define qglDrawArrays glDrawArrays
-#define qglDrawElements glDrawElements
-
-extern void (GLAPIENTRY *qglMTexCoord2f) (GLenum, GLfloat, GLfloat);
-extern void (GLAPIENTRY *qglSelectTexture) (GLenum);
//#ifndef MESA
//extern void (GLAPIENTRY *glColorTableEXT)(int, int, int, int, int, const void*);
//#endif
#include "r_modules.h"
-extern cvar_t gl_vertexarrays;
extern qboolean lighthalf;
-extern void R_DrawAliasModel (entity_t *ent, int cull, float alpha, model_t *clmodel, int frame, int skin, vec3_t org, vec3_t angles, int effects, int flags, int colormap);
+#include "r_lerpanim.h"
+
+void GL_LockArray(int first, int count);
+void GL_UnlockArray();
+
+void R_DrawAliasModel (entity_t *ent, int cull, float alpha, model_t *clmodel, frameblend_t *blend, int skin, vec3_t org, vec3_t angles, vec_t scale, int effects, int flags, int colormap);
extern cvar_t r_render;
extern cvar_t r_upload;
/*
-A server can allways be started, even if the system started out as a client
+A server can always be started, even if the system started out as a client
to a remote system.
A client can NOT be started if the system started as a dedicated server.
quakeparms_t host_parms;
qboolean host_initialized; // true if into command execution
+qboolean hostloopactive = 0; // LordHavoc: used to turn Host_Error into Sys_Error if Host_Frame has not yet run
double host_frametime;
double host_realframetime; // LordHavoc: the real frametime, before slowmo and clamping are applied (used for console scrolling)
This shuts down both the client and server
================
*/
-char hosterrorstring[1024];
+char hosterrorstring[4096];
+extern qboolean hostloopactive;
void Host_Error (char *error, ...)
{
va_list argptr;
static qboolean inerror = false;
-
+
+ // LordHavoc: if host_frame loop has not been run yet, do a Sys_Error instead
+ if (!hostloopactive)
+ {
+ char string[4096];
+ va_start (argptr,error);
+ vsprintf (string,error,argptr);
+ va_end (argptr);
+ Sys_Error ("%s", string);
+ }
+
if (inerror)
{
- char string[1024];
+ char string[4096];
va_start (argptr,error);
vsprintf (string,error,argptr);
va_end (argptr);
}
host_frametime *= slowmo.value;
+ cl.frametime = host_frametime;
return true;
}
==================
*/
-double frametimetotal = 0, lastservertime = 0;
void Host_ServerFrame (void)
{
+ static double frametimetotal = 0, lastservertime = 0;
frametimetotal += host_frametime;
// LordHavoc: cap server at sys_ticrate in listen games
if (!isDedicated && svs.maxclients > 1 && ((realtime - lastservertime) < sys_ticrate.value))
return;
// run the world state
- sv_frametime = pr_global_struct->frametime = frametimetotal;
+ sv.frametime = pr_global_struct->frametime = frametimetotal;
frametimetotal = 0;
+ lastservertime = realtime;
// pr_global_struct->frametime = host_frametime;
// set the time and clear the general datagram
if (setjmp (host_abortserver) )
return; // something bad happened, or the server disconnected
+ hostloopactive = 1;
// keep the random time dependent
rand ();
// fetch results from server
if (cls.state == ca_connected)
- {
CL_ReadFromServer ();
- }
// update video
if (host_speeds.value)
if (host_speeds.value)
{
- pass1 = (time1 - time3)*1000;
+ pass1 = (time1 - time3)*1000000;
time3 = Sys_FloatTime ();
- pass2 = (time2 - time1)*1000;
- pass3 = (time3 - time2)*1000;
- Con_Printf ("%3i tot %3i server %3i gfx %3i snd\n",
+ pass2 = (time2 - time1)*1000000;
+ pass3 = (time3 - time2)*1000000;
+ Con_Printf ("%6ius total %6ius server %6ius gfx %6ius snd\n",
pass1+pass2+pass3, pass1, pass2, pass3);
}
if (sv_player->v.health <= 0)
{
- SV_ClientPrintf ("Can't suicide -- allready dead!\n");
+ SV_ClientPrintf ("Can't suicide -- already dead!\n");
return;
}
if (host_client->spawned)
{
- Con_Printf ("prespawn not valid -- allready spawned\n");
+ Con_Printf ("prespawn not valid -- already spawned\n");
return;
}
if (host_client->spawned)
{
- Con_Printf ("Spawn not valid -- allready spawned\n");
+ Con_Printf ("Spawn not valid -- already spawned\n");
return;
}
// run the entrance script
if (sv.loadgame)
- { // loaded games are fully inited allready
+ { // loaded games are fully inited already
// if this is the last client to be connected, unpause
sv.paused = false;
void PrintFrameName (model_t *m, int frame)
{
- if (m->type != mod_alias)
- return;
- switch(m->aliastype)
- {
- case ALIASTYPE_MDL:
- {
- maliashdr_t *mheader;
- maliasframe_t *frameinfo;
-
- mheader = (maliashdr_t *)Mod_Extradata (m);
- if (!mheader)
- return;
- if (frame < 0 || frame >= mheader->numframes)
- frame = 0;
- frameinfo = &((maliasframe_t *)(mheader->framedata + (int) mheader))[frame];
-
- Con_Printf ("frame %i: %s\n", frame, frameinfo->name);
- }
- break;
- case ALIASTYPE_MD2:
- {
- md2mem_t *mheader;
- md2memframe_t *frameinfo;
-
- mheader = (md2mem_t *)Mod_Extradata (m);
- if (!mheader)
- return;
- if (frame < 0 || frame >= mheader->num_frames)
- frame = 0;
- frameinfo = (md2memframe_t *)(mheader->ofs_frames + (int) mheader) + frame;
-
- Con_Printf ("frame %i: %s\n", frame, frameinfo->name);
- }
- break;
- case ALIASTYPE_ZYM:
- {
- zymtype1header_t *mheader;
- zymscene_t *scene;
-
- mheader = (zymtype1header_t *)Mod_Extradata (m);
- if (!mheader)
- return;
- if (frame < 0 || frame >= mheader->numscenes)
- frame = 0;
- scene = (zymscene_t *)(mheader->lump_scenes.start + (int) mheader) + frame;
-
- Con_Printf ("frame %i: %s\n", frame, scene->name);
- }
- break;
- default:
- Con_Printf("frame %i: (unknown alias model type)\n", frame);
- break;
- }
+ int data;
+ data = (int) Mod_Extradata(m);
+ if (m->ofs_scenes && data)
+ Con_Printf("frame %i: %s\n", frame, ((animscene_t *) (m->ofs_scenes + data))[frame].name);
+ else
+ Con_Printf("frame %i\n", frame);
}
/*
}
}
-int loadtextureimage (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap)
+rtexture_t *loadtextureimage (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache)
{
- int texnum;
byte *data;
+ rtexture_t *rt;
if (!(data = loadimagepixels (filename, complain, matchwidth, matchheight)))
return 0;
- texnum = GL_LoadTexture (filename, image_width, image_height, data, mipmap, true, 4);
+ rt = R_LoadTexture (filename, image_width, image_height, data, TEXF_ALPHA | TEXF_RGBA | (mipmap ? TEXF_MIPMAP : 0) | (mipmap ? TEXF_PRECACHE : 0));
qfree(data);
- return texnum;
+ return rt;
}
-int loadtextureimagemask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap)
+rtexture_t *loadtextureimagemask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache)
{
- int texnum;
byte *data;
+ rtexture_t *rt;
if (!(data = loadimagepixelsmask (filename, complain, matchwidth, matchheight)))
return 0;
- texnum = GL_LoadTexture (filename, image_width, image_height, data, mipmap, true, 4);
+ rt = R_LoadTexture (filename, image_width, image_height, data, TEXF_ALPHA | TEXF_RGBA | (mipmap ? TEXF_MIPMAP : 0) | (mipmap ? TEXF_PRECACHE : 0));
qfree(data);
- return texnum;
+ return rt;
}
-int image_masktexnum;
-int loadtextureimagewithmask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap)
+rtexture_t *image_masktex;
+rtexture_t *loadtextureimagewithmask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache)
{
- int texnum, count;
+ int count;
byte *data;
char *filename2;
- image_masktexnum = 0;
+ rtexture_t *rt;
+ image_masktex = NULL;
if (!(data = loadimagepixels (filename, complain, matchwidth, matchheight)))
return 0;
- texnum = GL_LoadTexture (filename, image_width, image_height, data, mipmap, true, 4);
+ rt = R_LoadTexture (filename, image_width, image_height, data, TEXF_ALPHA | TEXF_RGBA | (mipmap ? TEXF_MIPMAP : 0) | (mipmap ? TEXF_PRECACHE : 0));
count = image_makemask(data, data, image_width * image_height);
if (count)
{
filename2 = qmalloc(strlen(filename) + 6);
sprintf(filename2, "%s_mask", filename);
- image_masktexnum = GL_LoadTexture (filename2, image_width, image_height, data, mipmap, true, 4);
+ image_masktex = R_LoadTexture (filename2, image_width, image_height, data, TEXF_ALPHA | TEXF_RGBA | (mipmap ? TEXF_MIPMAP : 0) | (mipmap ? TEXF_PRECACHE : 0));
qfree(filename2);
}
qfree(data);
- return texnum;
+ return rt;
}
void Image_WriteTGARGB_preflipped (char *filename, int width, int height, byte *data)
extern void Image_CopyRGBAGamma(byte *in, byte *out, int pixels);
extern int image_makemask (byte *in, byte *out, int size);
extern byte* loadimagepixels (char* filename, qboolean complain, int matchwidth, int matchheight);
-extern int loadtextureimage (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap);
+extern rtexture_t *loadtextureimage (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache);
extern byte* loadimagepixelsmask (char* filename, qboolean complain, int matchwidth, int matchheight);
-extern int loadtextureimagemask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap);
-extern int image_masktexnum;
-extern int loadtextureimagewithmask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap);
+extern rtexture_t *loadtextureimagemask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache);
+extern rtexture_t *image_masktex;
+extern rtexture_t *loadtextureimagewithmask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache);
extern void Image_WriteTGARGB_preflipped (char *filename, int width, int height, byte *data);
extern void Image_WriteTGARGB (char *filename, int width, int height, byte *data);
extern void Image_WriteTGARGBA (char *filename, int width, int height, byte *data);
if ((in_mlook.state & 1)) V_StopPitchDrift();
+ // LordHavoc: changed limits on pitch from -70 to 80, to -90 to 90
if ((in_mlook.state & 1) && !(in_strafe.state & 1)) {
cl.viewangles[PITCH] += m_pitch.value * mouse_y;
- if (cl.viewangles[PITCH] > 80) {
- cl.viewangles[PITCH] = 80;
+ if (cl.viewangles[PITCH] > 90) {
+ cl.viewangles[PITCH] = 90;
}
- if (cl.viewangles[PITCH] < -70) {
- cl.viewangles[PITCH] = -70;
+ if (cl.viewangles[PITCH] < -90) {
+ cl.viewangles[PITCH] = -90;
}
} else {
if ((in_strafe.state & 1) && noclip_anglehack) {
if (in_mlook.state & 1)
V_StopPitchDrift ();
-
+
+ // LordHavoc: changed limits on pitch from -70 to 80, to -90 to 90
if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
{
cl.viewangles[PITCH] += m_pitch.value * mouse_y;
- if (cl.viewangles[PITCH] > 80)
- cl.viewangles[PITCH] = 80;
- if (cl.viewangles[PITCH] < -70)
- cl.viewangles[PITCH] = -70;
+ if (cl.viewangles[PITCH] > 90)
+ cl.viewangles[PITCH] = 90;
+ if (cl.viewangles[PITCH] < -90)
+ cl.viewangles[PITCH] = -90;
}
else
{
speed = cl_movespeedkey.value;
else
speed = 1;
- aspeed = speed * host_frametime;
+ aspeed = speed * host_realframetime;
// loop through the axes
for (i = 0; i < JOY_MAX_AXES; i++)
+
+#uncomment one of these according to your sound driver
+#if you use ALSA version 0.9.x
SND=snd_alsa_0_9.o
-OBJECTS= buildnumber.o cd_linux.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o cpu_noasm.o crc.o cvar.o fractalnoise.o gl_draw.o gl_poly.o gl_refrag.o gl_rmain.o gl_rmisc.o gl_rsurf.o gl_screen.o gl_warp.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o net_vcr.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_part.o r_explosion.o sbar.o snd_dma.o snd_mem.o snd_mix.o $(SND) sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o sys_linux.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o
+#if you use ALSA version 0.5.x
+#SND=snd_alsa_0_5.o
+#if you use the kernel sound driver or OSS
+#SND=snd_oss.o
+
+OBJECTS= buildnumber.o cd_linux.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o gl_poly.o gl_refrag.o gl_rmain.o gl_rmisc.o gl_rsurf.o gl_screen.o gl_warp.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o net_vcr.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_part.o r_explosion.o sbar.o snd_dma.o snd_mem.o snd_mix.o $(SND) sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o sys_linux.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o r_explosion.o r_lerpanim.o cl_effects.o
OPTIMIZATIONS= -O6 -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimizations
#define DEG2RAD( a ) ( a * M_PI ) / 180.0F
+float m_bytenormals[NUMVERTEXNORMALS][3] =
+{
+{-0.525731, 0.000000, 0.850651}, {-0.442863, 0.238856, 0.864188},
+{-0.295242, 0.000000, 0.955423}, {-0.309017, 0.500000, 0.809017},
+{-0.162460, 0.262866, 0.951056}, {0.000000, 0.000000, 1.000000},
+{0.000000, 0.850651, 0.525731}, {-0.147621, 0.716567, 0.681718},
+{0.147621, 0.716567, 0.681718}, {0.000000, 0.525731, 0.850651},
+{0.309017, 0.500000, 0.809017}, {0.525731, 0.000000, 0.850651},
+{0.295242, 0.000000, 0.955423}, {0.442863, 0.238856, 0.864188},
+{0.162460, 0.262866, 0.951056}, {-0.681718, 0.147621, 0.716567},
+{-0.809017, 0.309017, 0.500000}, {-0.587785, 0.425325, 0.688191},
+{-0.850651, 0.525731, 0.000000}, {-0.864188, 0.442863, 0.238856},
+{-0.716567, 0.681718, 0.147621}, {-0.688191, 0.587785, 0.425325},
+{-0.500000, 0.809017, 0.309017}, {-0.238856, 0.864188, 0.442863},
+{-0.425325, 0.688191, 0.587785}, {-0.716567, 0.681718, -0.147621},
+{-0.500000, 0.809017, -0.309017}, {-0.525731, 0.850651, 0.000000},
+{0.000000, 0.850651, -0.525731}, {-0.238856, 0.864188, -0.442863},
+{0.000000, 0.955423, -0.295242}, {-0.262866, 0.951056, -0.162460},
+{0.000000, 1.000000, 0.000000}, {0.000000, 0.955423, 0.295242},
+{-0.262866, 0.951056, 0.162460}, {0.238856, 0.864188, 0.442863},
+{0.262866, 0.951056, 0.162460}, {0.500000, 0.809017, 0.309017},
+{0.238856, 0.864188, -0.442863}, {0.262866, 0.951056, -0.162460},
+{0.500000, 0.809017, -0.309017}, {0.850651, 0.525731, 0.000000},
+{0.716567, 0.681718, 0.147621}, {0.716567, 0.681718, -0.147621},
+{0.525731, 0.850651, 0.000000}, {0.425325, 0.688191, 0.587785},
+{0.864188, 0.442863, 0.238856}, {0.688191, 0.587785, 0.425325},
+{0.809017, 0.309017, 0.500000}, {0.681718, 0.147621, 0.716567},
+{0.587785, 0.425325, 0.688191}, {0.955423, 0.295242, 0.000000},
+{1.000000, 0.000000, 0.000000}, {0.951056, 0.162460, 0.262866},
+{0.850651, -0.525731, 0.000000}, {0.955423, -0.295242, 0.000000},
+{0.864188, -0.442863, 0.238856}, {0.951056, -0.162460, 0.262866},
+{0.809017, -0.309017, 0.500000}, {0.681718, -0.147621, 0.716567},
+{0.850651, 0.000000, 0.525731}, {0.864188, 0.442863, -0.238856},
+{0.809017, 0.309017, -0.500000}, {0.951056, 0.162460, -0.262866},
+{0.525731, 0.000000, -0.850651}, {0.681718, 0.147621, -0.716567},
+{0.681718, -0.147621, -0.716567}, {0.850651, 0.000000, -0.525731},
+{0.809017, -0.309017, -0.500000}, {0.864188, -0.442863, -0.238856},
+{0.951056, -0.162460, -0.262866}, {0.147621, 0.716567, -0.681718},
+{0.309017, 0.500000, -0.809017}, {0.425325, 0.688191, -0.587785},
+{0.442863, 0.238856, -0.864188}, {0.587785, 0.425325, -0.688191},
+{0.688191, 0.587785, -0.425325}, {-0.147621, 0.716567, -0.681718},
+{-0.309017, 0.500000, -0.809017}, {0.000000, 0.525731, -0.850651},
+{-0.525731, 0.000000, -0.850651}, {-0.442863, 0.238856, -0.864188},
+{-0.295242, 0.000000, -0.955423}, {-0.162460, 0.262866, -0.951056},
+{0.000000, 0.000000, -1.000000}, {0.295242, 0.000000, -0.955423},
+{0.162460, 0.262866, -0.951056}, {-0.442863, -0.238856, -0.864188},
+{-0.309017, -0.500000, -0.809017}, {-0.162460, -0.262866, -0.951056},
+{0.000000, -0.850651, -0.525731}, {-0.147621, -0.716567, -0.681718},
+{0.147621, -0.716567, -0.681718}, {0.000000, -0.525731, -0.850651},
+{0.309017, -0.500000, -0.809017}, {0.442863, -0.238856, -0.864188},
+{0.162460, -0.262866, -0.951056}, {0.238856, -0.864188, -0.442863},
+{0.500000, -0.809017, -0.309017}, {0.425325, -0.688191, -0.587785},
+{0.716567, -0.681718, -0.147621}, {0.688191, -0.587785, -0.425325},
+{0.587785, -0.425325, -0.688191}, {0.000000, -0.955423, -0.295242},
+{0.000000, -1.000000, 0.000000}, {0.262866, -0.951056, -0.162460},
+{0.000000, -0.850651, 0.525731}, {0.000000, -0.955423, 0.295242},
+{0.238856, -0.864188, 0.442863}, {0.262866, -0.951056, 0.162460},
+{0.500000, -0.809017, 0.309017}, {0.716567, -0.681718, 0.147621},
+{0.525731, -0.850651, 0.000000}, {-0.238856, -0.864188, -0.442863},
+{-0.500000, -0.809017, -0.309017}, {-0.262866, -0.951056, -0.162460},
+{-0.850651, -0.525731, 0.000000}, {-0.716567, -0.681718, -0.147621},
+{-0.716567, -0.681718, 0.147621}, {-0.525731, -0.850651, 0.000000},
+{-0.500000, -0.809017, 0.309017}, {-0.238856, -0.864188, 0.442863},
+{-0.262866, -0.951056, 0.162460}, {-0.864188, -0.442863, 0.238856},
+{-0.809017, -0.309017, 0.500000}, {-0.688191, -0.587785, 0.425325},
+{-0.681718, -0.147621, 0.716567}, {-0.442863, -0.238856, 0.864188},
+{-0.587785, -0.425325, 0.688191}, {-0.309017, -0.500000, 0.809017},
+{-0.147621, -0.716567, 0.681718}, {-0.425325, -0.688191, 0.587785},
+{-0.162460, -0.262866, 0.951056}, {0.442863, -0.238856, 0.864188},
+{0.162460, -0.262866, 0.951056}, {0.309017, -0.500000, 0.809017},
+{0.147621, -0.716567, 0.681718}, {0.000000, -0.525731, 0.850651},
+{0.425325, -0.688191, 0.587785}, {0.587785, -0.425325, 0.688191},
+{0.688191, -0.587785, 0.425325}, {-0.955423, 0.295242, 0.000000},
+{-0.951056, 0.162460, 0.262866}, {-1.000000, 0.000000, 0.000000},
+{-0.850651, 0.000000, 0.525731}, {-0.955423, -0.295242, 0.000000},
+{-0.951056, -0.162460, 0.262866}, {-0.864188, 0.442863, -0.238856},
+{-0.951056, 0.162460, -0.262866}, {-0.809017, 0.309017, -0.500000},
+{-0.864188, -0.442863, -0.238856}, {-0.951056, -0.162460, -0.262866},
+{-0.809017, -0.309017, -0.500000}, {-0.681718, 0.147621, -0.716567},
+{-0.681718, -0.147621, -0.716567}, {-0.850651, 0.000000, -0.525731},
+{-0.688191, 0.587785, -0.425325}, {-0.587785, 0.425325, -0.688191},
+{-0.425325, 0.688191, -0.587785}, {-0.425325, -0.688191, -0.587785},
+{-0.587785, -0.425325, -0.688191}, {-0.688191, -0.587785, -0.425325},
+};
+
+byte NormalToByte(vec3_t n)
+{
+ int i, best;
+ float bestdistance, distance;
+
+ best = 0;
+ bestdistance = DotProduct (n, m_bytenormals[0]);
+ for (i = 1;i < NUMVERTEXNORMALS;i++)
+ {
+ distance = DotProduct (n, m_bytenormals[i]);
+ if (distance > bestdistance)
+ {
+ bestdistance = distance;
+ best = i;
+ }
+ }
+ return best;
+}
+
+// note: uses byte partly to force unsigned for the validity check
+void ByteToNormal(byte num, vec3_t n)
+{
+ if (num < NUMVERTEXNORMALS)
+ VectorCopy(m_bytenormals[num], n)
+ else
+ VectorClear(n) // FIXME: complain?
+}
+
+#if 0
+// LordHavoc: no longer used at all
void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
{
+#if 0
+ // LordHavoc: the old way...
float d;
vec3_t n;
float inv_denom;
dst[0] = p[0] - d * n[0];
dst[1] = p[1] - d * n[1];
dst[2] = p[2] - d * n[2];
+#else
+ // LordHavoc: optimized to death and beyond
+ float d;
+
+ // LordHavoc: the normal is a unit vector by definition,
+ // therefore inv_denom was pointless.
+ d = DotProduct(normal, p);
+ dst[0] = p[0] - d * normal[0];
+ dst[1] = p[1] - d * normal[1];
+ dst[2] = p[2] - d * normal[2];
+#endif
}
+#endif
-/*
-** assumes "src" is normalized
-*/
+// assumes "src" is normalized
void PerpendicularVector( vec3_t dst, const vec3_t src )
{
+#if 0
+ // LordHavoc: the old way...
int pos;
int i;
- float minelem = 1.0F;
+ float minelem, d;
vec3_t tempvec;
- /*
- ** find the smallest magnitude axially aligned vector
- */
+ // find the smallest magnitude axially aligned vector
+ minelem = 1.0F;
for ( pos = 0, i = 0; i < 3; i++ )
{
if ( fabs( src[i] ) < minelem )
minelem = fabs( src[i] );
}
}
- tempvec[0] = tempvec[1] = tempvec[2] = 0.0F;
+ VectorClear(tempvec);
tempvec[pos] = 1.0F;
- /*
- ** project the point onto the plane defined by src
- */
+ // project the point onto the plane defined by src
ProjectPointOnPlane( dst, tempvec, src );
- /*
- ** normalize the result
- */
- VectorNormalize( dst );
+ // normalize the result
+ VectorNormalize(dst);
+#else
+ // LordHavoc: optimized to death and beyond
+ int pos;
+ float minelem;
+
+ if (src[0])
+ {
+ dst[0] = 0;
+ if (src[1])
+ {
+ dst[1] = 0;
+ if (src[2])
+ {
+ dst[2] = 0;
+ pos = 0;
+ minelem = fabs(src[0]);
+ if (fabs(src[1]) < minelem)
+ {
+ pos = 1;
+ minelem = fabs(src[1]);
+ }
+ if (fabs(src[2]) < minelem)
+ &nb