From f7aece9d4801ad13aa4cea4db395ca697496891a Mon Sep 17 00:00:00 2001 From: Spoike Date: Sat, 23 Apr 2011 20:37:20 +0000 Subject: [PATCH] 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 --- engine/client/cl_ents.c | 12 +- engine/client/cl_tent.c | 31 ++- engine/client/cl_ui.c | 1 + engine/client/clhl_game.c | 2 +- engine/client/clq2_ents.c | 11 +- engine/client/pr_csqc.c | 28 ++- engine/client/r_2d.c | 5 +- engine/client/r_surf.c | 2 +- engine/client/render.h | 2 + engine/client/sbar.c | 63 +++-- engine/d3d/d3d_backend.c | 236 +++--------------- engine/gl/gl_alias.c | 490 ++++++++++++++++++++++++++++++++++++++ engine/gl/gl_backend.c | 105 ++------ engine/gl/gl_model.c | 4 +- engine/gl/gl_rmain.c | 471 ------------------------------------ engine/gl/gl_shader.c | 45 ++-- engine/gl/glquake.h | 4 - engine/gl/shader.h | 7 +- engine/server/svq2_game.c | 2 + engine/server/svq3_game.c | 32 +-- 20 files changed, 684 insertions(+), 869 deletions(-) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index bbb7bdf6a..354ec8279 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -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; // diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 9ded8b274..db428bd43 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -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; diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index d134566e2..39af8eff4 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -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; diff --git a/engine/client/clhl_game.c b/engine/client/clhl_game.c index 26f44768a..00cf99747 100644 --- a/engine/client/clhl_game.c +++ b/engine/client/clhl_game.c @@ -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; diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index 9bc9b262f..0ec01210e 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -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; diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index c1a873c53..a9b5ea1ab 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -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; diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index 92bf193d1..ff72daeee 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -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; diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 9ee5040fd..204f63b22 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -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; diff --git a/engine/client/render.h b/engine/client/render.h index da2894493..9054072b5 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -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); diff --git a/engine/client/sbar.c b/engine/client/sbar.c index 60c1f3f90..e8580b38d 100644 --- a/engine/client/sbar.c +++ b/engine/client/sbar.c @@ -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); diff --git a/engine/d3d/d3d_backend.c b/engine/d3d/d3d_backend.c index e858a9844..e1d6ac75d 100644 --- a/engine/d3d/d3d_backend.c +++ b/engine/d3d/d3d_backend.c @@ -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<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 ; irtype) - { - 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; diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index c2cde29e3..db37135ca 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -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<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 ; irtype) + { + 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); +} \ No newline at end of file diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 5175dd7de..3633c4799 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -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 ; imodel) - 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); diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 93c54e24c..ca3fdefc3 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -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]; diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index fd1af6bb4..620e3a357 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -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<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 ; irtype) - { - 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")); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index acdc1fce0..849c422ac 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -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) { diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index dbd2b34b3..60bea31b6 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -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 // diff --git a/engine/gl/shader.h b/engine/gl/shader.h index f88193b9c..4ec95481a 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -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); diff --git a/engine/server/svq2_game.c b/engine/server/svq2_game.c index 73f05fb3d..d49ac39e1 100644 --- a/engine/server/svq2_game.c +++ b/engine/server/svq2_game.c @@ -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); diff --git a/engine/server/svq3_game.c b/engine/server/svq3_game.c index 24eb4d857..db48bbed7 100644 --- a/engine/server/svq3_game.c +++ b/engine/server/svq3_game.c @@ -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)