]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
fixed some dynamic lighting bugs related to glowing self
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 16 Oct 2002 21:48:14 +0000 (21:48 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 16 Oct 2002 21:48:14 +0000 (21:48 +0000)
rmeshstate_t now has alphascale
now clears stencil from shadows differently (draws shadow volume over again to clear)
R_LightModel now does GL_Color or GL_UseColorArray depending on whether the model has any shading
model->DrawBaseLighting function is gone, now just a few special cases in the normal Draw function
removed R_NotCulledBox
added PVS_CullBox, R_CullSphere, and PVS_CullSphere
visiblevolume flag is gone from shadow rendering code (visible volumes are now automatic depending on what stage the shadow system is in)
R_DrawShadowVolumes is gone (now just a special option to R_ShadowVolumeLighting)
cubemap textures now upload correctly
doubled the bumpyness of surfaces to make bumpmapping noticable (still less than tenebrae)
fixed crash when loading external map textures
now supports _luma as an alternate name for _glow map textures (tenebrae compatibility)
can now override _bump, _gloss, and _glow/_luma textures that were generated from the map
bumpmapping works on the map now (that was a stupid typo...)
now uses alpha buffering for multi-pass lighting effects
r_shadows 3 now works on Geforce2 (2tex no3D 3 pass per layer) and Radeon (2tex 3D 2 pass per layer - Radeon has 3 texture units but the lighting code is most efficient with 2 units, and 3D textures use up 2 texture units on Radeon... lame...)
gloss isn't working yet
r_shadows 3 mode supports up to 64x overbright lighting now (by rendering light multiple times)
fixed palettes (this fixes oddities like seeing sky behind fullbrights)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2531 d7cf8633-e32d-0410-b094-e92efae38249

20 files changed:
cl_main.c
gl_backend.c
gl_backend.h
gl_models.c
gl_rmain.c
gl_rsurf.c
gl_textures.c
image.c
model_alias.c
model_brush.c
model_brush.h
model_shared.h
model_sprite.c
palette.c
r_light.c
r_shadow.c
r_shadow.h
render.h
vid_glx.c
vid_wgl.c

index 1e04c31e793ee2772c1334d3c46e71da4771a5fa..819dae89606f95532c8ee6f23f980d1d1543e959 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -717,7 +717,7 @@ static void CL_RelinkNetworkEntities()
                {
                        VectorCopy(neworg, v);
                        // hack to make glowing player light shine on their gun
-                       if (i == cl.viewentity && !chase_active.integer)
+                       if (i == cl.viewentity/* && !chase_active.integer*/)
                                v[2] += 30;
                        CL_AllocDlight (&ent->render, v, 1, dlightcolor[0], dlightcolor[1], dlightcolor[2], 0, 0);
                }
index c9d9ec8a89bd2c737c761b1a3738f99e6d0700d2..c8ab4bef026ce66120b07b5e86a05c5a2ab03763 100644 (file)
@@ -291,7 +291,7 @@ typedef struct gltextureunit_s
 {
        unsigned int t1d, t2d, t3d, tcubemap;
        unsigned int arrayenabled;
-       float rgbscale;
+       float rgbscale, alphascale;
        int combinergb, combinealpha;
        // FIXME: add more combine stuff
 }
@@ -327,6 +327,7 @@ void GL_SetupTextureState(void)
                unit->t3d = 0;
                unit->tcubemap = 0;
                unit->rgbscale = 1;
+               unit->alphascale = 1;
                unit->combinergb = GL_MODULATE;
                unit->combinealpha = GL_MODULATE;
                unit->arrayenabled = false;
@@ -562,6 +563,7 @@ void R_Mesh_Finish(void)
                if (gl_combine.integer)
                {
                        qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1);CHECKGLERROR
+                       qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);CHECKGLERROR
                }
        }
        qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
@@ -637,7 +639,7 @@ void R_Mesh_MainState(const rmeshstate_t *m)
 void R_Mesh_TextureState(const rmeshstate_t *m)
 {
        int i, combinergb, combinealpha;
-       float rgbscale;
+       float scale;
        gltextureunit_t *unit;
 
        BACKENDACTIVECHECK
@@ -764,14 +766,23 @@ void R_Mesh_TextureState(const rmeshstate_t *m)
                                qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, (unit->tcubemap = m->texcubemap[i]));CHECKGLERROR
                        }
                }
-               rgbscale = max(m->texrgbscale[i], 1);
-               if (gl_state.units[i].rgbscale != rgbscale)
+               scale = max(m->texrgbscale[i], 1);
+               if (gl_state.units[i].rgbscale != scale)
+               {
+                       if (gl_state.unit != i)
+                       {
+                               qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
+                       }
+                       qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (gl_state.units[i].rgbscale = scale));CHECKGLERROR
+               }
+               scale = max(m->texalphascale[i], 1);
+               if (gl_state.units[i].alphascale != scale)
                {
                        if (gl_state.unit != i)
                        {
                                qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR
                        }
-                       qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (gl_state.units[i].rgbscale = rgbscale));CHECKGLERROR
+                       qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, (gl_state.units[i].alphascale = scale));CHECKGLERROR
                }
        }
 }
@@ -823,7 +834,7 @@ void R_ClearScreen(void)
                // clear to black
                qglClearColor(0,0,0,0);CHECKGLERROR
                // clear the screen
-               qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);CHECKGLERROR
+               qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (gl_stencil ? GL_STENCIL_BUFFER_BIT : 0));CHECKGLERROR
                // set dithering mode
                if (gl_dither.integer)
                {
index 587575458e493703c30272fbc3abdc42964638b1..40bb6cee53679f9d452a478bb702f0b15866b1dd 100644 (file)
@@ -35,6 +35,7 @@ typedef struct
        int tex3d[MAX_TEXTUREUNITS];
        int texcubemap[MAX_TEXTUREUNITS];
        int texrgbscale[MAX_TEXTUREUNITS]; // used only if COMBINE is present
+       int texalphascale[MAX_TEXTUREUNITS]; // used only if COMBINE is present
        int texcombinergb[MAX_TEXTUREUNITS]; // works with or without combine for some operations
        int texcombinealpha[MAX_TEXTUREUNITS]; // does nothing without combine
 }
index 4126c63a42c349b876b87b730a5830100a0c14fa..f77d722eeec2ec85f44311e60bb33c37f075b857 100644 (file)
@@ -289,7 +289,6 @@ void R_DrawQ1Q2AliasModelCallback (const void *calldata1, int calldata2)
                        varray_texcoord[0][i + 1] *= 8.0f;
                }
                R_LightModel(ent, model->numverts, varray_vertex, aliasvert_normals, varray_color, colorscale, colorscale, colorscale, false);
-               GL_UseColorArray();
                R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
                return;
        }
@@ -330,10 +329,7 @@ void R_DrawQ1Q2AliasModelCallback (const void *calldata1, int calldata2)
                if (fullbright)
                        GL_Color(colorscale * ifog, colorscale * ifog, colorscale * ifog, ent->alpha);
                else
-               {
-                       GL_UseColorArray();
                        R_LightModel(ent, model->numverts, varray_vertex, aliasvert_normals, varray_color, colorscale * ifog, colorscale * ifog, colorscale * ifog, false);
-               }
                R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
                c_alias_polys += model->numtris;
                blendfunc1 = GL_SRC_ALPHA;
@@ -361,10 +357,7 @@ void R_DrawQ1Q2AliasModelCallback (const void *calldata1, int calldata2)
                                if (pantsfullbright)
                                        GL_Color(pantscolor[0] * colorscale * ifog, pantscolor[1] * colorscale * ifog, pantscolor[2] * colorscale * ifog, ent->alpha);
                                else
-                               {
-                                       GL_UseColorArray();
                                        R_LightModel(ent, model->numverts, varray_vertex, aliasvert_normals, varray_color, pantscolor[0] * colorscale * ifog, pantscolor[1] * colorscale * ifog, pantscolor[2] * colorscale * ifog, false);
-                               }
                                R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
                                c_alias_polys += model->numtris;
                                blendfunc1 = GL_SRC_ALPHA;
@@ -390,10 +383,7 @@ void R_DrawQ1Q2AliasModelCallback (const void *calldata1, int calldata2)
                                if (shirtfullbright)
                                        GL_Color(shirtcolor[0] * colorscale * ifog, shirtcolor[1] * colorscale * ifog, shirtcolor[2] * colorscale * ifog, ent->alpha);
                                else
-                               {
-                                       GL_UseColorArray();
                                        R_LightModel(ent, model->numverts, varray_vertex, aliasvert_normals, varray_color, shirtcolor[0] * colorscale * ifog, shirtcolor[1] * colorscale * ifog, shirtcolor[2] * colorscale * ifog, false);
-                               }
                                R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
                                c_alias_polys += model->numtris;
                                blendfunc1 = GL_SRC_ALPHA;
@@ -454,64 +444,6 @@ void R_Model_Alias_DrawFakeShadow (entity_render_t *ent)
        model_t *model;
        float *v, planenormal[3], planedist, dist, projection[3], floororigin[3], surfnormal[3], lightdirection[3], v2[3];
 
-       /*
-       if (r_shadows.integer > 1)
-       {
-               float f, lightscale, lightcolor[3];
-               vec3_t temp;
-               mlight_t *sl;
-               rdlight_t *rd;
-               memset(&m, 0, sizeof(m));
-               m.blendfunc1 = GL_ONE;
-               m.blendfunc2 = GL_ONE;
-               R_Mesh_State(&m);
-               R_Mesh_Matrix(&ent->matrix);
-               for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights;i++, sl++)
-               {
-                       if (d_lightstylevalue[sl->style] > 0)
-                       {
-                               VectorSubtract(ent->origin, sl->origin, temp);
-                               f = DotProduct(temp,temp);
-                               if (f < (ent->model->radius2 + sl->cullradius2))
-                               {
-                                       model = ent->model;
-                                       R_Mesh_ResizeCheck(model->numverts * 2);
-                                       R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals);
-                                       Matrix4x4_Transform(&ent->inversematrix, sl->origin, temp);
-                                       GL_Color(0.1 * r_colorscale, 0.025 * r_colorscale, 0.0125 * r_colorscale, 1);
-                                       R_Shadow_Volume(model->numverts, model->numtris, varray_vertex, model->mdlmd2data_indices, model->mdlmd2data_triangleneighbors, temp, sl->cullradius + model->radius - sqrt(f), true);
-                                       GL_UseColorArray();
-                                       lightscale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f);
-                                       VectorScale(sl->light, lightscale, lightcolor);
-                                       R_Shadow_VertexLight(model->numverts, varray_vertex, aliasvert_normals, temp, sl->cullradius2, sl->distbias, sl->subtract, lightcolor);
-                                       R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
-                               }
-                       }
-               }
-               for (i = 0, rd = r_dlight;i < r_numdlights;i++, rd++)
-               {
-                       if (ent != rd->ent)
-                       {
-                               VectorSubtract(ent->origin, rd->origin, temp);
-                               f = DotProduct(temp,temp);
-                               if (f < (ent->model->radius2 + rd->cullradius2))
-                               {
-                                       model = ent->model;
-                                       R_Mesh_ResizeCheck(model->numverts * 2);
-                                       R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals);
-                                       Matrix4x4_Transform(&ent->inversematrix, rd->origin, temp);
-                                       GL_Color(0.1 * r_colorscale, 0.025 * r_colorscale, 0.0125 * r_colorscale, 1);
-                                       R_Shadow_Volume(model->numverts, model->numtris, varray_vertex, model->mdlmd2data_indices, model->mdlmd2data_triangleneighbors, temp, rd->cullradius + model->radius - sqrt(f), true);
-                                       GL_UseColorArray();
-                                       R_Shadow_VertexLight(model->numverts, varray_vertex, aliasvert_normals, temp, rd->cullradius2, LIGHTOFFSET, rd->subtract, rd->light);
-                                       R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
-                               }
-                       }
-               }
-               return;
-       }
-       */
-
        lightdirection[0] = 0.5;
        lightdirection[1] = 0.2;
        lightdirection[2] = -1;
@@ -559,16 +491,7 @@ void R_Model_Alias_DrawFakeShadow (entity_render_t *ent)
        R_Mesh_Draw(model->numverts, model->numtris, model->mdlmd2data_indices);
 }
 
-void R_Model_Alias_DrawBaseLighting(entity_render_t *ent)
-{
-       R_Mesh_Matrix(&ent->matrix);
-       GL_Color(0, 0, 0, 1);
-       R_Mesh_ResizeCheck(ent->model->numverts);
-       R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals);
-       R_Mesh_Draw(ent->model->numverts, ent->model->numtris, ent->model->mdlmd2data_indices);
-}
-
-void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume)
+void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius)
 {
        float projectdistance;
        projectdistance = lightradius + ent->model->radius - sqrt(DotProduct(relativelightorigin, relativelightorigin));
@@ -577,7 +500,7 @@ void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightor
                R_Mesh_Matrix(&ent->matrix);
                R_Mesh_ResizeCheck(ent->model->numverts * 2);
                R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals);
-               R_Shadow_Volume(ent->model->numverts, ent->model->numtris, varray_vertex, ent->model->mdlmd2data_indices, ent->model->mdlmd2data_triangleneighbors, relativelightorigin, lightradius, projectdistance, visiblevolume);
+               R_Shadow_Volume(ent->model->numverts, ent->model->numtris, varray_vertex, ent->model->mdlmd2data_indices, ent->model->mdlmd2data_triangleneighbors, relativelightorigin, lightradius, projectdistance);
        }
 }
 
index 4a8d46f5c5ac6d7e9eeef77c1166a50f116cd37b..6e24c18335e2cdde148ee909d8989ffa4a4bf493 100644 (file)
@@ -330,7 +330,7 @@ void GL_Init (void)
        Con_Printf ("\nengine extensions: %s\n", ENGINE_EXTENSIONS);
 }
 
