]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
moved light matrix generation out of the render code and into the light creation...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 21 Feb 2004 07:37:36 +0000 (07:37 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 21 Feb 2004 07:37:36 +0000 (07:37 +0000)
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

27 files changed:
cgame_api.h
cgamevm.c
cl_main.c
cl_parse.c
client.h
common.c
common.h
gl_models.c
gl_rmain.c
gl_rsurf.c
menu.c
model_alias.c
model_brush.c
model_shared.h
pr_cmds.c
pr_edict.c
progs.h
protocol.c
protocol.h
r_light.c
r_light.h
r_shadow.c
r_shadow.h
server.h
sv_main.c
sv_phys.c
todo

index 8e7c4a572145a6934cc21df7c5ccd1c66c7582bf..01eb847fb371765f22aa969c937164b648836b4c 100644 (file)
@@ -24,7 +24,8 @@ cgdrawentity_t;
 typedef struct cgdrawlight_s
 {
        float origin[3];
-       float light[3];
+       float color[3];
+       float radius;
 }
 cgdrawlight_t;
 
index a2dc929462c9dbade642f56abfab1723adb682eb..721c339212d61246b8258e6f4c2ffceca0bea580 100644 (file)
--- 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)
index 2ea477a3c4dc75bc501978c69e704975239f5856..42b01de1846b8194feaa63155b5202635d077190 100644 (file)
--- 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;
                }
index 45a8587b82aaac35ed8da3770a631100476641e5..43cb2c28b976d9224e6724d1980958c844b13f9e 100644 (file)
@@ -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());
index 468c8e1727986d8e521d756e308afc699f6fcf2b..692b0e50ad2df8e175e501a24bd06ce2d36fad91 100644 (file)
--- 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);
 
 //=============================================================================
index 8af5518b1ef3e0ac9baff0a141ad3706d294cd2d..43db21a3237c60848320995ff79055067a6d4496 100644 (file)
--- 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;
index 837b01c16463b5440b9f2625f2261be00e842937..62796b3799db926c4849041c4a6e7660e5dcb60f 100644 (file)
--- 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;
index 1f6fc96ff7bad12b6b359c8e8b47a7000372fd3c..46e13975a01b0de58ec0b8bcaa01351520f1af35 100644 (file)
@@ -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
 }
index c0d23b14322d382bedc7aa9494e0b27d67487ce6..375f4d566674e0fc20abad256543ea2819d9a6b0 100644 (file)
@@ -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);
                                                }
                                        }
                                }
index 253444eafc3a0181b31e81349859c2b83e762a5f..a3ddc491ee50b5c5ade5fe812a2cdd6e885ee18b 100644 (file)
@@ -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 456d3aa937b93900a95d6befce60e9a67c9cf433..4c772eceb40f74f52fd506e8f5ee99d4e5b876a4 100644 (file)
--- 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);
index d91ef816754e59cf9a7be021766369a2650ab454..f8625a8a3f26c0502a95e57316ce7942b6ca126e 100644 (file)
@@ -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;
index 22094635c5ce89dbebb90cb7c4ca3a095727628a..cea8a34effeefa0b40ae4519dc8399d6e54e2bd4 100644 (file)
@@ -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;
index 0aafccca4610ad0a5f12d88783159e6a66ff4383..18462985b2118aaadd857bb29a7e102928f25f32 100644 (file)
@@ -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
index 3a0c9d0f974329e37f54228f4738220d89ce8f32..9d9571a730041a0169a57994f38836b40862f4d4 100644 (file)
--- 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 "
 ;
 
index 2a77bac1d4df77add0a2927f635045d3f2c6103d..c447eae2bccdb73115cd680b7f6f4e4365889bd3 100644 (file)
@@ -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 1483c3b45342929809787a6cd3930841a0ec0013..e1e365c4166c9b70454375585277777783666e98 100644 (file)
--- 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)
 
index 86e760a51210bd82da3b4700127b7cfbfc20f9af..0ded4ed4e2c68f82a51bd9325b8f3b76c2ae7789 100644 (file)
@@ -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");
        }
 }
index 67417b3d6c7e9c11ef2ab75c7f7a35f8b7decfea..b57e4e6e25191677740bf7abc1c17e29b71514e5 100644 (file)
@@ -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)
index 364e456964bc71538ae7c73972f429ffc2f56d86..2facc1ffe279ccc1910b95fc060e8efb5e890234 100644 (file)
--- 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);
                }
        }
 }
index 379c1b8e2ddf873c2f7c6f98b7e54fb99dfd6d35..a3c7066e26fbe81c9177f3b8d948109f2fc57ca8 100644 (file)
--- 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;
 
index e57f8515a8bcf38d842e14ac2f7120b19a694df8..060ab75280bbaa92edea79d48d06587d7d620881 100644 (file)
@@ -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"
 "<nothing> : 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);
 }
+
index 7a2da06ee8e4ff81bd325526ae5b35ee8ecc272c..953c883cc7f3a391a11083a41fa37bdaf6076d46 100644 (file)
@@ -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
index fdc94cd2187d28b53c59c1e6dfa54776082cc9bf..de23230a57af5d8455c31d30f394606f6b25b2f4 100644 (file)
--- 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
index afc29be8f473b0faf8d2e350685c95258b9cb8ef..9893dc367afe252a22dc8579b65d66d398221a29 100644 (file)
--- 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)
index 82b74882ab9c7c5ec1e7c1b32a632fc83ee84ef8..62b1ff62ac55bb3a517cb3bfd30da68588a77468 100644 (file)
--- 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 fd77b1668bbbf3d378a8367c3c18c91a307b66eb..2b2c5e061d7c18d505757d0ef0cec834f0738ae1 100644 (file)
--- a/todo
+++ b/todo
 -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)