mirror of
https://github.com/nzp-team/fteqw.git
synced 2025-01-19 06:51:11 +00:00
Moved entity and poly handling code to a common location. This means sprites work in D3D. Fixed .alpha on mdls. Slightly better q2 compat.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3779 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
0ffb6c11e2
commit
f7aece9d48
20 changed files with 684 additions and 869 deletions
|
@ -1887,6 +1887,8 @@ void CL_LinkPacketEntities (void)
|
|||
ent->flags |= Q2RF_ADDITIVE;
|
||||
if (state->effects & EF_NODEPTHTEST)
|
||||
ent->flags |= RF_NODEPTHTEST;
|
||||
if (state->trans != 0xff)
|
||||
ent->flags |= Q2RF_TRANSLUCENT;
|
||||
|
||||
/*FIXME: pay attention to tags instead, so nexuiz can work with splitscreen*/
|
||||
if (ent->flags & Q2RF_EXTERNALMODEL)
|
||||
|
@ -2812,10 +2814,12 @@ void CL_LinkPlayers (void)
|
|||
#ifdef PEXT_SCALE
|
||||
ent->scale = state->scale;
|
||||
#endif
|
||||
ent->shaderRGBAf[0] = state->colourmod[0]/32;
|
||||
ent->shaderRGBAf[1] = state->colourmod[1]/32;
|
||||
ent->shaderRGBAf[2] = state->colourmod[2]/32;
|
||||
ent->shaderRGBAf[3] = state->alpha/255;
|
||||
ent->shaderRGBAf[0] = state->colourmod[0]/32.0f;
|
||||
ent->shaderRGBAf[1] = state->colourmod[1]/32.0f;
|
||||
ent->shaderRGBAf[2] = state->colourmod[2]/32.0f;
|
||||
ent->shaderRGBAf[3] = state->alpha/255.0f;
|
||||
if (state->alpha != 255)
|
||||
ent->flags |= Q2RF_TRANSLUCENT;
|
||||
|
||||
ent->fatness = state->fatness/16;
|
||||
//
|
||||
|
|
|
@ -1890,6 +1890,7 @@ void CL_SmokeAndFlash(vec3_t origin)
|
|||
// ex->type = ex_misc;
|
||||
ex->numframes = 4;
|
||||
ex->flags = Q2RF_TRANSLUCENT;
|
||||
ex->alpha = 1;
|
||||
ex->start = cl.time;
|
||||
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_smoke].modelname, false);
|
||||
|
||||
|
@ -2060,7 +2061,8 @@ void CLQ2_ParseTEnt (void)
|
|||
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explode].modelname, false);
|
||||
ex->firstframe = 0;
|
||||
ex->numframes = 4;
|
||||
ex->flags = Q2RF_FULLBRIGHT|Q2RF_ADDITIVE|RF_NOSHADOW;
|
||||
ex->flags = Q2RF_FULLBRIGHT|Q2RF_ADDITIVE|RF_NOSHADOW|Q2RF_TRANSLUCENT;
|
||||
ex->alpha = 1;
|
||||
|
||||
ex->angles[0] = acos(dir[2])/M_PI*180;
|
||||
// PMM - fixed to correct for pitch of 0
|
||||
|
@ -2137,8 +2139,8 @@ void CLQ2_ParseTEnt (void)
|
|||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/grenlx1a.wav"), pos, 1, 1, 0);
|
||||
|
||||
// sprite
|
||||
/*
|
||||
if (!R_ParticleExplosionHeart(pos))
|
||||
|
||||
// if (!R_ParticleExplosionHeart(pos))
|
||||
{
|
||||
ex = CL_AllocExplosion ();
|
||||
VectorCopy (pos, ex->origin);
|
||||
|
@ -2146,9 +2148,10 @@ void CLQ2_ParseTEnt (void)
|
|||
ex->start = cl.time;
|
||||
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explo4].modelname, true);
|
||||
ex->firstframe = 30;
|
||||
ex->alpha = 1;
|
||||
ex->flags |= Q2RF_TRANSLUCENT;
|
||||
ex->numframes = 19;
|
||||
}
|
||||
*/
|
||||
break;
|
||||
/*
|
||||
ex = CL_AllocExplosion ();
|
||||
|
@ -2232,19 +2235,21 @@ void CLQ2_ParseTEnt (void)
|
|||
S_StartSound (-2, 0, S_PrecacheSound ("weapons/rocklx1a.wav"), pos, 1, 1, 0);
|
||||
|
||||
// sprite
|
||||
/* if (!R_ParticleExplosionHeart(pos))
|
||||
// if (!R_ParticleExplosionHeart(pos))
|
||||
{
|
||||
ex = CL_AllocExplosion ();
|
||||
VectorCopy (pos, ex->origin);
|
||||
VectorClear(ex->angles);
|
||||
ex->start = cl.time;
|
||||
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_explo4].modelname, false);
|
||||
ex->alpha = 1;
|
||||
ex->flags |= Q2RF_TRANSLUCENT;
|
||||
if (rand()&1)
|
||||
ex->firstframe = 15;
|
||||
else
|
||||
ex->firstframe = 0;
|
||||
ex->numframes = 15;
|
||||
}*/
|
||||
}
|
||||
break;
|
||||
/*
|
||||
ex = CL_AllocExplosion ();
|
||||
|
@ -3011,11 +3016,23 @@ void CL_UpdateExplosions (void)
|
|||
ent->framestate.g[FS_REG].frame[1] = (int)f+firstframe;
|
||||
ent->framestate.g[FS_REG].frame[0] = of+firstframe;
|
||||
ent->framestate.g[FS_REG].lerpfrac = (f - (int)f);
|
||||
if (ent->model->type == mod_sprite)
|
||||
if (ent->model && ent->model->type == mod_sprite)
|
||||
ent->shaderRGBAf[3] = ex->alpha; /*sprites don't fade over time, the animation should do it*/
|
||||
else
|
||||
ent->shaderRGBAf[3] = (1.0 - f/(numframes))*ex->alpha;
|
||||
ent->flags = ex->flags;
|
||||
|
||||
if (ex->flags & Q2RF_BEAM)
|
||||
{
|
||||
ent->rtype = RT_BEAM;
|
||||
ent->shaderRGBAf[0] = ((d_8to24rgbtable[ex->skinnum & 0xFF] >> 0) & 0xFF)/255.0;
|
||||
ent->shaderRGBAf[1] = ((d_8to24rgbtable[ex->skinnum & 0xFF] >> 8) & 0xFF)/255.0;
|
||||
ent->shaderRGBAf[2] = ((d_8to24rgbtable[ex->skinnum & 0xFF] >> 16) & 0xFF)/255.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->skinnum = 7*f/(numframes);
|
||||
}
|
||||
}
|
||||
|
||||
explosions_running = lastrunningexplosion + 1;
|
||||
|
|
|
@ -406,6 +406,7 @@ void VQ3_AddEntity(const q3refEntity_t *q3)
|
|||
ent.shaderRGBAf[2] = q3->shaderRGBA[2]/255.0f;
|
||||
ent.shaderRGBAf[3] = q3->shaderRGBA[3]/255.0f;
|
||||
|
||||
/*don't set translucent, the shader is meant to already be correct*/
|
||||
// if (ent.shaderRGBAf[3] <= 0)
|
||||
// return;
|
||||
|
||||
|
|
|
@ -1307,7 +1307,7 @@ int CLHL_ParseGamePacket(void)
|
|||
ef->firstframe = 0;
|
||||
ef->numframes = ef->model->numframes;
|
||||
if (!(flags & 1))
|
||||
ef->flags = Q2RF_ADDATIVE;
|
||||
ef->flags = Q2RF_ADDITIVE;
|
||||
else
|
||||
ef->flags = 0;
|
||||
break;
|
||||
|
|
|
@ -1351,6 +1351,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
effects = s1->effects;
|
||||
renderfx = s1->renderfx;
|
||||
|
||||
ent.rtype = RT_MODEL;
|
||||
ent.keynum = s1->number;
|
||||
|
||||
ent.scale = 1;
|
||||
|
@ -1427,10 +1428,14 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
// tweak the color of beams
|
||||
if ( renderfx & Q2RF_BEAM )
|
||||
{ // the four beam colors are encoded in 32 bits of skinnum (hack)
|
||||
ent.shaderRGBAf[3] = 0.30;
|
||||
ent.skinnum = (s1->skinnum >> ((rand() % 4)*8)) & 0xff;
|
||||
ent.shaderRGBAf[0] = ((d_8to24rgbtable[ent.skinnum & 0xFF] >> 0) & 0xFF)/255.0;
|
||||
ent.shaderRGBAf[1] = ((d_8to24rgbtable[ent.skinnum & 0xFF] >> 8) & 0xFF)/255.0;
|
||||
ent.shaderRGBAf[2] = ((d_8to24rgbtable[ent.skinnum & 0xFF] >> 16) & 0xFF)/255.0;
|
||||
ent.shaderRGBAf[3] = 0.30;
|
||||
ent.model = NULL;
|
||||
ent.framestate.g[FS_REG].lerpfrac = 1;
|
||||
ent.rtype = RT_BEAM;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1629,14 +1634,12 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
}
|
||||
}
|
||||
// pmm
|
||||
ent.flags = renderfx | Q2RF_TRANSLUCENT;
|
||||
ent.flags = renderfx;
|
||||
ent.shaderRGBAf[3] = 0.30;
|
||||
ent.fatness = 1;
|
||||
ent.shaderRGBAf[0] = (!!(renderfx & Q2RF_SHELL_RED));
|
||||
ent.shaderRGBAf[1] = (!!(renderfx & Q2RF_SHELL_GREEN));
|
||||
ent.shaderRGBAf[2] = (!!(renderfx & Q2RF_SHELL_BLUE));
|
||||
ent.forcedshader = R_RegisterCustom("q2/shell", Shader_DefaultSkinShell, NULL);
|
||||
|
||||
VQ2_AddLerpEntity (&ent);
|
||||
}
|
||||
ent.forcedshader = NULL;
|
||||
|
|
|
@ -606,12 +606,12 @@ static model_t *CSQC_GetModelForIndex(int index)
|
|||
|
||||
static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
|
||||
{
|
||||
int i;
|
||||
int i, ival;
|
||||
model_t *model;
|
||||
unsigned int rflags;
|
||||
|
||||
i = in->v->modelindex;
|
||||
model = CSQC_GetModelForIndex(in->v->modelindex);
|
||||
ival = in->v->modelindex;
|
||||
model = CSQC_GetModelForIndex(ival);
|
||||
if (!model)
|
||||
return false; //there might be other ent types later as an extension that stop this.
|
||||
|
||||
|
@ -668,23 +668,31 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
|
|||
}
|
||||
}
|
||||
|
||||
if (in->v->colormap > 0 && in->v->colormap <= MAX_CLIENTS)
|
||||
ival = in->v->colormap;
|
||||
if (ival > 0 && ival <= MAX_CLIENTS)
|
||||
{
|
||||
out->scoreboard = &cl.players[(int)in->v->colormap-1];
|
||||
} // TODO: DP COLORMAP extension?
|
||||
out->scoreboard = &cl.players[ival-1];
|
||||
}
|
||||
// TODO: DP COLORMAP extension?
|
||||
|
||||
out->shaderRGBAf[0] = 1;
|
||||
out->shaderRGBAf[1] = 1;
|
||||
out->shaderRGBAf[2] = 1;
|
||||
if (!in->xv->alpha)
|
||||
out->shaderRGBAf[3] = 1;
|
||||
if (!in->xv->alpha || in->xv->alpha == 1)
|
||||
{
|
||||
out->shaderRGBAf[3] = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
out->flags |= Q2RF_TRANSLUCENT;
|
||||
out->shaderRGBAf[3] = in->xv->alpha;
|
||||
}
|
||||
|
||||
out->skinnum = in->v->skin;
|
||||
out->fatness = in->xv->fatness;
|
||||
if (in->xv->forceshader >= 1)
|
||||
out->forcedshader = r_shaders + ((int)in->xv->forceshader-1);
|
||||
ival = in->xv->forceshader;
|
||||
if (ival >= 1 && ival <= MAX_SHADERS)
|
||||
out->forcedshader = r_shaders + (ival-1);
|
||||
else
|
||||
out->forcedshader = NULL;
|
||||
|
||||
|
|
|
@ -253,7 +253,10 @@ void R2D_Init(void)
|
|||
|
||||
mpic_t *R2D_SafeCachePic (char *path)
|
||||
{
|
||||
shader_t *s = R_RegisterPic(path);
|
||||
shader_t *s;
|
||||
if (!qrenderer)
|
||||
return NULL;
|
||||
s = R_RegisterPic(path);
|
||||
if (s->width)
|
||||
return s;
|
||||
return NULL;
|
||||
|
|
|
@ -1933,7 +1933,7 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
|
|||
bef |= BEF_FORCETRANSPARENT;
|
||||
ent->shaderRGBAf[3] = r_wateralpha.value;
|
||||
}
|
||||
else if (ent->shaderRGBAf[3] < 1 && cls.protocol != CP_QUAKE3)
|
||||
else if (ent->flags & Q2RF_TRANSLUCENT && cls.protocol != CP_QUAKE3)
|
||||
bef |= BEF_FORCETRANSPARENT;
|
||||
if (ent->flags & RF_NODEPTHTEST)
|
||||
bef |= BEF_FORCENODEPTH;
|
||||
|
|
|
@ -169,6 +169,8 @@ extern struct texture_s *r_notexture_mip;
|
|||
|
||||
extern entity_t r_worldentity;
|
||||
|
||||
void BE_GenModelBatches(struct batch_s **batches);
|
||||
|
||||
//gl_alias.c
|
||||
void R_GAlias_DrawBatch(struct batch_s *batch);
|
||||
void R_GAlias_GenerateBatches(entity_t *e, struct batch_s **batches);
|
||||
|
|
|
@ -673,38 +673,59 @@ void Sbar_ShowScores (void)
|
|||
|
||||
void Sbar_Hexen2InvLeft_f(void)
|
||||
{
|
||||
int tries = 15;
|
||||
int pnum = CL_TargettedSplit(false);
|
||||
sb_hexen2_item_time[pnum] = realtime;
|
||||
while (tries-- > 0)
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
sb_hexen2_cur_item[pnum]--;
|
||||
if (sb_hexen2_cur_item[pnum] < 0)
|
||||
sb_hexen2_cur_item[pnum] = 14;
|
||||
CL_SendClientCommand(true, "invprev");
|
||||
}
|
||||
else
|
||||
{
|
||||
int tries = 15;
|
||||
int pnum = CL_TargettedSplit(false);
|
||||
sb_hexen2_item_time[pnum] = realtime;
|
||||
while (tries-- > 0)
|
||||
{
|
||||
sb_hexen2_cur_item[pnum]--;
|
||||
if (sb_hexen2_cur_item[pnum] < 0)
|
||||
sb_hexen2_cur_item[pnum] = 14;
|
||||
|
||||
if (cl.stats[pnum][STAT_H2_CNT_TORCH+sb_hexen2_cur_item[pnum]] > 0)
|
||||
break;
|
||||
if (cl.stats[pnum][STAT_H2_CNT_TORCH+sb_hexen2_cur_item[pnum]] > 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Sbar_Hexen2InvRight_f(void)
|
||||
{
|
||||
int tries = 15;
|
||||
int pnum = CL_TargettedSplit(false);
|
||||
sb_hexen2_item_time[pnum] = realtime;
|
||||
while (tries-- > 0)
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
sb_hexen2_cur_item[pnum]++;
|
||||
if (sb_hexen2_cur_item[pnum] > 14)
|
||||
sb_hexen2_cur_item[pnum] = 0;
|
||||
CL_SendClientCommand(true, "invnext");
|
||||
}
|
||||
else
|
||||
{
|
||||
int tries = 15;
|
||||
int pnum = CL_TargettedSplit(false);
|
||||
sb_hexen2_item_time[pnum] = realtime;
|
||||
while (tries-- > 0)
|
||||
{
|
||||
sb_hexen2_cur_item[pnum]++;
|
||||
if (sb_hexen2_cur_item[pnum] > 14)
|
||||
sb_hexen2_cur_item[pnum] = 0;
|
||||
|
||||
if (cl.stats[pnum][STAT_H2_CNT_TORCH+sb_hexen2_cur_item[pnum]] > 0)
|
||||
break;
|
||||
if (cl.stats[pnum][STAT_H2_CNT_TORCH+sb_hexen2_cur_item[pnum]] > 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Sbar_Hexen2InvUse_f(void)
|
||||
{
|
||||
int pnum = CL_TargettedSplit(false);
|
||||
Cmd_ExecuteString(va("impulse %d\n", 100+sb_hexen2_cur_item[pnum]), Cmd_ExecLevel);
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
CL_SendClientCommand(true, "invuse");
|
||||
}
|
||||
else
|
||||
{
|
||||
int pnum = CL_TargettedSplit(false);
|
||||
Cmd_ExecuteString(va("impulse %d\n", 100+sb_hexen2_cur_item[pnum]), Cmd_ExecLevel);
|
||||
}
|
||||
}
|
||||
void Sbar_Hexen2ShowInfo_f(void)
|
||||
{
|
||||
|
@ -938,6 +959,8 @@ void Sbar_Init (void)
|
|||
//stuff to get hexen2 working out-of-the-box
|
||||
Cmd_AddCommand ("invleft", Sbar_Hexen2InvLeft_f);
|
||||
Cmd_AddCommand ("invright", Sbar_Hexen2InvRight_f);
|
||||
Cmd_AddCommand ("invprev", Sbar_Hexen2InvLeft_f);
|
||||
Cmd_AddCommand ("invnext", Sbar_Hexen2InvRight_f);
|
||||
Cmd_AddCommand ("invuse", Sbar_Hexen2InvUse_f);
|
||||
Cmd_AddCommand ("+showinfo", Sbar_Hexen2ShowInfo_f);
|
||||
Cmd_AddCommand ("-showinfo", Sbar_Hexen2DontShowInfo_f);
|
||||
|
|
|
@ -123,6 +123,8 @@ typedef struct
|
|||
int curvertdecl;
|
||||
unsigned int shaderbits;
|
||||
unsigned int curcull;
|
||||
float depthbias;
|
||||
float depthfactor;
|
||||
unsigned int lastpasscount;
|
||||
|
||||
texid_t curtex[MAX_TMUS];
|
||||
|
@ -338,14 +340,17 @@ static void D3DBE_ApplyShaderBits(unsigned int bits)
|
|||
{
|
||||
unsigned int delta;
|
||||
|
||||
if (shaderstate.flags & ~BEF_PUSHDEPTH)
|
||||
if (shaderstate.flags & (BEF_FORCEADDITIVE|BEF_FORCETRANSPARENT|BEF_FORCENODEPTH|BEF_FORCEDEPTHTEST|BEF_FORCEDEPTHWRITE))
|
||||
{
|
||||
if (shaderstate.flags & BEF_FORCEADDITIVE)
|
||||
bits = (bits & ~(SBITS_MISC_DEPTHWRITE|SBITS_BLEND_BITS|SBITS_ATEST_BITS))
|
||||
| (SBITS_SRCBLEND_ONE | SBITS_DSTBLEND_ONE);
|
||||
else if ((shaderstate.flags & BEF_FORCETRANSPARENT) && !(bits & SBITS_BLEND_BITS)) /*if transparency is forced, clear alpha test bits*/
|
||||
bits = (bits & ~(SBITS_MISC_DEPTHWRITE|SBITS_BLEND_BITS|SBITS_ATEST_BITS))
|
||||
| (SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
|
||||
| (SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE);
|
||||
else if (shaderstate.flags & BEF_FORCETRANSPARENT)
|
||||
{
|
||||
if ((bits & SBITS_BLEND_BITS) == (SBITS_SRCBLEND_ONE|SBITS_DSTBLEND_ZERO) || !(bits & SBITS_BLEND_BITS)) /*if transparency is forced, clear alpha test bits*/
|
||||
bits = (bits & ~(SBITS_MISC_DEPTHWRITE|SBITS_BLEND_BITS|SBITS_ATEST_BITS))
|
||||
| (SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
if (shaderstate.flags & BEF_FORCENODEPTH) /*EF_NODEPTHTEST dp extension*/
|
||||
bits |= SBITS_MISC_NODEPTHTEST;
|
||||
|
@ -1549,8 +1554,24 @@ static void BE_DrawMeshChain_Internal(void)
|
|||
unsigned int mno;
|
||||
unsigned int passno = 0;
|
||||
shaderpass_t *pass = shaderstate.curshader->passes;
|
||||
extern cvar_t r_polygonoffset_submodel_offset, r_polygonoffset_submodel_factor;
|
||||
float pushdepth;
|
||||
// float pushfactor;
|
||||
|
||||
BE_Cull(shaderstate.curshader->flags & (SHADER_CULL_FRONT | SHADER_CULL_BACK));
|
||||
pushdepth = (shaderstate.curshader->polyoffset.factor + ((shaderstate.flags & BEF_PUSHDEPTH)?r_polygonoffset_submodel_offset.value:0))/0xffff;
|
||||
if (pushdepth != shaderstate.depthbias)
|
||||
{
|
||||
shaderstate.depthbias = pushdepth;
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DEPTHBIAS, *(DWORD*)&shaderstate.depthbias);
|
||||
}
|
||||
// pushdepth = shaderstate.curshader->polyoffset.unit/-1;// + ((shaderstate.flags & BEF_PUSHDEPTH)?8:0);
|
||||
// pushfactor = shaderstate.curshader->polyoffset.factor/-1;
|
||||
// if (pushfactor != shaderstate.depthfactor)
|
||||
// {
|
||||
// shaderstate.depthfactor = pushfactor;
|
||||
// IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&shaderstate.depthfactor);
|
||||
// }
|
||||
|
||||
for (mno = 0, vertcount = 0, idxcount = 0; mno < shaderstate.nummeshes; mno++)
|
||||
{
|
||||
|
@ -1995,18 +2016,19 @@ void D3DBE_SubmitBatch(batch_t *batch)
|
|||
BE_DrawMeshChain_Internal();
|
||||
}
|
||||
|
||||
void D3DBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo_t *vbo, texnums_t *texnums)
|
||||
void D3DBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo_t *vbo, texnums_t *texnums, unsigned int beflags)
|
||||
{
|
||||
shaderstate.curshader = shader;
|
||||
shaderstate.curtexnums = texnums;
|
||||
shaderstate.curlightmap = r_nulltex;
|
||||
shaderstate.meshlist = meshlist;
|
||||
shaderstate.nummeshes = nummeshes;
|
||||
shaderstate.flags = beflags;
|
||||
|
||||
BE_DrawMeshChain_Internal();
|
||||
}
|
||||
|
||||
void D3DBE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texnums_t *texnums)
|
||||
void D3DBE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texnums_t *texnums, unsigned int beflags)
|
||||
{
|
||||
shaderstate.curtime = realtime;
|
||||
shaderstate.curshader = shader;
|
||||
|
@ -2014,209 +2036,11 @@ void D3DBE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texn
|
|||
shaderstate.curlightmap = r_nulltex;
|
||||
shaderstate.meshlist = &meshchain;
|
||||
shaderstate.nummeshes = 1;
|
||||
shaderstate.flags = beflags;
|
||||
|
||||
BE_DrawMeshChain_Internal();
|
||||
}
|
||||
|
||||
qboolean BE_ShouldDraw(entity_t *e)
|
||||
{
|
||||
if (!r_refdef.externalview && (e->externalmodelview & (1<<r_refdef.currentplayernum)))
|
||||
return false;
|
||||
if (!Cam_DrawPlayer(r_refdef.currentplayernum, e->keynum-1))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef Q3CLIENT
|
||||
|
||||
//q3 lightning gun
|
||||
static void R_DrawLightning(entity_t *e)
|
||||
{
|
||||
vec3_t v;
|
||||
vec3_t dir, cr;
|
||||
float scale = e->scale;
|
||||
float length;
|
||||
|
||||
vecV_t points[4];
|
||||
vec2_t texcoords[4] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
|
||||
static index_t indexarray[6] = {0, 1, 2, 0, 2, 3};
|
||||
|
||||
mesh_t mesh;
|
||||
|
||||
if (!e->forcedshader)
|
||||
return;
|
||||
|
||||
if (!scale)
|
||||
scale = 10;
|
||||
|
||||
|
||||
VectorSubtract(e->origin, e->oldorigin, dir);
|
||||
length = Length(dir);
|
||||
|
||||
//this seems to be about right.
|
||||
texcoords[2][0] = length/128;
|
||||
texcoords[3][0] = length/128;
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->origin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(e->origin, -scale/2, cr, points[0]);
|
||||
VectorMA(e->origin, scale/2, cr, points[1]);
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->oldorigin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(e->oldorigin, scale/2, cr, points[2]);
|
||||
VectorMA(e->oldorigin, -scale/2, cr, points[3]);
|
||||
|
||||
memset(&mesh, 0, sizeof(mesh));
|
||||
mesh.vbofirstelement = 0;
|
||||
mesh.vbofirstvert = 0;
|
||||
mesh.xyz_array = points;
|
||||
mesh.indexes = indexarray;
|
||||
mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]);
|
||||
mesh.colors4f_array = NULL;
|
||||
mesh.lmst_array = NULL;
|
||||
mesh.normals_array = NULL;
|
||||
mesh.numvertexes = 4;
|
||||
mesh.st_array = texcoords;
|
||||
BE_DrawMesh_Single(e->forcedshader, &mesh, NULL, NULL, 0);
|
||||
}
|
||||
//q3 railgun beam
|
||||
static void R_DrawRailCore(entity_t *e)
|
||||
{
|
||||
vec3_t v;
|
||||
vec3_t dir, cr;
|
||||
float scale = e->scale;
|
||||
float length;
|
||||
|
||||
mesh_t mesh;
|
||||
vecV_t points[4];
|
||||
vec2_t texcoords[4] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
|
||||
static index_t indexarray[6] = {0, 1, 2, 0, 2, 3};
|
||||
vec4_t colors[4];
|
||||
|
||||
if (!e->forcedshader)
|
||||
return;
|
||||
|
||||
if (!scale)
|
||||
scale = 10;
|
||||
|
||||
|
||||
VectorSubtract(e->origin, e->oldorigin, dir);
|
||||
length = Length(dir);
|
||||
|
||||
//this seems to be about right.
|
||||
texcoords[2][0] = length/128;
|
||||
texcoords[3][0] = length/128;
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->origin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(e->origin, -scale/2, cr, points[0]);
|
||||
VectorMA(e->origin, scale/2, cr, points[1]);
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->oldorigin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(e->oldorigin, scale/2, cr, points[2]);
|
||||
VectorMA(e->oldorigin, -scale/2, cr, points[3]);
|
||||
|
||||
Vector4Copy(e->shaderRGBAf, colors[0]);
|
||||
Vector4Copy(e->shaderRGBAf, colors[1]);
|
||||
Vector4Copy(e->shaderRGBAf, colors[2]);
|
||||
Vector4Copy(e->shaderRGBAf, colors[3]);
|
||||
|
||||
memset(&mesh, 0, sizeof(mesh));
|
||||
mesh.vbofirstelement = 0;
|
||||
mesh.vbofirstvert = 0;
|
||||
mesh.xyz_array = points;
|
||||
mesh.indexes = indexarray;
|
||||
mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]);
|
||||
mesh.colors4f_array = (vec4_t*)colors;
|
||||
mesh.lmst_array = NULL;
|
||||
mesh.normals_array = NULL;
|
||||
mesh.numvertexes = 4;
|
||||
mesh.st_array = texcoords;
|
||||
|
||||
BE_DrawMesh_Single(e->forcedshader, &mesh, NULL, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
static void BE_GenModelBatches(batch_t **batches)
|
||||
{
|
||||
int i;
|
||||
entity_t *ent;
|
||||
|
||||
/*clear the batch list*/
|
||||
for (i = 0; i < SHADER_SORT_COUNT; i++)
|
||||
batches[i] = NULL;
|
||||
|
||||
if (!r_drawentities.ival)
|
||||
return;
|
||||
|
||||
// draw sprites seperately, because of alpha blending
|
||||
for (i=0 ; i<cl_numvisedicts ; i++)
|
||||
{
|
||||
ent = &cl_visedicts[i];
|
||||
|
||||
if (!BE_ShouldDraw(ent))
|
||||
continue;
|
||||
|
||||
switch(ent->rtype)
|
||||
{
|
||||
case RT_MODEL:
|
||||
default:
|
||||
if (!ent->model)
|
||||
continue;
|
||||
if (ent->model->needload)
|
||||
continue;
|
||||
switch(ent->model->type)
|
||||
{
|
||||
case mod_brush:
|
||||
if (r_drawentities.ival == 2)
|
||||
continue;
|
||||
Surf_GenBrushBatches(batches, ent);
|
||||
break;
|
||||
case mod_alias:
|
||||
if (r_drawentities.ival == 3)
|
||||
continue;
|
||||
R_GAlias_GenerateBatches(ent, batches);
|
||||
break;
|
||||
case mod_sprite:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RT_SPRITE:
|
||||
//RQ_AddDistReorder(GLR_DrawSprite, currententity, NULL, currententity->origin);
|
||||
break;
|
||||
|
||||
#ifdef Q3CLIENT
|
||||
case RT_BEAM:
|
||||
case RT_RAIL_RINGS:
|
||||
case RT_LIGHTNING:
|
||||
R_DrawLightning(ent);
|
||||
continue;
|
||||
case RT_RAIL_CORE:
|
||||
R_DrawRailCore(ent);
|
||||
continue;
|
||||
#endif
|
||||
|
||||
case RT_POLY:
|
||||
/*not implemented*/
|
||||
break;
|
||||
case RT_PORTALSURFACE:
|
||||
/*nothing*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void BE_SubmitMeshesSortList(batch_t *sortlist)
|
||||
{
|
||||
batch_t *batch;
|
||||
|
|
|
@ -991,6 +991,12 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches)
|
|||
b->lightmap = -1;
|
||||
b->surf_first = surfnum;
|
||||
b->flags = 0;
|
||||
if (e->flags & Q2RF_ADDITIVE)
|
||||
b->flags |= BEF_FORCEADDITIVE;
|
||||
if (e->flags & Q2RF_TRANSLUCENT)
|
||||
b->flags |= BEF_FORCETRANSPARENT;
|
||||
if (e->flags & RF_NODEPTHTEST)
|
||||
b->flags |= BEF_FORCENODEPTH;
|
||||
b->vbo = 0;
|
||||
b->next = batches[shader->sort];
|
||||
batches[shader->sort] = b;
|
||||
|
@ -1433,3 +1439,487 @@ void GL_GenerateNormals(float *orgs, float *normals, int *indicies, int numtris,
|
|||
#endif
|
||||
|
||||
#endif // defined(GLQUAKE)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
qboolean BE_ShouldDraw(entity_t *e)
|
||||
{
|
||||
if (!r_refdef.externalview && (e->externalmodelview & (1<<r_refdef.currentplayernum)))
|
||||
return false;
|
||||
if (!Cam_DrawPlayer(r_refdef.currentplayernum, e->keynum-1))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef Q3CLIENT
|
||||
//q3 lightning gun
|
||||
static void R_DB_LightningBeam(batch_t *batch)
|
||||
{
|
||||
entity_t *e = batch->ent;
|
||||
vec3_t v;
|
||||
vec3_t dir, cr;
|
||||
float scale = e->scale;
|
||||
float length;
|
||||
|
||||
static vecV_t points[4];
|
||||
static vec2_t texcoords[4] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
|
||||
static index_t indexarray[6] = {0, 1, 2, 0, 2, 3};
|
||||
static vec4_t colors[4];
|
||||
|
||||
static mesh_t mesh;
|
||||
static mesh_t *meshptr = &mesh;
|
||||
|
||||
scale *= -10;
|
||||
if (!scale)
|
||||
scale = 10;
|
||||
|
||||
|
||||
VectorSubtract(e->origin, e->oldorigin, dir);
|
||||
length = Length(dir);
|
||||
|
||||
//this seems to be about right.
|
||||
texcoords[2][0] = length/128;
|
||||
texcoords[3][0] = length/128;
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->origin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(e->origin, -scale/2, cr, points[0]);
|
||||
VectorMA(e->origin, scale/2, cr, points[1]);
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->oldorigin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(e->oldorigin, scale/2, cr, points[2]);
|
||||
VectorMA(e->oldorigin, -scale/2, cr, points[3]);
|
||||
|
||||
/*this is actually meant to be 4 separate quads at 45 degrees from each other*/
|
||||
|
||||
Vector4Copy(e->shaderRGBAf, colors[0]);
|
||||
Vector4Copy(e->shaderRGBAf, colors[1]);
|
||||
Vector4Copy(e->shaderRGBAf, colors[2]);
|
||||
Vector4Copy(e->shaderRGBAf, colors[3]);
|
||||
|
||||
batch->ent = &r_worldentity;
|
||||
batch->mesh = &meshptr;
|
||||
|
||||
memset(&mesh, 0, sizeof(mesh));
|
||||
mesh.vbofirstelement = 0;
|
||||
mesh.vbofirstvert = 0;
|
||||
mesh.xyz_array = points;
|
||||
mesh.indexes = indexarray;
|
||||
mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]);
|
||||
mesh.colors4f_array = (vec4_t*)colors;
|
||||
mesh.lmst_array = NULL;
|
||||
mesh.normals_array = NULL;
|
||||
mesh.numvertexes = 4;
|
||||
mesh.st_array = texcoords;
|
||||
}
|
||||
//q3 railgun beam
|
||||
static void R_DB_RailgunBeam(batch_t *batch)
|
||||
{
|
||||
entity_t *e = batch->ent;
|
||||
vec3_t v;
|
||||
vec3_t dir, cr;
|
||||
float scale = e->scale;
|
||||
float length;
|
||||
|
||||
static mesh_t mesh;
|
||||
static mesh_t *meshptr = &mesh;
|
||||
static vecV_t points[4];
|
||||
static vec2_t texcoords[4] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
|
||||
static index_t indexarray[6] = {0, 1, 2, 0, 2, 3};
|
||||
static vec4_t colors[4];
|
||||
|
||||
if (!e->forcedshader)
|
||||
return;
|
||||
|
||||
if (!scale)
|
||||
scale = 10;
|
||||
|
||||
|
||||
VectorSubtract(e->origin, e->oldorigin, dir);
|
||||
length = Length(dir);
|
||||
|
||||
//this seems to be about right.
|
||||
texcoords[2][0] = length/128;
|
||||
texcoords[3][0] = length/128;
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->origin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(e->origin, -scale/2, cr, points[0]);
|
||||
VectorMA(e->origin, scale/2, cr, points[1]);
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->oldorigin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(e->oldorigin, scale/2, cr, points[2]);
|
||||
VectorMA(e->oldorigin, -scale/2, cr, points[3]);
|
||||
|
||||
Vector4Copy(e->shaderRGBAf, colors[0]);
|
||||
Vector4Copy(e->shaderRGBAf, colors[1]);
|
||||
Vector4Copy(e->shaderRGBAf, colors[2]);
|
||||
Vector4Copy(e->shaderRGBAf, colors[3]);
|
||||
|
||||
batch->ent = &r_worldentity;
|
||||
batch->mesh = &meshptr;
|
||||
|
||||
memset(&mesh, 0, sizeof(mesh));
|
||||
mesh.vbofirstelement = 0;
|
||||
mesh.vbofirstvert = 0;
|
||||
mesh.xyz_array = points;
|
||||
mesh.indexes = indexarray;
|
||||
mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]);
|
||||
mesh.colors4f_array = (vec4_t*)colors;
|
||||
mesh.lmst_array = NULL;
|
||||
mesh.normals_array = NULL;
|
||||
mesh.numvertexes = 4;
|
||||
mesh.st_array = texcoords;
|
||||
|
||||
}
|
||||
#endif
|
||||
static void R_DB_Sprite(batch_t *batch)
|
||||
{
|
||||
entity_t *e = batch->ent;
|
||||
vec3_t point;
|
||||
mspriteframe_t *frame, genframe;
|
||||
vec3_t forward, right, up;
|
||||
msprite_t *psprite;
|
||||
vec3_t sprorigin;
|
||||
unsigned int fl = 0;
|
||||
unsigned int sprtype;
|
||||
|
||||
static vec2_t texcoords[4]={{0, 1},{0,0},{1,0},{1,1}};
|
||||
static index_t indexes[6] = {0, 1, 2, 0, 2, 3};
|
||||
static vecV_t vertcoords[4];
|
||||
static avec4_t colours[4];
|
||||
static mesh_t mesh;
|
||||
static mesh_t *meshptr = &mesh;
|
||||
|
||||
|
||||
if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum >= 0)
|
||||
{
|
||||
sprorigin[0] = cl.viewent[r_refdef.currentplayernum].origin[0];
|
||||
sprorigin[1] = cl.viewent[r_refdef.currentplayernum].origin[1];
|
||||
sprorigin[2] = cl.viewent[r_refdef.currentplayernum].origin[2];
|
||||
VectorMA(sprorigin, e->origin[0], cl.viewent[r_refdef.currentplayernum].axis[0], sprorigin);
|
||||
VectorMA(sprorigin, e->origin[1], cl.viewent[r_refdef.currentplayernum].axis[1], sprorigin);
|
||||
VectorMA(sprorigin, e->origin[2], cl.viewent[r_refdef.currentplayernum].axis[2], sprorigin);
|
||||
VectorMA(sprorigin, 12, vpn, sprorigin);
|
||||
|
||||
batch->flags |= BEF_FORCENODEPTH;
|
||||
}
|
||||
else
|
||||
VectorCopy(e->origin, sprorigin);
|
||||
|
||||
if (!e->model || e->forcedshader)
|
||||
{
|
||||
genframe.shader = e->forcedshader;
|
||||
genframe.up = genframe.left = -1;
|
||||
genframe.down = genframe.right = 1;
|
||||
sprtype = SPR_VP_PARALLEL;
|
||||
frame = &genframe;
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't even bother culling, because it's just a single
|
||||
// polygon without a surface cache
|
||||
frame = R_GetSpriteFrame (e);
|
||||
psprite = e->model->cache.data;
|
||||
sprtype = psprite->type;
|
||||
}
|
||||
if (!frame->shader)
|
||||
return;
|
||||
|
||||
switch(sprtype)
|
||||
{
|
||||
case SPR_ORIENTED:
|
||||
// bullet marks on walls
|
||||
AngleVectors (e->angles, forward, right, up);
|
||||
break;
|
||||
|
||||
case SPR_FACING_UPRIGHT:
|
||||
up[0] = 0;up[1] = 0;up[2]=1;
|
||||
right[0] = sprorigin[1] - r_origin[1];
|
||||
right[1] = -(sprorigin[0] - r_origin[0]);
|
||||
right[2] = 0;
|
||||
VectorNormalize (right);
|
||||
break;
|
||||
case SPR_VP_PARALLEL_UPRIGHT:
|
||||
up[0] = 0;up[1] = 0;up[2]=1;
|
||||
VectorCopy (vright, right);
|
||||
break;
|
||||
|
||||
default:
|
||||
case SPR_VP_PARALLEL:
|
||||
//normal sprite
|
||||
VectorCopy(vup, up);
|
||||
VectorCopy(vright, right);
|
||||
break;
|
||||
}
|
||||
up[0]*=e->scale;
|
||||
up[1]*=e->scale;
|
||||
up[2]*=e->scale;
|
||||
right[0]*=e->scale;
|
||||
right[1]*=e->scale;
|
||||
right[2]*=e->scale;
|
||||
|
||||
if (e->shaderRGBAf[0] > 1)
|
||||
e->shaderRGBAf[0] = 1;
|
||||
if (e->shaderRGBAf[1] > 1)
|
||||
e->shaderRGBAf[1] = 1;
|
||||
if (e->shaderRGBAf[2] > 1)
|
||||
e->shaderRGBAf[2] = 1;
|
||||
|
||||
Vector4Copy(e->shaderRGBAf, colours[0]);
|
||||
Vector4Copy(e->shaderRGBAf, colours[1]);
|
||||
Vector4Copy(e->shaderRGBAf, colours[2]);
|
||||
Vector4Copy(e->shaderRGBAf, colours[3]);
|
||||
|
||||
VectorMA (sprorigin, frame->down, up, point);
|
||||
VectorMA (point, frame->left, right, vertcoords[0]);
|
||||
|
||||
VectorMA (sprorigin, frame->up, up, point);
|
||||
VectorMA (point, frame->left, right, vertcoords[1]);
|
||||
|
||||
VectorMA (sprorigin, frame->up, up, point);
|
||||
VectorMA (point, frame->right, right, vertcoords[2]);
|
||||
|
||||
VectorMA (sprorigin, frame->down, up, point);
|
||||
VectorMA (point, frame->right, right, vertcoords[3]);
|
||||
|
||||
batch->ent = &r_worldentity;
|
||||
batch->flags |= fl;
|
||||
batch->mesh = &meshptr;
|
||||
|
||||
memset(&mesh, 0, sizeof(mesh));
|
||||
mesh.vbofirstelement = 0;
|
||||
mesh.vbofirstvert = 0;
|
||||
mesh.xyz_array = vertcoords;
|
||||
mesh.indexes = indexes;
|
||||
mesh.numindexes = sizeof(indexes)/sizeof(indexes[0]);
|
||||
mesh.colors4f_array = colours;
|
||||
mesh.lmst_array = NULL;
|
||||
mesh.normals_array = NULL;
|
||||
mesh.numvertexes = 4;
|
||||
mesh.st_array = texcoords;
|
||||
mesh.istrifan = true;
|
||||
}
|
||||
static void R_Sprite_GenerateBatch(entity_t *e, batch_t **batches, void (*drawfunc)(batch_t *batch))
|
||||
{
|
||||
extern cvar_t gl_blendsprites;
|
||||
shader_t *shader = NULL;
|
||||
batch_t *b;
|
||||
shadersort_t sort;
|
||||
|
||||
if (!e->model || e->model->type != mod_sprite || e->forcedshader)
|
||||
{
|
||||
shader = e->forcedshader;
|
||||
if (!shader)
|
||||
shader = R_RegisterShader("q2beam",
|
||||
"{\n"
|
||||
"{\n"
|
||||
"map $whiteimage\n"
|
||||
"rgbgen vertex\n"
|
||||
"alphagen vertex\n"
|
||||
"blendfunc blend\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't even bother culling, because it's just a single
|
||||
// polygon without a surface cache
|
||||
shader = R_GetSpriteFrame(e)->shader;
|
||||
}
|
||||
|
||||
if (!shader)
|
||||
return;
|
||||
|
||||
b = BE_GetTempBatch();
|
||||
if (!b)
|
||||
return;
|
||||
|
||||
b->flags = 0;
|
||||
sort = shader->sort;
|
||||
if (e->flags & Q2RF_ADDITIVE)
|
||||
{
|
||||
b->flags |= BEF_FORCEADDITIVE;
|
||||
if (sort < SHADER_SORT_ADDITIVE)
|
||||
sort = SHADER_SORT_ADDITIVE;
|
||||
}
|
||||
if (e->flags & Q2RF_TRANSLUCENT || (gl_blendsprites.ival && drawfunc == R_DB_Sprite))
|
||||
{
|
||||
b->flags |= BEF_FORCETRANSPARENT;
|
||||
if (sort < SHADER_SORT_BLEND)
|
||||
sort = SHADER_SORT_BLEND;
|
||||
}
|
||||
if (e->flags & RF_NODEPTHTEST)
|
||||
{
|
||||
b->flags |= BEF_FORCENODEPTH;
|
||||
if (sort < SHADER_SORT_BANNER)
|
||||
sort = SHADER_SORT_BANNER;
|
||||
}
|
||||
|
||||
b->buildmeshes = drawfunc;
|
||||
b->ent = e;
|
||||
b->mesh = NULL;
|
||||
b->firstmesh = 0;
|
||||
b->meshes = 1;
|
||||
b->skin = &shader->defaulttextures;
|
||||
b->texture = NULL;
|
||||
b->shader = shader;
|
||||
b->lightmap = -1;
|
||||
b->surf_first = 0;
|
||||
b->flags |= BEF_NODLIGHT|BEF_NOSHADOWS;
|
||||
b->vbo = 0;
|
||||
b->next = batches[sort];
|
||||
batches[sort] = b;
|
||||
}
|
||||
|
||||
static void R_DB_Poly(batch_t *batch)
|
||||
{
|
||||
static mesh_t mesh;
|
||||
static mesh_t *meshptr = &mesh;
|
||||
unsigned int i = batch->surf_first;
|
||||
|
||||
batch->mesh = &meshptr;
|
||||
|
||||
mesh.xyz_array = cl_strisvertv + cl_stris[i].firstvert;
|
||||
mesh.st_array = cl_strisvertt + cl_stris[i].firstvert;
|
||||
mesh.colors4f_array = cl_strisvertc + cl_stris[i].firstvert;
|
||||
mesh.indexes = cl_strisidx + cl_stris[i].firstidx;
|
||||
mesh.numindexes = cl_stris[i].numidx;
|
||||
mesh.numvertexes = cl_stris[i].numvert;
|
||||
}
|
||||
void BE_GenPolyBatches(batch_t **batches)
|
||||
{
|
||||
shader_t *shader = NULL;
|
||||
batch_t *b;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < cl_numstris; i++)
|
||||
{
|
||||
b = BE_GetTempBatch();
|
||||
if (!b)
|
||||
return;
|
||||
|
||||
shader = cl_stris[i].shader;
|
||||
|
||||
b->buildmeshes = R_DB_Poly;
|
||||
b->ent = &r_worldentity;
|
||||
b->mesh = NULL;
|
||||
b->firstmesh = 0;
|
||||
b->meshes = 1;
|
||||
b->skin = &shader->defaulttextures;
|
||||
b->texture = NULL;
|
||||
b->shader = shader;
|
||||
b->lightmap = -1;
|
||||
b->surf_first = i;
|
||||
b->flags = BEF_NODLIGHT|BEF_NOSHADOWS;
|
||||
b->vbo = 0;
|
||||
b->next = batches[shader->sort];
|
||||
batches[shader->sort] = b;
|
||||
}
|
||||
}
|
||||
|
||||
void BE_GenModelBatches(batch_t **batches)
|
||||
{
|
||||
int i;
|
||||
entity_t *ent;
|
||||
|
||||
/*clear the batch list*/
|
||||
for (i = 0; i < SHADER_SORT_COUNT; i++)
|
||||
batches[i] = NULL;
|
||||
|
||||
if (!r_drawentities.ival)
|
||||
return;
|
||||
|
||||
// draw sprites seperately, because of alpha blending
|
||||
for (i=0 ; i<cl_numvisedicts ; i++)
|
||||
{
|
||||
ent = &cl_visedicts[i];
|
||||
|
||||
if (!BE_ShouldDraw(ent))
|
||||
continue;
|
||||
|
||||
switch(ent->rtype)
|
||||
{
|
||||
case RT_MODEL:
|
||||
default:
|
||||
if (!ent->model)
|
||||
continue;
|
||||
if (ent->model->needload)
|
||||
continue;
|
||||
|
||||
if (cl.lerpents && (cls.allow_anyparticles || ent->visframe)) //allowed or static
|
||||
{
|
||||
if (gl_part_flame.value)
|
||||
{
|
||||
if (ent->model->engineflags & MDLF_ENGULPHS)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ent->model->engineflags & MDLF_NOTREPLACEMENTS)
|
||||
{
|
||||
if (ent->model->fromgame != fg_quake || ent->model->type != mod_alias)
|
||||
if (!ruleset_allow_sensative_texture_replacements.value)
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(ent->model->type)
|
||||
{
|
||||
case mod_brush:
|
||||
if (r_drawentities.ival == 2)
|
||||
continue;
|
||||
Surf_GenBrushBatches(batches, ent);
|
||||
break;
|
||||
case mod_alias:
|
||||
if (r_drawentities.ival == 3)
|
||||
continue;
|
||||
R_GAlias_GenerateBatches(ent, batches);
|
||||
break;
|
||||
case mod_sprite:
|
||||
R_Sprite_GenerateBatch(ent, batches, R_DB_Sprite);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RT_SPRITE:
|
||||
R_Sprite_GenerateBatch(ent, batches, R_DB_Sprite);
|
||||
break;
|
||||
|
||||
#ifdef Q3CLIENT
|
||||
case RT_BEAM:
|
||||
case RT_RAIL_RINGS:
|
||||
case RT_LIGHTNING:
|
||||
R_Sprite_GenerateBatch(ent, batches, R_DB_LightningBeam);
|
||||
continue;
|
||||
case RT_RAIL_CORE:
|
||||
R_Sprite_GenerateBatch(ent, batches, R_DB_RailgunBeam);
|
||||
continue;
|
||||
#endif
|
||||
|
||||
case RT_POLY:
|
||||
/*not implemented*/
|
||||
break;
|
||||
case RT_PORTALSURFACE:
|
||||
/*nothing*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cl_numstris)
|
||||
BE_GenPolyBatches(batches);
|
||||
}
|
|
@ -395,12 +395,9 @@ struct {
|
|||
texid_t lighttexture;
|
||||
};
|
||||
|
||||
int wmesh;
|
||||
int maxwmesh;
|
||||
int wbatch;
|
||||
int maxwbatches;
|
||||
batch_t *wbatches;
|
||||
mesh_t **wmeshes;
|
||||
} shaderstate;
|
||||
|
||||
struct {
|
||||
|
@ -1943,14 +1940,17 @@ static void BE_SendPassBlendDepthMask(unsigned int sbits)
|
|||
sbits &= ~(SBITS_MISC_DEPTHWRITE|SBITS_MISC_DEPTHEQUALONLY);
|
||||
sbits |= SBITS_MISC_NODEPTHTEST;
|
||||
}
|
||||
if (shaderstate.flags & ~BEF_PUSHDEPTH)
|
||||
if (shaderstate.flags & (BEF_FORCEADDITIVE|BEF_FORCETRANSPARENT|BEF_FORCENODEPTH|BEF_FORCEDEPTHTEST|BEF_FORCEDEPTHWRITE))
|
||||
{
|
||||
if (shaderstate.flags & BEF_FORCEADDITIVE)
|
||||
sbits = (sbits & ~(SBITS_MISC_DEPTHWRITE|SBITS_BLEND_BITS|SBITS_ATEST_BITS))
|
||||
| (SBITS_SRCBLEND_ONE | SBITS_DSTBLEND_ONE);
|
||||
else if ((shaderstate.flags & BEF_FORCETRANSPARENT) && !(sbits & SBITS_BLEND_BITS)) /*if transparency is forced, clear alpha test bits*/
|
||||
sbits = (sbits & ~(SBITS_MISC_DEPTHWRITE|SBITS_BLEND_BITS|SBITS_ATEST_BITS))
|
||||
| (SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
|
||||
| (SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE);
|
||||
else if (shaderstate.flags & BEF_FORCETRANSPARENT)
|
||||
{
|
||||
if ((sbits & SBITS_BLEND_BITS) == (SBITS_SRCBLEND_ONE| SBITS_DSTBLEND_ZERO) || !(sbits & SBITS_BLEND_BITS)) /*if transparency is forced, clear alpha test bits*/
|
||||
sbits = (sbits & ~(SBITS_MISC_DEPTHWRITE|SBITS_BLEND_BITS|SBITS_ATEST_BITS))
|
||||
| (SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
if (shaderstate.flags & BEF_FORCENODEPTH) /*EF_NODEPTHTEST dp extension*/
|
||||
sbits |= SBITS_MISC_NODEPTHTEST;
|
||||
|
@ -2568,6 +2568,7 @@ void GLBE_SelectMode(backendmode_t mode)
|
|||
if (mode != shaderstate.mode)
|
||||
{
|
||||
shaderstate.mode = mode;
|
||||
shaderstate.flags = 0;
|
||||
#ifdef RTLIGHTS
|
||||
if (mode == BEM_STENCIL)
|
||||
{
|
||||
|
@ -2957,29 +2958,6 @@ void GLBE_DrawMesh_Single(shader_t *shader, mesh_t *mesh, vbo_t *vbo, texnums_t
|
|||
BE_DrawMesh_List(shader, 1, &mesh, NULL, texnums, beflags);
|
||||
}
|
||||
|
||||
void BE_DrawPolys(qboolean decalsset)
|
||||
{
|
||||
unsigned int i;
|
||||
mesh_t m;
|
||||
|
||||
if (!cl_numstris)
|
||||
return;
|
||||
|
||||
memset(&m, 0, sizeof(m));
|
||||
for (i = 0; i < cl_numstris; i++)
|
||||
{
|
||||
if ((cl_stris[i].shader->sort <= SHADER_SORT_DECAL) ^ decalsset)
|
||||
continue;
|
||||
|
||||
m.xyz_array = cl_strisvertv + cl_stris[i].firstvert;
|
||||
m.st_array = cl_strisvertt + cl_stris[i].firstvert;
|
||||
m.colors4f_array = cl_strisvertc + cl_stris[i].firstvert;
|
||||
m.indexes = cl_strisidx + cl_stris[i].firstidx;
|
||||
m.numindexes = cl_stris[i].numidx;
|
||||
m.numvertexes = cl_stris[i].numvert;
|
||||
BE_DrawMesh_Single(cl_stris[i].shader, &m, NULL, &cl_stris[i].shader->defaulttextures, 0);
|
||||
}
|
||||
}
|
||||
void GLBE_SubmitBatch(batch_t *batch)
|
||||
{
|
||||
int lm;
|
||||
|
@ -3102,6 +3080,13 @@ static void BE_SubmitMeshesSortList(batch_t *sortlist)
|
|||
if (batch->meshes == batch->firstmesh)
|
||||
continue;
|
||||
|
||||
if (batch->flags & BEF_NODLIGHT)
|
||||
if (shaderstate.mode == BEM_LIGHT || shaderstate.mode == BEM_SMAPLIGHT)
|
||||
continue;
|
||||
if (batch->flags & BEF_NOSHADOWS)
|
||||
if (shaderstate.mode == BEM_STENCIL)
|
||||
continue;
|
||||
|
||||
if (batch->buildmeshes)
|
||||
batch->buildmeshes(batch);
|
||||
else if (batch->texture)
|
||||
|
@ -3216,46 +3201,6 @@ batch_t *GLBE_GetTempBatch(void)
|
|||
return &shaderstate.wbatches[shaderstate.wbatch++];
|
||||
}
|
||||
|
||||
void BE_GenModelBatches(batch_t **batches)
|
||||
{
|
||||
int i;
|
||||
entity_t *ent;
|
||||
|
||||
/*clear the batch list*/
|
||||
for (i = 0; i < SHADER_SORT_COUNT; i++)
|
||||
batches[i] = NULL;
|
||||
|
||||
if (!r_drawentities.ival)
|
||||
return;
|
||||
|
||||
// draw sprites seperately, because of alpha blending
|
||||
for (i=0 ; i<cl_numvisedicts ; i++)
|
||||
{
|
||||
ent = &cl_visedicts[i];
|
||||
if (!ent->model)
|
||||
continue;
|
||||
if (ent->model->needload)
|
||||
continue;
|
||||
if (!R_ShouldDraw(ent))
|
||||
continue;
|
||||
switch(ent->model->type)
|
||||
{
|
||||
case mod_brush:
|
||||
if (r_drawentities.ival == 2)
|
||||
continue;
|
||||
Surf_GenBrushBatches(batches, ent);
|
||||
break;
|
||||
case mod_alias:
|
||||
if (r_drawentities.ival == 3)
|
||||
continue;
|
||||
R_GAlias_GenerateBatches(ent, batches);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*called from shadowmapping code*/
|
||||
#ifdef RTLIGHTS
|
||||
void BE_BaseEntTextures(void)
|
||||
|
@ -3279,13 +3224,6 @@ void GLBE_DrawWorld (qbyte *vis)
|
|||
|
||||
if (!r_refdef.recurse)
|
||||
{
|
||||
if (shaderstate.wmesh > shaderstate.maxwmesh)
|
||||
{
|
||||
int newm = shaderstate.wmesh;
|
||||
shaderstate.wmeshes = BZ_Realloc(shaderstate.wmeshes, newm * sizeof(*shaderstate.wmeshes));
|
||||
memset(shaderstate.wmeshes + shaderstate.maxwmesh, 0, (newm - shaderstate.maxwmesh) * sizeof(*shaderstate.wmeshes));
|
||||
shaderstate.maxwmesh = newm;
|
||||
}
|
||||
if (shaderstate.wbatch > shaderstate.maxwbatches)
|
||||
{
|
||||
int newm = shaderstate.wbatch;
|
||||
|
@ -3294,7 +3232,6 @@ void GLBE_DrawWorld (qbyte *vis)
|
|||
shaderstate.maxwbatches = newm;
|
||||
}
|
||||
|
||||
shaderstate.wmesh = 0;
|
||||
shaderstate.wbatch = 0;
|
||||
}
|
||||
BE_GenModelBatches(batches);
|
||||
|
@ -3341,8 +3278,6 @@ void GLBE_DrawWorld (qbyte *vis)
|
|||
RSpeedEnd(RSPEED_STENCILSHADOWS);
|
||||
#endif
|
||||
|
||||
BE_DrawPolys(false);
|
||||
|
||||
if (r_refdef.gfog_alpha)
|
||||
{
|
||||
BE_SelectMode(BEM_FOG);
|
||||
|
@ -3362,13 +3297,6 @@ void BE_DrawNonWorld (void)
|
|||
|
||||
checkglerror();
|
||||
|
||||
if (shaderstate.wmesh > shaderstate.maxwmesh)
|
||||
{
|
||||
int newm = shaderstate.wmesh;
|
||||
shaderstate.wmeshes = BZ_Realloc(shaderstate.wmeshes, newm * sizeof(*shaderstate.wmeshes));
|
||||
memset(shaderstate.wmeshes + shaderstate.maxwmesh, 0, (newm - shaderstate.maxwmesh) * sizeof(*shaderstate.wmeshes));
|
||||
shaderstate.maxwmesh = newm;
|
||||
}
|
||||
if (shaderstate.wbatch > shaderstate.maxwbatches)
|
||||
{
|
||||
int newm = shaderstate.wbatch;
|
||||
|
@ -3377,7 +3305,6 @@ void BE_DrawNonWorld (void)
|
|||
shaderstate.maxwbatches = newm;
|
||||
}
|
||||
|
||||
shaderstate.wmesh = 0;
|
||||
shaderstate.wbatch = 0;
|
||||
BE_GenModelBatches(batches);
|
||||
|
||||
|
|
|
@ -3513,8 +3513,8 @@ qboolean RMod_LoadSprite2Model (model_t *mod, void *buffer)
|
|||
origin[0] = LittleLong (pframetype->origin_x);
|
||||
origin[1] = LittleLong (pframetype->origin_y);
|
||||
|
||||
frame->up = -origin[1];
|
||||
frame->down = h - origin[1];
|
||||
frame->down = -origin[1];
|
||||
frame->up = h - origin[1];
|
||||
frame->left = -origin[0];
|
||||
frame->right = w - origin[0];
|
||||
|
||||
|
|
|
@ -460,476 +460,8 @@ void R_RotateForEntity (float *modelview, const entity_t *e, const model_t *mod)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
SPRITE MODELS
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_DrawSpriteModel
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_DrawSpriteModel (entity_t *e)
|
||||
{
|
||||
vec3_t point;
|
||||
mspriteframe_t *frame, genframe;
|
||||
vec3_t forward, right, up;
|
||||
msprite_t *psprite;
|
||||
vec3_t sprorigin;
|
||||
unsigned int fl;
|
||||
unsigned int sprtype;
|
||||
|
||||
static vec2_t texcoords[4]={{0, 1},{0,0},{1,0},{1,1}};
|
||||
static index_t indexes[6] = {0, 1, 2, 0, 2, 3};
|
||||
vecV_t vertcoords[4];
|
||||
avec4_t colours[4];
|
||||
mesh_t mesh;
|
||||
|
||||
|
||||
if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum >= 0)
|
||||
{
|
||||
sprorigin[0] = cl.viewent[r_refdef.currentplayernum].origin[0];
|
||||
sprorigin[1] = cl.viewent[r_refdef.currentplayernum].origin[1];
|
||||
sprorigin[2] = cl.viewent[r_refdef.currentplayernum].origin[2];
|
||||
VectorMA(sprorigin, e->origin[0], cl.viewent[r_refdef.currentplayernum].axis[0], sprorigin);
|
||||
VectorMA(sprorigin, e->origin[1], cl.viewent[r_refdef.currentplayernum].axis[1], sprorigin);
|
||||
VectorMA(sprorigin, e->origin[2], cl.viewent[r_refdef.currentplayernum].axis[2], sprorigin);
|
||||
VectorMA(sprorigin, 12, vpn, sprorigin);
|
||||
|
||||
e->flags |= RF_NODEPTHTEST;
|
||||
}
|
||||
else
|
||||
VectorCopy(e->origin, sprorigin);
|
||||
|
||||
if (!e->model || e->forcedshader)
|
||||
{
|
||||
genframe.shader = e->forcedshader;
|
||||
genframe.up = genframe.left = -1;
|
||||
genframe.down = genframe.right = 1;
|
||||
sprtype = SPR_VP_PARALLEL;
|
||||
frame = &genframe;
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't even bother culling, because it's just a single
|
||||
// polygon without a surface cache
|
||||
frame = R_GetSpriteFrame (e);
|
||||
psprite = e->model->cache.data;
|
||||
sprtype = psprite->type;
|
||||
}
|
||||
if (!frame->shader)
|
||||
return;
|
||||
|
||||
switch(sprtype)
|
||||
{
|
||||
case SPR_ORIENTED:
|
||||
// bullet marks on walls
|
||||
AngleVectors (e->angles, forward, right, up);
|
||||
break;
|
||||
|
||||
case SPR_FACING_UPRIGHT:
|
||||
up[0] = 0;up[1] = 0;up[2]=1;
|
||||
right[0] = sprorigin[1] - r_origin[1];
|
||||
right[1] = -(sprorigin[0] - r_origin[0]);
|
||||
right[2] = 0;
|
||||
VectorNormalize (right);
|
||||
break;
|
||||
case SPR_VP_PARALLEL_UPRIGHT:
|
||||
up[0] = 0;up[1] = 0;up[2]=1;
|
||||
VectorCopy (vright, right);
|
||||
break;
|
||||
|
||||
default:
|
||||
case SPR_VP_PARALLEL:
|
||||
//normal sprite
|
||||
VectorCopy(vup, up);
|
||||
VectorCopy(vright, right);
|
||||
break;
|
||||
}
|
||||
up[0]*=e->scale;
|
||||
up[1]*=e->scale;
|
||||
up[2]*=e->scale;
|
||||
right[0]*=e->scale;
|
||||
right[1]*=e->scale;
|
||||
right[2]*=e->scale;
|
||||
|
||||
|
||||
Vector4Copy(e->shaderRGBAf, colours[0]);
|
||||
Vector4Copy(e->shaderRGBAf, colours[1]);
|
||||
Vector4Copy(e->shaderRGBAf, colours[2]);
|
||||
Vector4Copy(e->shaderRGBAf, colours[3]);
|
||||
|
||||
fl = 0;
|
||||
if (e->flags & Q2RF_ADDITIVE)
|
||||
fl |= BEF_FORCEADDITIVE;
|
||||
if (e->shaderRGBAf[3]<1 || gl_blendsprites.value)
|
||||
fl |= BEF_FORCETRANSPARENT;
|
||||
if (e->flags & RF_NODEPTHTEST)
|
||||
fl |= BEF_FORCENODEPTH;
|
||||
|
||||
VectorMA (sprorigin, frame->down, up, point);
|
||||
VectorMA (point, frame->left, right, vertcoords[0]);
|
||||
|
||||
VectorMA (sprorigin, frame->up, up, point);
|
||||
VectorMA (point, frame->left, right, vertcoords[1]);
|
||||
|
||||
VectorMA (sprorigin, frame->up, up, point);
|
||||
VectorMA (point, frame->right, right, vertcoords[2]);
|
||||
|
||||
VectorMA (sprorigin, frame->down, up, point);
|
||||
VectorMA (point, frame->right, right, vertcoords[3]);
|
||||
|
||||
|
||||
memset(&mesh, 0, sizeof(mesh));
|
||||
mesh.vbofirstelement = 0;
|
||||
mesh.vbofirstvert = 0;
|
||||
mesh.xyz_array = vertcoords;
|
||||
mesh.indexes = indexes;
|
||||
mesh.numindexes = sizeof(indexes)/sizeof(indexes[0]);
|
||||
mesh.colors4f_array = colours;
|
||||
mesh.lmst_array = NULL;
|
||||
mesh.normals_array = NULL;
|
||||
mesh.numvertexes = 4;
|
||||
mesh.st_array = texcoords;
|
||||
mesh.istrifan = true;
|
||||
BE_DrawMesh_Single(frame->shader, &mesh, NULL, &frame->shader->defaulttextures, fl);
|
||||
}
|
||||
|
||||
//==================================================================================
|
||||
|
||||
void GLR_DrawSprite(int count, void **e, void *parm)
|
||||
{
|
||||
while(count--)
|
||||
{
|
||||
#pragma message("this needs merging or q3 railgun will lag like hell")
|
||||
currententity = e[count];
|
||||
|
||||
R_DrawSpriteModel (currententity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef Q3CLIENT
|
||||
|
||||
//q3 lightning gun
|
||||
void R_DrawLightning(entity_t *e)
|
||||
{
|
||||
vec3_t v;
|
||||
vec3_t dir, cr;
|
||||
float scale = e->scale;
|
||||
float length;
|
||||
|
||||
vecV_t points[4];
|
||||
vec2_t texcoords[4] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
|
||||
static index_t indexarray[6] = {0, 1, 2, 0, 2, 3};
|
||||
|
||||
mesh_t mesh;
|
||||
|
||||
if (!e->forcedshader)
|
||||
return;
|
||||
|
||||
if (!scale)
|
||||
scale = 10;
|
||||
|
||||
|
||||
VectorSubtract(e->origin, e->oldorigin, dir);
|
||||
length = Length(dir);
|
||||
|
||||
//this seems to be about right.
|
||||
texcoords[2][0] = length/128;
|
||||
texcoords[3][0] = length/128;
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->origin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(e->origin, -scale/2, cr, points[0]);
|
||||
VectorMA(e->origin, scale/2, cr, points[1]);
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->oldorigin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(e->oldorigin, scale/2, cr, points[2]);
|
||||
VectorMA(e->oldorigin, -scale/2, cr, points[3]);
|
||||
|
||||
memset(&mesh, 0, sizeof(mesh));
|
||||
mesh.vbofirstelement = 0;
|
||||
mesh.vbofirstvert = 0;
|
||||
mesh.xyz_array = points;
|
||||
mesh.indexes = indexarray;
|
||||
mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]);
|
||||
mesh.colors4f_array = NULL;
|
||||
mesh.lmst_array = NULL;
|
||||
mesh.normals_array = NULL;
|
||||
mesh.numvertexes = 4;
|
||||
mesh.st_array = texcoords;
|
||||
BE_DrawMesh_Single(e->forcedshader, &mesh, NULL, NULL, 0);
|
||||
}
|
||||
//q3 railgun beam
|
||||
void R_DrawRailCore(entity_t *e)
|
||||
{
|
||||
vec3_t v;
|
||||
vec3_t dir, cr;
|
||||
float scale = e->scale;
|
||||
float length;
|
||||
|
||||
mesh_t mesh;
|
||||
vecV_t points[4];
|
||||
vec2_t texcoords[4] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
|
||||
static index_t indexarray[6] = {0, 1, 2, 0, 2, 3};
|
||||
vec4_t colors[4];
|
||||
|
||||
if (!e->forcedshader)
|
||||
return;
|
||||
|
||||
if (!scale)
|
||||
scale = 10;
|
||||
|
||||
|
||||
VectorSubtract(e->origin, e->oldorigin, dir);
|
||||
length = Length(dir);
|
||||
|
||||
//this seems to be about right.
|
||||
texcoords[2][0] = length/128;
|
||||
texcoords[3][0] = length/128;
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->origin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(e->origin, -scale/2, cr, points[0]);
|
||||
VectorMA(e->origin, scale/2, cr, points[1]);
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->oldorigin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(e->oldorigin, scale/2, cr, points[2]);
|
||||
VectorMA(e->oldorigin, -scale/2, cr, points[3]);
|
||||
|
||||
Vector4Copy(e->shaderRGBAf, colors[0]);
|
||||
Vector4Copy(e->shaderRGBAf, colors[1]);
|
||||
Vector4Copy(e->shaderRGBAf, colors[2]);
|
||||
Vector4Copy(e->shaderRGBAf, colors[3]);
|
||||
|
||||
memset(&mesh, 0, sizeof(mesh));
|
||||
mesh.vbofirstelement = 0;
|
||||
mesh.vbofirstvert = 0;
|
||||
mesh.xyz_array = points;
|
||||
mesh.indexes = indexarray;
|
||||
mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]);
|
||||
mesh.colors4f_array = (vec4_t*)colors;
|
||||
mesh.lmst_array = NULL;
|
||||
mesh.normals_array = NULL;
|
||||
mesh.numvertexes = 4;
|
||||
mesh.st_array = texcoords;
|
||||
|
||||
BE_DrawMesh_Single(e->forcedshader, &mesh, NULL, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*quick test: map bunk1 ware1 */
|
||||
void R_DrawBeam(entity_t *e)
|
||||
{
|
||||
float r, g, b;
|
||||
|
||||
vec3_t dir, v, cr;
|
||||
vecV_t points[4];
|
||||
float length, scale;
|
||||
static byte_vec4_t colours[4];
|
||||
static vec2_t texcoords[4] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
|
||||
static index_t indexarray[6] = {0, 1, 2, 0, 2, 3};
|
||||
mesh_t mesh;
|
||||
|
||||
shader_t *beamshader;
|
||||
beamshader = R_RegisterShader("q2beam",
|
||||
"{\n"
|
||||
"{\n"
|
||||
"map $whiteimage\n"
|
||||
"rgbgen vertex\n"
|
||||
"alphagen vertex\n"
|
||||
"blendfunc blend\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
VectorSubtract(e->origin, e->oldorigin, dir);
|
||||
length = Length(dir);
|
||||
|
||||
scale = e->scale;
|
||||
if (!scale)
|
||||
scale = 1;
|
||||
scale *= e->framestate.g[FS_REG].frame[0];
|
||||
if (!scale)
|
||||
scale = 6;
|
||||
|
||||
scale/= 2;
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->origin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
VectorMA(e->origin, scale, cr, points[0]);
|
||||
VectorMA(e->origin, -scale, cr, points[1]);
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, e->oldorigin, v);
|
||||
CrossProduct(v, dir, cr);
|
||||
VectorNormalize(cr);
|
||||
VectorMA(e->oldorigin, -scale, cr, points[2]);
|
||||
VectorMA(e->oldorigin, scale, cr, points[3]);
|
||||
|
||||
r = ( d_8to24rgbtable[e->skinnum & 0xFF] ) & 0xFF;
|
||||
g = ( d_8to24rgbtable[e->skinnum & 0xFF] >> 8 ) & 0xFF;
|
||||
b = ( d_8to24rgbtable[e->skinnum & 0xFF] >> 16 ) & 0xFF;
|
||||
|
||||
r *= e->shaderRGBAf[0];
|
||||
g *= e->shaderRGBAf[1];
|
||||
b *= e->shaderRGBAf[2];
|
||||
|
||||
colours[0][0] = r;
|
||||
colours[0][1] = g;
|
||||
colours[0][2] = b;
|
||||
colours[0][3] = 255*0.666;
|
||||
*(int*)colours[1] = *(int*)colours[0];
|
||||
*(int*)colours[2] = *(int*)colours[0];
|
||||
*(int*)colours[3] = *(int*)colours[0];
|
||||
|
||||
memset(&mesh, 0, sizeof(mesh));
|
||||
mesh.vbofirstelement = 0;
|
||||
mesh.vbofirstvert = 0;
|
||||
mesh.xyz_array = points;
|
||||
mesh.indexes = indexarray;
|
||||
mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]);
|
||||
mesh.colors4b_array = colours;
|
||||
mesh.lmst_array = NULL;
|
||||
mesh.normals_array = NULL;
|
||||
mesh.numvertexes = sizeof(points)/sizeof(points[0]);
|
||||
mesh.st_array = texcoords;
|
||||
BE_DrawMesh_Single(beamshader, &mesh, NULL, &beamshader->defaulttextures, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_ShouldDraw
|
||||
Ents are added to the list regardless.
|
||||
This is where they're filtered (based on which view is currently being drawn).
|
||||
=============
|
||||
*/
|
||||
qboolean R_ShouldDraw(entity_t *e)
|
||||
{
|
||||
if (!r_refdef.externalview && (e->externalmodelview & (1<<r_refdef.currentplayernum)))
|
||||
return false;
|
||||
if (!Cam_DrawPlayer(r_refdef.currentplayernum, e->keynum-1))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_DrawEntitiesOnList
|
||||
=============
|
||||
*/
|
||||
void GLR_DrawEntitiesOnList (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!r_drawentities.value)
|
||||
return;
|
||||
|
||||
// draw sprites seperately, because of alpha blending
|
||||
for (i=0 ; i<cl_numvisedicts ; i++)
|
||||
{
|
||||
currententity = &cl_visedicts[i];
|
||||
|
||||
if (!R_ShouldDraw(currententity))
|
||||
continue;
|
||||
|
||||
|
||||
switch (currententity->rtype)
|
||||
{
|
||||
case RT_SPRITE:
|
||||
RQ_AddDistReorder(GLR_DrawSprite, currententity, NULL, currententity->origin);
|
||||
// R_DrawSpriteModel(currententity);
|
||||
continue;
|
||||
#ifdef Q3CLIENT
|
||||
case RT_BEAM:
|
||||
case RT_RAIL_RINGS:
|
||||
case RT_LIGHTNING:
|
||||
R_DrawLightning(currententity);
|
||||
continue;
|
||||
case RT_RAIL_CORE:
|
||||
R_DrawRailCore(currententity);
|
||||
continue;
|
||||
#endif
|
||||
case RT_MODEL: //regular model
|
||||
break;
|
||||
case RT_PORTALSURFACE:
|
||||
continue; //this doesn't do anything anyway, does it?
|
||||
default:
|
||||
case RT_POLY: //these are a little painful, we need to do them some time... just not yet.
|
||||
continue;
|
||||
}
|
||||
if (currententity->flags & Q2RF_BEAM)
|
||||
{
|
||||
R_DrawBeam(currententity);
|
||||
continue;
|
||||
}
|
||||
if (!currententity->model)
|
||||
continue;
|
||||
|
||||
|
||||
if (cl.lerpents && (cls.allow_anyparticles || currententity->visframe)) //allowed or static
|
||||
{
|
||||
if (gl_part_flame.value)
|
||||
{
|
||||
if (currententity->model->engineflags & MDLF_ENGULPHS)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (currententity->model->engineflags & MDLF_NOTREPLACEMENTS)
|
||||
{
|
||||
if (currententity->model->fromgame != fg_quake || currententity->model->type != mod_alias)
|
||||
if (!ruleset_allow_sensative_texture_replacements.value)
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (currententity->model->type)
|
||||
{
|
||||
case mod_alias:
|
||||
break;
|
||||
|
||||
#ifdef HALFLIFEMODELS
|
||||
case mod_halflife:
|
||||
R_DrawHLModel (currententity);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case mod_brush:
|
||||
break;
|
||||
|
||||
case mod_sprite:
|
||||
RQ_AddDistReorder(GLR_DrawSprite, currententity, NULL, currententity->origin);
|
||||
break;
|
||||
|
||||
#ifdef TERRAIN
|
||||
case mod_heightmap:
|
||||
GL_DrawHeightmapModel(currententity);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_SetupGL
|
||||
|
@ -1076,9 +608,6 @@ void R_RenderScene (void)
|
|||
|
||||
S_ExtraUpdate (); // don't let sound get messed up if going slow
|
||||
|
||||
TRACE(("dbg: calling GLR_DrawEntitiesOnList\n"));
|
||||
GLR_DrawEntitiesOnList ();
|
||||
|
||||
// R_DrawDecals();
|
||||
|
||||
TRACE(("dbg: calling R_RenderDlights\n"));
|
||||
|
|
|
@ -67,10 +67,6 @@ qbyte FloatToByte( float x )
|
|||
|
||||
cvar_t r_detailtextures;
|
||||
|
||||
|
||||
#define MAX_SHADERS 2048 //fixme: this takes a lot of bss in the r_shaders list
|
||||
|
||||
|
||||
#define MAX_TOKEN_CHARS 1024
|
||||
|
||||
char *COM_ParseExt (char **data_p, qboolean nl)
|
||||
|
@ -1209,6 +1205,7 @@ struct sbuiltin_s
|
|||
"#endif\n"
|
||||
"varying vec2 tc;\n"
|
||||
"varying vec3 light;\n"
|
||||
"uniform vec4 e_colour;\n"
|
||||
|
||||
"void main (void)\n"
|
||||
"{\n"
|
||||
|
@ -1223,6 +1220,7 @@ struct sbuiltin_s
|
|||
"#ifdef FULLBRIGHT\n"
|
||||
" gl_FragColor += texture2D(s_t3, tc);\n"
|
||||
"#endif\n"
|
||||
" gl_FragColor *= e_colour;\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
},
|
||||
|
@ -3811,33 +3809,18 @@ void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args)
|
|||
}
|
||||
void Shader_DefaultSkinShell(char *shortname, shader_t *s, const void *args)
|
||||
{
|
||||
shaderpass_t *pass;
|
||||
pass = &s->passes[0];
|
||||
pass->shaderbits |= SBITS_MISC_DEPTHWRITE;
|
||||
pass->anim_frames[0] = R_LoadHiResTexture(shortname, NULL, 0);
|
||||
if (!TEXVALID(pass->anim_frames[0]))
|
||||
pass->anim_frames[0] = missing_texture;
|
||||
pass->rgbgen = RGB_GEN_ENTITY;
|
||||
pass->alphagen = ALPHA_GEN_ENTITY;
|
||||
pass->numtcmods = 0;
|
||||
pass->tcgen = TC_GEN_BASE;
|
||||
pass->shaderbits |= SBITS_SRCBLEND_SRC_ALPHA;
|
||||
pass->shaderbits |= SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
|
||||
pass->numMergedPasses = 1;
|
||||
Shader_SetBlendmode(pass);
|
||||
|
||||
if (!TEXVALID(pass->anim_frames[0]))
|
||||
{
|
||||
Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname );
|
||||
pass->anim_frames[0] = missing_texture;
|
||||
}
|
||||
|
||||
s->numpasses = 1;
|
||||
s->numdeforms = 0;
|
||||
s->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT;
|
||||
s->features = MF_STCOORDS|MF_NORMALS;
|
||||
s->sort = SHADER_SORT_OPAQUE;
|
||||
s->uses = 1;
|
||||
Shader_DefaultScript(shortname, s,
|
||||
"{\n"
|
||||
"sort blend\n"
|
||||
"deformvertexes normal 1 1\n"
|
||||
"{\n"
|
||||
"map $diffuse\n"
|
||||
"rgbgen entity\n"
|
||||
"alphagen entity\n"
|
||||
"blendfunc blend\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
}
|
||||
void Shader_Default2D(char *shortname, shader_t *s, const void *genargs)
|
||||
{
|
||||
|
|
|
@ -277,10 +277,6 @@ void GL_SelectTexture (int tmunum);
|
|||
void GL_SetShaderState2D(qboolean is2d);
|
||||
void GL_ForceDepthWritable(void);
|
||||
|
||||
void R_DrawRailCore(entity_t *e);
|
||||
void R_DrawLightning(entity_t *e);
|
||||
void R_DrawBeam( entity_t *e );
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
|
|
@ -392,6 +392,7 @@ struct shader_s
|
|||
bucket_t bucket;
|
||||
};
|
||||
|
||||
#define MAX_SHADERS 2048 //fixme: this takes a lot of bss in the r_shaders list
|
||||
extern shader_t *r_shaders;
|
||||
extern int be_maxpasses;
|
||||
|
||||
|
@ -431,6 +432,8 @@ mfog_t *CM_FogForOrigin(vec3_t org);
|
|||
#define BEF_FORCETRANSPARENT 8 //texenv replace -> modulate
|
||||
#define BEF_FORCENODEPTH 16 //disables any and all depth.
|
||||
#define BEF_PUSHDEPTH 32 //additional polygon offset
|
||||
#define BEF_NODLIGHT 64 //don't use a dlight pass
|
||||
#define BEF_NOSHADOWS 128 //don't appear in shadows
|
||||
|
||||
#ifdef GLQUAKE
|
||||
void GLBE_Init(void);
|
||||
|
@ -449,8 +452,8 @@ void GLBE_SelectEntity(entity_t *ent);
|
|||
#ifdef D3DQUAKE
|
||||
void D3DBE_Init(void);
|
||||
void D3DBE_SelectMode(backendmode_t mode);
|
||||
void D3DBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **mesh, vbo_t *vbo, texnums_t *texnums);
|
||||
void D3DBE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texnums_t *texnums);
|
||||
void D3DBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **mesh, vbo_t *vbo, texnums_t *texnums, unsigned int beflags);
|
||||
void D3DBE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texnums_t *texnums, unsigned int beflags);
|
||||
void D3DBE_SubmitBatch(batch_t *batch);
|
||||
batch_t *D3DBE_GetTempBatch(void);
|
||||
void D3DBE_GenBrushModelVBO(model_t *mod);
|
||||
|
|
|
@ -747,6 +747,8 @@ qboolean SVQ2_InitGameProgs(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!deathmatch.value && !coop.value)
|
||||
maxclients.value = 1;
|
||||
if (maxclients.value > MAX_CLIENTS)
|
||||
Cvar_SetValue(&maxclients, MAX_CLIENTS);
|
||||
|
||||
|
|
|
@ -421,13 +421,13 @@ static void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs
|
|||
{
|
||||
if (start[i] < end[i])
|
||||
{
|
||||
mmins[i] = start[i]+mins[i];
|
||||
mmaxs[i] = end[i]+maxs[i];
|
||||
mmins[i] = start[i]+mins[i]-1;
|
||||
mmaxs[i] = end[i]+maxs[i]+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mmins[i] = end[i]+mins[i];
|
||||
mmaxs[i] = start[i]+maxs[i];
|
||||
mmins[i] = end[i]+mins[i]-1;
|
||||
mmaxs[i] = start[i]+maxs[i]+1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -454,12 +454,12 @@ static void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs
|
|||
|
||||
if (entnum != ENTITYNUM_WORLD)
|
||||
{
|
||||
// if (contactlist[i] == entnum)
|
||||
// continue; // don't clip against the pass entity
|
||||
// if (es->r.ownerNum == entnum)
|
||||
// continue; // don't clip against own missiles
|
||||
// if (es->r.ownerNum == ourowner)
|
||||
// continue; // don't clip against other missiles from our owner
|
||||
if (contactlist[i] == entnum)
|
||||
continue;
|
||||
if (es->r.ownerNum == entnum)
|
||||
continue;
|
||||
if (es->r.ownerNum == ourowner)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (es->r.bmodel)
|
||||
|
@ -528,12 +528,12 @@ static int SVQ3_PointContents(vec3_t pos, int entnum)
|
|||
|
||||
if (entnum != ENTITYNUM_WORLD)
|
||||
{
|
||||
// if (contactlist[i] == entnum)
|
||||
// continue; // don't clip against the pass entity
|
||||
// if (es->r.ownerNum == entnum)
|
||||
// continue; // don't clip against own missiles
|
||||
// if (es->r.ownerNum == ourowner)
|
||||
// continue; // don't clip against other missiles from our owner
|
||||
if (contactlist[i] == entnum)
|
||||
continue; // don't clip against the pass entity
|
||||
if (es->r.ownerNum == entnum)
|
||||
continue; // don't clip against own missiles
|
||||
if (es->r.ownerNum == ourowner)
|
||||
continue; // don't clip against other missiles from our owner
|
||||
}
|
||||
|
||||
if (es->r.bmodel)
|
||||
|
|
Loading…
Reference in a new issue