-int R_CullBox(const vec3_t emins, const vec3_t emaxs)
+int R_CullBox(const vec3_t mins, const vec3_t maxs)
 {
        int i;
        mplane_t *p;
@@ -341,35 +341,35 @@ int R_CullBox(const vec3_t emins, const vec3_t emaxs)
                {
                default:
                case 0:
-                       if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
+                       if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
                                return true;
                        break;
                case 1:
-                       if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
+                       if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
                                return true;
                        break;
                case 2:
-                       if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
+                       if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
                                return true;
                        break;
                case 3:
-                       if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
+                       if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
                                return true;
                        break;
                case 4:
-                       if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
+                       if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
                                return true;
                        break;
                case 5:
-                       if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
+                       if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
                                return true;
                        break;
                case 6:
-                       if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
+                       if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
                                return true;
                        break;
                case 7:
-                       if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
+                       if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
                                return true;
                        break;
                }
@@ -377,48 +377,62 @@ int R_CullBox(const vec3_t emins, const vec3_t emaxs)
        return false;
 }
 
-int R_NotCulledBox(const vec3_t emins, const vec3_t emaxs)
+int PVS_CullBox(const vec3_t mins, const vec3_t maxs)
 {
-       int i;
-       mplane_t *p;
-       for (i = 0;i < 4;i++)
+       int stackpos, sides;
+       mnode_t *node, *stack[4096];
+       stackpos = 0;
+       stack[stackpos++] = cl.worldmodel->nodes;
+       while (stackpos)
        {
-               p = frustum + i;
-               switch(p->signbits)
+               node = stack[--stackpos];
+               if (node->contents < 0)
                {
-               default:
-               case 0:
-                       if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
-                               return false;
-                       break;
-               case 1:
-                       if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
+                       if (((mleaf_t *)node)->pvsframe == cl.worldmodel->pvsframecount)
                                return false;
-                       break;
-               case 2:
-                       if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
-                               return false;
-                       break;
-               case 3:
-                       if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
-                               return false;
-                       break;
-               case 4:
-                       if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
-                               return false;
-                       break;
-               case 5:
-                       if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
-                               return false;
-                       break;
-               case 6:
-                       if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
-                               return false;
-                       break;
-               case 7:
-                       if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
+               }
+               else
+               {
+                       sides = BoxOnPlaneSide(mins, maxs, node->plane);
+                       if (sides & 2 && stackpos < 4096)
+                               stack[stackpos++] = node->children[1];
+                       if (sides & 1 && stackpos < 4096)
+                               stack[stackpos++] = node->children[0];
+               }
+       }
+       return true;
+}
+
+int R_CullSphere(const vec3_t origin, vec_t radius)
+{
+       return (DotProduct(frustum[0].normal, origin) + radius < frustum[0].dist
+            || DotProduct(frustum[1].normal, origin) + radius < frustum[1].dist
+            || DotProduct(frustum[2].normal, origin) + radius < frustum[2].dist
+            || DotProduct(frustum[3].normal, origin) + radius < frustum[3].dist);
+}
+
+int PVS_CullSphere(const vec3_t origin, vec_t radius)
+{
+       int stackpos;
+       mnode_t *node, *stack[4096];
+       float dist;
+       stackpos = 0;
+       stack[stackpos++] = cl.worldmodel->nodes;
+       while (stackpos)
+       {
+               node = stack[--stackpos];
+               if (node->contents < 0)
+               {
+                       if (((mleaf_t *)node)->pvsframe == cl.worldmodel->pvsframecount)
                                return false;
-                       break;
+               }
+               else
+               {
+                       dist = PlaneDiff(origin, node->plane);
+                       if (dist <= radius)
+                               stack[stackpos++] = node->children[1];
+                       if (dist >= -radius)
+                               stack[stackpos++] = node->children[0];
                }
        }
        return true;
@@ -469,7 +483,10 @@ static void R_MarkEntities (void)
                Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix);
                R_LerpAnimation(ent);
                R_UpdateEntLights(ent);
-               if (R_NotCulledBox(ent->mins, ent->maxs))
+               if (!R_CullSphere(ent->origin, ent->model->radius * ent->scale)
+                && !PVS_CullSphere(ent->origin, ent->model->radius * ent->scale)
+                && !R_CullBox(ent->mins, ent->maxs)
+                && !PVS_CullBox(ent->mins, ent->maxs))
                {
                        ent->visframe = r_framecount;
                        R_FarClip_Box(ent->mins, ent->maxs);
@@ -522,7 +539,7 @@ void R_DrawViewModel (void)
 }
 
 void R_DrawNoModel(entity_render_t *ent);
-void R_DrawModels (int baselighting)
+void R_DrawModels ()
 {
        int i;
        entity_render_t *ent;
@@ -536,16 +553,8 @@ void R_DrawModels (int baselighting)
                ent = r_refdef.entities[i];
                if (ent->visframe == r_framecount)
                {
-                       if (ent->model)
-                       {
-                               if (baselighting && ent->model->DrawBaseLighting != NULL)
-                               {
-                                       if (ent->model->DrawBaseLighting)
-                                               ent->model->DrawBaseLighting(ent);
-                               }
-                               else if (ent->model->Draw)
-                                       ent->model->Draw(ent);
-                       }
+                       if (ent->model && ent->model->Draw != NULL)
+                               ent->model->Draw(ent);
                        else
                                R_DrawNoModel(ent);
                }
@@ -573,7 +582,7 @@ void R_DrawFakeShadows (void)
 
 #include "r_shadow.h"
 
-void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float lightradius, int visiblevolume)
+void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float lightradius)
 {
        int i;
        vec3_t p, p2, temp, relativelightorigin;
@@ -631,144 +640,25 @@ void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float l
                                if (mins[1] > p2[1]) mins[1] = p2[1];if (maxs[1] < p2[1]) maxs[1] = p2[1];
                                if (mins[2] > p2[2]) mins[2] = p2[2];if (maxs[2] < p2[2]) maxs[2] = p2[2];
                        }
-                       if (R_NotCulledBox(mins, maxs))
+                       if (!R_CullBox(mins, maxs))
 #endif
                        {
                                Matrix4x4_Transform(&ent->inversematrix, lightorigin, relativelightorigin);
-                               ent->model->DrawShadowVolume (ent, relativelightorigin, lightradius, visiblevolume);
+                               ent->model->DrawShadowVolume (ent, relativelightorigin, lightradius);
                        }
                        }
                }
        }
 }
 
-void R_DrawWorldLightShadowVolume(mlight_t *sl, int visiblevolume)
+void R_DrawWorldLightShadowVolume(mlight_t *sl)
 {
        shadowmesh_t *mesh;
        R_Mesh_Matrix(&cl_entities[0].render.matrix);
        for (mesh = sl->shadowvolume;mesh;mesh = mesh->next)
        {
                memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
-               R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements, visiblevolume);
-       }
-}
-
-void R_DrawShadowVolumes (void)
-{
-       int i, lnum;
-       entity_render_t *ent;
-       vec3_t mins, maxs;//, relativelightorigin;
-       mlight_t *sl;
-       rdlight_t *rd;
-       rmeshstate_t m;
-
-       for (lnum = 0, sl = cl.worldmodel->lights;lnum < cl.worldmodel->numlights;lnum++, sl++)
-       {
-               if (d_lightstylevalue[sl->style] <= 0)
-                       continue;
-               if (r_light_debuglight.integer >= 0 && lnum != r_light_debuglight.integer)
-                       continue;
-               /*
-               mins[0] = sl->origin[0] - sl->cullradius;
-               maxs[0] = sl->origin[0] + sl->cullradius;
-               mins[1] = sl->origin[1] - sl->cullradius;
-               maxs[1] = sl->origin[1] + sl->cullradius;
-               mins[2] = sl->origin[2] - sl->cullradius;
-               maxs[2] = sl->origin[2] + sl->cullradius;
-               if (R_CullBox(mins, maxs))
-                       continue;
-               */
-               if (R_CullBox(sl->mins, sl->maxs))
-                       continue;
-               memset(&m, 0, sizeof(m));
-               m.blendfunc1 = GL_ONE;
-               m.blendfunc2 = GL_ONE;
-               R_Mesh_State(&m);
-               GL_Color(0.0 * r_colorscale, 0.0125 * r_colorscale, 0.1 * r_colorscale, 1);
-               if (sl->shadowvolume && r_staticworldlights.integer)
-                       R_DrawWorldLightShadowVolume(sl, true);
-               else
-               {
-                       ent = &cl_entities[0].render;
-                       R_TestAndDrawShadowVolume(ent, sl->origin, sl->cullradius, true);
-               }
-               /*
-               ent = &cl_entities[0].render;
-               if (ent->model && ent->model->DrawShadowVolume && ent->maxs[0] >= mins[0] && ent->mins[0] <= maxs[0] && ent->maxs[1] >= mins[1] && ent->mins[1] <= maxs[1] && ent->maxs[2] >= mins[2] && ent->mins[2] <= maxs[2])
-               {
-                       Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
-                       ent->model->DrawShadowVolume (ent, relativelightorigin, sl->cullradius, true);
-               }
-               */
-               if (r_drawentities.integer)
-               {
-                       for (i = 0;i < r_refdef.numentities;i++)
-                       {
-                               ent = r_refdef.entities[i];
-                               /*
-                               if (ent->mins[0] <= sl->maxs[0]
-                                && ent->maxs[0] >= sl->mins[0]
-                                && ent->mins[1] <= sl->maxs[1]
-                                && ent->maxs[1] >= sl->mins[1]
-                                && ent->mins[2] <= sl->maxs[2]
-                                && ent->maxs[2] >= sl->mins[2])
-                               */
-                                       R_TestAndDrawShadowVolume(ent, sl->origin, sl->cullradius, true);
-                               /*
-                               ent = r_refdef.entities[i];
-                               if (ent->model && ent->model->DrawShadowVolume && ent->maxs[0] >= mins[0] && ent->mins[0] <= maxs[0] && ent->maxs[1] >= mins[1] && ent->mins[1] <= maxs[1] && ent->maxs[2] >= mins[2] && ent->mins[2] <= maxs[2])
-                               {
-                                       Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
-                                       ent->model->DrawShadowVolume (ent, relativelightorigin, sl->cullradius, true);
-                               }
-                               */
-                       }
-               }
-       }
-
-       for (lnum = 0, rd = r_dlight;lnum < r_numdlights;lnum++, rd++)
-       {
-               mins[0] = rd->origin[0] - rd->cullradius;
-               maxs[0] = rd->origin[0] + rd->cullradius;
-               mins[1] = rd->origin[1] - rd->cullradius;
-               maxs[1] = rd->origin[1] + rd->cullradius;
-               mins[2] = rd->origin[2] - rd->cullradius;
-               maxs[2] = rd->origin[2] + rd->cullradius;
-               if (R_CullBox(mins, maxs))
-                       continue;
-               memset(&m, 0, sizeof(m));
-               m.blendfunc1 = GL_ONE;
-               m.blendfunc2 = GL_ONE;
-               R_Mesh_State(&m);
-               GL_Color(0.1 * r_colorscale, 0.0125 * r_colorscale, 0.0 * r_colorscale, 1);
-               ent = &cl_entities[0].render;
-               if (ent != rd->ent)
-                       R_TestAndDrawShadowVolume(ent, rd->origin, rd->cullradius, true);
-               /*
-               ent = &cl_entities[0].render;
-               if (ent != rd->ent && ent->model && ent->model->DrawShadowVolume && ent->maxs[0] >= mins[0] && ent->mins[0] <= maxs[0] && ent->maxs[1] >= mins[1] && ent->mins[1] <= maxs[1] && ent->maxs[2] >= mins[2] && ent->mins[2] <= maxs[2])
-               {
-                       Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
-                       ent->model->DrawShadowVolume (ent, relativelightorigin, rd->cullradius, true);
-               }
-               */
-               if (r_drawentities.integer)
-               {
-                       for (i = 0;i < r_refdef.numentities;i++)
-                       {
-                               ent = r_refdef.entities[i];
-                               if (ent != rd->ent)
-                                       R_TestAndDrawShadowVolume(ent, rd->origin, rd->cullradius, true);
-                               /*
-                               ent = r_refdef.entities[i];
-                               if (ent != rd->ent && ent->model && ent->model->DrawShadowVolume && ent->maxs[0] >= mins[0] && ent->mins[0] <= maxs[0] && ent->maxs[1] >= mins[1] && ent->mins[1] <= maxs[1] && ent->maxs[2] >= mins[2] && ent->mins[2] <= maxs[2])
-                               {
-                                       Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
-                                       ent->model->DrawShadowVolume (ent, relativelightorigin, rd->cullradius, true);
-                               }
-                               */
-                       }
-               }
+               R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements);
        }
 }
 
@@ -804,24 +694,13 @@ void R_CreateShadowSphere(void)
                        VectorScale(&verts[6], 1.0f, &verts[6]);
                        VectorScale(&verts[9], 1.0f, &verts[9]);
                        Mod_ShadowMesh_AddPolygon(zonemempool, shadowsphere, 4, verts);
-                       /*
-                       AngleVectorsFLU(angles, verts, NULL, NULL);
-                       AngleVectorsFLU(angles2, verts + 3, NULL, NULL);
-                       AngleVectorsFLU(angles3, verts + 6, NULL, NULL);
-                       AngleVectorsFLU(angles4, verts + 9, NULL, NULL);
-                       VectorScale(&verts[0], -4.0f, &verts[0]);
-                       VectorScale(&verts[3], -4.0f, &verts[3]);
-                       VectorScale(&verts[6], -4.0f, &verts[6]);
-                       VectorScale(&verts[9], -4.0f, &verts[9]);
-                       Mod_ShadowMesh_AddPolygon(zonemempool, shadowsphere, 4, verts);
-                       */
                }
        }
        shadowsphere = Mod_ShadowMesh_Finish(zonemempool, shadowsphere);
 }
 
 
-void R_DrawShadowSphere(vec3_t origin, float cullradius, float lightradius, int visiblevolume)
+void R_DrawShadowSphere(vec3_t origin, float cullradius, float lightradius)
 {
        shadowmesh_t *mesh;
        matrix4x4_t matrix;
@@ -833,7 +712,7 @@ void R_DrawShadowSphere(vec3_t origin, float cullradius, float lightradius, int
        for (mesh = shadowsphere;mesh;mesh = mesh->next)
        {
                memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
-               R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements, visiblevolume);
+               R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements);
        }
        Matrix4x4_CreateScale(&matrix, -cullradius);
        Matrix4x4_ConcatTranslate(&matrix, origin[0], origin[1], origin[2]);
