From 713ff59c3b4958a58e5d1a4365c780c557cb3fcb Mon Sep 17 00:00:00 2001 From: havoc Date: Sun, 4 Oct 2009 11:35:47 +0000 Subject: [PATCH] added DP_ENT_GLOWMOD extension, like DP_ENT_COLORMOD but alters glow color (fullbrights or glow texture) instead of diffuse git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9300 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_main.c | 10 ++++++++++ client.h | 1 + clvm_cmds.c | 5 +++++ csprogs.c | 5 +++++ gl_rmain.c | 4 +++- progsvm.h | 1 + protocol.c | 19 ++++++++++++++++++- protocol.h | 7 ++++--- prvm_edict.c | 1 + render.h | 2 ++ sv_main.c | 11 +++++++++++ svvm_cmds.c | 1 + 12 files changed, 62 insertions(+), 5 deletions(-) diff --git a/cl_main.c b/cl_main.c index 0fe873bc..af8c3103 100644 --- a/cl_main.c +++ b/cl_main.c @@ -595,6 +595,7 @@ entity_render_t *CL_NewTempEntity(double shadertime) render->shadertime = shadertime; render->alpha = 1; VectorSet(render->colormod, 1, 1, 1); + VectorSet(render->glowmod, 1, 1, 1); return render; } @@ -824,6 +825,7 @@ void CL_AddQWCTFFlagModel(entity_t *player, int skin) flagrender->skinnum = skin; flagrender->alpha = 1; VectorSet(flagrender->colormod, 1, 1, 1); + VectorSet(flagrender->glowmod, 1, 1, 1); // attach the flag to the player matrix Matrix4x4_CreateFromQuakeEntity(&flagmatrix, -f, -22, 0, 0, 0, -45, 1); Matrix4x4_Concat(&flagrender->matrix, &player->render.matrix, &flagmatrix); @@ -877,6 +879,7 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat e->render.flags = e->state_current.flags; e->render.effects = e->state_current.effects; VectorScale(e->state_current.colormod, (1.0f / 32.0f), e->render.colormod); + VectorScale(e->state_current.glowmod, (1.0f / 32.0f), e->render.glowmod); if(e >= cl.entities && e < cl.entities + cl.num_entities) e->render.entitynumber = e - cl.entities; else @@ -990,7 +993,10 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat if (e->render.model->type == mod_alias) angles[0] = -angles[0]; if ((e->render.effects & EF_SELECTABLE) && cl.cmd.cursor_entitynumber == e->state_current.number) + { VectorScale(e->render.colormod, 2, e->render.colormod); + VectorScale(e->render.glowmod, 2, e->render.glowmod); + } } // if model is alias or this is a tenebrae-like dlight, reverse pitch direction else if (e->state_current.lightpflags & PFLAGS_FULLDYNAMIC) @@ -1447,6 +1453,7 @@ void CL_RelinkWorld(void) if (!r_fullbright.integer) ent->render.flags |= RENDER_LIGHT; VectorSet(ent->render.colormod, 1, 1, 1); + VectorSet(ent->render.glowmod, 1, 1, 1); CL_UpdateRenderEntity(&ent->render); r_refdef.scene.worldentity = &ent->render; r_refdef.scene.worldmodel = cl.worldmodel; @@ -1469,6 +1476,7 @@ static void CL_RelinkStaticEntities(void) if (!(e->render.effects & (EF_NOSHADOW | EF_ADDITIVE | EF_NODEPTHTEST)) && (e->render.alpha >= 1)) e->render.flags |= RENDER_SHADOW; VectorSet(e->render.colormod, 1, 1, 1); + VectorSet(e->render.glowmod, 1, 1, 1); R_LerpAnimation(&e->render); CL_UpdateRenderEntity(&e->render); r_refdef.scene.entities[r_refdef.scene.numentities++] = &e->render; @@ -1555,6 +1563,7 @@ static void CL_RelinkEffects(void) entrender->model = cl.csqc_model_precache[-(e->modelindex+1)]; entrender->alpha = 1; VectorSet(entrender->colormod, 1, 1, 1); + VectorSet(entrender->glowmod, 1, 1, 1); Matrix4x4_CreateFromQuakeEntity(&entrender->matrix, e->origin[0], e->origin[1], e->origin[2], 0, 0, 0, 1); CL_UpdateRenderEntity(entrender); @@ -1701,6 +1710,7 @@ static void CL_RelinkQWNails(void) entrender->model = cl.model_precache[cl.qw_modelindex_spike]; entrender->alpha = 1; VectorSet(entrender->colormod, 1, 1, 1); + VectorSet(entrender->glowmod, 1, 1, 1); Matrix4x4_CreateFromQuakeEntity(&entrender->matrix, v[0], v[1], v[2], v[3], v[4], v[5], 1); CL_UpdateRenderEntity(entrender); diff --git a/client.h b/client.h index 32348dc4..5ac54832 100644 --- a/client.h +++ b/client.h @@ -290,6 +290,7 @@ typedef struct entity_render_s // colormod tinting of models float colormod[3]; + float glowmod[3]; // interpolated animation - active framegroups and blend factors framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS]; diff --git a/clvm_cmds.c b/clvm_cmds.c index 3ce123ae..c317b452 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -1442,6 +1442,11 @@ static void VM_CL_makestatic (void) staticent->render.scale = 1; if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)) && val->_float) staticent->render.scale = val->_float; if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.colormod)) && VectorLength2(val->vector)) VectorCopy(val->vector, staticent->render.colormod); + if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.glowmod)) && VectorLength2(val->vector)) VectorCopy(val->vector, staticent->render.glowmod); + if (!VectorLength2(staticent->render.colormod)) + VectorSet(staticent->render.colormod, 1, 1, 1); + if (!VectorLength2(staticent->render.glowmod)) + VectorSet(staticent->render.glowmod, 1, 1, 1); renderflags = 0; if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.renderflags)) && val->_float) renderflags = (int)val->_float; diff --git a/csprogs.c b/csprogs.c index 5ed99d11..58d631ef 100644 --- a/csprogs.c +++ b/csprogs.c @@ -180,6 +180,7 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed) if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.alpha)) && val->_float) entrender->alpha = val->_float; if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.scale)) && val->_float) entrender->scale = scale = val->_float; if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.colormod)) && VectorLength2(val->vector)) VectorCopy(val->vector, entrender->colormod); + if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.glowmod)) && VectorLength2(val->vector)) VectorCopy(val->vector, entrender->glowmod); if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.effects)) && val->_float) entrender->effects |= (int)val->_float; if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.tag_entity)) && val->edict) { @@ -192,6 +193,10 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed) } else Matrix4x4_CreateIdentity(&tagmatrix); + if (!VectorLength2(entrender->colormod)) + VectorSet(entrender->colormod, 1, 1, 1); + if (!VectorLength2(entrender->glowmod)) + VectorSet(entrender->glowmod, 1, 1, 1); if (renderflags & RF_USEAXIS) { diff --git a/gl_rmain.c b/gl_rmain.c index 1e578d9d..d811bfd4 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -2211,7 +2211,7 @@ void R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, f if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_refdef.lightmapintensity * specularscale); } if (r_glsl_permutation->loc_TintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_TintColor, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2], rsurface.texture->lightmapcolor[3]); - if (r_glsl_permutation->loc_GlowColor >= 0) qglUniform1fARB(r_glsl_permutation->loc_GlowColor, r_hdr_glowintensity.value, r_hdr_glowintensity.value, r_hdr_glowintensity.value); + if (r_glsl_permutation->loc_GlowColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_GlowColor, rsurface.glowmod[0] * r_hdr_glowintensity.value, rsurface.glowmod[1] * r_hdr_glowintensity.value, rsurface.glowmod[2] * r_hdr_glowintensity.value); // additive passes are only darkened by fog, not tinted if (r_glsl_permutation->loc_FogColor >= 0) { @@ -5655,6 +5655,7 @@ void RSurf_ActiveWorldEntity(void) VectorSet(rsurface.modellight_lightdir, 0, 0, 1); VectorSet(rsurface.colormap_pantscolor, 0, 0, 0); VectorSet(rsurface.colormap_shirtcolor, 0, 0, 0); + VectorSet(rsurface.glowmod, 1, 1, 1); memset(rsurface.frameblend, 0, sizeof(rsurface.frameblend)); rsurface.frameblend[0].lerp = 1; rsurface.basepolygonfactor = r_refdef.polygonfactor; @@ -5726,6 +5727,7 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q VectorCopy(ent->modellight_lightdir, rsurface.modellight_lightdir); VectorCopy(ent->colormap_pantscolor, rsurface.colormap_pantscolor); VectorCopy(ent->colormap_shirtcolor, rsurface.colormap_shirtcolor); + VectorCopy(ent->glowmod, rsurface.glowmod); memcpy(rsurface.frameblend, ent->frameblend, sizeof(ent->frameblend)); rsurface.basepolygonfactor = r_refdef.polygonfactor; rsurface.basepolygonoffset = r_refdef.polygonoffset; diff --git a/progsvm.h b/progsvm.h index 1d9fd7bd..97660c28 100644 --- a/progsvm.h +++ b/progsvm.h @@ -192,6 +192,7 @@ typedef struct prvm_prog_fieldoffsets_s int glow_color; // ssqc int glow_size; // ssqc int glow_trail; // ssqc + int glowmod; // ssqc / csqc int gravity; // ssqc int groundentity; // ssqc / csqc int hull; // ssqc / csqc diff --git a/protocol.c b/protocol.c index 9cc93d5d..6ae92b26 100644 --- a/protocol.c +++ b/protocol.c @@ -50,8 +50,9 @@ entity_state_t defaultstate = 0,//unsigned char internaleffects; // INTEF_FLAG1QW and so on 0,//unsigned char tagindex; {32, 32, 32},//unsigned char colormod[3]; + {32, 32, 32},//unsigned char glowmod[3]; // padding to a multiple of 8 bytes (to align the double time) - {0,0,0,0,0}//unsigned char unused[5]; // ! + {0,0}//unsigned char unused[2]; // ! }; // LordHavoc: I own protocol ranges 96, 97, 3500-3599 @@ -2158,6 +2159,12 @@ void EntityState5_WriteUpdate(int number, const entity_state_t *s, int changedbi MSG_WriteByte(msg, s->colormod[1]); MSG_WriteByte(msg, s->colormod[2]); } + if (bits & E5_GLOWMOD) + { + MSG_WriteByte(msg, s->glowmod[0]); + MSG_WriteByte(msg, s->glowmod[1]); + MSG_WriteByte(msg, s->glowmod[2]); + } } ENTITYSIZEPROFILING_END(msg, s->number); @@ -2270,6 +2277,12 @@ static void EntityState5_ReadUpdate(entity_state_t *s, int number) s->colormod[1] = MSG_ReadByte(); s->colormod[2] = MSG_ReadByte(); } + if (bits & E5_GLOWMOD) + { + s->glowmod[0] = MSG_ReadByte(); + s->glowmod[1] = MSG_ReadByte(); + s->glowmod[2] = MSG_ReadByte(); + } if (developer_networkentities.integer >= 2) @@ -2325,6 +2338,8 @@ static void EntityState5_ReadUpdate(entity_state_t *s, int number) Con_Printf(" E5_GLOW %i:%i", s->glowsize * 4, s->glowcolor); if (bits & E5_COLORMOD) Con_Printf(" E5_COLORMOD %f:%f:%f", s->colormod[0] / 32.0f, s->colormod[1] / 32.0f, s->colormod[2] / 32.0f); + if (bits & E5_GLOWMOD) + Con_Printf(" E5_GLOWMOD %f:%f:%f", s->glowmod[0] / 32.0f, s->glowmod[1] / 32.0f, s->glowmod[2] / 32.0f); Con_Print("\n"); } } @@ -2364,6 +2379,8 @@ static int EntityState5_DeltaBits(const entity_state_t *o, const entity_state_t bits |= E5_GLOW; if (o->colormod[0] != n->colormod[0] || o->colormod[1] != n->colormod[1] || o->colormod[2] != n->colormod[2]) bits |= E5_COLORMOD; + if (o->glowmod[0] != n->glowmod[0] || o->glowmod[1] != n->glowmod[1] || o->glowmod[2] != n->glowmod[2]) + bits |= E5_GLOWMOD; } else if (o->active == ACTIVE_NETWORK) diff --git a/protocol.h b/protocol.h index cfb2084e..78697e7c 100644 --- a/protocol.h +++ b/protocol.h @@ -378,8 +378,9 @@ typedef struct entity_state_s unsigned char internaleffects; // INTEF_FLAG1QW and so on unsigned char tagindex; unsigned char colormod[3]; + unsigned char glowmod[3]; // padding to a multiple of 8 bytes (to align the double time) - unsigned char unused[5]; + unsigned char unused[2]; } entity_state_t; @@ -705,8 +706,8 @@ void EntityFrame4_CL_ReadFrame(void); // bits >= (1<<24) #define E5_EXTEND3 (1<<23) -// unused -#define E5_UNUSED24 (1<<24) +// byte[3] = s->glowmod[0], s->glowmod[1], s->glowmod[2] +#define E5_GLOWMOD (1<<24) // unused #define E5_UNUSED25 (1<<25) // unused diff --git a/prvm_edict.c b/prvm_edict.c index da9dec06..f29b50c4 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -1596,6 +1596,7 @@ void PRVM_FindOffsets(void) prog->fieldoffsets.glow_color = PRVM_ED_FindFieldOffset("glow_color"); prog->fieldoffsets.glow_size = PRVM_ED_FindFieldOffset("glow_size"); prog->fieldoffsets.glow_trail = PRVM_ED_FindFieldOffset("glow_trail"); + prog->fieldoffsets.glowmod = PRVM_ED_FindFieldOffset("glowmod"); prog->fieldoffsets.gravity = PRVM_ED_FindFieldOffset("gravity"); prog->fieldoffsets.groundentity = PRVM_ED_FindFieldOffset("groundentity"); prog->fieldoffsets.hull = PRVM_ED_FindFieldOffset("hull"); diff --git a/render.h b/render.h index 66128bb5..5298ca95 100644 --- a/render.h +++ b/render.h @@ -312,6 +312,8 @@ typedef struct rsurfacestate_s // colormapping state from entity (these are black if colormapping is off) vec3_t colormap_pantscolor; vec3_t colormap_shirtcolor; + // special coloring of glow textures + vec3_t glowmod; // view location in model space vec3_t modelorg; // TODO: rename this // polygon offset data for submodels diff --git a/sv_main.c b/sv_main.c index 1de8afc0..6d2a6568 100644 --- a/sv_main.c +++ b/sv_main.c @@ -290,6 +290,7 @@ prvm_required_field_t reqfields[] = {ev_vector, "cursor_screen"}, {ev_vector, "cursor_trace_endpos"}, {ev_vector, "cursor_trace_start"}, + {ev_vector, "glowmod"}, {ev_vector, "movement"}, {ev_vector, "punchvector"}, }; @@ -1141,6 +1142,16 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c i = (int)(val->vector[2] * 32.0f);cs->colormod[2] = bound(0, i, 255); } + // don't need to init cs->glowmod because the defaultstate did that for us + //cs->glowmod[0] = cs->glowmod[1] = cs->glowmod[2] = 32; + val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.glowmod); + if (val->vector[0] || val->vector[1] || val->vector[2]) + { + i = (int)(val->vector[0] * 32.0f);cs->glowmod[0] = bound(0, i, 255); + i = (int)(val->vector[1] * 32.0f);cs->glowmod[1] = bound(0, i, 255); + i = (int)(val->vector[2] * 32.0f);cs->glowmod[2] = bound(0, i, 255); + } + cs->modelindex = modelindex; cs->alpha = 255; diff --git a/svvm_cmds.c b/svvm_cmds.c index d91ce4bb..ede31ff3 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -38,6 +38,7 @@ char *vm_sv_extensions = "DP_ENT_CUSTOMCOLORMAP " "DP_ENT_EXTERIORMODELTOCLIENT " "DP_ENT_GLOW " +"DP_ENT_GLOWMOD " "DP_ENT_LOWPRECISION " "DP_ENT_SCALE " "DP_ENT_VIEWMODEL " -- 2.39.2