From 093c41bf532834207d8a23df44f5b39fa707815d Mon Sep 17 00:00:00 2001 From: havoc Date: Sat, 21 Feb 2004 07:37:36 +0000 Subject: [PATCH] moved light matrix generation out of the render code and into the light creation code (rtlight and dlight setup) to save time and simplify things rtlights and dlights now have an orientation matrix (this allows cubemaps to be rotated) rtlights can now have corona flares, and it is adjustable per light (also on dlights) r_coronas cvar now controls corona intensity, and menu now has r_coronas slider instead of checkbox dlights now have color[]/radius settings instead of just colored intensity, so the radius can be independently controlled again (this mainly improves realtime dlight behaviors) dlights can now have cubemaps, light styles, optional shadows (rather than always on), and better color/radius settings (and all this is tenebrae compatible) using the light_lev, color, style, skin (cubemap number, only available if modelindex is 0), and pflags (1 is no shadow, 2 is draw corona which is ignored by darkplaces because it always draws a corona) fields in the quakec entities now supports tenebrae dlight fields (light_lev, color, style, pflags), this means dlights can now have cubemaps (skin, only used if modelindex is 0), light style (style), color (color) and radius (light_lev) with more precision than glow_ fields, and pflags (flag 1 is no shadow, flag 2 is corona which is ignored because dlights always have a corona in darkplaces), also loads tenebrae mods added TENEBRAE_GFX_DLIGHTS extension git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3913 d7cf8633-e32d-0410-b094-e92efae38249 --- cgame_api.h | 3 +- cgamevm.c | 4 +- cl_main.c | 124 +++++++++++++++++--------- cl_parse.c | 81 +++++++++++++---- client.h | 18 +++- common.c | 8 ++ common.h | 1 + gl_models.c | 8 +- gl_rmain.c | 87 +++++++----------- gl_rsurf.c | 16 ++-- menu.c | 68 +++++--------- model_alias.c | 4 +- model_brush.c | 4 +- model_shared.h | 2 +- pr_cmds.c | 1 + pr_edict.c | 16 +++- progs.h | 4 + protocol.c | 41 ++++++++- protocol.h | 17 ++-- r_light.c | 46 ++++++++-- r_light.h | 11 +++ r_shadow.c | 235 ++++++++++++++++++++++++++++++++++++------------- r_shadow.h | 28 ++++-- server.h | 1 + sv_main.c | 13 ++- sv_phys.c | 4 +- todo | 12 +++ 27 files changed, 583 insertions(+), 274 deletions(-) diff --git a/cgame_api.h b/cgame_api.h index 8e7c4a57..01eb847f 100644 --- a/cgame_api.h +++ b/cgame_api.h @@ -24,7 +24,8 @@ cgdrawentity_t; typedef struct cgdrawlight_s { float origin[3]; - float light[3]; + float color[3]; + float radius; } cgdrawlight_t; diff --git a/cgamevm.c b/cgamevm.c index a2dc9294..721c3392 100644 --- a/cgamevm.c +++ b/cgamevm.c @@ -167,7 +167,9 @@ void CGVM_Draw_Entity(const cgdrawentity_t *e) void CGVM_Draw_Light(const cgdrawlight_t *l) { - CL_AllocDlight(NULL, (float *) l->origin, 1, l->light[0], l->light[1], l->light[2], 0, 0); + matrix4x4_t matrix; + Matrix4x4_CreateTranslate(&matrix, l->origin[0], l->origin[1], l->origin[2]); + CL_AllocDlight(NULL, &matrix, l->radius, l->color[0], l->color[1], l->color[2], 0, 0, 0, 0, true, 1); } void *CGVM_Malloc(const int size) diff --git a/cl_main.c b/cl_main.c index 2ea477a3..42b01de1 100644 --- a/cl_main.c +++ b/cl_main.c @@ -414,7 +414,7 @@ void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float } } -void CL_AllocDlight(entity_render_t *ent, vec3_t org, float radius, float red, float green, float blue, float decay, float lifetime) +void CL_AllocDlight(entity_render_t *ent, matrix4x4_t *matrix, float radius, float red, float green, float blue, float decay, float lifetime, int cubemapnum, int style, int shadowenable, vec_t corona) { int i; dlight_t *dl; @@ -442,9 +442,15 @@ void CL_AllocDlight(entity_render_t *ent, vec3_t org, float radius, float red, f dlightsetup: //Con_Printf("dlight %i : %f %f %f : %f %f %f\n", i, org[0], org[1], org[2], red * radius, green * radius, blue * radius); memset (dl, 0, sizeof(*dl)); + dl->matrix = *matrix; dl->ent = ent; - CL_FindNonSolidLocation(org, dl->origin, 6); - //VectorCopy(org, dl->origin); + dl->origin[0] = dl->matrix.m[0][3]; + dl->origin[1] = dl->matrix.m[1][3]; + dl->origin[2] = dl->matrix.m[2][3]; + CL_FindNonSolidLocation(dl->origin, dl->origin, 6); + dl->matrix.m[0][3] = dl->origin[0]; + dl->matrix.m[1][3] = dl->origin[1]; + dl->matrix.m[2][3] = dl->origin[2]; dl->radius = radius; dl->color[0] = red; dl->color[1] = green; @@ -454,6 +460,10 @@ dlightsetup: dl->die = cl.time + lifetime; else dl->die = 0; + dl->cubemapnum = cubemapnum; + dl->style = style; + dl->shadow = shadowenable; + dl->corona = corona; } void CL_DecayLights(void) @@ -486,9 +496,9 @@ extern void V_CalcRefdef(void); // note this is a recursive function, but it can never get in a runaway loop (because of the delayedlink flags) void CL_LinkNetworkEntity(entity_t *e) { - matrix4x4_t *matrix, blendmatrix, tempmatrix, matrix2; + matrix4x4_t *matrix, blendmatrix, tempmatrix, matrix2, dlightmatrix; int j, k, l, trailtype, temp; - float origin[3], angles[3], delta[3], lerp, dlightcolor[3], mins[3], maxs[3], v[3], v2[3], d; + float origin[3], angles[3], delta[3], lerp, dlightcolor[3], dlightradius, mins[3], maxs[3], v[3], v2[3], d; entity_t *t; model_t *model; //entity_persistent_t *p = &e->persistent; @@ -637,6 +647,7 @@ void CL_LinkNetworkEntity(entity_t *e) origin[1] = e->render.matrix.m[1][3]; origin[2] = e->render.matrix.m[2][3]; trailtype = -1; + dlightradius = 0; dlightcolor[0] = 0; dlightcolor[1] = 0; dlightcolor[2] = 0; @@ -647,9 +658,10 @@ void CL_LinkNetworkEntity(entity_t *e) { if (gamemode == GAME_NEXUIZ) { - dlightcolor[0] += 100.0f; - dlightcolor[1] += 200.0f; - dlightcolor[2] += 400.0f; + dlightradius = max(dlightradius, 200); + dlightcolor[0] += 0.390625f; + dlightcolor[1] += 0.781250f; + dlightcolor[2] += 1.562500f; trailtype = 8; } else @@ -659,28 +671,32 @@ void CL_LinkNetworkEntity(entity_t *e) e->persistent.muzzleflash = 100.0f; if (e->render.effects & EF_DIMLIGHT) { - dlightcolor[0] += 200.0f; - dlightcolor[1] += 200.0f; - dlightcolor[2] += 200.0f; + dlightradius = max(dlightradius, 200); + dlightcolor[0] += 0.781250f; + dlightcolor[1] += 0.781250f; + dlightcolor[2] += 0.781250f; } if (e->render.effects & EF_BRIGHTLIGHT) { - dlightcolor[0] += 400.0f; - dlightcolor[1] += 400.0f; - dlightcolor[2] += 400.0f; + dlightradius = max(dlightradius, 400); + dlightcolor[0] += 1.562500f; + dlightcolor[1] += 1.562500f; + dlightcolor[2] += 1.562500f; } // LordHavoc: more effects if (e->render.effects & EF_RED) // red { - dlightcolor[0] += 200.0f; - dlightcolor[1] += 20.0f; - dlightcolor[2] += 20.0f; + dlightradius = max(dlightradius, 200); + dlightcolor[0] += 0.781250f; + dlightcolor[1] += 0.078125f; + dlightcolor[2] += 0.078125f; } if (e->render.effects & EF_BLUE) // blue { - dlightcolor[0] += 20.0f; - dlightcolor[1] += 20.0f; - dlightcolor[2] += 200.0f; + dlightradius = max(dlightradius, 200); + dlightcolor[0] += 0.078125f; + dlightcolor[1] += 0.078125f; + dlightcolor[2] += 0.781250f; } if (e->render.effects & EF_FLAME) { @@ -693,7 +709,8 @@ void CL_LinkNetworkEntity(entity_t *e) // how many flames to make temp = (int) (cl.time * 300) - (int) (cl.oldtime * 300); CL_FlameCube(mins, maxs, temp); - d = lhrandom(200, 250); + d = lhrandom(0.75f, 1); + dlightradius = max(dlightradius, 200); dlightcolor[0] += d * 1.0f; dlightcolor[1] += d * 0.7f; dlightcolor[2] += d * 0.3f; @@ -709,7 +726,8 @@ void CL_LinkNetworkEntity(entity_t *e) // how many particles to make temp = (int) (cl.time * 200) - (int) (cl.oldtime * 200); CL_Stardust(mins, maxs, temp); - d = 100; + d = 0.390625f; + dlightradius = max(dlightradius, 200); dlightcolor[0] += d * 1.0f; dlightcolor[1] += d * 0.7f; dlightcolor[2] += d * 0.3f; @@ -720,7 +738,11 @@ void CL_LinkNetworkEntity(entity_t *e) { Matrix4x4_Transform(&e->render.matrix, muzzleflashorigin, v2); CL_TraceLine(origin, v2, v, NULL, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY); - CL_AllocDlight(NULL, v, e->persistent.muzzleflash, 1, 1, 1, 0, 0); + tempmatrix = e->render.matrix; + tempmatrix.m[0][3] = v[0]; + tempmatrix.m[1][3] = v[1]; + tempmatrix.m[2][3] = v[2]; + CL_AllocDlight(NULL, &tempmatrix, e->persistent.muzzleflash, 1, 1, 1, 0, 0, 0, 0, true, 1); e->persistent.muzzleflash -= cl.frametime * 1000; } // LordHavoc: if the model has no flags, don't check each @@ -733,23 +755,26 @@ void CL_LinkNetworkEntity(entity_t *e) else if (e->render.model->flags & EF_TRACER) { trailtype = 3; - dlightcolor[0] += 0x10; - dlightcolor[1] += 0x40; - dlightcolor[2] += 0x10; + dlightradius = max(dlightradius, 100); + dlightcolor[0] += 0.060000f; + dlightcolor[1] += 0.250000f; + dlightcolor[2] += 0.062500f; } else if (e->render.model->flags & EF_TRACER2) { trailtype = 5; - dlightcolor[0] += 0x50; - dlightcolor[1] += 0x30; - dlightcolor[2] += 0x10; + dlightradius = max(dlightradius, 100); + dlightcolor[0] += 0.312500f; + dlightcolor[1] += 0.187500f; + dlightcolor[2] += 0.062500f; } else if (e->render.model->flags & EF_ROCKET) { trailtype = 0; - dlightcolor[0] += 200.0f; - dlightcolor[1] += 160.0f; - dlightcolor[2] += 80.0f; + dlightradius = max(dlightradius, 200); + dlightcolor[0] += 0.781250f; + dlightcolor[1] += 0.625000f; + dlightcolor[2] += 0.312500f; } else if (e->render.model->flags & EF_GRENADE) { @@ -759,9 +784,10 @@ void CL_LinkNetworkEntity(entity_t *e) else if (e->render.model->flags & EF_TRACER3) { trailtype = 6; - dlightcolor[0] += 0x50; - dlightcolor[1] += 0x20; - dlightcolor[2] += 0x40; + dlightradius = max(dlightradius, 200); + dlightcolor[0] += 0.312500f; + dlightcolor[1] += 0.125000f; + dlightcolor[2] += 0.250000f; } } // LordHavoc: customizable glow @@ -769,16 +795,25 @@ void CL_LinkNetworkEntity(entity_t *e) { // * 4 for the expansion from 0-255 to 0-1023 range, // / 255 to scale down byte colors - VectorMA(dlightcolor, e->state_current.glowsize * (4.0f / 255.0f), (qbyte *)&palette_complete[e->state_current.glowcolor], dlightcolor); + dlightradius = max(dlightradius, e->state_current.glowsize * 4); + VectorMA(dlightcolor, (1.0f / 255.0f), (qbyte *)&palette_complete[e->state_current.glowcolor], dlightcolor); + } + if (e->state_current.light[3]) + { + dlightradius = max(dlightradius, e->state_current.light[3]); + if (VectorLength2(dlightcolor) == 0) + (dlightcolor[0] += 1, dlightcolor[1] += 1, dlightcolor[2] += 1); + else + VectorMA(dlightcolor, (1.0f/256.0f), e->state_current.light, dlightcolor); } // make the dlight - if ((dlightcolor[0] || dlightcolor[1] || dlightcolor[2]) && !(e->render.flags & RENDER_VIEWMODEL) && !e->state_current.tagentity) + if (dlightradius > 0 && (dlightcolor[0] || dlightcolor[1] || dlightcolor[2]) && !(e->render.flags & RENDER_VIEWMODEL)) { - VectorCopy(origin, v); + dlightmatrix = e->render.matrix; // hack to make glowing player light shine on their gun if ((e - cl_entities) == cl.viewentity/* && !chase_active.integer*/) - v[2] += 30; - CL_AllocDlight(&e->render, v, 1, dlightcolor[0], dlightcolor[1], dlightcolor[2], 0, 0); + dlightmatrix.m[2][3] += 30; + CL_AllocDlight(&e->render, &dlightmatrix, dlightradius, dlightcolor[0], dlightcolor[1], dlightcolor[2], 0, 0, e->state_current.skin >= 16 ? e->state_current.skin : 0, e->state_current.lightstyle, !(e->state_current.lightpflags & 1), 1); } // trails need the previous frame if (e->state_previous.active && e->state_previous.modelindex == e->state_current.modelindex) @@ -808,6 +843,8 @@ void CL_LinkNetworkEntity(entity_t *e) r_refdef.entities[r_refdef.numentities++] = &e->render; if (cl_num_entities < e->state_current.number + 1) cl_num_entities = e->state_current.number + 1; + //if (cl.viewentity && e - cl_entities == cl.viewentity) + // Matrix4x4_Print(&e->render.matrix); } } @@ -939,6 +976,7 @@ void CL_RelinkBeams(void) entity_t *ent; float yaw, pitch; float forward; + matrix4x4_t tempmatrix; for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++) { @@ -986,7 +1024,11 @@ void CL_RelinkBeams(void) if (b->lightning) { if (cl_beams_lightatend.integer) - CL_AllocDlight (NULL, b->end, 200, 0.3, 0.7, 1, 0, 0); + { + // FIXME: create a matrix from the beam start/end orientation + Matrix4x4_CreateTranslate(&tempmatrix, b->end[0], b->end[1], b->end[2]); + CL_AllocDlight (NULL, &tempmatrix, 200, 0.3, 0.7, 1, 0, 0, 0, 0, true, 1); + } if (cl_beams_polygons.integer) continue; } diff --git a/cl_parse.c b/cl_parse.c index 45a8587b..43cb2c28 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -1007,6 +1007,7 @@ void CL_ParseTempEntity(void) int colorStart, colorLength, count; float velspeed, radius; qbyte *tempcolor; + matrix4x4_t tempmatrix; type = MSG_ReadByte(); switch (type) @@ -1015,7 +1016,8 @@ void CL_ParseTempEntity(void) // spike hitting wall MSG_ReadVector(pos); CL_FindNonSolidLocation(pos, pos, 4); - CL_AllocDlight(NULL, pos, 50, 0.25f, 1.00f, 0.25f, 250, 0.2); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 150, 0.25f, 1.00f, 0.25f, 250, 0.2, 0, 0, false, 1); CL_RunParticleEffect(pos, vec3_origin, 20, 30); S_StartSound(-1, 0, cl_sfx_wizhit, pos, 1, 1); break; @@ -1024,7 +1026,8 @@ void CL_ParseTempEntity(void) // spike hitting wall MSG_ReadVector(pos); CL_FindNonSolidLocation(pos, pos, 4); - CL_AllocDlight(NULL, pos, 50, 1.0f, 0.60f, 0.20f, 250, 0.2); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 150, 1.0f, 0.60f, 0.20f, 250, 0.2, 0, 0, false, 1); CL_RunParticleEffect(pos, vec3_origin, 226, 20); S_StartSound(-1, 0, cl_sfx_knighthit, pos, 1, 1); break; @@ -1054,7 +1057,8 @@ void CL_ParseTempEntity(void) CL_FindNonSolidLocation(pos, pos, 4); // LordHavoc: changed to spark shower CL_SparkShower(pos, vec3_origin, 15); - CL_AllocDlight(NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2, 0, 0, true, 1); S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1); if (rand() % 5) S_StartSound(-1, 0, cl_sfx_tink1, pos, 1, 1); @@ -1094,7 +1098,8 @@ void CL_ParseTempEntity(void) CL_FindNonSolidLocation(pos, pos, 4); // LordHavoc: changed to dust shower CL_SparkShower(pos, vec3_origin, 30); - CL_AllocDlight(NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2, 0, 0, true, 1); if (rand() % 5) S_StartSound(-1, 0, cl_sfx_tink1, pos, 1, 1); else @@ -1132,7 +1137,8 @@ void CL_ParseTempEntity(void) case TE_PLASMABURN: MSG_ReadVector(pos); CL_FindNonSolidLocation(pos, pos, 4); - CL_AllocDlight(NULL, pos, 200, 1, 1, 1, 1000, 0.2); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 200, 1, 1, 1, 1000, 0.2, 0, 0, true, 1); CL_PlasmaBurn(pos); break; // LordHavoc: added for improved gore @@ -1189,7 +1195,8 @@ void CL_ParseTempEntity(void) MSG_ReadVector(pos); CL_FindNonSolidLocation(pos, pos, 4); CL_SparkShower(pos, vec3_origin, 15); - CL_AllocDlight(NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2, 0, 0, true, 1); break; case TE_EXPLOSION: @@ -1198,7 +1205,8 @@ void CL_ParseTempEntity(void) CL_FindNonSolidLocation(pos, pos, 10); CL_ParticleExplosion(pos); // LordHavoc: boosted color from 1.0, 0.8, 0.4 to 1.25, 1.0, 0.5 - CL_AllocDlight(NULL, pos, 350, 1.25f, 1.0f, 0.5f, 700, 0.5); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 350, 1.25f, 1.0f, 0.5f, 700, 0.5, 0, 0, true, 1); S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; @@ -1207,7 +1215,8 @@ void CL_ParseTempEntity(void) MSG_ReadVector(pos); CL_FindNonSolidLocation(pos, pos, 10); CL_ParticleExplosion(pos); - CL_AllocDlight(NULL, pos, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5, 0, 0, true, 1); S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; @@ -1216,7 +1225,8 @@ void CL_ParseTempEntity(void) MSG_ReadVector(pos); CL_FindNonSolidLocation(pos, pos, 10); CL_ParticleExplosion(pos); - CL_AllocDlight(NULL, pos, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5, 0, 0, true, 1); S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; @@ -1228,7 +1238,8 @@ void CL_ParseTempEntity(void) color[0] = MSG_ReadByte() * (1.0 / 255.0); color[1] = MSG_ReadByte() * (1.0 / 255.0); color[2] = MSG_ReadByte() * (1.0 / 255.0); - CL_AllocDlight(NULL, pos, 350, color[0], color[1], color[2], 700, 0.5); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 350, color[0], color[1], color[2], 700, 0.5, 0, 0, true, 1); S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; @@ -1240,13 +1251,15 @@ void CL_ParseTempEntity(void) S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1); S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1); - CL_AllocDlight(NULL, pos, 600, 0.8f, 0.4f, 1.0f, 1200, 0.5); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 600, 0.8f, 0.4f, 1.0f, 1200, 0.5, 0, 0, true, 1); break; case TE_SMALLFLASH: MSG_ReadVector(pos); CL_FindNonSolidLocation(pos, pos, 10); - CL_AllocDlight(NULL, pos, 200, 1, 1, 1, 1000, 0.2); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 200, 1, 1, 1, 1000, 0.2, 0, 0, true, 1); break; case TE_CUSTOMFLASH: @@ -1257,7 +1270,8 @@ void CL_ParseTempEntity(void) color[0] = MSG_ReadByte() * (1.0 / 255.0); color[1] = MSG_ReadByte() * (1.0 / 255.0); color[2] = MSG_ReadByte() * (1.0 / 255.0); - CL_AllocDlight(NULL, pos, radius, color[0], color[1], color[2], radius / velspeed, velspeed); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, radius, color[0], color[1], color[2], radius / velspeed, velspeed, 0, 0, true, 1); break; case TE_FLAMEJET: @@ -1313,7 +1327,8 @@ void CL_ParseTempEntity(void) pos[0] = MSG_ReadCoord(); pos[1] = MSG_ReadCoord(); pos[2] = MSG_ReadCoord(); - CL_AllocDlight(NULL, pos, 500, 1.0f, 1.0f, 1.0f, 1500, 99.0f); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 500, 1.0f, 1.0f, 1.0f, 1500, 99.0f, 0, 0, true, 1); // CL_TeleportSplash(pos); break; @@ -1325,7 +1340,8 @@ void CL_ParseTempEntity(void) colorLength = MSG_ReadByte(); CL_ParticleExplosion2(pos, colorStart, colorLength); tempcolor = (qbyte *)&palette_complete[(rand()%colorLength) + colorStart]; - CL_AllocDlight(NULL, pos, 350, tempcolor[0] * (1.0f / 255.0f), tempcolor[1] * (1.0f / 255.0f), tempcolor[2] * (1.0f / 255.0f), 700, 0.5); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 350, tempcolor[0] * (1.0f / 255.0f), tempcolor[1] * (1.0f / 255.0f), tempcolor[2] * (1.0f / 255.0f), 700, 0.5, 0, 0, true, 1); S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; @@ -1349,7 +1365,8 @@ void CL_ParseTempEntity(void) MSG_ReadVector(pos); CL_FindNonSolidLocation(pos, pos, 10); CL_ParticleExplosion(pos); - CL_AllocDlight(NULL, pos, 500, 1.25f, 1.0f, 0.5f, 500, 9999); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 500, 1.25f, 1.0f, 0.5f, 500, 9999, 0, 0, true, 1); S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; @@ -1359,7 +1376,8 @@ void CL_ParseTempEntity(void) count = MSG_ReadByte(); CL_FindNonSolidLocation(pos, pos, 5); CL_Tei_PlasmaHit(pos, dir, count); - CL_AllocDlight(NULL, pos, 500, 0.3, 0.6, 1.0f, 2000, 9999); + Matrix4x4_CreateTranslate(&tempmatrix, pos[0], pos[1], pos[2]); + CL_AllocDlight(NULL, &tempmatrix, 500, 0.3, 0.6, 1.0f, 2000, 9999, 0, 0, true, 1); break; default: @@ -1693,10 +1711,35 @@ void CL_ParseServerMessage(void) Cmd_ExecuteString ("help", src_command); break; case svc_hidelmp: - SHOWLMP_decodehide(); + if (gamemode == GAME_TENEBRAE) + { + // repeating particle effect + MSG_ReadCoord(); + MSG_ReadCoord(); + MSG_ReadCoord(); + MSG_ReadCoord(); + MSG_ReadCoord(); + MSG_ReadCoord(); + MSG_ReadByte(); + MSG_ReadLong(); + MSG_ReadLong(); + MSG_ReadString(); + } + else + SHOWLMP_decodehide(); break; case svc_showlmp: - SHOWLMP_decodeshow(); + if (gamemode == GAME_TENEBRAE) + { + // particle effect + MSG_ReadCoord(); + MSG_ReadCoord(); + MSG_ReadCoord(); + MSG_ReadByte(); + MSG_ReadString(); + } + else + SHOWLMP_decodeshow(); break; case svc_skybox: R_SetSkyBox(MSG_ReadString()); diff --git a/client.h b/client.h index 468c8e17..692b0e50 100644 --- a/client.h +++ b/client.h @@ -75,15 +75,25 @@ typedef struct // location vec3_t origin; // stop lighting after this time - float die; + vec_t die; // color of light vec3_t color; // brightness (not really radius anymore) - float radius; + vec_t radius; // drop this each second - float decay; + vec_t decay; // the entity that owns this light (can be NULL) struct entity_render_s *ent; + // orientation/scaling/location + matrix4x4_t matrix; + // cubemap number to use on this light + int cubemapnum; + // light style which controls intensity of this light + int style; + // cast shadows + int shadow; + // corona intensity + vec_t corona; } dlight_t; @@ -499,7 +509,7 @@ extern lightstyle_t *cl_lightstyle; extern client_state_t cl; -extern void CL_AllocDlight (entity_render_t *ent, vec3_t org, float radius, float red, float green, float blue, float decay, float lifetime); +extern void CL_AllocDlight (entity_render_t *ent, matrix4x4_t *matrix, float radius, float red, float green, float blue, float decay, float lifetime, int cubemapnum, int style, int shadowenable, vec_t corona); extern void CL_DecayLights (void); //============================================================================= diff --git a/common.c b/common.c index 8af5518b..43db21a3 100644 --- a/common.c +++ b/common.c @@ -765,6 +765,8 @@ void COM_InitGameType (void) gamemode = GAME_SETHERAL; else if (strstr(name, "som")) gamemode = GAME_SOM; + else if (strstr(name, "tenebrae")) + gamemode = GAME_TENEBRAE; else gamemode = GAME_NORMAL; @@ -794,6 +796,8 @@ void COM_InitGameType (void) gamemode = GAME_SETHERAL; else if (COM_CheckParm ("-som")) gamemode = GAME_SOM; + else if (COM_CheckParm ("-tenebrae")) + gamemode = GAME_TENEBRAE; switch(gamemode) { @@ -849,6 +853,10 @@ void COM_InitGameType (void) gamename = "Son of Man"; gamedirname = "data"; break; + case GAME_TENEBRAE: + gamename = "DarkPlaces-Tenebrae"; + gamedirname = "tenebrae"; + break; default: Sys_Error("COM_InitGameType: unknown gamemode %i\n", gamemode); break; diff --git a/common.h b/common.h index 837b01c1..62796b37 100644 --- a/common.h +++ b/common.h @@ -174,6 +174,7 @@ extern struct cvar_s registered; #define GAME_FNIGGIUM 10 #define GAME_SETHERAL 11 #define GAME_SOM 12 +#define GAME_TENEBRAE 13 // full of evil hackery extern int gamemode; extern char *gamename; diff --git a/gl_models.c b/gl_models.c index 1f6fc96f..46e13975 100644 --- a/gl_models.c +++ b/gl_models.c @@ -328,7 +328,7 @@ void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightor } } -void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap) +void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap) { int c, meshnum, layernum; float fog, ifog, lightcolor2[3]; @@ -383,7 +383,7 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v if (layer->flags & ALIASLAYER_SPECULAR) { c_alias_polys += mesh->num_triangles; - R_Shadow_SpecularLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, aliasvert_vertex3f, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, lightcubemap); + R_Shadow_SpecularLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, aliasvert_vertex3f, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor2, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, lightcubemap); } else if (layer->flags & ALIASLAYER_DIFFUSE) { @@ -412,7 +412,7 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v lightcolor2[2] *= bcolor[2] * (1.0f / 255.0f); } c_alias_polys += mesh->num_triangles; - R_Shadow_DiffuseLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, aliasvert_vertex3f, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, lightcubemap); + R_Shadow_DiffuseLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, aliasvert_vertex3f, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, lightradius, lightcolor2, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, lightcubemap); } } } @@ -807,7 +807,7 @@ void R_Model_Zymotic_DrawShadowVolume(entity_render_t *ent, vec3_t relativelight // FIXME } -void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap) +void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap) { // FIXME } diff --git a/gl_rmain.c b/gl_rmain.c index c0d23b14..375f4d56 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -538,9 +538,8 @@ void R_ShadowVolumeLighting(int visiblevolumes) worldlight_t *wl; rdlight_t *rd; rmeshstate_t m; - matrix4x4_t matrix; - matrix4x4_t matrix_worldtofilter, matrix_worldtoattenuationxyz, matrix_worldtoattenuationz; - matrix4x4_t matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz; + rtexture_t *cubemaptexture; + matrix4x4_t matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz; if (visiblevolumes) { @@ -571,19 +570,19 @@ void R_ShadowVolumeLighting(int visiblevolumes) continue; cullradius = wl->cullradius; - lightradius = wl->lightradius; + lightradius = wl->radius; VectorCopy(wl->mins, clipmins); VectorCopy(wl->maxs, clipmaxs); f = d_lightstylevalue[wl->style] * (1.0f / 256.0f); - VectorScale(wl->light, f, lightcolor); + VectorScale(wl->color, f, lightcolor); if (wl->selected) { f = 2 + sin(realtime * M_PI * 4.0); VectorScale(lightcolor, f, lightcolor); } - if (r_shadow_worldshadows.integer && wl->castshadows && (gl_stencil || visiblevolumes)) + if (r_shadow_worldshadows.integer && wl->drawshadows && (gl_stencil || visiblevolumes)) { if (!visiblevolumes) R_Shadow_Stage_ShadowVolumes(); @@ -599,37 +598,23 @@ void R_ShadowVolumeLighting(int visiblevolumes) if (!visiblevolumes) { - if (r_shadow_worldshadows.integer && wl->castshadows && gl_stencil) + if (r_shadow_worldshadows.integer && wl->drawshadows && gl_stencil) R_Shadow_Stage_LightWithShadows(); else R_Shadow_Stage_LightWithoutShadows(); - // calculate world to filter matrix - //Matrix4x4_CreateFromQuakeEntity(&matrix, wl->origin[0], wl->origin[1], wl->origin[2], wl->angles[0] + cl.time * 12, wl->angles[1] + cl.time * 45, wl->angles[2], lightradius); - Matrix4x4_CreateFromQuakeEntity(&matrix, wl->origin[0], wl->origin[1], wl->origin[2], wl->angles[0], wl->angles[1], wl->angles[2], lightradius); - Matrix4x4_Invert_Simple(&matrix_worldtofilter, &matrix); - // calculate world to attenuationxyz/xy matrix - Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5, 0.5, 0.5, 0, 0, 0, 0.5); - Matrix4x4_Concat(&matrix_worldtoattenuationxyz, &matrix, &matrix_worldtofilter); - // calculate world to attenuationz matrix - matrix.m[0][0] = 0;matrix.m[0][1] = 0;matrix.m[0][2] = 0.5;matrix.m[0][3] = 0.5; - matrix.m[1][0] = 0;matrix.m[1][1] = 0;matrix.m[1][2] = 0 ;matrix.m[1][3] = 0.5; - matrix.m[2][0] = 0;matrix.m[2][1] = 0;matrix.m[2][2] = 0 ;matrix.m[2][3] = 0.5; - matrix.m[3][0] = 0;matrix.m[3][1] = 0;matrix.m[3][2] = 0 ;matrix.m[3][3] = 1; - Matrix4x4_Concat(&matrix_worldtoattenuationz, &matrix, &matrix_worldtofilter); - ent = &cl_entities[0].render; if (ent->model && ent->model->DrawLight) { Matrix4x4_Transform(&ent->inversematrix, wl->origin, relativelightorigin); Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin); - Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltolight, &wl->matrix_worldtolight, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &wl->matrix_worldtoattenuationxyz, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationz, &wl->matrix_worldtoattenuationz, &ent->matrix); if (r_shadow_staticworldlights.integer) - R_Shadow_DrawStaticWorldLight_Light(wl, &ent->matrix, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); + R_Shadow_DrawStaticWorldLight_Light(wl, &ent->matrix, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); else - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, wl->cubemap); + ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, wl->cubemap); } if (r_drawentities.integer) { @@ -642,10 +627,10 @@ void R_ShadowVolumeLighting(int visiblevolumes) { Matrix4x4_Transform(&ent->inversematrix, wl->origin, relativelightorigin); Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin); - Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, wl->cubemap); + Matrix4x4_Concat(&matrix_modeltolight, &wl->matrix_worldtolight, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &wl->matrix_worldtoattenuationxyz, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationz, &wl->matrix_worldtoattenuationz, &ent->matrix); + ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, wl->cubemap); } } } @@ -656,7 +641,7 @@ void R_ShadowVolumeLighting(int visiblevolumes) { for (lnum = 0, rd = r_dlight;lnum < r_numdlights;lnum++, rd++) { - lightradius = rd->cullradius; + lightradius = rd->radius; clipmins[0] = rd->origin[0] - lightradius; clipmins[1] = rd->origin[1] - lightradius; clipmins[2] = rd->origin[2] - lightradius; @@ -667,9 +652,14 @@ void R_ShadowVolumeLighting(int visiblevolumes) continue; cullradius = RadiusFromBoundsAndOrigin(clipmins, clipmaxs, rd->origin); - VectorScale(rd->light, (1.0f / 4096.0f), lightcolor); + VectorCopy(rd->color, lightcolor); + + if (rd->cubemapnum > 0) + cubemaptexture = R_Shadow_Cubemap(va("cubemaps/%i", rd->cubemapnum)); + else + cubemaptexture = NULL; - if (r_shadow_dlightshadows.integer && (gl_stencil || visiblevolumes)) + if (r_shadow_dlightshadows.integer && rd->shadow && (gl_stencil || visiblevolumes)) { if (!visiblevolumes) R_Shadow_Stage_ShadowVolumes(); @@ -688,33 +678,20 @@ void R_ShadowVolumeLighting(int visiblevolumes) if (!visiblevolumes) { - if (r_shadow_dlightshadows.integer && gl_stencil) + if (r_shadow_dlightshadows.integer && gl_stencil && rd->shadow) R_Shadow_Stage_LightWithShadows(); else R_Shadow_Stage_LightWithoutShadows(); - // calculate world to filter matrix - Matrix4x4_CreateFromQuakeEntity(&matrix, rd->origin[0], rd->origin[1], rd->origin[2], 0, 0, 0, lightradius); - Matrix4x4_Invert_Simple(&matrix_worldtofilter, &matrix); - // calculate world to attenuationxyz/xy matrix - Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5, 0.5, 0.5, 0, 0, 0, 0.5); - Matrix4x4_Concat(&matrix_worldtoattenuationxyz, &matrix, &matrix_worldtofilter); - // calculate world to attenuationz matrix - matrix.m[0][0] = 0;matrix.m[0][1] = 0;matrix.m[0][2] = 0.5;matrix.m[0][3] = 0.5; - matrix.m[1][0] = 0;matrix.m[1][1] = 0;matrix.m[1][2] = 0 ;matrix.m[1][3] = 0.5; - matrix.m[2][0] = 0;matrix.m[2][1] = 0;matrix.m[2][2] = 0 ;matrix.m[2][3] = 0.5; - matrix.m[3][0] = 0;matrix.m[3][1] = 0;matrix.m[3][2] = 0 ;matrix.m[3][3] = 1; - Matrix4x4_Concat(&matrix_worldtoattenuationz, &matrix, &matrix_worldtofilter); - ent = &cl_entities[0].render; if (ent->model && ent->model->DrawLight) { Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin); Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin); - Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, NULL); + Matrix4x4_Concat(&matrix_modeltolight, &rd->matrix_worldtolight, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &rd->matrix_worldtoattenuationxyz, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationz, &rd->matrix_worldtoattenuationz, &ent->matrix); + ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture); } if (r_drawentities.integer) { @@ -727,10 +704,10 @@ void R_ShadowVolumeLighting(int visiblevolumes) { Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin); Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin); - Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, NULL); + Matrix4x4_Concat(&matrix_modeltolight, &rd->matrix_worldtolight, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &rd->matrix_worldtoattenuationxyz, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationz, &rd->matrix_worldtoattenuationz, &ent->matrix); + ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture); } } } diff --git a/gl_rsurf.c b/gl_rsurf.c index 253444ea..a3ddc491 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -1851,7 +1851,7 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto } } -void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap) +void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap) { int surfnum; msurface_t *surf; @@ -1879,8 +1879,8 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v t = surf->texinfo->texture->currentframe; if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT) { - R_Shadow_DiffuseLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, lightcubemap); - R_Shadow_SpecularLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, lightcubemap); + R_Shadow_DiffuseLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, lightcubemap); + R_Shadow_SpecularLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, lightcubemap); } } } @@ -2395,15 +2395,15 @@ void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, } } -void R_Q3BSP_DrawFaceLight(entity_render_t *ent, q3mface_t *face, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap) +void R_Q3BSP_DrawFaceLight(entity_render_t *ent, q3mface_t *face, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap) { if ((face->texture->surfaceflags & Q3SURFACEFLAG_NODRAW) || !face->num_triangles) return; - R_Shadow_DiffuseLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.base, face->texture->skin.nmap, lightcubemap); - R_Shadow_SpecularLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.gloss, face->texture->skin.nmap, lightcubemap); + R_Shadow_DiffuseLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.base, face->texture->skin.nmap, lightcubemap); + R_Shadow_SpecularLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.gloss, face->texture->skin.nmap, lightcubemap); } -void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap) +void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap) { int i; q3mface_t *face; @@ -2427,7 +2427,7 @@ void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t //else for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++) if ((ent != &cl_entities[0].render || face->visframe == r_framecount) && BoxesOverlap(lightmins, lightmaxs, face->mins, face->maxs)) - R_Q3BSP_DrawFaceLight(ent, face, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, lightcubemap); + R_Q3BSP_DrawFaceLight(ent, face, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, lightcubemap); } } diff --git a/menu.c b/menu.c index 456d3aa9..4c772ece 100644 --- a/menu.c +++ b/menu.c @@ -1398,50 +1398,28 @@ void M_Menu_Options_Effects_AdjustSliders (int dir) S_LocalSound ("misc/menu3.wav"); optnum = 0; - if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&r_modellights, bound(0, r_modellights.value + dir, 8)); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&r_coronas, !r_coronas.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&gl_flashblend, !gl_flashblend.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&cl_particles, !cl_particles.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&cl_particles_quality, bound(1, cl_particles_quality.value + dir * 0.5, 4)); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&cl_explosions, !cl_explosions.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&r_explosionclip, !r_explosionclip.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&cl_stainmaps, !cl_stainmaps.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&cl_decals, !cl_decals.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&r_detailtextures, !r_detailtextures.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&cl_particles_bulletimpacts, !cl_particles_bulletimpacts.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&cl_particles_smoke, !cl_particles_smoke.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&cl_particles_sparks, !cl_particles_sparks.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&cl_particles_bubbles, !cl_particles_bubbles.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&cl_particles_blood, !cl_particles_blood.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&cl_particles_blood_alpha, bound(0.2, cl_particles_blood_alpha.value + dir * 0.1, 1)); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&cl_particles_blood_bloodhack, !cl_particles_blood_bloodhack.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&r_lerpmodels, !r_lerpmodels.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&r_lerpsprites, !r_lerpsprites.integer); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&r_wateralpha, bound(0, r_wateralpha.value + dir * 0.1, 1)); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&r_waterscroll, bound(0, r_waterscroll.value + dir * 0.5, 10)); - else if (options_effects_cursor == optnum++) - Cvar_SetValueQuick (&r_watershader, bound(0, r_watershader.value + dir * 0.25, 10)); + if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_modellights, bound(0, r_modellights.value + dir, 8)); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_coronas, bound(0, r_coronas.value + dir * 0.125, 4)); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&gl_flashblend, !gl_flashblend.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles, !cl_particles.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_quality, bound(1, cl_particles_quality.value + dir * 0.5, 4)); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_explosions, !cl_explosions.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_explosionclip, !r_explosionclip.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_stainmaps, !cl_stainmaps.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_decals, !cl_decals.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_detailtextures, !r_detailtextures.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_bulletimpacts, !cl_particles_bulletimpacts.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_smoke, !cl_particles_smoke.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_sparks, !cl_particles_sparks.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_bubbles, !cl_particles_bubbles.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_blood, !cl_particles_blood.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_blood_alpha, bound(0.2, cl_particles_blood_alpha.value + dir * 0.1, 1)); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&cl_particles_blood_bloodhack, !cl_particles_blood_bloodhack.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_lerpmodels, !r_lerpmodels.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_lerpsprites, !r_lerpsprites.integer); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_wateralpha, bound(0, r_wateralpha.value + dir * 0.1, 1)); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_waterscroll, bound(0, r_waterscroll.value + dir * 0.5, 10)); + else if (options_effects_cursor == optnum++) Cvar_SetValueQuick (&r_watershader, bound(0, r_watershader.value + dir * 0.25, 10)); } void M_Options_Effects_Draw (void) @@ -1461,7 +1439,7 @@ void M_Options_Effects_Draw (void) opty = 32 - bound(0, optcursor - (visible >> 1), max(0, OPTIONS_EFFECTS_ITEMS - visible)) * 8; M_Options_PrintSlider( " Lights Per Model", true, r_modellights.value, 0, 8); - M_Options_PrintCheckbox(" Coronas", true, r_coronas.integer); + M_Options_PrintSlider( " Corona Intensity", true, r_coronas.value, 0, 4); M_Options_PrintCheckbox(" Use Only Coronas", true, gl_flashblend.integer); M_Options_PrintCheckbox(" Particles", true, cl_particles.integer); M_Options_PrintSlider( " Particles Quality", true, cl_particles_quality.value, 1, 4); diff --git a/model_alias.c b/model_alias.c index d91ef816..f8625a8a 100644 --- a/model_alias.c +++ b/model_alias.c @@ -312,7 +312,7 @@ void Mod_BuildAliasSkinsFromSkinFiles(aliasskin_t *skin, skinfile_t *skinfile, c #define BOUNDF(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%f exceeds %f - %f)\n", loadmodel->name, VALUE, MIN, MAX); extern void R_Model_Alias_Draw(entity_render_t *ent); extern void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius); -extern void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap); +extern void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap); void Mod_IDP0_Load(model_t *mod, void *buffer) { int i, j, version, totalskins, skinwidth, skinheight, groupframes, groupskins, numverts; @@ -970,7 +970,7 @@ void Mod_IDP3_Load(model_t *mod, void *buffer) extern void R_Model_Zymotic_DrawSky(entity_render_t *ent); extern void R_Model_Zymotic_Draw(entity_render_t *ent); extern void R_Model_Zymotic_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius); -extern void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap); +extern void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap); void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer) { zymtype1header_t *pinmodel, *pheader; diff --git a/model_brush.c b/model_brush.c index 22094635..cea8a34e 100644 --- a/model_brush.c +++ b/model_brush.c @@ -2819,7 +2819,7 @@ static void Mod_Q1BSP_RoundUpToHullSize(model_t *cmodel, const vec3_t inmins, co extern void R_Model_Brush_DrawSky(entity_render_t *ent); extern void R_Model_Brush_Draw(entity_render_t *ent); extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius); -extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap); +extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap); void Mod_Q1BSP_Load(model_t *mod, void *buffer) { int i, j, k; @@ -5259,7 +5259,7 @@ static int Mod_Q3BSP_NativeContentsFromSuperContents(model_t *model, int superco extern void R_Q3BSP_DrawSky(struct entity_render_s *ent); extern void R_Q3BSP_Draw(struct entity_render_s *ent); extern void R_Q3BSP_DrawShadowVolume(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius); -extern void R_Q3BSP_DrawLight(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap); +extern void R_Q3BSP_DrawLight(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap); void Mod_Q3BSP_Load(model_t *mod, void *buffer) { int i, j; diff --git a/model_shared.h b/model_shared.h index 0aafccca..18462985 100644 --- a/model_shared.h +++ b/model_shared.h @@ -576,7 +576,7 @@ typedef struct model_s // draw a shadow volume for the model based on light source void(*DrawShadowVolume)(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius); // draw the lighting on a model (through stencil) - void(*DrawLight)(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap); + void(*DrawLight)(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap); // trace a box against this model void (*TraceBox)(struct model_s *model, int frame, struct trace_s *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask); // fields belonging to each type of model diff --git a/pr_cmds.c b/pr_cmds.c index 3a0c9d0f..9d9571a7 100644 --- a/pr_cmds.c +++ b/pr_cmds.c @@ -145,6 +145,7 @@ char *ENGINE_EXTENSIONS = "KRIMZON_SV_PARSECLIENTCOMMAND " "NEH_CMD_PLAY2 " "NEH_RESTOREGAME " +"TENEBRAE_GFX_DLIGHTS " "TW_SV_STEPCONTROL " ; diff --git a/pr_edict.c b/pr_edict.c index 2a77bac1..c447eae2 100644 --- a/pr_edict.c +++ b/pr_edict.c @@ -122,6 +122,10 @@ int eval_viewzoom; int eval_clientcolors; int eval_tag_entity; int eval_tag_index; +int eval_light_lev; +int eval_color; +int eval_style; +int eval_pflags; mfunction_t *SV_PlayerPhysicsQC; mfunction_t *EndFrameQC; @@ -176,6 +180,10 @@ void FindEdictFieldOffsets(void) eval_clientcolors = FindFieldOffset("clientcolors"); eval_tag_entity = FindFieldOffset("tag_entity"); eval_tag_index = FindFieldOffset("tag_index"); + eval_light_lev = FindFieldOffset("light_lev"); + eval_color = FindFieldOffset("color"); + eval_style = FindFieldOffset("style"); + eval_pflags = FindFieldOffset("pflags"); // LordHavoc: allowing QuakeC to override the player movement code SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics"); @@ -1225,7 +1233,11 @@ dpfield_t dpfields[] = {ev_vector, "punchvector"}, {ev_float, "clientcolors"}, {ev_entity, "tag_entity"}, - {ev_float, "tag_index"} + {ev_float, "tag_index"}, + {ev_float, "light_lev"}, + {ev_float, "color"}, + {ev_float, "style"}, + {ev_float, "pflags"} }; /* @@ -1268,7 +1280,7 @@ void PR_LoadProgs (void) if (progs->version != PROG_VERSION) Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION); - if (progs->crc != PROGHEADER_CRC) + if (progs->crc != PROGHEADER_CRC && progs->crc != 32401) // tenebrae crc also allowed Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date"); //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions); diff --git a/progs.h b/progs.h index 1483c3b4..e1e365c4 100644 --- a/progs.h +++ b/progs.h @@ -123,6 +123,10 @@ extern int eval_viewzoom; extern int eval_clientcolors; extern int eval_tag_entity; extern int eval_tag_index; +extern int eval_light_lev; +extern int eval_color; +extern int eval_style; +extern int eval_pflags; #define GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (eval_t *)((qbyte *)ed->v + fieldoffset) : NULL) diff --git a/protocol.c b/protocol.c index 86e760a5..0ded4ed4 100644 --- a/protocol.c +++ b/protocol.c @@ -17,6 +17,9 @@ entity_state_t defaultstate = 0,//unsigned short exteriormodelforclient; 0,//unsigned short nodrawtoclient; 0,//unsigned short drawonlytoclient; + {0,0,0,0},//short light[4]; + 0,//qbyte lightstyle; + 0,//qbyte lightpflags; 0,//qbyte colormap; 0,//qbyte skin; 255,//qbyte alpha; @@ -25,6 +28,7 @@ entity_state_t defaultstate = 254,//qbyte glowcolor; 0,//qbyte flags; 0,//qbyte tagindex; + {0,0,0,0,0,0}//qbyte unused[6]; }; void ClearStateToDefault(entity_state_t *s) @@ -120,6 +124,12 @@ void EntityState_Write(entity_state_t *ent, sizebuf_t *msg, entity_state_t *delt bits |= E_FLAGS; if (ent->tagindex != delta->tagindex || ent->tagentity != delta->tagentity) bits |= E_TAGATTACHMENT; + if (ent->light[0] != delta->light[0] || ent->light[1] != delta->light[1] || ent->light[2] != delta->light[2] || ent->light[3] != delta->light[3]) + bits |= E_LIGHT; + if (ent->lightstyle != delta->lightstyle) + bits |= E_LIGHTSTYLE; + if (ent->lightpflags != delta->lightpflags) + bits |= E_LIGHTPFLAGS; if (bits) // don't send anything if it hasn't changed { @@ -198,6 +208,17 @@ void EntityState_Write(entity_state_t *ent, sizebuf_t *msg, entity_state_t *delt MSG_WriteShort(msg, ent->tagentity); MSG_WriteByte(msg, ent->tagindex); } + if (bits & E_LIGHT) + { + MSG_WriteShort(msg, ent->light[0]); + MSG_WriteShort(msg, ent->light[1]); + MSG_WriteShort(msg, ent->light[2]); + MSG_WriteShort(msg, ent->light[3]); + } + if (bits & E_LIGHTSTYLE) + MSG_WriteByte(msg, ent->lightstyle); + if (bits & E_LIGHTPFLAGS) + MSG_WriteByte(msg, ent->lightpflags); } } else if (delta->active) @@ -294,6 +315,17 @@ void EntityState_ReadUpdate(entity_state_t *e, int number) e->tagentity = MSG_ReadShort(); e->tagindex = MSG_ReadByte(); } + if (bits & E_LIGHT) + { + e->light[0] = MSG_ReadShort(); + e->light[1] = MSG_ReadShort(); + e->light[2] = MSG_ReadShort(); + e->light[3] = MSG_ReadShort(); + } + if (bits & E_LIGHTSTYLE) + e->lightstyle = MSG_ReadByte(); + if (bits & E_LIGHTPFLAGS) + e->lightpflags = MSG_ReadByte(); if (developer_networkentities.integer >= 2) { @@ -328,12 +360,19 @@ void EntityState_ReadUpdate(entity_state_t *e, int number) Con_Printf(" E_SKIN %i", e->skin); if (bits & E_GLOWSIZE) - Con_Printf(" E_GLOWSIZE %i", e->glowsize * 8); + Con_Printf(" E_GLOWSIZE %i", e->glowsize * 4); if (bits & E_GLOWCOLOR) Con_Printf(" E_GLOWCOLOR %i", e->glowcolor); + + if (bits & E_LIGHT) + Con_Printf(" E_LIGHT %i:%i:%i:%i", e->light[0], e->light[1], e->light[2], e->light[3]); + if (bits & E_LIGHTPFLAGS) + Con_Printf(" E_LIGHTPFLAGS %i", e->lightpflags); if (bits & E_TAGATTACHMENT) Con_Printf(" E_TAGATTACHMENT e%i:%i", e->tagentity, e->tagindex); + if (bits & E_LIGHTSTYLE) + Con_Printf(" E_LIGHTSTYLE %i", e->lightstyle); Con_Printf("\n"); } } diff --git a/protocol.h b/protocol.h index 67417b3d..b57e4e6e 100644 --- a/protocol.h +++ b/protocol.h @@ -87,7 +87,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define U_ALPHA (1<<17) // 1 byte, 0.0-1.0 maps to 0-255, not sent if exactly 1, and the entity is not sent if <=0 unless it has effects (model effects are checked as well) #define U_SCALE (1<<18) // 1 byte, scale / 16 positive, not sent if 1.0 #define U_EFFECTS2 (1<<19) // 1 byte, this is .effects & 0xFF00 (second byte) -#define U_GLOWSIZE (1<<20) // 1 byte, encoding is float/8.0, signed (negative is darklight), not sent if 0 +#define U_GLOWSIZE (1<<20) // 1 byte, encoding is float/4.0, unsigned, not sent if 0 #define U_GLOWCOLOR (1<<21) // 1 byte, palette index, default is 254 (white), this IS used for darklight (allowing colored darklight), however the particles from a darklight are always black, not sent if default value (even if glowsize or glowtrail is set) // LordHavoc: colormod feature has been removed, because no one used it #define U_COLORMOD (1<<22) // 1 byte, 3 bit red, 3 bit green, 2 bit blue, this lets you tint an object artifically, so you could make a red rocket, or a blue fiend... @@ -319,19 +319,24 @@ typedef struct unsigned short frame; unsigned short effects; unsigned short tagentity; - unsigned short specialvisibilityradius; + unsigned short specialvisibilityradius; // larger if it has effects/light unsigned short viewmodelforclient; unsigned short exteriormodelforclient; unsigned short nodrawtoclient; unsigned short drawonlytoclient; + unsigned short light[4]; // color*256 (0.00 to almost 64.00), and radius*1 + qbyte lightstyle; + qbyte lightpflags; qbyte colormap; - qbyte skin; + qbyte skin; // also chooses cubemap for rtlights if there is no model qbyte alpha; qbyte scale; qbyte glowsize; qbyte glowcolor; qbyte flags; qbyte tagindex; + // padding to a multiple of 8 bytes (to align the double time) + qbyte unused[6]; } entity_state_t; @@ -471,15 +476,15 @@ entity_frame_t; #define E_EFFECTS2 (1<<18) #define E_GLOWSIZE (1<<19) #define E_GLOWCOLOR (1<<20) -#define E_UNUSED1 (1<<21) -#define E_UNUSED2 (1<<22) +#define E_LIGHT (1<<21) +#define E_LIGHTPFLAGS (1<<22) #define E_EXTEND3 (1<<23) #define E_SOUND1 (1<<24) #define E_SOUNDVOL (1<<25) #define E_SOUNDATTEN (1<<26) #define E_TAGATTACHMENT (1<<27) -#define E_UNUSED5 (1<<28) +#define E_LIGHTSTYLE (1<<28) #define E_UNUSED6 (1<<29) #define E_UNUSED7 (1<<30) #define E_EXTEND4 (1<<31) diff --git a/r_light.c b/r_light.c index 364e4569..2facc1ff 100644 --- a/r_light.c +++ b/r_light.c @@ -126,41 +126,69 @@ void R_BuildLightList(void) continue; rd = &r_dlight[r_numdlights++]; VectorCopy(cd->origin, rd->origin); - VectorScale(cd->color, cd->radius * 64.0f, rd->light); + VectorScale(cd->color, d_lightstylevalue[cd->style] * (1.0f / 256.0f), rd->color); + rd->radius = bound(0, cd->radius, 2048.0f); + VectorScale(rd->color, rd->radius * 64.0f, rd->light); +#if 0 rd->cullradius2 = DotProduct(rd->light, rd->light) * (0.25f / (64.0f * 64.0f)) + 4096.0f; // clamp radius to avoid overflowing division table in lightmap code - if (rd->cullradius2 > (2048.0f * 2048.0f)) - rd->cullradius2 = (2048.0f * 2048.0f); + rd->cullradius2 = bound(0, rd->cullradius2, 2048.0f*2048.0f); rd->cullradius = sqrt(rd->cullradius2); +#else + rd->cullradius = rd->radius; + rd->cullradius2 = rd->cullradius * rd->cullradius; +#endif rd->subtract = 1.0f / rd->cullradius2; rd->ent = cd->ent; + rd->cubemapnum = cd->cubemapnum; + rd->shadow = cd->shadow; + rd->corona = cd->corona; + + rd->matrix_lighttoworld = cd->matrix; + Matrix4x4_ConcatScale(&rd->matrix_lighttoworld, rd->cullradius); + Matrix4x4_Invert_Simple(&rd->matrix_worldtolight, &rd->matrix_lighttoworld); + Matrix4x4_Concat(&rd->matrix_worldtoattenuationxyz, &matrix_attenuationxyz, &rd->matrix_worldtolight); + Matrix4x4_Concat(&rd->matrix_worldtoattenuationz, &matrix_attenuationz, &rd->matrix_worldtolight); + c_dlights++; // count every dlight in use } } void R_DrawCoronas(void) { - int i; + int i, lnum; float cscale, scale, viewdist, dist; rdlight_t *rd; + worldlight_t *wl; if (!r_coronas.integer) return; R_Mesh_Matrix(&r_identitymatrix); viewdist = DotProduct(r_vieworigin, r_viewforward); + if (r_shadow_realtime_world.integer) + { + for (lnum = 0, wl = r_shadow_worldlightchain;wl;wl = wl->next, lnum++) + { + if (wl->corona * r_coronas.value > 0 && (r_shadow_debuglight.integer < 0 || r_shadow_debuglight.integer == lnum) && (dist = (DotProduct(wl->origin, r_viewforward) - viewdist)) >= 24.0f && CL_TraceLine(wl->origin, r_vieworigin, NULL, NULL, true, NULL, SUPERCONTENTS_SOLID) == 1) + { + cscale = wl->corona * r_coronas.value * 0.25f; + scale = wl->radius * 0.25f; + R_DrawSprite(GL_ONE, GL_ONE, lightcorona, true, rd->origin, r_viewright, r_viewup, scale, -scale, -scale, scale, wl->color[0] * cscale, wl->color[1] * cscale, wl->color[2] * cscale, 1); + } + } + } for (i = 0;i < r_numdlights;i++) { rd = r_dlight + i; - dist = (DotProduct(rd->origin, r_viewforward) - viewdist); - if (dist >= 24.0f && CL_TraceLine(rd->origin, r_vieworigin, NULL, NULL, true, NULL, SUPERCONTENTS_SOLID) == 1) + if (rd->corona * r_coronas.value > 0 && (dist = (DotProduct(rd->origin, r_viewforward) - viewdist)) >= 24.0f && CL_TraceLine(rd->origin, r_vieworigin, NULL, NULL, true, NULL, SUPERCONTENTS_SOLID) == 1) { - cscale = (1.0f / 131072.0f); - scale = rd->cullradius * 0.25f; + cscale = rd->corona * r_coronas.value * 0.25f; + scale = rd->radius * 0.25f; if (gl_flashblend.integer) { cscale *= 4.0f; scale *= 2.0f; } - R_DrawSprite(GL_ONE, GL_ONE, lightcorona, true, rd->origin, r_viewright, r_viewup, scale, -scale, -scale, scale, rd->light[0] * cscale, rd->light[1] * cscale, rd->light[2] * cscale, 1); + R_DrawSprite(GL_ONE, GL_ONE, lightcorona, true, rd->origin, r_viewright, r_viewup, scale, -scale, -scale, scale, rd->color[0] * cscale, rd->color[1] * cscale, rd->color[2] * cscale, 1); } } } diff --git a/r_light.h b/r_light.h index 379c1b8e..a3c7066e 100644 --- a/r_light.h +++ b/r_light.h @@ -10,6 +10,17 @@ typedef struct vec_t cullradius; // only for culling comparisons vec_t subtract; // to avoid sudden brightness change at cullradius, subtract this entity_render_t *ent; // owner of this light + + matrix4x4_t matrix_lighttoworld; + matrix4x4_t matrix_worldtolight; + matrix4x4_t matrix_worldtoattenuationxyz; + matrix4x4_t matrix_worldtoattenuationz; + + vec3_t color; + vec_t radius; + int cubemapnum; + int shadow; + vec_t corona; } rdlight_t; diff --git a/r_shadow.c b/r_shadow.c index e57f8515..060ab752 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -302,6 +302,26 @@ void R_Shadow_Init(void) R_RegisterModule("R_Shadow", r_shadow_start, r_shadow_shutdown, r_shadow_newmap); } +matrix4x4_t matrix_attenuationxyz = +{ + { + {0.5, 0.0, 0.0, 0.5}, + {0.0, 0.5, 0.0, 0.5}, + {0.0, 0.0, 0.5, 0.5}, + {0.0, 0.0, 0.0, 1.0} + } +}; + +matrix4x4_t matrix_attenuationz = +{ + { + {0.0, 0.0, 0.5, 0.5}, + {0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0} + } +}; + void R_Shadow_ResizeTriangleFacingLight(int numtris) { // make sure trianglefacinglight is big enough for this volume @@ -1259,7 +1279,7 @@ void R_Shadow_GenTexCoords_Specular_NormalCubeMap(float *out3f, int numverts, co } } -void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap) +void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap) { int renders; float color[3], color2[3]; @@ -1302,7 +1322,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element { m.texcubemap[1] = R_GetTexture(lightcubemap); m.pointer_texcoord[1] = varray_texcoord3f[1]; - R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight); } R_Mesh_State_Texture(&m); qglColorMask(1,1,1,0); @@ -1354,7 +1374,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element { m.texcubemap[1] = R_GetTexture(lightcubemap); m.pointer_texcoord[1] = varray_texcoord3f[1]; - R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight); } R_Mesh_State_Texture(&m); qglColorMask(1,1,1,0); @@ -1441,7 +1461,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element { m.texcubemap[1] = R_GetTexture(lightcubemap); m.pointer_texcoord[1] = varray_texcoord3f[1]; - R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight); } R_Mesh_State_Texture(&m); qglColorMask(1,1,1,0); @@ -1496,7 +1516,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element { m.texcubemap[1] = R_GetTexture(lightcubemap); m.pointer_texcoord[1] = varray_texcoord3f[1]; - R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight); } R_Mesh_State_Texture(&m); qglColorMask(1,1,1,0); @@ -1538,9 +1558,9 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element color[1] = bound(0, color2[1], 1); color[2] = bound(0, color2[2], 1); if (r_textureunits.integer >= 2) - R_Shadow_VertexLightingWithXYAttenuationTexture(numverts, vertex3f, normal3f, color, matrix_modeltofilter); + R_Shadow_VertexLightingWithXYAttenuationTexture(numverts, vertex3f, normal3f, color, matrix_modeltolight); else - R_Shadow_VertexLighting(numverts, vertex3f, normal3f, color, matrix_modeltofilter); + R_Shadow_VertexLighting(numverts, vertex3f, normal3f, color, matrix_modeltolight); R_Mesh_Draw(numverts, numtriangles, elements); c_rt_lightmeshes++; c_rt_lighttris += numtriangles; @@ -1548,7 +1568,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element } } -void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap) +void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap) { int renders; float color[3], color2[3], colorscale; @@ -1615,7 +1635,7 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen { m.texcubemap[1] = R_GetTexture(lightcubemap); m.pointer_texcoord[1] = varray_texcoord3f[1]; - R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight); } m.pointer_texcoord[0] = texcoord2f; R_Mesh_State_Texture(&m); @@ -1739,7 +1759,7 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen { m.texcubemap[1] = R_GetTexture(lightcubemap); m.pointer_texcoord[1] = varray_texcoord3f[1]; - R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter); + R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltolight); } m.pointer_texcoord[0] = texcoord2f; R_Mesh_State_Texture(&m); @@ -1794,7 +1814,7 @@ void R_Shadow_DrawStaticWorldLight_Shadow(worldlight_t *light, matrix4x4_t *matr R_Shadow_RenderShadowMeshVolume(light->meshchain_shadow); } -void R_Shadow_DrawStaticWorldLight_Light(worldlight_t *light, matrix4x4_t *matrix, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz) +void R_Shadow_DrawStaticWorldLight_Light(worldlight_t *light, matrix4x4_t *matrix, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz) { shadowmesh_t *mesh; R_Mesh_Matrix(matrix); @@ -1823,8 +1843,8 @@ void R_Shadow_DrawStaticWorldLight_Light(worldlight_t *light, matrix4x4_t *matri } for (mesh = light->meshchain_light;mesh;mesh = mesh->next) { - R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, mesh->map_diffuse, mesh->map_normal, light->cubemap); - R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, mesh->map_specular, mesh->map_normal, light->cubemap); + R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, mesh->map_diffuse, mesh->map_normal, light->cubemap); + R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, mesh->map_specular, mesh->map_normal, light->cubemap); } } @@ -1963,7 +1983,7 @@ void R_Shadow_FreeCubemaps(void) R_FreeTexturePool(&r_shadow_filters_texturepool); } -void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style, const char *cubemapname, int castshadow) +void R_Shadow_NewWorldLight(vec3_t origin, vec3_t angles, vec3_t color, vec_t radius, vec_t corona, int style, int shadowenable, const char *cubemapname) { int i, j, k, l, maxverts = 256, tris; float *vertex3f = NULL, mins[3], maxs[3]; @@ -1978,21 +1998,28 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style e = Mem_Alloc(r_shadow_mempool, sizeof(worldlight_t)); VectorCopy(origin, e->origin); - VectorCopy(color, e->light); - e->lightradius = radius; + VectorCopy(angles, e->angles); + VectorCopy(color, e->color); + e->radius = radius; e->style = style; if (e->style < 0 || e->style >= MAX_LIGHTSTYLES) { Con_Printf("R_Shadow_NewWorldLight: invalid light style number %i, must be >= 0 and < %i\n", e->style, MAX_LIGHTSTYLES); e->style = 0; } - e->castshadows = castshadow; + e->drawshadows = shadowenable; + e->corona = corona; - e->cullradius = e->lightradius; + Matrix4x4_CreateFromQuakeEntity(&e->matrix_lighttoworld, e->origin[0], e->origin[1], e->origin[2], e->angles[0], e->angles[1], e->angles[2], e->radius); + Matrix4x4_Invert_Simple(&e->matrix_worldtolight, &e->matrix_lighttoworld); + Matrix4x4_Concat(&e->matrix_worldtoattenuationxyz, &matrix_attenuationxyz, &e->matrix_worldtolight); + Matrix4x4_Concat(&e->matrix_worldtoattenuationz, &matrix_attenuationz, &e->matrix_worldtolight); + + e->cullradius = e->radius; for (k = 0;k < 3;k++) { - mins[k] = e->origin[k] - e->lightradius; - maxs[k] = e->origin[k] + e->lightradius; + mins[k] = e->origin[k] - e->radius; + maxs[k] = e->origin[k] + e->radius; } e->next = r_shadow_worldlightchain; @@ -2004,7 +2031,7 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style e->cubemap = R_Shadow_Cubemap(e->cubemapname); } // FIXME: rewrite this to store ALL geometry into a cache in the light - if (e->castshadows) + if (e->drawshadows) castmesh = Mod_ShadowMesh_Begin(r_shadow_mempool, 32768, 32768, NULL, NULL, NULL, false, false, true); e->meshchain_light = Mod_ShadowMesh_Begin(r_shadow_mempool, 32768, 32768, NULL, NULL, NULL, true, false, true); if (cl.worldmodel) @@ -2044,7 +2071,7 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style face->lighttemp_castshadow = false; if (!(face->texture->surfaceflags & (Q3SURFACEFLAG_NODRAW | Q3SURFACEFLAG_SKY))) { - if (e->castshadows) + if (e->drawshadows) if (!(face->texture->nativecontents & CONTENTSQ3_TRANSLUCENT)) Mod_ShadowMesh_AddMesh(r_shadow_mempool, castmesh, NULL, NULL, NULL, face->data_vertex3f, NULL, NULL, NULL, NULL, face->num_triangles, face->data_element3i); if (!(face->texture->surfaceflags & Q3SURFACEFLAG_SKY)) @@ -2121,7 +2148,7 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style if (surf->lighttemp_castshadow) { surf->lighttemp_castshadow = false; - if (e->castshadows && (surf->flags & SURF_SHADOWCAST)) + if (e->drawshadows && (surf->flags & SURF_SHADOWCAST)) Mod_ShadowMesh_AddMesh(r_shadow_mempool, castmesh, NULL, NULL, NULL, surf->mesh.data_vertex3f, NULL, NULL, NULL, NULL, surf->mesh.num_triangles, surf->mesh.data_element3i); if (!(surf->flags & SURF_DRAWSKY)) Mod_ShadowMesh_AddMesh(r_shadow_mempool, e->meshchain_light, surf->texinfo->texture->skin.base, surf->texinfo->texture->skin.gloss, surf->texinfo->texture->skin.nmap, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, surf->mesh.num_triangles, surf->mesh.data_element3i); @@ -2133,8 +2160,8 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style // limit box to light bounds (in case it grew larger) for (k = 0;k < 3;k++) { - if (e->mins[k] < e->origin[k] - e->lightradius) e->mins[k] = e->origin[k] - e->lightradius; - if (e->maxs[k] > e->origin[k] + e->lightradius) e->maxs[k] = e->origin[k] + e->lightradius; + if (e->mins[k] < e->origin[k] - e->radius) e->mins[k] = e->origin[k] - e->radius; + if (e->maxs[k] > e->origin[k] + e->radius) e->maxs[k] = e->origin[k] + e->radius; } e->cullradius = RadiusFromBoundsAndOrigin(e->mins, e->maxs, e->origin); @@ -2154,7 +2181,7 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style vertex3f = Mem_Alloc(r_shadow_mempool, maxverts * sizeof(float[3])); // now that we have the buffers big enough, construct and add // the shadow volume mesh - if (e->castshadows) + if (e->drawshadows) e->meshchain_shadow = Mod_ShadowMesh_Begin(r_shadow_mempool, 32768, 32768, NULL, NULL, NULL, false, false, true); for (mesh = castmesh;mesh;mesh = mesh->next) { @@ -2282,7 +2309,7 @@ void R_Shadow_LoadWorldLights(void) { int n, a, style, shadow; char name[MAX_QPATH], cubemapname[MAX_QPATH], *lightsstring, *s, *t; - float origin[3], radius, color[3]; + float origin[3], radius, color[3], angles[3], corona; if (cl.worldmodel == NULL) { Con_Printf("No map loaded.\n"); @@ -2310,7 +2337,12 @@ void R_Shadow_LoadWorldLights(void) shadow = false; t++; } - a = sscanf(t, "%f %f %f %f %f %f %f %d %s", &origin[0], &origin[1], &origin[2], &radius, &color[0], &color[1], &color[2], &style, cubemapname); + a = sscanf(t, "%f %f %f %f %f %f %f %d %s %f %f %f %f", &origin[0], &origin[1], &origin[2], &radius, &color[0], &color[1], &color[2], &style, cubemapname, &corona, &angles[0], &angles[1], &angles[2]); + if (a < 13) + { + corona = 0; + VectorClear(angles); + } if (a < 9) cubemapname[0] = 0; *s = '\n'; @@ -2321,7 +2353,7 @@ void R_Shadow_LoadWorldLights(void) } VectorScale(color, r_editlights_rtlightscolorscale.value, color); radius *= r_editlights_rtlightssizescale.value; - R_Shadow_NewWorldLight(origin, radius, color, style, cubemapname, shadow); + R_Shadow_NewWorldLight(origin, angles, color, radius, corona, style, shadow, cubemapname); s++; n++; } @@ -2351,7 +2383,7 @@ void R_Shadow_SaveWorldLights(void) buf = NULL; for (light = r_shadow_worldlightchain;light;light = light->next) { - sprintf(line, "%s%f %f %f %f %f %f %f %d %s\n", light->castshadows ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->lightradius / r_editlights_rtlightssizescale.value, light->light[0] / r_editlights_rtlightscolorscale.value, light->light[1] / r_editlights_rtlightscolorscale.value, light->light[2] / r_editlights_rtlightscolorscale.value, light->style, light->cubemapname ? light->cubemapname : ""); + sprintf(line, "%s%f %f %f %f %f %f %f %d %s\n", light->drawshadows ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius / r_editlights_rtlightssizescale.value, light->color[0] / r_editlights_rtlightscolorscale.value, light->color[1] / r_editlights_rtlightscolorscale.value, light->color[2] / r_editlights_rtlightscolorscale.value, light->style, light->cubemapname ? light->cubemapname : ""); if (bufchars + (int) strlen(line) > bufmaxchars) { bufmaxchars = bufchars + strlen(line) + 2048; @@ -2411,7 +2443,7 @@ void R_Shadow_LoadLightsFile(void) radius = sqrt(DotProduct(color, color) / (falloff * falloff * 8192.0f * 8192.0f)); radius = bound(15, radius, 4096); VectorScale(color, (2.0f / (8388608.0f)), color); - R_Shadow_NewWorldLight(origin, radius, color, style, NULL, true); + R_Shadow_NewWorldLight(origin, vec3_origin, color, radius, 0, style, true, NULL); s++; n++; } @@ -2565,7 +2597,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void) VectorScale(color, light, color); VectorAdd(origin, originhack, origin); if (radius >= 15) - R_Shadow_NewWorldLight(origin, radius, color, style, NULL, true); + R_Shadow_NewWorldLight(origin, vec3_origin, color, radius, 0, style, true, NULL); } } @@ -2645,13 +2677,13 @@ void R_Shadow_EditLights_Spawn_f(void) return; } color[0] = color[1] = color[2] = 1; - R_Shadow_NewWorldLight(r_editlights_cursorlocation, 200, color, 0, NULL, true); + R_Shadow_NewWorldLight(r_editlights_cursorlocation, vec3_origin, color, 200, 0, 0, true, NULL); } void R_Shadow_EditLights_Edit_f(void) { - vec3_t origin, color; - vec_t radius; + vec3_t origin, angles, color; + vec_t radius, corona; int style, shadows; char cubemapname[1024]; if (!r_editlights.integer) @@ -2665,19 +2697,21 @@ void R_Shadow_EditLights_Edit_f(void) return; } VectorCopy(r_shadow_selectedlight->origin, origin); - radius = r_shadow_selectedlight->lightradius; - VectorCopy(r_shadow_selectedlight->light, color); + VectorCopy(r_shadow_selectedlight->angles, angles); + VectorCopy(r_shadow_selectedlight->color, color); + radius = r_shadow_selectedlight->radius; style = r_shadow_selectedlight->style; if (r_shadow_selectedlight->cubemapname) strcpy(cubemapname, r_shadow_selectedlight->cubemapname); else cubemapname[0] = 0; - shadows = r_shadow_selectedlight->castshadows; + shadows = r_shadow_selectedlight->drawshadows; + corona = r_shadow_selectedlight->corona; if (!strcmp(Cmd_Argv(1), "origin")) { if (Cmd_Argc() != 5) { - Con_Printf("usage: r_editlights_edit %s x y z\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s x y z\n", Cmd_Argv(1)); return; } origin[0] = atof(Cmd_Argv(2)); @@ -2688,7 +2722,7 @@ void R_Shadow_EditLights_Edit_f(void) { if (Cmd_Argc() != 3) { - Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); return; } origin[0] = atof(Cmd_Argv(2)); @@ -2697,7 +2731,7 @@ void R_Shadow_EditLights_Edit_f(void) { if (Cmd_Argc() != 3) { - Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); return; } origin[1] = atof(Cmd_Argv(2)); @@ -2706,7 +2740,7 @@ void R_Shadow_EditLights_Edit_f(void) { if (Cmd_Argc() != 3) { - Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); return; } origin[2] = atof(Cmd_Argv(2)); @@ -2715,7 +2749,7 @@ void R_Shadow_EditLights_Edit_f(void) { if (Cmd_Argc() != 5) { - Con_Printf("usage: r_editlights_edit %s x y z\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s x y z\n", Cmd_Argv(1)); return; } origin[0] += atof(Cmd_Argv(2)); @@ -2726,7 +2760,7 @@ void R_Shadow_EditLights_Edit_f(void) { if (Cmd_Argc() != 3) { - Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); return; } origin[0] += atof(Cmd_Argv(2)); @@ -2735,7 +2769,7 @@ void R_Shadow_EditLights_Edit_f(void) { if (Cmd_Argc() != 3) { - Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); return; } origin[1] += atof(Cmd_Argv(2)); @@ -2744,16 +2778,54 @@ void R_Shadow_EditLights_Edit_f(void) { if (Cmd_Argc() != 3) { - Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); return; } origin[2] += atof(Cmd_Argv(2)); } + if (!strcmp(Cmd_Argv(1), "angles")) + { + if (Cmd_Argc() != 5) + { + Con_Printf("usage: r_editlights_edit %s x y z\n", Cmd_Argv(1)); + return; + } + angles[0] = atof(Cmd_Argv(2)); + angles[1] = atof(Cmd_Argv(3)); + angles[2] = atof(Cmd_Argv(4)); + } + else if (!strcmp(Cmd_Argv(1), "anglesx")) + { + if (Cmd_Argc() != 3) + { + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); + return; + } + angles[0] = atof(Cmd_Argv(2)); + } + else if (!strcmp(Cmd_Argv(1), "anglesy")) + { + if (Cmd_Argc() != 3) + { + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); + return; + } + angles[1] = atof(Cmd_Argv(2)); + } + else if (!strcmp(Cmd_Argv(1), "anglesz")) + { + if (Cmd_Argc() != 3) + { + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); + return; + } + angles[2] = atof(Cmd_Argv(2)); + } else if (!strcmp(Cmd_Argv(1), "color")) { if (Cmd_Argc() != 5) { - Con_Printf("usage: r_editlights_edit %s red green blue\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s red green blue\n", Cmd_Argv(1)); return; } color[0] = atof(Cmd_Argv(2)); @@ -2764,7 +2836,7 @@ void R_Shadow_EditLights_Edit_f(void) { if (Cmd_Argc() != 3) { - Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); return; } radius = atof(Cmd_Argv(2)); @@ -2773,7 +2845,7 @@ void R_Shadow_EditLights_Edit_f(void) { if (Cmd_Argc() != 3) { - Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); return; } style = atoi(Cmd_Argv(2)); @@ -2782,7 +2854,7 @@ void R_Shadow_EditLights_Edit_f(void) { if (Cmd_Argc() > 3) { - Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); return; } if (Cmd_Argc() == 3) @@ -2794,26 +2866,37 @@ void R_Shadow_EditLights_Edit_f(void) { if (Cmd_Argc() != 3) { - Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(0)); + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); return; } shadows = Cmd_Argv(2)[0] == 'y' || Cmd_Argv(2)[0] == 'Y' || Cmd_Argv(2)[0] == 't' || atoi(Cmd_Argv(2)); } + else if (!strcmp(Cmd_Argv(1), "corona")) + { + if (Cmd_Argc() != 3) + { + Con_Printf("usage: r_editlights_edit %s value\n", Cmd_Argv(1)); + return; + } + corona = atof(Cmd_Argv(2)); + } else { Con_Printf("usage: r_editlights_edit [property] [value]\n"); Con_Printf("Selected light's properties:\n"); - Con_Printf("Origin: %f %f %f\n", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]); - Con_Printf("Radius: %f\n", r_shadow_selectedlight->lightradius); - Con_Printf("Color: %f %f %f\n", r_shadow_selectedlight->light[0], r_shadow_selectedlight->light[1], r_shadow_selectedlight->light[2]); - Con_Printf("Style: %i\n", r_shadow_selectedlight->style); + Con_Printf("Origin : %f %f %f\n", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]); + Con_Printf("Angles : %f %f %f\n", r_shadow_selectedlight->angles[0], r_shadow_selectedlight->angles[1], r_shadow_selectedlight->angles[2]); + Con_Printf("Color : %f %f %f\n", r_shadow_selectedlight->color[0], r_shadow_selectedlight->color[1], r_shadow_selectedlight->color[2]); + Con_Printf("Radius : %f\n", r_shadow_selectedlight->radius); + Con_Printf("Corona : %f\n", r_shadow_selectedlight->corona); + Con_Printf("Style : %i\n", r_shadow_selectedlight->style); + Con_Printf("Shadows: %s\n", r_shadow_selectedlight->drawshadows ? "yes" : "no"); Con_Printf("Cubemap: %s\n", r_shadow_selectedlight->cubemapname); - Con_Printf("Shadows: %s\n", r_shadow_selectedlight->castshadows ? "yes" : "no"); return; } R_Shadow_FreeWorldLight(r_shadow_selectedlight); r_shadow_selectedlight = NULL; - R_Shadow_NewWorldLight(origin, radius, color, style, cubemapname, shadows); + R_Shadow_NewWorldLight(origin, angles, color, radius, corona, style, shadows, cubemapname); } extern int con_vislines; @@ -2826,12 +2909,14 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void) x = 0; y = con_vislines; sprintf(temp, "Light properties");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Origin %f %f %f", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Radius %f", r_shadow_selectedlight->lightradius);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Color %f %f %f", r_shadow_selectedlight->light[0], r_shadow_selectedlight->light[1], r_shadow_selectedlight->light[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Style %i", r_shadow_selectedlight->style);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; + sprintf(temp, "Origin %f %f %f", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; + sprintf(temp, "Angles %f %f %f", r_shadow_selectedlight->angles[0], r_shadow_selectedlight->angles[1], r_shadow_selectedlight->angles[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; + sprintf(temp, "Color %f %f %f", r_shadow_selectedlight->color[0], r_shadow_selectedlight->color[1], r_shadow_selectedlight->color[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; + sprintf(temp, "Radius %f", r_shadow_selectedlight->radius);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; + sprintf(temp, "Corona %f", r_shadow_selectedlight->corona);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; + sprintf(temp, "Style %i", r_shadow_selectedlight->style);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; + sprintf(temp, "Shadows %s", r_shadow_selectedlight->drawshadows ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; sprintf(temp, "Cubemap %s", r_shadow_selectedlight->cubemapname);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Shadows %s", r_shadow_selectedlight->castshadows ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; } void R_Shadow_EditLights_ToggleShadow_f(void) @@ -2846,7 +2931,24 @@ void R_Shadow_EditLights_ToggleShadow_f(void) Con_Printf("No selected light.\n"); return; } - R_Shadow_NewWorldLight(r_shadow_selectedlight->origin, r_shadow_selectedlight->lightradius, r_shadow_selectedlight->light, r_shadow_selectedlight->style, r_shadow_selectedlight->cubemapname, !r_shadow_selectedlight->castshadows); + R_Shadow_NewWorldLight(r_shadow_selectedlight->origin, r_shadow_selectedlight->angles, r_shadow_selectedlight->color, r_shadow_selectedlight->radius, r_shadow_selectedlight->corona, r_shadow_selectedlight->style, !r_shadow_selectedlight->drawshadows, r_shadow_selectedlight->cubemapname); + R_Shadow_FreeWorldLight(r_shadow_selectedlight); + r_shadow_selectedlight = NULL; +} + +void R_Shadow_EditLights_ToggleCorona_f(void) +{ + if (!r_editlights.integer) + { + Con_Printf("Cannot spawn light when not in editing mode. Set r_editlights to 1.\n"); + return; + } + if (!r_shadow_selectedlight) + { + Con_Printf("No selected light.\n"); + return; + } + R_Shadow_NewWorldLight(r_shadow_selectedlight->origin, r_shadow_selectedlight->angles, r_shadow_selectedlight->color, r_shadow_selectedlight->radius, !r_shadow_selectedlight->corona, r_shadow_selectedlight->style, r_shadow_selectedlight->drawshadows, r_shadow_selectedlight->cubemapname); R_Shadow_FreeWorldLight(r_shadow_selectedlight); r_shadow_selectedlight = NULL; } @@ -2900,11 +3002,16 @@ void R_Shadow_EditLights_Help_f(void) "movex x: adjust x component of light location\n" "movey y: adjust y component of light location\n" "movez z: adjust z component of light location\n" +"angles x y z : set light angles\n" +"anglesx x: set x component of light angles\n" +"anglesy y: set y component of light angles\n" +"anglesz z: set z component of light angles\n" "color r g b : set color of light (can be brighter than 1 1 1)\n" "radius radius : set radius (size) of light\n" "style style : set lightstyle of light (flickering patterns, switches, etc)\n" "cubemap basename : set filter cubemap of light (not yet supported)\n" "shadows 1/0 : turn on/off shadows\n" +"corona n : set corona intensity\n" " : print light properties to console\n" ); } @@ -2927,6 +3034,8 @@ void R_Shadow_EditLights_Init(void) Cmd_AddCommand("r_editlights_edit", R_Shadow_EditLights_Edit_f); Cmd_AddCommand("r_editlights_remove", R_Shadow_EditLights_Remove_f); Cmd_AddCommand("r_editlights_toggleshadow", R_Shadow_EditLights_ToggleShadow_f); + Cmd_AddCommand("r_editlights_togglecorona", R_Shadow_EditLights_ToggleCorona_f); Cmd_AddCommand("r_editlights_importlightentitiesfrommap", R_Shadow_EditLights_ImportLightEntitiesFromMap_f); Cmd_AddCommand("r_editlights_importlightsfile", R_Shadow_EditLights_ImportLightsFile_f); } + diff --git a/r_shadow.h b/r_shadow.h index 7a2da06e..953c883c 100644 --- a/r_shadow.h +++ b/r_shadow.h @@ -17,8 +17,8 @@ extern cvar_t r_shadow_dlightshadows; void R_Shadow_Init(void); void R_Shadow_Volume(int numverts, int numtris, const float *invertex3f, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance); -void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtofilter, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap); -void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtofilter, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap); +void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtolight, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *basetexture, rtexture_t *bumptexture, rtexture_t *lightcubemap); +void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertices, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_worldtolight, const matrix4x4_t *matrix_worldtoattenuationxyz, const matrix4x4_t *matrix_worldtoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap); void R_Shadow_ClearStencil(void); void R_Shadow_RenderShadowMeshVolume(shadowmesh_t *mesh); @@ -30,14 +30,21 @@ void R_Shadow_Stage_LightWithoutShadows(void); void R_Shadow_Stage_End(void); int R_Shadow_ScissorForBBox(const float *mins, const float *maxs); +// these never change, they are used to create attenuation matrices +extern matrix4x4_t matrix_attenuationxyz; +extern matrix4x4_t matrix_attenuationz; + +rtexture_t *R_Shadow_Cubemap(const char *basename); + typedef struct worldlight_s { // saved properties vec3_t origin; - vec_t lightradius; - vec3_t light; vec3_t angles; - int castshadows; + vec3_t color; + vec_t radius; + vec_t corona; + int drawshadows; char *cubemapname; // shadow volumes are done entirely in model space, so there are no matrices for dealing with them... @@ -45,8 +52,8 @@ typedef struct worldlight_s // note that the world to light matrices are inversely scaled (divided) by lightradius // matrix for transforming world coordinates to light filter coordinates - //matrix4x4_t matrix_worldtofilter; - // based on worldtofilter this transforms -1 to +1 to 0 to 1 for purposes + //matrix4x4_t matrix_worldtolight; + // based on worldtolight this transforms -1 to +1 to 0 to 1 for purposes // of attenuation texturing in full 3D (z result often ignored) //matrix4x4_t matrix_worldtoattenuationxyz; // this transforms only the Z to S, and T is always 0.5 @@ -61,6 +68,11 @@ typedef struct worldlight_s int style; int selected; + matrix4x4_t matrix_lighttoworld; + matrix4x4_t matrix_worldtolight; + matrix4x4_t matrix_worldtoattenuationxyz; + matrix4x4_t matrix_worldtoattenuationz; + // premade shadow volumes and lit surfaces to render shadowmesh_t *meshchain_shadow; shadowmesh_t *meshchain_light; @@ -72,6 +84,6 @@ extern worldlight_t *r_shadow_worldlightchain; void R_Shadow_UpdateWorldLightSelection(void); void R_Shadow_DrawStaticWorldLight_Shadow(worldlight_t *light, matrix4x4_t *matrix); -void R_Shadow_DrawStaticWorldLight_Light(worldlight_t *light, matrix4x4_t *matrix, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz); +void R_Shadow_DrawStaticWorldLight_Light(worldlight_t *light, matrix4x4_t *matrix, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz); #endif diff --git a/server.h b/server.h index fdc94cd2..de23230a 100644 --- a/server.h +++ b/server.h @@ -178,6 +178,7 @@ typedef struct client_s #define MOVETYPE_BOUNCE 10 #define MOVETYPE_BOUNCEMISSILE 11 // bounce w/o gravity #define MOVETYPE_FOLLOW 12 // track movement of aiment +#define MOVETYPE_FAKEPUSH 13 // tenebrae's push that doesn't push // edict->solid values #define SOLID_NOT 0 // no interaction with other objects diff --git a/sv_main.c b/sv_main.c index afc29be8..9893dc36 100644 --- a/sv_main.c +++ b/sv_main.c @@ -805,7 +805,18 @@ void SV_PrepareEntitiesForSending(void) if (cs.viewmodelforclient) cs.flags |= RENDER_VIEWMODEL; // show relative to the view - cs.specialvisibilityradius = 0; + f = GETEDICTFIELDVALUE(ent, eval_color)->vector[0]*256; + cs.light[0] = (unsigned short)bound(0, f, 65535); + f = GETEDICTFIELDVALUE(ent, eval_color)->vector[1]*256; + cs.light[1] = (unsigned short)bound(0, f, 65535); + f = GETEDICTFIELDVALUE(ent, eval_color)->vector[2]*256; + cs.light[2] = (unsigned short)bound(0, f, 65535); + f = GETEDICTFIELDVALUE(ent, eval_light_lev)->_float; + cs.light[3] = (unsigned short)bound(0, f, 65535); + cs.lightstyle = (qbyte)GETEDICTFIELDVALUE(ent, eval_style)->_float; + cs.lightpflags = (qbyte)GETEDICTFIELDVALUE(ent, eval_pflags)->_float; + + cs.specialvisibilityradius = cs.light[3]; if (cs.glowsize) cs.specialvisibilityradius = max(cs.specialvisibilityradius, cs.glowsize * 4); if (cs.flags & RENDER_GLOWTRAIL) diff --git a/sv_phys.c b/sv_phys.c index 82b74882..62b1ff62 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -703,7 +703,8 @@ void SV_PushMove (edict_t *pusher, float movetime) if (check->v->movetype == MOVETYPE_PUSH || check->v->movetype == MOVETYPE_NONE || check->v->movetype == MOVETYPE_FOLLOW - || check->v->movetype == MOVETYPE_NOCLIP) + || check->v->movetype == MOVETYPE_NOCLIP + || check->v->movetype == MOVETYPE_FAKEPUSH) continue; // if the entity is standing on the pusher, it will definitely be moved @@ -1413,6 +1414,7 @@ void SV_Physics (void) switch ((int) ent->v->movetype) { case MOVETYPE_PUSH: + case MOVETYPE_FAKEPUSH: SV_Physics_Pusher (ent); break; case MOVETYPE_NONE: diff --git a/todo b/todo index fd77b166..2b2c5e06 100644 --- a/todo +++ b/todo @@ -35,6 +35,18 @@ -n darkplaces: server is starting before the "port" cvar is set by commandline and scripts? (yummyluv) -n darkplaces: typing ip in join game menu should show 'trying' and 'no response' after a while, or 'no network' if networking is not initialized (yummyluv) -n dpmod: make grapple off-hand (joe hill) +0 darkplaces: change cl_fakelocalping_min and _max to only lag by half each way, as currently it results in 2x ping +0 darkplaces: make MAX_PACKETFRAGMENT a property of each net connection, so memory loopbacks could use huge limits (Sajt) +d darkplaces: add extension for tenebrae dlight entities +0 darkplaces: fix broken mouse button display in key binding menu, it shows ??? for mouse buttons (Mercury, Tomaz) +0 darkplaces: fix broken key repeat on backspace key in console (Mercury) +d darkplaces: add constant insertion capabilities to Image_CopyMux +1 darkplaces: add palette conversion capabilities to Image_CopyMux +0 darkplaces: add scaling capabilities to Image_CopyMux +4 dpmod: figure out why intermission camera pitch changes after a moment (Tomaz) +0 darkplaces: add -benchmark commandline option which plays a demo, appends the resulting min/max/avg fps to gamedir/benchmark.log with commandline so people know what settings were used, like +exec realtimelow.cfg, +exec realtimemed.cfg, etc (romi) +0 darkplaces: keep track of min and max fps (based on single frame frametime) during timedemo and print these stats (romi) +d darkplaces: add tenebrae light entity properties, like cubemap and style and such -n darkplaces: implement cubemap support on rtlights (romi, Vermeulen, Mitchell) d darkplaces: add r_shadow_realtime_world_lightmaps cvar to control lightmap brightness (Mitchell) -n darkplaces: add gl_lightmaps cvar to disable texturing except lightmaps for testing (Vic) -- 2.39.2