@@ -841,148 +720,172 @@ void R_DrawShadowSphere(vec3_t origin, float cullradius, float lightradius, int
        for (mesh = shadowsphere;mesh;mesh = mesh->next)
        {
                memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
-               R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements, visiblevolume);
+               R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements);
        }
 }
 
-void R_ShadowVolumeLighting (void)
+void R_ShadowVolumeLighting (int visiblevolumes)
 {
        int i;
        entity_render_t *ent;
        int lnum;
-       float f;
-       vec3_t mins, maxs, relativelightorigin, relativeeyeorigin, lightcolor;
+       float f, lightradius, cullradius;
+       vec3_t relativelightorigin, relativeeyeorigin, lightcolor;
        mlight_t *sl;
        rdlight_t *rd;
+       rmeshstate_t m;
 
-       R_Shadow_Stage_Begin();
+       if (visiblevolumes)
+       {
+               memset(&m, 0, sizeof(m));
+               m.blendfunc1 = GL_ONE;
+               m.blendfunc2 = GL_ONE;
+               R_Mesh_State(&m);
+               GL_Color(0.0 * r_colorscale, 0.0125 * r_colorscale, 0.1 * r_colorscale, 1);
+       }
+       else
+               R_Shadow_Stage_Begin();
        for (lnum = 0, sl = cl.worldmodel->lights;lnum < cl.worldmodel->numlights;lnum++, sl++)
        {
                if (d_lightstylevalue[sl->style] <= 0)
                        continue;
                if (r_light_debuglight.integer >= 0 && lnum != r_light_debuglight.integer)
                        continue;
-               VectorCopy(sl->mins, mins);
-               VectorCopy(sl->maxs, maxs);
-               if (R_CullBox(mins, maxs))
+               cullradius = sl->cullradius;
+               lightradius = sl->lightradius;
+               if (R_CullBox(sl->mins, sl->maxs) || PVS_CullBox(sl->mins, sl->maxs) || R_CullSphere(sl->origin, cullradius) || PVS_CullSphere(sl->origin, cullradius))
                        continue;
 
                f = d_lightstylevalue[sl->style] * (1.0f / 32768.0f);
                VectorScale(sl->light, f, lightcolor);
 
-               R_Shadow_Stage_ShadowVolumes();
-               R_DrawShadowSphere(sl->origin, sl->cullradius, sl->lightradius * 2, false);
+               if (!visiblevolumes)
+                       R_Shadow_Stage_ShadowVolumes();
+               R_DrawShadowSphere(sl->origin, cullradius, lightradius * 2);
                if (sl->shadowvolume && r_staticworldlights.integer)
-                       R_DrawWorldLightShadowVolume(sl, false);
+                       R_DrawWorldLightShadowVolume(sl);
                else
-                       R_TestAndDrawShadowVolume(&cl_entities[0].render, sl->origin, sl->cullradius, false);
+                       R_TestAndDrawShadowVolume(&cl_entities[0].render, sl->origin, cullradius);
                if (r_drawentities.integer)
                {
                        for (i = 0;i < r_refdef.numentities;i++)
                        {
                                ent = r_refdef.entities[i];
-                               /*
-                               if (ent->maxs[0] >= mins[0]
-                                && ent->mins[0] <= maxs[0]
-                                && ent->maxs[1] >= mins[1]
-                                && ent->mins[1] <= maxs[1]
-                                && ent->maxs[2] >= mins[2]
-                                && ent->mins[2] <= maxs[2])
-                               */
-                                       R_TestAndDrawShadowVolume(r_refdef.entities[i], sl->origin, sl->cullradius, false);
+                               if (ent->maxs[0] >= sl->mins[0] && ent->mins[0] <= sl->maxs[0]
+                                && ent->maxs[1] >= sl->mins[1] && ent->mins[1] <= sl->maxs[1]
+                                && ent->maxs[2] >= sl->mins[2] && ent->mins[2] <= sl->maxs[2])
+                                       R_TestAndDrawShadowVolume(r_refdef.entities[i], sl->origin, cullradius);
                        }
                }
 
-               R_Shadow_Stage_Light();
-               ent = &cl_entities[0].render;
-               if (ent->model && ent->model->DrawLight)
-               {
-                       Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
-                       Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
-                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, sl->lightradius, sl->distbias, sl->subtract, lightcolor);
-               }
-               if (r_drawentities.integer)
+               if (!visiblevolumes)
                {
-                       for (i = 0;i < r_refdef.numentities;i++)
+                       R_Shadow_Stage_Light();
+                       ent = &cl_entities[0].render;
+                       if (ent->model && ent->model->DrawLight)
                        {
-                               ent = r_refdef.entities[i];
-                               if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight
-                               /*
-                                && ent->maxs[0] >= mins[0]
-                                && ent->mins[0] <= maxs[0]
-                                && ent->maxs[1] >= mins[1]
-                                && ent->mins[1] <= maxs[1]
-                                && ent->maxs[2] >= mins[2]
-                                && ent->mins[2] <= maxs[2]*/)
+                               Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
+                               Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
+                               ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius, sl->distbias, sl->subtract, lightcolor);
+                       }
+                       if (r_drawentities.integer)
+                       {
+                               for (i = 0;i < r_refdef.numentities;i++)
+                               {
+                                       ent = r_refdef.entities[i];
+                                       if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight
+                                        && ent->maxs[0] >= sl->mins[0] && ent->mins[0] <= sl->maxs[0]
+                                        && ent->maxs[1] >= sl->mins[1] && ent->mins[1] <= sl->maxs[1]
+                                        && ent->maxs[2] >= sl->mins[2] && ent->mins[2] <= sl->maxs[2])
+                                       {
+                                               Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
+                                               Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
+                                               ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius, sl->distbias, sl->subtract, lightcolor);
+                                       }
+                               }
+                       }
+
+                       R_Shadow_Stage_EraseShadowVolumes();
+                       R_DrawShadowSphere(sl->origin, cullradius, lightradius * 2);
+                       if (sl->shadowvolume && r_staticworldlights.integer)
+                               R_DrawWorldLightShadowVolume(sl);
+                       else
+                               R_TestAndDrawShadowVolume(&cl_entities[0].render, sl->origin, cullradius);
+                       if (r_drawentities.integer)
+                       {
+                               for (i = 0;i < r_refdef.numentities;i++)
                                {
-                                       Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
-                                       Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
-                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, sl->lightradius, sl->distbias, sl->subtract, lightcolor);
+                                       ent = r_refdef.entities[i];
+                                       if (ent->maxs[0] >= sl->mins[0] && ent->mins[0] <= sl->maxs[0]
+                                        && ent->maxs[1] >= sl->mins[1] && ent->mins[1] <= sl->maxs[1]
+                                        && ent->maxs[2] >= sl->mins[2] && ent->mins[2] <= sl->maxs[2])
+                                               R_TestAndDrawShadowVolume(r_refdef.entities[i], sl->origin, cullradius);
                                }
                        }
                }
        }
        for (lnum = 0, rd = r_dlight;lnum < r_numdlights;lnum++, rd++)
        {
-               mins[0] = rd->origin[0] - rd->cullradius;
-               maxs[0] = rd->origin[0] + rd->cullradius;
-               mins[1] = rd->origin[1] - rd->cullradius;
-               maxs[1] = rd->origin[1] + rd->cullradius;
-               mins[2] = rd->origin[2] - rd->cullradius;
-               maxs[2] = rd->origin[2] + rd->cullradius;
-               if (R_CullBox(mins, maxs))
+               cullradius = rd->cullradius;
+               lightradius = rd->cullradius;
+               if (R_CullSphere(rd->origin, cullradius) || PVS_CullSphere(rd->origin, cullradius))
                        continue;
 
-               R_Shadow_Stage_ShadowVolumes();
-               R_TestAndDrawShadowVolume(&cl_entities[0].render, rd->origin, rd->cullradius, false);
+               VectorScale(rd->light, 4.0f, lightcolor);
+
+               if (!visiblevolumes)
+                       R_Shadow_Stage_ShadowVolumes();
+               R_TestAndDrawShadowVolume(&cl_entities[0].render, rd->origin, cullradius);
                if (r_drawentities.integer)
                {
                        for (i = 0;i < r_refdef.numentities;i++)
                        {
                                ent = r_refdef.entities[i];
-                               /*
-                               if (ent->maxs[0] >= mins[0]
-                                && ent->mins[0] <= maxs[0]
-                                && ent->maxs[1] >= mins[1]
-                                && ent->mins[1] <= maxs[1]
-                                && ent->maxs[2] >= mins[2]
-                                && ent->mins[2] <= maxs[2])
-                               */
-                                       R_TestAndDrawShadowVolume(ent, rd->origin, rd->cullradius, false);
+                               if (ent != rd->ent)
+                                       R_TestAndDrawShadowVolume(ent, rd->origin, cullradius);
                        }
                }
 
-               R_Shadow_Stage_Light();
-               ent = &cl_entities[0].render;
-               if (ent->model && ent->model->DrawLight)
-               {
-                       Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
-                       Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
-                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rd->cullradius, LIGHTOFFSET, rd->subtract, rd->light);
-               }
-               if (r_drawentities.integer)
+               if (!visiblevolumes)
                {
-                       for (i = 0;i < r_refdef.numentities;i++)
+                       R_Shadow_Stage_Light();
+                       ent = &cl_entities[0].render;
+                       if (ent->model && ent->model->DrawLight)
                        {
-                               ent = r_refdef.entities[i];
-                               if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight
-                               /*
-                                && ent->maxs[0] >= mins[0]
-                                && ent->mins[0] <= maxs[0]
-                                && ent->maxs[1] >= mins[1]
-                                && ent->mins[1] <= maxs[1]
-                                && ent->maxs[2] >= mins[2]
-                                && ent->mins[2] <= maxs[2]*/)
+                               Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
+                               Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
+                               ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, cullradius, LIGHTOFFSET, rd->subtract, lightcolor);
+                       }
+                       if (r_drawentities.integer)
+                       {
+                               for (i = 0;i < r_refdef.numentities;i++)
                                {
-                                       Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
-                                       Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
-                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rd->cullradius, LIGHTOFFSET, rd->subtract, rd->light);
+                                       ent = r_refdef.entities[i];
+                                       if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight)
+                                       {
+                                               Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
+                                               Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin);
+                                               ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, cullradius, LIGHTOFFSET, rd->subtract, lightcolor);
+                                       }
+                               }
+                       }
+
+                       R_Shadow_Stage_EraseShadowVolumes();
+                       R_TestAndDrawShadowVolume(&cl_entities[0].render, rd->origin, cullradius);
+                       if (r_drawentities.integer)
+                       {
+                               for (i = 0;i < r_refdef.numentities;i++)
+                               {
+                                       ent = r_refdef.entities[i];
+                                       if (ent != rd->ent)
+                                               R_TestAndDrawShadowVolume(ent, rd->origin, cullradius);
                                }
                        }
                }
        }
 
-       R_Shadow_Stage_End();
+       if (!visiblevolumes)
+               R_Shadow_Stage_End();
 }
 
 static void R_SetFrustum (void)
@@ -1135,7 +1038,7 @@ void R_RenderView (void)
                R_TimeReport("bmodelsky");
 
        // must occur early because it can draw sky
-       R_DrawWorld(world, r_shadows.integer == 3);
+       R_DrawWorld(world);
        R_TimeReport("world");
 
        // don't let sound skip if going slow
@@ -1148,11 +1051,14 @@ void R_RenderView (void)
        if (r_shadows.integer == 1)
        {
                R_DrawFakeShadows();
-               R_TimeReport("fakeshadows");
+               R_TimeReport("fakeshadow");
        }
 
        if (r_shadows.integer == 3)
-               R_ShadowVolumeLighting();
+       {
+               R_ShadowVolumeLighting(false);
+               R_TimeReport("dynlight");
+       }
 
        R_DrawParticles();
        R_TimeReport("particles");
@@ -1176,8 +1082,8 @@ void R_RenderView (void)
        R_MeshQueue_EndScene();
        if (r_shadows.integer == 2)
        {
-               R_DrawShadowVolumes();
-               R_TimeReport("shadowvolumes");
+               R_ShadowVolumeLighting(true);
+               R_TimeReport("shadowvolume");
        }
        R_Mesh_Finish();
        R_TimeReport("meshfinish");
index a587d658a1abb7f7919c657cdc91bc6414383d34..1ca9202178d9a796683b63993e015017dc6e0308 100644 (file)
@@ -1304,6 +1304,7 @@ static void RSurfShader_Wall_Vertex_Callback(const void *calldata1, int calldata
                RSurfShader_Wall_Pass_Fog(ent, surf);
 }
 
+extern cvar_t r_shadows;
 static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
 {
        const msurface_t *surf;
@@ -1320,6 +1321,13 @@ static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const texture_
                        }
                }
        }
+       else if (r_shadows.integer == 3 && cl.worldmodel->numlights)
+       {
+               // opaque base lighting
+               RSurfShader_OpaqueWall_Pass_OpaqueGlow(ent, texture, firstsurf);
+               if (fogenabled)
+                       RSurfShader_OpaqueWall_Pass_Fog(ent, texture, firstsurf);
+       }
        else if (r_vertexsurfaces.integer)
        {
                // opaque vertex shaded from lightmap
@@ -1365,53 +1373,9 @@ static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const texture_
        }
 }
 
-static void RSurfShader_Wall_Lightmap_BaseLighting(const entity_render_t *ent, const texture_t *texture, const msurface_t *firstsurf)
-{
-       const msurface_t *surf;
-       if (cl.worldmodel->numlights)
-               RSurfShader_OpaqueWall_Pass_OpaqueGlow(ent, texture, firstsurf);
-       else if (r_vertexsurfaces.integer)
-       {
-               // opaque vertex shaded from lightmap
-               for (surf = firstsurf;surf;surf = surf->texturechain)
-                       if (surf->visframe == r_framecount)
-                               RSurfShader_Wall_Pass_BaseVertex(ent, surf);
-               if (texture->glowtexture)
-                       for (surf = firstsurf;surf;surf = surf->texturechain)
-                               if (surf->visframe == r_framecount)
-                                       RSurfShader_Wall_Pass_Glow(ent, surf);
-       }
-       else
-       {
-               // opaque lightmapped
-               if (r_textureunits.integer >= 2)
-               {
-                       if (r_textureunits.integer >= 3 && gl_combine.integer && r_detailtextures.integer)
-                               RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(ent, texture, firstsurf);
-                       else
-                       {
-                               RSurfShader_OpaqueWall_Pass_BaseDoubleTex(ent, texture, firstsurf);
-                               if (r_detailtextures.integer)
-                                       RSurfShader_OpaqueWall_Pass_BaseDetail(ent, texture, firstsurf);
-                       }
-               }
-               else
-               {
-                       RSurfShader_OpaqueWall_Pass_BaseTexture(ent, texture, firstsurf);
-                       RSurfShader_OpaqueWall_Pass_BaseLightmap(ent, texture, firstsurf);
-                       if (r_detailtextures.integer)
-                               RSurfShader_OpaqueWall_Pass_BaseDetail(ent, texture, firstsurf);
-               }
-               if (!r_dlightmap.integer && !(ent->effects & EF_FULLBRIGHT))
-                       RSurfShader_OpaqueWall_Pass_Light(ent, texture, firstsurf);
-               if (texture->glowtexture)
-                       RSurfShader_OpaqueWall_Pass_Glow(ent, texture, firstsurf);
-       }
-}
-
-Cshader_t Cshader_wall_lightmap = {{NULL, RSurfShader_Wall_Lightmap, RSurfShader_Wall_Lightmap_BaseLighting}, SHADERFLAGS_NEEDLIGHTMAP};
-Cshader_t Cshader_water = {{NULL, RSurfShader_Water, NULL}, 0};
-Cshader_t Cshader_sky = {{RSurfShader_Sky, NULL, NULL}, 0};
+Cshader_t Cshader_wall_lightmap = {{NULL, RSurfShader_Wall_Lightmap}, SHADERFLAGS_NEEDLIGHTMAP};
+Cshader_t Cshader_water = {{NULL, RSurfShader_Water}, 0};
+Cshader_t Cshader_sky = {{RSurfShader_Sky, NULL}, 0};
 
 int Cshader_count = 3;
 Cshader_t *Cshaders[3] =
@@ -1421,6 +1385,7 @@ Cshader_t *Cshaders[3] =
        &Cshader_sky
 };
 
+extern cvar_t r_shadows;
 void R_PrepareSurfaces(entity_render_t *ent)
 {
        int i, texframe, numsurfaces, *surfacevisframes;
@@ -1455,7 +1420,7 @@ void R_PrepareSurfaces(entity_render_t *ent)
                }
        }
 
-       if (r_dynamic.integer)
+       if (r_dynamic.integer && r_shadows.integer != 3)
                R_MarkLights(ent);
 
        for (i = 0, surf = surfaces;i < numsurfaces;i++, surf++)
@@ -1636,16 +1601,16 @@ void R_SurfaceWorldNode (entity_render_t *ent)
 #if WORLDNODECULLBACKFACES
                        if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
                        {
-                               if ((surf->flags & SURF_PLANEBACK) && R_NotCulledBox (surf->poly_mins, surf->poly_maxs))
+                               if ((surf->flags & SURF_PLANEBACK) && !R_CullBox (surf->poly_mins, surf->poly_maxs))
                                        surfacevisframes[i] = r_framecount;
                        }
                        else
                        {
-                               if (!(surf->flags & SURF_PLANEBACK) && R_NotCulledBox (surf->poly_mins, surf->poly_maxs))
+                               if (!(surf->flags & SURF_PLANEBACK) && !R_CullBox (surf->poly_mins, surf->poly_maxs))
                                        surfacevisframes[i] = r_framecount;
                        }
 #else
-                       if (R_NotCulledBox (surf->poly_mins, surf->poly_maxs))
+                       if (!R_CullBox (surf->poly_mins, surf->poly_maxs))
                                surfacevisframes[i] = r_framecount;
 #endif
                }
@@ -1697,8 +1662,8 @@ loc0:
                if (leaf->worldnodeframe != r_framecount)
                {
                        leaf->worldnodeframe = r_framecount;
-                       // FIXME: R_NotCulledBox is absolute, should be done relative
-                       if (leaf->pvsframe == ent->model->pvsframecount && R_NotCulledBox(leaf->mins, leaf->maxs))
+                       // FIXME: R_CullBox is absolute, should be done relative
+                       if (leaf->pvsframe == ent->model->pvsframecount && !R_CullBox(leaf->mins, leaf->maxs))
                        {
                                p->visframe = r_framecount;
                                pstack[portalstack++] = p;
@@ -1775,8 +1740,8 @@ static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf)
                                if (leaf->worldnodeframe != r_framecount)
                                {
                                        leaf->worldnodeframe = r_framecount;
-                                       // FIXME: R_NotCulledBox is absolute, should be done relative
-                                       if (leaf->pvsframe == ent->model->pvsframecount && R_NotCulledBox(leaf->mins, leaf->maxs))
+                                       // FIXME: R_CullBox is absolute, should be done relative
+                                       if (leaf->pvsframe == ent->model->pvsframecount && !R_CullBox(leaf->mins, leaf->maxs))
                                                leafstack[leafstackpos++] = leaf;
                                }
                        }
@@ -1833,7 +1798,7 @@ void R_PVSUpdate (entity_render_t *ent, mleaf_t *viewleaf)
 R_DrawWorld
 =============
 */
-void R_DrawWorld (entity_render_t *ent, int baselighting)
+void R_DrawWorld (entity_render_t *ent)
 {
        vec3_t modelorg;
        mleaf_t *viewleaf;
@@ -1851,10 +1816,7 @@ void R_DrawWorld (entity_render_t *ent, int baselighting)
                R_PortalWorldNode (ent, viewleaf);
        R_PrepareSurfaces(ent);
        R_DrawSurfaces(ent, SHADERSTAGE_SKY);
-       if (baselighting)
-               R_DrawSurfaces(ent, SHADERSTAGE_BASELIGHTING);
-       else
-               R_DrawSurfaces(ent, SHADERSTAGE_NORMAL);
+       R_DrawSurfaces(ent, SHADERSTAGE_NORMAL);
 }
 
 void R_Model_Brush_DrawSky (entity_render_t *ent)
@@ -1872,28 +1834,7 @@ void R_Model_Brush_Draw (entity_render_t *ent)
        R_DrawSurfaces(ent, SHADERSTAGE_NORMAL);
 }
 
-void R_Model_Brush_DrawBaseLighting (entity_render_t *ent)
-{
-       c_bmodels++;
-       if (ent != &cl_entities[0].render)
-               R_PrepareBrushModel(ent);
-       R_DrawSurfaces(ent, SHADERSTAGE_BASELIGHTING);
-       /*
-       shadowmesh_t *mesh;
-       if (!cl.worldmodel->numlights)
-               GL_Color(0.3, 0.3, 0.3, 1);
-       for (mesh = ent->model->shadowmesh;mesh;mesh = mesh->next)
-       {
-               R_Mesh_ResizeCheck(mesh->numverts);
-               memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
-               R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->elements);
-       }
-       if (!cl.worldmodel->numlights)
-               GL_Color(0, 0, 0, 1);
-       */
-}
-
-void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume)
+void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelightorigin, float lightradius)
 {
 #if 1
        float projectdistance, temp[3];
@@ -1907,7 +1848,7 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto
                {
                        R_Mesh_ResizeCheck(mesh->numverts * 2);
                        memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
-                       R_Shadow_Volume(mesh->numverts, mesh->numtriangles, varray_vertex, mesh->elements, mesh->neighbors, relativelightorigin, lightradius, projectdistance, visiblevolume);
+                       R_Shadow_Volume(mesh->numverts, mesh->numtriangles, varray_vertex, mesh->elements, mesh->neighbors, relativelightorigin, lightradius, projectdistance);
                }
        }
 #else
@@ -1935,7 +1876,7 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto
                                        {
                                                R_Mesh_ResizeCheck(mesh->numverts * 2);
                                                memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
-                                               R_Shadow_Volume(mesh->numverts, mesh->numtriangles, varray_vertex, mesh->index, mesh->triangleneighbors, relativelightorigin, lightradius, projectdistance, visiblevolume);
+                                               R_Shadow_Volume(mesh->numverts, mesh->numtriangles, varray_vertex, mesh->index, mesh->triangleneighbors, relativelightorigin, lightradius, projectdistance);
                                        }
                                }
                        }
@@ -1983,73 +1924,6 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v
        }
 }
 
-/*
-extern cvar_t r_shadows;
-void R_DrawBrushModelFakeShadow (entity_render_t *ent)
-{
-       int i;
-       vec3_t relativelightorigin;
-       rmeshstate_t m;
-       mlight_t *sl;
-       rdlight_t *rd;
-       svbspmesh_t *mesh;
-
-       if (r_shadows.integer < 2)
-               return;
-
-       memset(&m, 0, sizeof(m));
-       m.blendfunc1 = GL_ONE;
-       m.blendfunc2 = GL_ONE;
-       R_Mesh_State(&m);
-       R_Mesh_Matrix(&ent->matrix);
-       GL_Color(0.0125 * r_colorscale, 0.025 * r_colorscale, 0.1 * r_colorscale, 1);
-       if (0)//ent->model == cl.worldmodel)
-       {
-               for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights;i++, sl++)
-               {
-                       if (d_lightstylevalue[sl->style] > 0 && R_NotCulledBox(sl->shadowvolumemins, sl->shadowvolumemaxs))
-                       {
-                               for (mesh = sl->shadowvolume;mesh;mesh = mesh->next)
-                               {
-                                       memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
-                                       R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->elements);
-                               }
-                       }
-               }
-       }
-       else
-       {
-               for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights;i++, sl++)
-               {
-                       if (d_lightstylevalue[sl->style] > 0
-                        && ent->maxs[0] >= sl->origin[0] - sl->cullradius
-                        && ent->mins[0] <= sl->origin[0] + sl->cullradius
-                        && ent->maxs[1] >= sl->origin[1] - sl->cullradius
-                        && ent->mins[1] <= sl->origin[1] + sl->cullradius
-                        && ent->maxs[2] >= sl->origin[2] - sl->cullradius
-                        && ent->mins[2] <= sl->origin[2] + sl->cullradius)
-                       {
-                               Matrix4x4_Transform(&ent->inversematrix, sl->origin, relativelightorigin);
-                               R_DrawBrushModelShadowVolume (ent, relativelightorigin, sl->cullradius, true);
-                       }
-               }
-       }
-       for (i = 0, rd = r_dlight;i < r_numdlights;i++, rd++)
-       {
-               if (ent->maxs[0] >= rd->origin[0] - rd->cullradius
-                && ent->mins[0] <= rd->origin[0] + rd->cullradius
-                && ent->maxs[1] >= rd->origin[1] - rd->cullradius
-                && ent->mins[1] <= rd->origin[1] + rd->cullradius
-                && ent->maxs[2] >= rd->origin[2] - rd->cullradius
-                && ent->mins[2] <= rd->origin[2] + rd->cullradius)
-               {
-                       Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin);
-                       R_DrawBrushModelShadowVolume (ent, relativelightorigin, rd->cullradius, true);
-               }
-       }
-}
-*/
-
 static void gl_surf_start(void)
 {
 }
index a502f81a84e00773f8f057e535f4d0e2de93804d..558b1f59cb457bfab6721dec5a539c06e0e5c99e 100644 (file)
@@ -554,8 +554,7 @@ static void GL_SetupTextureParameters(int flags, int texturetype)
        CHECKGLERROR
 
        qglTexParameteri(textureenum, GL_TEXTURE_WRAP_S, wrapmode);
-       if (gltexturetypedimensions[texturetype] >= 2)
-               qglTexParameteri(textureenum, GL_TEXTURE_WRAP_T, wrapmode);
+       qglTexParameteri(textureenum, GL_TEXTURE_WRAP_T, wrapmode);
        if (gltexturetypedimensions[texturetype] >= 3)
                qglTexParameteri(textureenum, GL_TEXTURE_WRAP_R, wrapmode);
 
@@ -621,7 +620,7 @@ static void R_Upload(gltexture_t *glt, qbyte *data)
                {
                        // promote paletted to RGBA, so we only have to worry about RGB and
                        // RGBA in the rest of this code
-                       R_MakeResizeBufferBigger(glt->image->width * glt->image->height * glt->image->depth * glt->image->bytesperpixel);
+                       R_MakeResizeBufferBigger(glt->image->width * glt->image->height * glt->image->depth * glt->image->sides * glt->image->bytesperpixel);
                        Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, glt->width * glt->height * glt->depth, glt->palette);
                        prevbuffer = colorconvertbuffer;
                }
@@ -655,7 +654,7 @@ static void R_Upload(gltexture_t *glt, qbyte *data)
        for (height = 1;height < glt->height;height <<= 1);
        for (depth  = 1;depth  < glt->depth ;depth  <<= 1);
 
-       R_MakeResizeBufferBigger(width * height * depth * glt->image->bytesperpixel);
+       R_MakeResizeBufferBigger(width * height * depth * glt->image->sides * glt->image->bytesperpixel);
 
        if (prevbuffer == NULL)
        {
@@ -671,29 +670,31 @@ static void R_Upload(gltexture_t *glt, qbyte *data)
                {
                        // promote paletted to RGBA, so we only have to worry about RGB and
                        // RGBA in the rest of this code
-                       Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, glt->width * glt->height * glt->depth, glt->palette);
+                       Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, glt->width * glt->height * glt->depth * glt->image->sides, glt->palette);
                        prevbuffer = colorconvertbuffer;
                }
+       }
 
+       // 3 and 4 are converted by the driver to it's preferred format for the current display mode
+       internalformat = 3;
+       if (glt->flags & TEXF_ALPHA)
+               internalformat = 4;
+
+       // cubemaps contain multiple images and thus get processed a bit differently
+       if (glt->image->texturetype != GLTEXTURETYPE_CUBEMAP)
+       {
                if (glt->width != width || glt->height != height || glt->depth != depth)
                {
                        Image_Resample(prevbuffer, glt->width, glt->height, glt->depth, resizebuffer, width, height, depth, glt->image->bytesperpixel, r_lerpimages.integer);
                        prevbuffer = resizebuffer;
                }
-
-               // apply picmip/max_size limitations
+               // picmip/max_size
                while (width > glt->image->width || height > glt->image->height || depth > glt->image->depth)
                {
                        Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, glt->image->width, glt->image->height, glt->image->depth, glt->image->bytesperpixel);
                        prevbuffer = resizebuffer;
                }
        }
-
-       // 3 and 4 are converted by the driver to it's preferred format for the current display mode
-       internalformat = 3;
-       if (glt->flags & TEXF_ALPHA)
-               internalformat = 4;
-
        mip = 0;
        switch(glt->image->texturetype)
        {
@@ -747,6 +748,18 @@ static void R_Upload(gltexture_t *glt, qbyte *data)
                {
                        prevbuffer = texturebuffer;
                        texturebuffer += width * height * depth * glt->textype->inputbytesperpixel;
+                       if (glt->width != width || glt->height != height || glt->depth != depth)
+                       {
+                               Image_Resample(prevbuffer, glt->width, glt->height, glt->depth, resizebuffer, width, height, depth, glt->image->bytesperpixel, r_lerpimages.integer);
+                               prevbuffer = resizebuffer;
+                       }
+                       // picmip/max_size
+                       while (width > glt->image->width || height > glt->image->height || depth > glt->image->depth)
+                       {
+                               Image_MipReduce(prevbuffer, resizebuffer, &width, &height, &depth, glt->image->width, glt->image->height, glt->image->depth, glt->image->bytesperpixel);
+                               prevbuffer = resizebuffer;
+                       }
+                       mip = 0;
                        qglTexImage2D(cubemapside[i], mip++, internalformat, width, height, 0, glt->image->glformat, GL_UNSIGNED_BYTE, prevbuffer);
                        CHECKGLERROR
                        if (glt->flags & TEXF_MIPMAP)
diff --git a/image.c b/image.c
index dce3b365915d375c7d3649f6544c77d676e4e3ff..0ce0886ad11365c0b2a027659847ddee307fd806 100644 (file)
--- a/image.c
+++ b/image.c
@@ -1296,7 +1296,7 @@ void Image_HeightmapToNormalmap(const unsigned char *inpixels, unsigned char *ou
        float iwidth, iheight, ibumpscale, n[3];
        iwidth = 1.0f / width;
        iheight = 1.0f / height;
-       ibumpscale = (255.0f * 3.0f) / (bumpscale * 16.0f);
+       ibumpscale = (255.0f * 3.0f) / (bumpscale * 8.0f);
        out = outpixels;
        for (y = 0;y < height;y++)
        {
index 112df181cb583b712bb731c743bbd5e3f290d786..9adc1b7792763ff795fe4b46b1a1082838851bf3 100644 (file)
@@ -211,8 +211,7 @@ static int Mod_LoadInternalSkin (char *basename, qbyte *skindata, int width, int
 #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_DrawFakeShadow(entity_render_t *ent);
-extern void R_Model_Alias_DrawBaseLighting(entity_render_t *ent);
-extern void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume);
+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 lightradius2, float lightdistbias, float lightsubtract, float *lightcolor);
 void Mod_LoadAliasModel (model_t *mod, void *buffer)
 {
@@ -248,7 +247,6 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer)
        loadmodel->DrawSky = NULL;
        loadmodel->Draw = R_Model_Alias_Draw;
        loadmodel->DrawFakeShadow = R_Model_Alias_DrawFakeShadow;
-       loadmodel->DrawBaseLighting = R_Model_Alias_DrawBaseLighting;
        loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
        loadmodel->DrawLight = R_Model_Alias_DrawLight;
 
@@ -572,7 +570,6 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer)
        loadmodel->DrawSky = NULL;
        loadmodel->Draw = R_Model_Alias_Draw;
        loadmodel->DrawFakeShadow = R_Model_Alias_DrawFakeShadow;
-       loadmodel->DrawBaseLighting = R_Model_Alias_DrawBaseLighting;
        loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
        loadmodel->DrawLight = R_Model_Alias_DrawLight;
 
@@ -766,8 +763,7 @@ void Mod_LoadQ2AliasModel (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_DrawFakeShadow(entity_render_t *ent);
-extern void R_Model_Zymotic_DrawBaseLighting(entity_render_t *ent);
-extern void R_Model_Zymotic_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume);
+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 lightradius2, float lightdistbias, float lightsubtract, float *lightcolor);
 void Mod_LoadZymoticModel(model_t *mod, void *buffer)
 {
@@ -786,7 +782,6 @@ void Mod_LoadZymoticModel(model_t *mod, void *buffer)
        loadmodel->DrawSky = NULL;
        loadmodel->Draw = R_Model_Zymotic_Draw;
        loadmodel->DrawFakeShadow = NULL;//R_Model_Zymotic_DrawFakeShadow;
-       loadmodel->DrawBaseLighting = NULL;//R_Model_Zymotic_DrawBaseLighting;
        loadmodel->DrawShadowVolume = NULL;//R_Model_Zymotic_DrawShadowVolume;
        loadmodel->DrawLight = NULL;//R_Model_Zymotic_DrawLight;
 
index 665483c2afa2c505e9462009eac3ff5d4cfea235..c91368de3b2bfd2ca61507ac877135cbcc7e3e5c 100644 (file)
@@ -296,12 +296,12 @@ static void Mod_LoadTextures (lump_t *l)
                        Con_Printf("warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, tx->name);
                }
 
-               basepixels = NULL;
-               bumppixels = NULL;
-               nmappixels = NULL;
-               glosspixels = NULL;
-               glowpixels = NULL;
-               maskpixels = NULL;
+               basepixels = NULL;basepixels_width = 0;basepixels_height = 0;
+               bumppixels = NULL;bumppixels_width = 0;bumppixels_height = 0;
+               nmappixels = NULL;nmappixels_width = 0;nmappixels_height = 0;
+               glosspixels = NULL;glosspixels_width = 0;glosspixels_height = 0;
+               glowpixels = NULL;glowpixels_width = 0;glowpixels_height = 0;
+               maskpixels = NULL;maskpixels_width = 0;maskpixels_height = 0;
                detailtexture = NULL;
 
                // LordHavoc: HL sky textures are entirely different than quake
@@ -331,14 +331,30 @@ static void Mod_LoadTextures (lump_t *l)
                }
                else
                {
-                       basepixels = loadimagepixels(tx->name, false, 0, 0);
-                       if (basepixels)
+                       if ((basepixels = loadimagepixels(tx->name, false, 0, 0)) != NULL)
                        {
-                               strcpy(name, tx->name);
-                               strcat(name, "_glow");
-                               glowpixels = loadimagepixels(name, false, 0, 0);
+                               basepixels_width = image_width;
+                               basepixels_height = image_height;
                        }
-                       else
+                       // _luma is supported for tenebrae compatibility
+                       // (I think it's a very stupid name, but oh well)
+                       if ((glowpixels = loadimagepixels(va("%s_glow", tx->name), false, 0, 0)) != NULL
+                        || (glowpixels = loadimagepixels(va("%s_luma", tx->name), false, 0, 0)) != NULL)
+                       {
+                               glowpixels_width = image_width;
+                               glowpixels_height = image_height;
+                       }
+                       if ((bumppixels = loadimagepixels(va("%s_bump", tx->name), false, 0, 0)) != NULL)
+                       {
+                               bumppixels_width = image_width;
+                               bumppixels_height = image_height;
+                       }
+                       if ((glosspixels = loadimagepixels(va("%s_gloss", tx->name), false, 0, 0)) != NULL)
+                       {
+                               glosspixels_width = image_width;
+                               glosspixels_height = image_height;
+                       }
+                       if (!basepixels)
                        {
                                if (loadmodel->ishlbsp)
                                {
@@ -365,15 +381,18 @@ static void Mod_LoadTextures (lump_t *l)
                                                        basepixels_height = tx->height;
                                                        basepixels = Mem_Alloc(loadmodel->mempool, basepixels_width * basepixels_height * 4);
                                                        Image_Copy8bitRGBA(mtdata, basepixels, basepixels_width * basepixels_height, palette_nofullbrights);
-                                                       for (j = 0;j < tx->width*tx->height;j++)
-                                                               if (((qbyte *)&palette_onlyfullbrights[mtdata[j]])[3] > 0) // fullbright
-                                                                       break;
-                                                       if (j < tx->width * tx->height)
+                                                       if (!glowpixels)
                                                        {
-                                                               glowpixels_width = tx->width;
-                                                               glowpixels_height = tx->height;
-                                                               glowpixels = Mem_Alloc(loadmodel->mempool, glowpixels_width * glowpixels_height * 4);
-                                                               Image_Copy8bitRGBA(mtdata, glowpixels, glowpixels_width * glowpixels_height, palette_onlyfullbrights);
+                                                               for (j = 0;j < tx->width*tx->height;j++)
+                                                                       if (((qbyte *)&palette_onlyfullbrights[mtdata[j]])[3] > 0) // fullbright
+                                                                               break;
+                                                               if (j < tx->width * tx->height)
+                                                               {
+                                                                       glowpixels_width = tx->width;
+                                                                       glowpixels_height = tx->height;
+                                                                       glowpixels = Mem_Alloc(loadmodel->mempool, glowpixels_width * glowpixels_height * 4);
+                                                                       Image_Copy8bitRGBA(mtdata, glowpixels, glowpixels_width * glowpixels_height, palette_onlyfullbrights);
+                                                               }
                                                        }
                                                }
                                                else
@@ -431,7 +450,7 @@ static void Mod_LoadTextures (lump_t *l)
                {
                        tx->texture = R_LoadTexture2D (loadmodel->texturepool, tx->name, basepixels_width, basepixels_height, basepixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
                        if (nmappixels)
-                               tx->nmaptexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_nmap", tx->name), basepixels_width, basepixels_height, basepixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
+                               tx->nmaptexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_nmap", tx->name), basepixels_width, basepixels_height, nmappixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
                        if (glosspixels)
                                tx->glosstexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_gloss", tx->name), glosspixels_width, glosspixels_height, glosspixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
                        if (glowpixels)
@@ -3511,9 +3530,7 @@ Mod_LoadBrushModel
 */
 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_DrawFakeShadow(entity_render_t *ent);
-extern void R_Model_Brush_DrawBaseLighting(entity_render_t *ent);
-extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume);
+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 lightradius2, float lightdistbias, float lightsubtract, float *lightcolor);
 void Mod_LoadBrushModel (model_t *mod, void *buffer)
 {
@@ -3607,7 +3624,6 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
                mod->DrawSky = NULL;
                mod->Draw = R_Model_Brush_Draw;
                mod->DrawFakeShadow = NULL;
-               mod->DrawBaseLighting = R_Model_Brush_DrawBaseLighting;
                mod->DrawShadowVolume = R_Model_Brush_DrawShadowVolume;
                mod->DrawLight = R_Model_Brush_DrawLight;
                mod->texturesurfacechains = Mem_Alloc(originalloadmodel->mempool, mod->numtextures * sizeof(msurface_t *));
index 3d031e73934bfe75817f37edd115dacf1a7304e1..2998a1063e477d317803daf6f62499c63a90081e 100644 (file)
@@ -57,8 +57,7 @@ mplane_t;
 
 #define SHADERSTAGE_SKY 0
 #define SHADERSTAGE_NORMAL 1
-#define SHADERSTAGE_BASELIGHTING 2
-#define SHADERSTAGE_COUNT 3
+#define SHADERSTAGE_COUNT 2
 
 #define SHADERFLAGS_NEEDLIGHTMAP 1
 
index f013bb2813f8d805772284d9fe20ab0fecc84d9f..776b1af54cc0a8a34408aa59995ec1bb84d6d293 100644 (file)
@@ -245,10 +245,8 @@ typedef struct model_s
        void(*DrawFakeShadow)(struct entity_render_s *ent);
 
        // functions used only in shadow volume rendering mode
-       // draw the base lighting for the model (glowing areas, etc)
-       void(*DrawBaseLighting)(struct entity_render_s *ent);
        // draw a shadow volume for the model based on light source
-       void(*DrawShadowVolume)(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius, int visiblevolume);
+       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 lightdistbias, float lightsubtract, float *lightcolor);
 
index 732b8c6383cf4ad3e8cf29df785f76f32181b3e9..edcec46644806bbaef968aa8edeb6876a44782c0 100644 (file)
@@ -249,7 +249,6 @@ void Mod_LoadSpriteModel (model_t *mod, void *buffer)
        loadmodel->DrawSky = NULL;
        loadmodel->Draw = R_Model_Sprite_Draw;
        loadmodel->DrawFakeShadow = NULL;
-       loadmodel->DrawBaseLighting = NULL;
        loadmodel->DrawShadowVolume = NULL;
        loadmodel->DrawLight = NULL;
 
index 7dbc82f01d85a53c70f9b02592fcf2ecdcc25612..1978eefe1fded65a6595b0cd1144141d8a51079a 100644 (file)
--- a/palette.c
+++ b/palette.c
@@ -55,48 +55,56 @@ void Palette_Setup8to24(void)
        reversed_start = 128;
        reversed_end = 224;
 
-       memset(palette_nofullbrights, 0, sizeof(palette_nofullbrights));
        for (i = 0;i < fullbright_start;i++)
                palette_nofullbrights[i] = palette_complete[i];
+       for (i = fullbright_start;i < 255;i++)
+               palette_nofullbrights[i] = palette_complete[0];
+       palette_nofullbrights[255] = 0;
 
-       memset(palette_onlyfullbrights, 0, sizeof(palette_onlyfullbrights));
+       for (i = 0;i < 256;i++)
+               palette_onlyfullbrights[i] = palette_complete[0];
        for (i = fullbright_start;i < fullbright_end;i++)
                palette_onlyfullbrights[i] = palette_complete[i];
+       palette_onlyfullbrights[255] = 0;
 
        for (i = 0;i < 256;i++)
                palette_nocolormapnofullbrights[i] = palette_complete[i];
        for (i = pants_start;i < pants_end;i++)
-               palette_nocolormapnofullbrights[i] = 0;
+               palette_nocolormapnofullbrights[i] = palette_complete[0];
        for (i = shirt_start;i < shirt_end;i++)
-               palette_nocolormapnofullbrights[i] = 0;
+               palette_nocolormapnofullbrights[i] = palette_complete[0];
        for (i = fullbright_start;i < fullbright_end;i++)
-               palette_nocolormapnofullbrights[i] = 0;
+               palette_nocolormapnofullbrights[i] = palette_complete[0];
+       palette_nocolormapnofullbrights[255] = 0;
 
-       memset(palette_pantsaswhite, 0, sizeof(palette_pantsaswhite));
+       for (i = 0;i < 256;i++)
+               palette_pantsaswhite[i] = palette_complete[0];
        for (i = pants_start;i < pants_end;i++)
        {
                if (i >= reversed_start && i < reversed_end)
-                       palette_pantsaswhite[i] = 15 - (i - pants_start);
+                       palette_pantsaswhite[i] = palette_complete[15 - (i - pants_start)];
                else
-                       palette_pantsaswhite[i] = i - pants_start;
+                       palette_pantsaswhite[i] = palette_complete[i - pants_start];
        }
 
-       memset(palette_shirtaswhite, 0, sizeof(palette_shirtaswhite));
+       for (i = 0;i < 256;i++)
+               palette_shirtaswhite[i] = palette_complete[0];
        for (i = shirt_start;i < shirt_end;i++)
        {
                if (i >= reversed_start && i < reversed_end)
-                       palette_shirtaswhite[i] = 15 - (i - shirt_start);
+                       palette_shirtaswhite[i] = palette_complete[15 - (i - shirt_start)];
                else
-                       palette_shirtaswhite[i] = i - shirt_start;
+                       palette_shirtaswhite[i] = palette_complete[i - shirt_start];
        }
 
-       memset(palette_alpha, 0, sizeof(palette_alpha));
        for (i = 0;i < 255;i++)
                palette_alpha[i] = 0xFFFFFFFF;
+       palette_alpha[255] = 0;
 
-       memset(palette_font, 0, sizeof(palette_font));
+       palette_font[0] = 0;
        for (i = 1;i < 255;i++)
                palette_font[i] = palette_complete[i];
+       palette_font[255] = 0;
 }
 
 
index e233ff7e188c4ffdc98a77cd539fa62f2e8c7f1c..1c46419d1f7f66d7e0bf2bec9c2e24442742f195 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -662,6 +662,7 @@ void R_ModelLightPoint (const entity_render_t *ent, vec3_t color, const vec3_t p
                RecursiveLightPoint (color, cl.worldmodel->nodes, p[0], p[1], p[2], p[2] - 65536);
 }
 
+extern cvar_t r_shadows;
 void R_LightModel(const entity_render_t *ent, int numverts, float *vertices, float *normals, float *colors, float colorr, float colorg, float colorb, int worldcoords)
 {
        int i, j, nearlights = 0, maxnearlights = r_modellights.integer;
@@ -690,72 +691,16 @@ void R_LightModel(const entity_render_t *ent, int numverts, float *vertices, flo
        {
                R_ModelLightPoint(ent, basecolor, ent->origin);
 
-               nl = &nearlight[0];
-               for (i = 0;i < ent->numentlights;i++)
+               if (r_shadows.integer != 3)
                {
-                       sl = cl.worldmodel->lights + ent->entlights[i];
-                       stylescale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f);
-                       VectorSubtract (ent->origin, sl->origin, v);
-                       f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract) * stylescale;
-                       VectorScale(sl->light, f, ambientcolor);
-                       intensity = DotProduct(ambientcolor, ambientcolor);
-                       if (f < 0)
-                               intensity *= -1.0f;
-                       if (nearlights < maxnearlights)
-                               j = nearlights++;
-                       else
+                       nl = &nearlight[0];
+                       for (i = 0;i < ent->numentlights;i++)
                        {
-                               for (j = 0;j < maxnearlights;j++)
-                               {
-                                       if (nearlight[j].intensity < intensity)
-                                       {
-                                               if (nearlight[j].intensity > 0)
-                                                       VectorAdd(basecolor, nearlight[j].ambientlight, basecolor);
-                                               break;
-                                       }
-                               }
-                       }
-                       if (j >= maxnearlights)
-                       {
-                               // this light is less significant than all others,
-                               // add it to ambient
-                               if (intensity > 0)
-                                       VectorAdd(basecolor, ambientcolor, basecolor);
-                       }
-                       else
-                       {
-                               nl = nearlight + j;
-                               nl->intensity = intensity;
-                               // transform the light into the model's coordinate system
-                               if (worldcoords)
-                                       VectorCopy(sl->origin, nl->origin);
-                               else
-                                       Matrix4x4_Transform(&ent->inversematrix, sl->origin, nl->origin);
-                               // integrate mscale into falloff, for maximum speed
-                               nl->falloff = sl->falloff * mscale;
-                               VectorCopy(ambientcolor, nl->ambientlight);
-                               nl->light[0] = sl->light[0] * stylescale * colorr * 4.0f;
-                               nl->light[1] = sl->light[1] * stylescale * colorg * 4.0f;
-                               nl->light[2] = sl->light[2] * stylescale * colorb * 4.0f;
-                               nl->subtract = sl->subtract;
-                               nl->offset = sl->distbias;
-                       }
-               }
-               for (i = 0;i < r_numdlights;i++)
-               {
-                       rd = r_dlight + i;
-                       VectorCopy(rd->origin, v);
-                       if (v[0] < ent->mins[0]) v[0] = ent->mins[0];if (v[0] > ent->maxs[0]) v[0] = ent->maxs[0];
-                       if (v[1] < ent->mins[1]) v[1] = ent->mins[1];if (v[1] > ent->maxs[1]) v[1] = ent->maxs[1];
-                       if (v[2] < ent->mins[2]) v[2] = ent->mins[2];if (v[2] > ent->maxs[2]) v[2] = ent->maxs[2];
-                       VectorSubtract (v, rd->origin, v);
-                       if (DotProduct(v, v) < rd->cullradius2)
-                       {
-                               if (CL_TraceLine(ent->origin, rd->origin, NULL, NULL, 0, false, NULL) != 1)
-                                       continue;
-                               VectorSubtract (ent->origin, rd->origin, v);
-                               f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - rd->subtract);
-                               VectorScale(rd->light, f, ambientcolor);
+                               sl = cl.worldmodel->lights + ent->entlights[i];
+                               stylescale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f);
+                               VectorSubtract (ent->origin, sl->origin, v);
+                               f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract) * stylescale;
+                               VectorScale(sl->light, f, ambientcolor);
                                intensity = DotProduct(ambientcolor, ambientcolor);
                                if (f < 0)
                                        intensity *= -1.0f;
@@ -786,43 +731,101 @@ void R_LightModel(const entity_render_t *ent, int numverts, float *vertices, flo
                                        nl->intensity = intensity;
                                        // transform the light into the model's coordinate system
                                        if (worldcoords)
-                                               VectorCopy(rd->origin, nl->origin);
+                                               VectorCopy(sl->origin, nl->origin);
                                        else
-                                       {
-                                               Matrix4x4_Transform(&ent->inversematrix, rd->origin, nl->origin);
-                                               /*
-                                               Con_Printf("%i %s : %f %f %f : %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n"
-                                               , rd - r_dlight, ent->model->name
-                                               , rd->origin[0], rd->origin[1], rd->origin[2]
-                                               , nl->origin[0], nl->origin[1], nl->origin[2]
-                                               , ent->inversematrix.m[0][0], ent->inversematrix.m[0][1], ent->inversematrix.m[0][2], ent->inversematrix.m[0][3]
-                                               , ent->inversematrix.m[1][0], ent->inversematrix.m[1][1], ent->inversematrix.m[1][2], ent->inversematrix.m[1][3]
-                                               , ent->inversematrix.m[2][0], ent->inversematrix.m[2][1], ent->inversematrix.m[2][2], ent->inversematrix.m[2][3]
-                                               , ent->inversematrix.m[3][0], ent->inversematrix.m[3][1], ent->inversematrix.m[3][2], ent->inversematrix.m[3][3]);
-                                               */
-                                       }
+                                               Matrix4x4_Transform(&ent->inversematrix, sl->origin, nl->origin);
                                        // integrate mscale into falloff, for maximum speed
-                                       nl->falloff = mscale;
+                                       nl->falloff = sl->falloff * mscale;
                                        VectorCopy(ambientcolor, nl->ambientlight);
-                                       nl->light[0] = rd->light[0] * colorr * 4.0f;
-                                       nl->light[1] = rd->light[1] * colorg * 4.0f;
-                                       nl->light[2] = rd->light[2] * colorb * 4.0f;
-                                       nl->subtract = rd->subtract;
-                                       nl->offset = LIGHTOFFSET;
+                                       nl->light[0] = sl->light[0] * stylescale * colorr * 4.0f;
+                                       nl->light[1] = sl->light[1] * stylescale * colorg * 4.0f;
+                                       nl->light[2] = sl->light[2] * stylescale * colorb * 4.0f;
+                                       nl->subtract = sl->subtract;
+                                       nl->offset = sl->distbias;
+                               }
+                       }
+                       for (i = 0;i < r_numdlights;i++)
+                       {
+                               rd = r_dlight + i;
+                               VectorCopy(rd->origin, v);
+                               if (v[0] < ent->mins[0]) v[0] = ent->mins[0];if (v[0] > ent->maxs[0]) v[0] = ent->maxs[0];
+                               if (v[1] < ent->mins[1]) v[1] = ent->mins[1];if (v[1] > ent->maxs[1]) v[1] = ent->maxs[1];
+                               if (v[2] < ent->mins[2]) v[2] = ent->mins[2];if (v[2] > ent->maxs[2]) v[2] = ent->maxs[2];
+                               VectorSubtract (v, rd->origin, v);
+                               if (DotProduct(v, v) < rd->cullradius2)
+                               {
+                                       if (CL_TraceLine(ent->origin, rd->origin, NULL, NULL, 0, false, NULL) != 1)
+                                               continue;
+                                       VectorSubtract (ent->origin, rd->origin, v);
+                                       f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - rd->subtract);
+                                       VectorScale(rd->light, f, ambientcolor);
+                                       intensity = DotProduct(ambientcolor, ambientcolor);
+                                       if (f < 0)
+                                               intensity *= -1.0f;
+                                       if (nearlights < maxnearlights)
+                                               j = nearlights++;
+                                       else
+                                       {
+                                               for (j = 0;j < maxnearlights;j++)
+                                               {
+                                                       if (nearlight[j].intensity < intensity)
+                                                       {
+                                                               if (nearlight[j].intensity > 0)
+                                                                       VectorAdd(basecolor, nearlight[j].ambientlight, basecolor);
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       if (j >= maxnearlights)
+                                       {
+                                               // this light is less significant than all others,
+                                               // add it to ambient
+                                               if (intensity > 0)
+                                                       VectorAdd(basecolor, ambientcolor, basecolor);
+                                       }
+                                       else
+                                       {
+                                               nl = nearlight + j;
+                                               nl->intensity = intensity;
+                                               // transform the light into the model's coordinate system
+                                               if (worldcoords)
+                                                       VectorCopy(rd->origin, nl->origin);
+                                               else
+                                               {
+                                                       Matrix4x4_Transform(&ent->inversematrix, rd->origin, nl->origin);
+                                                       /*
+                                                       Con_Printf("%i %s : %f %f %f : %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n"
+                                                       , rd - r_dlight, ent->model->name
+                                                       , rd->origin[0], rd->origin[1], rd->origin[2]
+                                                       , nl->origin[0], nl->origin[1], nl->origin[2]
+                                                       , ent->inversematrix.m[0][0], ent->inversematrix.m[0][1], ent->inversematrix.m[0][2], ent->inversematrix.m[0][3]
+                                                       , ent->inversematrix.m[1][0], ent->inversematrix.m[1][1], ent->inversematrix.m[1][2], ent->inversematrix.m[1][3]
+                                                       , ent->inversematrix.m[2][0], ent->inversematrix.m[2][1], ent->inversematrix.m[2][2], ent->inversematrix.m[2][3]
+                                                       , ent->inversematrix.m[3][0], ent->inversematrix.m[3][1], ent->inversematrix.m[3][2], ent->inversematrix.m[3][3]);
+                                                       */
+                                               }
+                                               // integrate mscale into falloff, for maximum speed
+                                               nl->falloff = mscale;
+                                               VectorCopy(ambientcolor, nl->ambientlight);
+                                               nl->light[0] = rd->light[0] * colorr * 4.0f;
+                                               nl->light[1] = rd->light[1] * colorg * 4.0f;
+                                               nl->light[2] = rd->light[2] * colorb * 4.0f;
+                                               nl->subtract = rd->subtract;
+                                               nl->offset = LIGHTOFFSET;
+                                       }
                                }
                        }
                }
        }
        else
-       {
                R_CompleteLightPoint (basecolor, ent->origin, true, NULL);
-       }
        basecolor[0] *= colorr;
        basecolor[1] *= colorg;
        basecolor[2] *= colorb;
        avc = colors;
        if (nearlights)
        {
+               GL_UseColorArray();
                av = vertices;
                avn = normals;
                for (i = 0;i < numverts;i++)
@@ -870,14 +873,7 @@ void R_LightModel(const entity_render_t *ent, int numverts, float *vertices, flo
                }
        }
        else
-       {
-               for (i = 0;i < numverts;i++)
-               {
-                       VectorCopy(basecolor, avc);
-                       avc[3] = a;
-                       avc += 4;
-               }
-       }
+               GL_Color(basecolor[0], basecolor[1], basecolor[2], a);
 }
 
 void R_UpdateEntLights(entity_render_t *ent)
index f648a5e54b038b73a12c429ab196cfa79212ddf4..5e3cfde40ddb67059cb6785d03b7714b17e034b5 100644 (file)
@@ -2,6 +2,13 @@
 #include "quakedef.h"
 #include "r_shadow.h"
 
+#define SHADOWSTAGE_NONE 0
+#define SHADOWSTAGE_STENCIL 1
+#define SHADOWSTAGE_LIGHT 2
+#define SHADOWSTAGE_ERASESTENCIL 3
+
+int r_shadowstage = SHADOWSTAGE_NONE;
+
 mempool_t *r_shadow_mempool;
 
 int maxshadowelements;
@@ -15,12 +22,12 @@ rtexture_t *r_shadow_normalscubetexture;
 rtexture_t *r_shadow_attenuation2dtexture;
 rtexture_t *r_shadow_blankbumptexture;
 
-cvar_t r_shadow1 = {0, "r_shadow1", "16"};
-cvar_t r_shadow2 = {0, "r_shadow2", "2"};
-cvar_t r_shadow3 = {0, "r_shadow3", "65536"};
-cvar_t r_shadow4 = {0, "r_shadow4", "1"};
+cvar_t r_shadow1 = {0, "r_shadow1", "2"};
+cvar_t r_shadow2 = {0, "r_shadow2", "0"};
+cvar_t r_shadow3 = {0, "r_shadow3", "32768"};
+cvar_t r_shadow4 = {0, "r_shadow4", "0"};
 cvar_t r_shadow5 = {0, "r_shadow5", "0"};
-cvar_t r_shadow6 = {0, "r_shadow6", "1"};
+cvar_t r_shadow6 = {0, "r_shadow6", "0"};
 cvar_t r_light_realtime = {0, "r_light_realtime", "0"};
 cvar_t r_light_quality = {0, "r_light_quality", "1"};
 cvar_t r_light_gloss = {0, "r_light_gloss", "0"};
@@ -74,7 +81,7 @@ void R_Shadow_Init(void)
        R_RegisterModule("R_Shadow", r_shadow_start, r_shadow_shutdown, r_shadow_newmap);
 }
 
-void R_Shadow_Volume(int numverts, int numtris, float *vertex, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance, int visiblevolume)
+void R_Shadow_Volume(int numverts, int numtris, float *vertex, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance)
 {
        int i, *e, *n, *out, tris;
        float *v0, *v1, *v2, temp[3], f;
@@ -262,19 +269,15 @@ void R_Shadow_Volume(int numverts, int numtris, float *vertex, int *elements, in
                        }
                }
        }
-       R_Shadow_RenderVolume(numverts * 2, tris, shadowelements, visiblevolume);
+       R_Shadow_RenderVolume(numverts * 2, tris, shadowelements);
 }
 
-void R_Shadow_RenderVolume(int numverts, int numtris, int *elements, int visiblevolume)
+void R_Shadow_RenderVolume(int numverts, int numtris, int *elements)
 {
+       if (!numverts || !numtris)
+               return;
        // draw the volume
-       if (visiblevolume)
-       {
-               //qglDisable(GL_CULL_FACE);
-               R_Mesh_Draw(numverts, numtris, elements);
-               //qglEnable(GL_CULL_FACE);
-       }
-       else
+       if (r_shadowstage == SHADOWSTAGE_STENCIL)
        {
                // increment stencil if backface is behind depthbuffer
                qglCullFace(GL_BACK); // quake is backwards, this culls front faces
@@ -285,6 +288,8 @@ void R_Shadow_RenderVolume(int numverts, int numtris, int *elements, int visible
                qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
                R_Mesh_Draw(numverts, numtris, elements);
        }
+       else
+               R_Mesh_Draw(numverts, numtris, elements);
 }
 
 float r_shadow_atten1, r_shadow_atten2, r_shadow_atten5;
@@ -305,12 +310,10 @@ static void R_Shadow_Make3DTextures(void)
                                v[0] = (x + 0.5f) * (2.0f / (float) ATTEN3DSIZE) - 1.0f;
                                v[1] = (y + 0.5f) * (2.0f / (float) ATTEN3DSIZE) - 1.0f;
                                v[2] = (z + 0.5f) * (2.0f / (float) ATTEN3DSIZE) - 1.0f;
-                               length = sqrt(DotProduct(v, v));
-                               if (DotProduct(v, v) < 1)
-                                       intensity = (((r_shadow_atten1 / (length*length + r_shadow_atten5)) - (r_shadow_atten1 * r_shadow_atten2))) / 256.0f;
-                               else
-                                       intensity = 0;
-                               ilen = 127.0f * bound(0, intensity, 1) / length;
+                               intensity = 1.0f - sqrt(DotProduct(v, v));
+                               if (intensity > 0)
+                                       intensity *= intensity;
+                               ilen = 127.0f * bound(0, intensity * r_shadow_atten1, 1) / sqrt(DotProduct(v, v));
                                data[z][y][x][0] = 128.0f + ilen * v[0];
                                data[z][y][x][1] = 128.0f + ilen * v[1];
                                data[z][y][x][2] = 128.0f + ilen * v[2];
@@ -404,18 +407,18 @@ static void R_Shadow_MakeTextures(void)
                        v[0] = (x + 0.5f) * (2.0f / 128.0f) - 1.0f;
                        v[1] = (y + 0.5f) * (2.0f / 128.0f) - 1.0f;
                        v[2] = 0;
-                       if (DotProduct(v, v) < 1)
-                               intensity = (((r_shadow_atten1 / (DotProduct(v, v)+r_shadow_atten5)) - (r_shadow_atten1 * r_shadow_atten2))) / 256.0f;
-                       else
-                               intensity = 0;
-                       d = bound(0, intensity, 255) / sqrt(DotProduct(v, v));
+                       intensity = 1.0f - sqrt(DotProduct(v, v));
+                       if (intensity > 0)
+                               intensity *= intensity;
+                       intensity = bound(0, intensity * r_shadow_atten1 * 256.0f, 255.0f);
+                       d = bound(0, intensity, 255);
                        data[0][y][x][0] = d;
                        data[0][y][x][1] = d;
                        data[0][y][x][2] = d;
-                       data[0][y][x][3] = 255;
+                       data[0][y][x][3] = d;
                }
        }
-       r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", 128, 128, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
+       r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", 128, 128, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALPHA | TEXF_MIPMAP, NULL);
        R_Shadow_Make3DTextures();
 }
 
@@ -441,6 +444,7 @@ void R_Shadow_Stage_Begin(void)
        m.blendfunc2 = GL_ZERO;
        R_Mesh_State(&m);
        GL_Color(0, 0, 0, 1);
+       r_shadowstage = SHADOWSTAGE_NONE;
 }
 
 void R_Shadow_Stage_ShadowVolumes(void)
@@ -458,6 +462,9 @@ void R_Shadow_Stage_ShadowVolumes(void)
        qglEnable(GL_STENCIL_TEST);
        qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
        qglStencilFunc(GL_ALWAYS, 0, 0xFF);
+       qglEnable(GL_CULL_FACE);
+       qglEnable(GL_DEPTH_TEST);
+       r_shadowstage = SHADOWSTAGE_STENCIL;
 }
 
 void R_Shadow_Stage_Light(void)
@@ -478,11 +485,33 @@ void R_Shadow_Stage_Light(void)
        // only draw light where this geometry was already rendered AND the
        // stencil is 0 (non-zero means shadow)
        qglStencilFunc(GL_EQUAL, 0, 0xFF);
+       qglEnable(GL_CULL_FACE);
+       qglEnable(GL_DEPTH_TEST);
+       r_shadowstage = SHADOWSTAGE_LIGHT;
 }
 
-void R_Shadow_Stage_End(void)
+void R_Shadow_Stage_EraseShadowVolumes(void)
 {
        rmeshstate_t m;
+       memset(&m, 0, sizeof(m));
+       R_Mesh_TextureState(&m);
+       GL_Color(1, 1, 1, 1);
+       qglColorMask(0, 0, 0, 0);
+       qglDisable(GL_BLEND);
+       qglDepthMask(0);
+       qglDepthFunc(GL_LESS);
+       qglClearStencil(0);
+       qglClear(GL_STENCIL_BUFFER_BIT);
+       qglEnable(GL_STENCIL_TEST);
+       qglStencilOp(GL_ZERO, GL_KEEP, GL_KEEP);
+       qglStencilFunc(GL_NOTEQUAL, 0, 0xFF);
+       qglDisable(GL_CULL_FACE);
+       qglDisable(GL_DEPTH_TEST);
+       r_shadowstage = SHADOWSTAGE_ERASESTENCIL;
+}
+
+void R_Shadow_Stage_End(void)
+{
        // attempt to restore state to what Mesh_State thinks it is
        qglDisable(GL_BLEND);
        qglBlendFunc(GL_ONE, GL_ZERO);
@@ -494,31 +523,25 @@ void R_Shadow_Stage_End(void)
        qglDisable(GL_STENCIL_TEST);
        qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
        qglStencilFunc(GL_ALWAYS, 0, 0xFF);
+       qglEnable(GL_CULL_FACE);
+       qglEnable(GL_DEPTH_TEST);
+       r_shadowstage = SHADOWSTAGE_NONE;
 }
 
-void R_Shadow_GenTexCoords_Attenuation2D(float *out, int numverts, const float *vertex, const float *svectors, const float *tvectors, const vec3_t relativelightorigin, float lightradius)
+void R_Shadow_GenTexCoords_Attenuation2D1D(float *out2d, float *out1d, int numverts, const float *vertex, const float *svectors, const float *tvectors, const float *normals, const vec3_t relativelightorigin, float lightradius)
 {
        int i;
        float lightvec[3], iradius;
        iradius = 0.5f / lightradius;
-       for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, out += 4)
+       for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, normals += 4, out2d += 4, out1d += 4)
        {
                VectorSubtract(vertex, relativelightorigin, lightvec);
-               out[0] = 0.5f + DotProduct(svectors, lightvec) * iradius;
-               out[1] = 0.5f + DotProduct(tvectors, lightvec) * iradius;
-       }
-}
-
-void R_Shadow_GenTexCoords_Attenuation1D(float *out, int numverts, const float *vertex, const float *normals, const vec3_t relativelightorigin, float lightradius)
-{
-       int i;
-       float lightvec[3], iradius;
-       iradius = 0.5f / lightradius;
-       for (i = 0;i < numverts;i++, vertex += 4, normals += 4, out += 4)
-       {
-               VectorSubtract(vertex, relativelightorigin, lightvec);
-               out[0] = 0.5f + DotProduct(normals, lightvec) * iradius;
-               out[1] = 0.5f;
+               out2d[0] = 0.5f + DotProduct(svectors, lightvec) * iradius;
+               out2d[1] = 0.5f + DotProduct(tvectors, lightvec) * iradius;
+               out2d[2] = 0;
+               out1d[0] = 0.5f + DotProduct(normals, lightvec) * iradius;
+               out1d[1] = 0.5f;
+               out1d[2] = 0;
        }
 }
 
@@ -530,40 +553,16 @@ void R_Shadow_GenTexCoords_Diffuse_Attenuation3D(float *out, int numverts, const
        for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, normals += 4, out += 4)
        {
                VectorSubtract(vertex, relativelightorigin, lightvec);
-               if (r_shadow6.integer != 0)
-               {
-                       VectorClear(lightvec);
-                       if (r_shadow6.integer > 0)
-                               lightvec[(r_shadow6.integer - 1) % 3] = 64;
-                       else
-                               lightvec[((-r_shadow6.integer) - 1) % 3] = -64;
-               }
-               if (r_shadow4.integer & 8)
-                       lightvec[0] = -lightvec[0];
-               if (r_shadow4.integer & 16)
-                       lightvec[1] = -lightvec[1];
-               if (r_shadow4.integer & 32)
-                       lightvec[2] = -lightvec[2];
-               if (r_shadow4.integer & 1)
-                       out[0] = 0.5f - DotProduct(svectors, lightvec) * iradius;
-               else
-                       out[0] = 0.5f + DotProduct(svectors, lightvec) * iradius;
-               if (r_shadow4.integer & 2)
-                       out[1] = 0.5f - DotProduct(tvectors, lightvec) * iradius;
-               else
-                       out[2] = 0.5f + DotProduct(tvectors, lightvec) * iradius;
-               if (r_shadow4.integer & 4)
-                       out[2] = 0.5f - DotProduct(normals, lightvec) * iradius;
-               else
-                       out[2] = 0.5f + DotProduct(normals, lightvec) * iradius;
+               out[0] = 0.5f + DotProduct(svectors, lightvec) * iradius;
+               out[1] = 0.5f + DotProduct(tvectors, lightvec) * iradius;
+               out[2] = 0.5f + DotProduct(normals, lightvec) * iradius;
        }
 }
 
-void R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(float *out, int numverts, const float *vertex, const float *svectors, const float *tvectors, const float *normals, const vec3_t relativelightorigin, float lightradius)
+void R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(float *out, int numverts, const float *vertex, const float *svectors, const float *tvectors, const float *normals, const vec3_t relativelightorigin)
 {
        int i;
        float lightdir[3], iradius;
-       iradius = 0.5f / lightradius;
        for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, normals += 4, out += 4)
        {
                VectorSubtract(vertex, relativelightorigin, lightdir);
@@ -595,11 +594,10 @@ void R_Shadow_GenTexCoords_Specular_Attenuation3D(float *out, int numverts, cons
        }
 }
 
-void R_Shadow_GenTexCoords_Specular_NormalCubeMap(float *out, int numverts, const float *vertex, const float *svectors, const float *tvectors, const float *normals, const vec3_t relativelightorigin, const vec3_t relativeeyeorigin, float lightradius)
+void R_Shadow_GenTexCoords_Specular_NormalCubeMap(float *out, int numverts, const float *vertex, const float *svectors, const float *tvectors, const float *normals, const vec3_t relativelightorigin, const vec3_t relativeeyeorigin)
 {
        int i;
        float lightdir[3], eyedir[3], halfdir[3], lightdirlen, ilen, iradius;
-       iradius = 0.5f / lightradius;
        for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, normals += 4, out += 4)
        {
                VectorSubtract(vertex, relativelightorigin, lightdir);
@@ -617,61 +615,155 @@ void R_Shadow_GenTexCoords_Specular_NormalCubeMap(float *out, int numverts, cons
 void R_Shadow_GenTexCoords_LightCubeMap(float *out, int numverts, const float *vertex, const vec3_t relativelightorigin)
 {
        int i;
+       // FIXME: this needs to be written
+       // this code assumes the vertices are in worldspace (a false assumption)
        for (i = 0;i < numverts;i++, vertex += 4, out += 4)
                VectorSubtract(vertex, relativelightorigin, out);
 }
 
 void R_Shadow_RenderLighting(int numverts, int numtriangles, const int *elements, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, rtexture_t *basetexture, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap)
 {
-       float f;
+       int mult;
+       float scale, colorscale;
        rmeshstate_t m;
        memset(&m, 0, sizeof(m));
        if (!bumptexture)
                bumptexture = r_shadow_blankbumptexture;
-       f = 1.0f / r_shadow3.value;
+       // colorscale accounts for how much we multiply the brightness during combine
        if (r_light_quality.integer == 1)
        {
-               // 4 texture 3D path, two pass
-               GL_Color(1,1,1,1);
-               //lightcolor[0] * f, lightcolor[1] * f, lightcolor[2] * f, 1);
-               memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4]));
-               memcpy(varray_texcoord[2], texcoords, numverts * sizeof(float[4]));
-               if (r_light_gloss.integer != 2)
+               if (r_textureunits.integer >= 4)
+                       colorscale = r_colorscale * 0.125f / r_shadow3.value;
+               else
+                       colorscale = r_colorscale * 0.5f / r_shadow3.value;
+       }
+       else
+               colorscale = r_colorscale * 0.5f / r_shadow3.value;
+       // limit mult to 64 for sanity sake
+       for (mult = 1, scale = ixtable[mult];mult < 64 && (lightcolor[0] * scale * colorscale > 1 || lightcolor[1] * scale * colorscale > 1 || lightcolor[2] * scale * colorscale > 1);mult++, scale = ixtable[mult]);
+       colorscale *= scale;
+       for (;mult > 0;mult--)
+       {
+               if (r_light_quality.integer == 1)
                {
-                       m.tex[0] = R_GetTexture(bumptexture);
-                       m.tex3d[1] = R_GetTexture(r_shadow_normalsattenuationtexture);
-                       m.tex[2] = R_GetTexture(basetexture);
-                       m.texcubemap[3] = R_GetTexture(lightcubemap);
-                       m.texcombinergb[0] = GL_REPLACE;
-                       m.texcombinergb[1] = GL_DOT3_RGB_ARB;
-                       m.texcombinergb[2] = GL_MODULATE;
-                       m.texcombinergb[3] = GL_MODULATE;
-                       m.texrgbscale[2] = 2;
-                       R_Mesh_TextureState(&m);
-                       R_Shadow_GenTexCoords_Diffuse_Attenuation3D(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, lightradius);
-                       if (m.texcubemap[3])
-                               R_Shadow_GenTexCoords_LightCubeMap(varray_texcoord[3], numverts, varray_vertex, relativelightorigin);
-                       R_Mesh_Draw(numverts, numtriangles, elements);
+                       if (r_textureunits.integer >= 4)
+                       {
+                               // 4 texture 3D path, two pass
+                               m.tex[0] = R_GetTexture(bumptexture);
+                               m.tex3d[1] = R_GetTexture(r_shadow_normalsattenuationtexture);
+                               m.tex[2] = R_GetTexture(basetexture);
+                               m.texcubemap[3] = R_GetTexture(lightcubemap);
+                               m.tex[3] = R_GetTexture(r_notexture);
+                               m.texcombinergb[0] = GL_REPLACE;
+                               m.texcombinergb[1] = GL_DOT3_RGB_ARB;
+                               m.texcombinergb[2] = GL_MODULATE;
+                               m.texcombinergb[3] = GL_MODULATE;
+                               m.texrgbscale[1] = 2;
+                               m.texrgbscale[3] = 4;
+                               R_Mesh_TextureState(&m);
+                               GL_Color(lightcolor[0] * colorscale, lightcolor[1] * colorscale, lightcolor[2] * colorscale, 1);
+                               memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4]));
+                               memcpy(varray_texcoord[2], texcoords, numverts * sizeof(float[4]));
+                               if (lightcubemap)
+                                       R_Shadow_GenTexCoords_LightCubeMap(varray_texcoord[3], numverts, varray_vertex, relativelightorigin);
+                               else
+                               {
+                                       qglActiveTexture(GL_TEXTURE3_ARB);
+                                       qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB);
+                               }
+                               R_Shadow_GenTexCoords_Diffuse_Attenuation3D(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, lightradius);
+                               R_Mesh_Draw(numverts, numtriangles, elements);
+                               if (!lightcubemap)
+                               {
+                                       qglActiveTexture(GL_TEXTURE3_ARB);
+                                       qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+                               }
+                               if (r_light_gloss.integer && glosstexture)
+                               {
+                                       m.tex[2] = R_GetTexture(glosstexture);
+                                       R_Mesh_TextureState(&m);
+                                       R_Shadow_GenTexCoords_Specular_Attenuation3D(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin, lightradius);
+                                       if (!lightcubemap)
+                                       {
+                                               qglActiveTexture(GL_TEXTURE3_ARB);
+                                               qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB);
+                                       }
+                                       R_Mesh_Draw(numverts, numtriangles, elements);
+                                       if (!lightcubemap)
+                                       {
+                                               qglActiveTexture(GL_TEXTURE3_ARB);
+                                               qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               // 2 texture 3D path, four pass
+                               m.tex[0] = R_GetTexture(bumptexture);
+                               m.tex3d[1] = R_GetTexture(r_shadow_normalsattenuationtexture);
+                               m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+                               m.texalphascale[1] = 2;
+                               R_Mesh_TextureState(&m);
+                               qglColorMask(0,0,0,1);
+                               qglDisable(GL_BLEND);
+                               GL_Color(1,1,1,1);
+                               memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4]));
+                               R_Shadow_GenTexCoords_Diffuse_Attenuation3D(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, lightradius);
+                               R_Mesh_Draw(numverts, numtriangles, elements);
+
+                               m.tex[0] = R_GetTexture(basetexture);
+                               m.tex3d[1] = 0;
+                               m.texcubemap[1] = R_GetTexture(lightcubemap);
+                               m.texcombinergb[1] = GL_MODULATE;
+                               m.texrgbscale[1] = 1;
+                               m.texalphascale[1] = 1;
+                               R_Mesh_TextureState(&m);
+                               qglColorMask(1,1,1,1);
+                               qglBlendFunc(GL_DST_ALPHA, GL_ONE);
+                               qglEnable(GL_BLEND);
+                               GL_Color(lightcolor[0] * colorscale, lightcolor[1] * colorscale, lightcolor[2] * colorscale, 1);
+                               if (lightcubemap)
+                                       R_Shadow_GenTexCoords_LightCubeMap(varray_texcoord[1], numverts, varray_vertex, relativelightorigin);
+                               R_Mesh_Draw(numverts, numtriangles, elements);
+                       }
                }
-               if (r_light_gloss.integer && glosstexture)
+               else
                {
+                       // 2 texture no3D path, six pass
+                       m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture);
+                       m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture);
+                       R_Mesh_TextureState(&m);
+                       qglColorMask(0,0,0,1);
+                       qglDisable(GL_BLEND);
+                       GL_Color(1,1,1,1);
+                       R_Shadow_GenTexCoords_Attenuation2D1D(varray_texcoord[0], varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, lightradius);
+                       R_Mesh_Draw(numverts, numtriangles, elements);
+
                        m.tex[0] = R_GetTexture(bumptexture);
-                       m.tex3d[1] = R_GetTexture(r_shadow_normalsattenuationtexture);
-                       m.tex[2] = R_GetTexture(glosstexture);
-                       m.texcubemap[3] = R_GetTexture(lightcubemap);
-                       m.texcombinergb[0] = GL_REPLACE;
-                       m.texcombinergb[1] = GL_DOT3_RGB_ARB;
-                       m.texcombinergb[2] = GL_MODULATE;
-                       m.texcombinergb[3] = GL_MODULATE;
-                       m.texrgbscale[2] = 2;
+                       m.tex[1] = 0;
+                       m.texcubemap[1] = R_GetTexture(r_shadow_normalscubetexture);
+                       m.texcombinergb[1] = GL_DOT3_RGBA_ARB;
+                       m.texalphascale[1] = 2;
                        R_Mesh_TextureState(&m);
-                       R_Shadow_GenTexCoords_Specular_Attenuation3D(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin, lightradius);
+                       qglBlendFunc(GL_DST_ALPHA, GL_ZERO);
+                       qglEnable(GL_BLEND);
+                       memcpy(varray_texcoord[0], texcoords, numverts * sizeof(float[4]));
+                       R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin);
+                       R_Mesh_Draw(numverts, numtriangles, elements);
+
+                       m.tex[0] = R_GetTexture(basetexture);
+                       m.texcubemap[1] = R_GetTexture(lightcubemap);
+                       m.texcombinergb[1] = GL_MODULATE;
+                       m.texrgbscale[1] = 1;
+                       m.texalphascale[1] = 1;
+                       R_Mesh_TextureState(&m);
+                       qglColorMask(1,1,1,1);
+                       qglBlendFunc(GL_DST_ALPHA, GL_ONE);
+                       GL_Color(lightcolor[0] * colorscale, lightcolor[1] * colorscale, lightcolor[2] * colorscale, 1);
+                       if (lightcubemap)
+                               R_Shadow_GenTexCoords_LightCubeMap(varray_texcoord[1], numverts, varray_vertex, relativelightorigin);
                        R_Mesh_Draw(numverts, numtriangles, elements);
                }
        }
-       else
-       {
-               //R_Mesh_TextureState(&m);
-       }
 }
 
index e2dedad6277c673b8876f29317414bd17d27dab2..01ae581cc7aaab6878729df6eab539cdb0469c35 100644 (file)
@@ -8,14 +8,15 @@ extern cvar_t r_light_gloss;
 extern cvar_t r_light_debuglight;
 
 void R_Shadow_Init(void);
-void R_Shadow_Volume(int numverts, int numtris, float *vertex, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance, int visiblevolume);
+void R_Shadow_Volume(int numverts, int numtris, float *vertex, int *elements, int *neighbors, vec3_t relativelightorigin, float lightradius, float projectdistance);
 void R_Shadow_RenderLighting(int numverts, int numtriangles, const int *elements, const float *svectors, const float *tvectors, const float *normals, const float *texcoords, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, rtexture_t *basetexture, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap);
 void R_Shadow_ClearStencil(void);
 
-void R_Shadow_RenderVolume(int numverts, int numtris, int *elements, int visiblevolume);
+void R_Shadow_RenderVolume(int numverts, int numtris, int *elements);
 void R_Shadow_Stage_Begin(void);
 void R_Shadow_Stage_ShadowVolumes(void);
 void R_Shadow_Stage_Light(void);
+void R_Shadow_Stage_EraseShadowVolumes(void);
 void R_Shadow_Stage_End(void);
 
 #endif
index 7ca8cfc7511d655c66ce2ce4799e008c55cb2838..5b2c71260a3d92d0aaa4303dac24bc9fa098eb53 100644 (file)
--- a/render.h
+++ b/render.h
@@ -108,7 +108,7 @@ void R_InitSky (qbyte *src, int bytesperpixel); // called at level load
 
 void R_NewMap (void);
 
-void R_DrawWorld(entity_render_t *ent, int baselighting);
+void R_DrawWorld(entity_render_t *ent);
 void R_DrawParticles(void);
 void R_DrawExplosions(void);
 
@@ -120,8 +120,10 @@ void R_DrawExplosions(void);
 
 //#define PARANOID 1
 
-int R_CullBox(const vec3_t emins, const vec3_t emaxs);
-int R_NotCulledBox(const vec3_t emins, const vec3_t emaxs);
+int R_CullBox(const vec3_t mins, const vec3_t maxs);
+int PVS_CullBox(const vec3_t mins, const vec3_t maxs);
+int R_CullSphere(const vec3_t origin, vec_t radius);
+int PVS_CullSphere(const vec3_t origin, vec_t radius);
 
 extern qboolean fogenabled;
 extern vec3_t fogcolor;
index 542690a6f8b6548b2b05f3bfef9e4eb7cafad47b..22075cb485455d05e6afecb8828fa19554b0e033 100644 (file)
--- a/vid_glx.c
+++ b/vid_glx.c
@@ -654,9 +654,11 @@ void VID_BuildGLXAttrib(int *attrib, int stencil, int gamma)
        *attrib++ = GLX_BLUE_SIZE;*attrib++ = 1;
        *attrib++ = GLX_DOUBLEBUFFER;
        *attrib++ = GLX_DEPTH_SIZE;*attrib++ = 1;
+       // if stencil is enabled, ask for alpha too
        if (stencil)
        {
                *attrib++ = GLX_STENCIL_SIZE;*attrib++ = 8;
+               *attrib++ = GLX_ALPHA_SIZE;*attrib++ = 1;
        }
        if (gamma)
        {
index bdc0076fe446db1c301432e3f87d2f10ddc0b233..969cfcc088ab38afbb0349332dc6dec8be9b82ac 100644 (file)
--- a/vid_wgl.c
+++ b/vid_wgl.c
@@ -809,14 +809,21 @@ int VID_InitMode (int fullscreen, int width, int height, int bpp, int stencil)
        HGLRC baseRC;
        int CenterX, CenterY;
        const char *gldrivername;
-       
+
        if (vid_initialized)
                Sys_Error("VID_InitMode called when video is already initialised\n");
 
+       // if stencil is enabled, ask for alpha too
        if (stencil)
+       {
                pfd.cStencilBits = 8;
+               pfd.cAlphaBits = 8;
+       }
        else
+       {
                pfd.cStencilBits = 0;
+               pfd.cAlphaBits = 0;
+       }
 
        gldrivername = "opengl32.dll";
        i = COM_CheckParm("-gl_driver");