added GLSL shader path for normal rendering stage, reworked a lot of things to do...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 17 Mar 2006 06:33:11 +0000 (06:33 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 17 Mar 2006 06:33:11 +0000 (06:33 +0000)
removed .lights file loading and the corresponding directional model shading (these were only produced by hlight for q1bsp, very rare files) so that the GLSL normal rendering stage would not have to deal with .lights files
changed R_CompleteLightPoint to properly match rtlight shading, not the old dlights, this allowed removal of the old lightmap_* rtlight fields

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

client.h
gl_rmain.c
model_brush.c
model_brush.h
model_shared.h
r_light.c
r_light.h
r_shadow.c
render.h

index cbe86f4..17bb541 100644 (file)
--- a/client.h
+++ b/client.h
@@ -26,10 +26,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 // LordHavoc: 256 dynamic lights
 #define MAX_DLIGHTS 256
-// LordHavoc: this affects the lighting scale of the whole game
-#define LIGHTOFFSET 1024.0f
-// max lights shining on one entity
-#define MAXENTLIGHTS 128
 
 // flags for rtlight rendering
 #define LIGHTFLAG_NORMALMODE 1
@@ -117,16 +113,6 @@ typedef struct rtlight_s
        // this is R_Shadow_Cubemap(rtlight->cubemapname)
        rtexture_t *currentcubemap;
 
-       // lightmap renderer stuff (remove someday!)
-       // the size of the light
-       vec_t lightmap_cullradius;
-       // the size of the light, squared
-       vec_t lightmap_cullradius2;
-       // the brightness of the light
-       vec3_t lightmap_light;
-       // to avoid sudden brightness change at cullradius, subtract this
-       vec_t lightmap_subtract;
-
        // static light info
        // true if this light should be compiled as a static light
        int isstatic;
@@ -280,12 +266,10 @@ typedef struct entity_render_s
        // 4 frame numbers (-1 if not used) and their blending scalers (0-1), if interpolation is not desired, use frame instead
        frameblend_t frameblend[4];
 
-       // caching results of static light traces (this is semi-persistent)
-       double entlightstime;
-       vec3_t entlightsorigin;
-       int entlightsframe;
-       int numentlights;
-       unsigned short entlights[MAXENTLIGHTS];
+       // current lighting from map
+       vec3_t modellight_ambient;
+       vec3_t modellight_diffuse; // q3bsp
+       vec3_t modellight_lightdir; // q3bsp
 }
 entity_render_t;
 
index 505bcaf..a7dc2c3 100644 (file)
@@ -656,17 +656,29 @@ void R_GLSL_CompilePermutation(int permutation)
        vertstrings_count = 1;
        fragstrings_count = 1;
        permutationname[0] = 0;
-       if (permutation & SHADERPERMUTATION_DELUXEMAPPING)
+       if (permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE)
        {
-               vertstrings_list[vertstrings_count++] = "#define USEDELUXEMAP\n";
-               fragstrings_list[fragstrings_count++] = "#define USEDELUXEMAP\n";
-               strlcat(permutationname, " deluxemap", sizeof(permutationname));
+               vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTSOURCE\n";
+               fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTSOURCE\n";
+               strlcat(permutationname, " lightsource", sizeof(permutationname));
        }
-       if (permutation & SHADERPERMUTATION_LIGHTSOURCE)
+       if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP)
        {
-               vertstrings_list[vertstrings_count++] = "#define USELIGHTSOURCE\n";
-               fragstrings_list[fragstrings_count++] = "#define USELIGHTSOURCE\n";
-               strlcat(permutationname, " lightsource", sizeof(permutationname));
+               vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP\n";
+               fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP\n";
+               strlcat(permutationname, " lightdirectionmap", sizeof(permutationname));
+       }
+       if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTION)
+       {
+               vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTION\n";
+               fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTION\n";
+               strlcat(permutationname, " lightdirection", sizeof(permutationname));
+       }
+       if (permutation & SHADERPERMUTATION_GLOW)
+       {
+               vertstrings_list[vertstrings_count++] = "#define USEGLOW\n";
+               fragstrings_list[fragstrings_count++] = "#define USEGLOW\n";
+               strlcat(permutationname, " glow", sizeof(permutationname));
        }
        if (permutation & SHADERPERMUTATION_COLORMAPPING)
        {
@@ -732,6 +744,9 @@ void R_GLSL_CompilePermutation(int permutation)
                p->loc_Texture_FogMask     = qglGetUniformLocationARB(p->program, "Texture_FogMask");
                p->loc_Texture_Pants       = qglGetUniformLocationARB(p->program, "Texture_Pants");
                p->loc_Texture_Shirt       = qglGetUniformLocationARB(p->program, "Texture_Shirt");
+               p->loc_Texture_Lightmap    = qglGetUniformLocationARB(p->program, "Texture_Lightmap");
+               p->loc_Texture_Deluxemap   = qglGetUniformLocationARB(p->program, "Texture_Deluxemap");
+               p->loc_Texture_Glow        = qglGetUniformLocationARB(p->program, "Texture_Glow");
                p->loc_FogColor            = qglGetUniformLocationARB(p->program, "FogColor");
                p->loc_LightPosition       = qglGetUniformLocationARB(p->program, "LightPosition");
                p->loc_EyePosition         = qglGetUniformLocationARB(p->program, "EyePosition");
@@ -745,15 +760,20 @@ void R_GLSL_CompilePermutation(int permutation)
                p->loc_SpecularScale       = qglGetUniformLocationARB(p->program, "SpecularScale");
                p->loc_OffsetMapping_Scale = qglGetUniformLocationARB(p->program, "OffsetMapping_Scale");
                p->loc_OffsetMapping_Bias  = qglGetUniformLocationARB(p->program, "OffsetMapping_Bias");
-               if (p->loc_Texture_Normal)   qglUniform1iARB(p->loc_Texture_Normal, 0);
-               if (p->loc_Texture_Color)    qglUniform1iARB(p->loc_Texture_Color, 1);
-               if (p->loc_Texture_Gloss)    qglUniform1iARB(p->loc_Texture_Gloss, 2);
-               if (p->loc_Texture_Cube)     qglUniform1iARB(p->loc_Texture_Cube, 3);
-               if (p->loc_Texture_FogMask)  qglUniform1iARB(p->loc_Texture_FogMask, 4);
-               if (p->loc_Texture_Pants)    qglUniform1iARB(p->loc_Texture_Pants, 5);
-               if (p->loc_Texture_Shirt)    qglUniform1iARB(p->loc_Texture_Shirt, 6);
-               if (p->loc_Texture_Lightmap) qglUniform1iARB(p->loc_Texture_Lightmap, 7);
-               if (p->loc_Texture_Deluxemap) qglUniform1iARB(p->loc_Texture_Deluxemap, 8);
+               p->loc_AmbientColor        = qglGetUniformLocationARB(p->program, "AmbientColor");
+               p->loc_DiffuseColor        = qglGetUniformLocationARB(p->program, "DiffuseColor");
+               p->loc_SpecularColor       = qglGetUniformLocationARB(p->program, "SpecularColor");
+               p->loc_LightDir            = qglGetUniformLocationARB(p->program, "LightDir");
+               if (p->loc_Texture_Normal >= 0)    qglUniform1iARB(p->loc_Texture_Normal, 0);
+               if (p->loc_Texture_Color >= 0)     qglUniform1iARB(p->loc_Texture_Color, 1);
+               if (p->loc_Texture_Gloss >= 0)     qglUniform1iARB(p->loc_Texture_Gloss, 2);
+               if (p->loc_Texture_Cube >= 0)      qglUniform1iARB(p->loc_Texture_Cube, 3);
+               if (p->loc_Texture_FogMask >= 0)   qglUniform1iARB(p->loc_Texture_FogMask, 4);
+               if (p->loc_Texture_Pants >= 0)     qglUniform1iARB(p->loc_Texture_Pants, 5);
+               if (p->loc_Texture_Shirt >= 0)     qglUniform1iARB(p->loc_Texture_Shirt, 6);
+               if (p->loc_Texture_Lightmap >= 0)  qglUniform1iARB(p->loc_Texture_Lightmap, 7);
+               if (p->loc_Texture_Deluxemap >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap, 8);
+               if (p->loc_Texture_Glow >= 0)      qglUniform1iARB(p->loc_Texture_Glow, 9);
                qglUseProgramObjectARB(0);
                CHECKGLERROR
        }
@@ -761,26 +781,45 @@ void R_GLSL_CompilePermutation(int permutation)
                Con_Printf("permutation%s failed for shader %s, some features may not work properly!\n", permutationname, "glsl/default.glsl");
 }
 
-void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float specularscale, qboolean dopants, qboolean doshirt)
+void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture, const vec3_t modelorg, const vec3_t lightcolorbase, qboolean modellighting)
 {
        // select a permutation of the lighting shader appropriate to this
        // combination of texture, entity, light source, and fogging, only use the
        // minimum features necessary to avoid wasting rendering time in the
        // fragment shader on features that are not being used
        int permutation = 0;
+       float specularscale = texture->specularscale;
        r_glsl_permutation = NULL;
        if (r_shadow_rtlight)
-               permutation |= SHADERPERMUTATION_LIGHTSOURCE;
+       {
+               permutation |= SHADERPERMUTATION_MODE_LIGHTSOURCE;
+               specularscale *= r_shadow_rtlight->specularscale;
+               if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
+                       permutation |= SHADERPERMUTATION_CUBEFILTER;
+       }
+       else if (modellighting)
+       {
+               permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION;
+               if (texture->skin.glow)
+                       permutation |= SHADERPERMUTATION_GLOW;
+       }
        else if (false)
-               permutation |= SHADERPERMUTATION_DELUXEMAPPING;
+       {
+               permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP;
+               if (texture->skin.glow)
+                       permutation |= SHADERPERMUTATION_GLOW;
+       }
+       else
+       {
+               if (texture->skin.glow)
+                       permutation |= SHADERPERMUTATION_GLOW;
+       }
+       if (specularscale > 0)
+               permutation |= SHADERPERMUTATION_SPECULAR;
        if (fogenabled)
                permutation |= SHADERPERMUTATION_FOG;
-       if ((dopants || doshirt))
+       if (texture->colormapping)
                permutation |= SHADERPERMUTATION_COLORMAPPING;
-       if (specularscale > 0)
-               permutation |= SHADERPERMUTATION_SPECULAR;
-       if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
-               permutation |= SHADERPERMUTATION_CUBEFILTER;
        if (r_glsl_offsetmapping.integer)
                permutation |= SHADERPERMUTATION_OFFSETMAPPING;
        if (r_glsl_surfacenormalize.integer)
@@ -814,11 +853,41 @@ void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture,
        CHECKGLERROR
        qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR
        R_Mesh_TexMatrix(0, &texture->currenttexmatrix);
-       if (r_shadow_rtlight)
+       if (permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE)
+       {
                R_Mesh_TexMatrix(3, &r_shadow_entitytolight);
-       if (r_glsl_permutation->loc_Texture_Normal) R_Mesh_TexBind(0, R_GetTexture(normalmaptexture));
-       if (r_glsl_permutation->loc_Texture_Color) R_Mesh_TexBind(1, R_GetTexture(basetexture));
-       if (r_glsl_permutation->loc_FogColor)
+               if (r_glsl_permutation->loc_Texture_Cube >= 0) R_Mesh_TexBind(3, R_GetTexture(r_shadow_rtlight->currentcubemap));
+               if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, r_shadow_entitylightorigin[0], r_shadow_entitylightorigin[1], r_shadow_entitylightorigin[2]);
+               if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
+               if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_shadow_rtlight->ambientscale);
+               if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_shadow_rtlight->diffusescale);
+               if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, specularscale);
+       }
+       else if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTION)
+       {
+               if (r_glsl_permutation->loc_AmbientColor >= 0)
+                       qglUniform3fARB(r_glsl_permutation->loc_AmbientColor, ent->modellight_ambient[0], ent->modellight_ambient[1], ent->modellight_ambient[2]);
+               if (r_glsl_permutation->loc_DiffuseColor >= 0)
+                       qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor, ent->modellight_diffuse[0], ent->modellight_diffuse[1], ent->modellight_diffuse[2]);
+               if (r_glsl_permutation->loc_SpecularColor >= 0)
+                       qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, ent->modellight_diffuse[0] * texture->specularscale, ent->modellight_diffuse[1] * texture->specularscale, ent->modellight_diffuse[2] * texture->specularscale);
+               if (r_glsl_permutation->loc_LightDir >= 0)
+                       qglUniform3fARB(r_glsl_permutation->loc_LightDir, ent->modellight_lightdir[0], ent->modellight_lightdir[1], ent->modellight_lightdir[2]);
+       }
+       else
+       {
+               if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_ambient.value * 2.0f / 128.0f);
+               if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_lightmapintensity * 2.0f);
+               if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, specularscale * 2.0f);
+       }
+       if (r_glsl_permutation->loc_Texture_Normal >= 0) R_Mesh_TexBind(0, R_GetTexture(texture->skin.nmap));
+       if (r_glsl_permutation->loc_Texture_Color >= 0) R_Mesh_TexBind(1, R_GetTexture(texture->basetexture));
+       if (r_glsl_permutation->loc_Texture_Gloss >= 0) R_Mesh_TexBind(2, R_GetTexture(texture->glosstexture));
+       if (r_glsl_permutation->loc_Texture_FogMask >= 0) R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation));
+       if (r_glsl_permutation->loc_Texture_Pants >= 0) R_Mesh_TexBind(5, R_GetTexture(texture->skin.pants));
+       if (r_glsl_permutation->loc_Texture_Shirt >= 0) R_Mesh_TexBind(6, R_GetTexture(texture->skin.shirt));
+       if (r_glsl_permutation->loc_Texture_Glow >= 0) R_Mesh_TexBind(9, R_GetTexture(texture->skin.glow));
+       if (r_glsl_permutation->loc_FogColor >= 0)
        {
                // additive passes are only darkened by fog, not tinted
                if (r_shadow_rtlight || (texture->currentmaterialflags & MATERIALFLAG_ADD))
@@ -826,21 +895,13 @@ void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture,
                else
                        qglUniform3fARB(r_glsl_permutation->loc_FogColor, fogcolor[0], fogcolor[1], fogcolor[2]);
        }
-       if (r_glsl_permutation->loc_LightPosition) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, r_shadow_entitylightorigin[0], r_shadow_entitylightorigin[1], r_shadow_entitylightorigin[2]);
-       if (r_glsl_permutation->loc_EyePosition) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, r_shadow_entityeyeorigin[0], r_shadow_entityeyeorigin[1], r_shadow_entityeyeorigin[2]);
-       if (r_glsl_permutation->loc_LightColor) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
-       if (r_glsl_permutation->loc_Texture_Pants) R_Mesh_TexBind(5, R_GetTexture(pantstexture));
-       if (r_glsl_permutation->loc_Texture_Shirt) R_Mesh_TexBind(6, R_GetTexture(shirttexture));
-       if (r_glsl_permutation->loc_Color_Pants) qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, ent->colormap_pantscolor[0], ent->colormap_pantscolor[1], ent->colormap_pantscolor[2]);
-       if (r_glsl_permutation->loc_Color_Shirt) qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, ent->colormap_shirtcolor[0], ent->colormap_shirtcolor[1], ent->colormap_shirtcolor[2]);
-       if (r_glsl_permutation->loc_FogRangeRecip) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, fograngerecip);
-       if (r_glsl_permutation->loc_AmbientScale) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_shadow_rtlight->ambientscale);
-       if (r_glsl_permutation->loc_DiffuseScale) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_shadow_rtlight->diffusescale);
-       if (r_glsl_permutation->loc_Texture_Gloss) R_Mesh_TexBind(2, R_GetTexture(glosstexture));
-       if (r_glsl_permutation->loc_SpecularPower) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, 8);
-       if (r_glsl_permutation->loc_SpecularScale) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, specularscale);
-       if (r_glsl_permutation->loc_OffsetMapping_Scale) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
-       if (r_glsl_permutation->loc_OffsetMapping_Bias) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Bias, r_glsl_offsetmapping_bias.value);
+       if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, modelorg[0], modelorg[1], modelorg[2]);
+       if (r_glsl_permutation->loc_Color_Pants >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, ent->colormap_pantscolor[0], ent->colormap_pantscolor[1], ent->colormap_pantscolor[2]);
+       if (r_glsl_permutation->loc_Color_Shirt >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, ent->colormap_shirtcolor[0], ent->colormap_shirtcolor[1], ent->colormap_shirtcolor[2]);
+       if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, fograngerecip);
+       if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, texture->specularpower);
+       if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
+       if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Bias, r_glsl_offsetmapping_bias.value);
        CHECKGLERROR
 }
 
@@ -1113,6 +1174,26 @@ int R_CullBox(const vec3_t mins, const vec3_t maxs)
 
 //==================================================================================
 
+static void R_UpdateEntityLighting(entity_render_t *ent)
+{
+       vec3_t tempdiffusenormal;
+       VectorSet(ent->modellight_ambient, r_ambient.value * (2.0f / 128.0f), r_ambient.value * (2.0f / 128.0f), r_ambient.value * (2.0f / 128.0f));
+       VectorClear(ent->modellight_diffuse);
+       VectorClear(ent->modellight_lightdir);
+       if ((ent->flags & RENDER_LIGHT) && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
+               r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, ent->origin, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
+       else // highly rare
+               VectorSet(ent->modellight_ambient, 1, 1, 1);
+       Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
+       VectorNormalize(ent->modellight_lightdir);
+       ent->modellight_ambient[0] *= ent->colormod[0] * r_lightmapintensity;
+       ent->modellight_ambient[1] *= ent->colormod[1] * r_lightmapintensity;
+       ent->modellight_ambient[2] *= ent->colormod[2] * r_lightmapintensity;
+       ent->modellight_diffuse[0] *= ent->colormod[0] * r_lightmapintensity;
+       ent->modellight_diffuse[1] *= ent->colormod[1] * r_lightmapintensity;
+       ent->modellight_diffuse[2] *= ent->colormod[2] * r_lightmapintensity;
+}
+
 static void R_MarkEntities (void)
 {
        int i, renderimask;
@@ -1135,8 +1216,8 @@ static void R_MarkEntities (void)
                        ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
                        if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && ((ent->effects & EF_NODEPTHTEST) || r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.worldmodel, r_worldleafvisible, ent->mins, ent->maxs)))
                        {
-                               R_UpdateEntLights(ent);
                                ent->visframe = r_framecount;
+                               R_UpdateEntityLighting(ent);
                        }
                }
        }
@@ -1152,8 +1233,8 @@ static void R_MarkEntities (void)
                        ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
                        if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && (ent->effects & EF_NODEPTHTEST))
                        {
-                               R_UpdateEntLights(ent);
                                ent->visframe = r_framecount;
+                               R_UpdateEntityLighting(ent);
                        }
                }
        }
@@ -1659,6 +1740,9 @@ void R_RenderScene(void)
 
        r_framecount++;
 
+       if (gl_support_fragment_shader)
+               qglUseProgramObjectARB(0);
+
        R_MeshQueue_BeginScene();
 
        R_SetFrustum();
@@ -1810,6 +1894,9 @@ void R_RenderScene(void)
        // don't let sound skip if going slow
        if (r_refdef.extraupdate)
                S_ExtraUpdate ();
+
+       if (gl_support_fragment_shader)
+               qglUseProgramObjectARB(0);
 }
 
 /*
@@ -2145,18 +2232,32 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
                t->currenttexmatrix = r_waterscrollmatrix;
        else
                t->currenttexmatrix = identitymatrix;
+
+       t->colormapping = VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f);
+       t->basetexture = (!t->colormapping && t->skin.merged) ? t->skin.merged : t->skin.base;
+       t->glosstexture = r_texture_white;
+       t->specularpower = 8;
+       t->specularscale = 0;
+       if (r_shadow_gloss.integer > 0)
+       {
+               if (t->skin.gloss)
+               {
+                       if (r_shadow_glossintensity.value > 0)
+                       {
+                               t->glosstexture = t->skin.gloss;
+                               t->specularscale = r_shadow_glossintensity.value;
+                       }
+               }
+               else if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0)
+                       t->specularscale = r_shadow_gloss2intensity.value;
+       }
+
        t->currentnumlayers = 0;
        if (!(t->currentmaterialflags & MATERIALFLAG_NODRAW))
        {
                if (gl_lightmaps.integer)
                        R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS, r_texture_white, &identitymatrix, 1, 1, 1, 1);
-               else if (t->currentmaterialflags & MATERIALFLAG_SKY)
-               {
-                       // transparent sky would be ridiculous
-                       if (!(t->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
-                               R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_SKY, r_texture_white, &identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], 1);
-               }
-               else
+               else if (!(t->currentmaterialflags & MATERIALFLAG_SKY))
                {
                        int blendfunc1, blendfunc2, depthmask;
                        if (t->currentmaterialflags & MATERIALFLAG_ADD)
@@ -2336,34 +2437,61 @@ void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture
        R_Mesh_VertexPointer(rsurface_vertex3f);
 }
 
+static void RSurf_Draw(const msurface_t *surface)
+{
+       GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
+       GL_LockArrays(0, 0);
+}
+
 static void RSurf_DrawLightmap(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog)
 {
        int i;
        float f;
        float *v, *c, *c2;
-       RSurf_SetVertexPointer(ent, texture, surface, modelorg, lightmode == 2, false);
+       RSurf_SetVertexPointer(ent, texture, surface, modelorg, lightmode >= 2, false);
        if (lightmode >= 2)
        {
                // model lighting
-               vec4_t ambientcolor4f;
+               vec4_t ambientcolor;
                vec3_t diffusecolor;
-               vec3_t diffusenormal;
-               if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, r*0.5f, g*0.5f, b*0.5f, a, false))
+               vec3_t lightdir;
+               VectorCopy(ent->modellight_lightdir, lightdir);
+               ambientcolor[0] = ent->modellight_ambient[0] * r * 0.5f;
+               ambientcolor[1] = ent->modellight_ambient[1] * g * 0.5f;
+               ambientcolor[2] = ent->modellight_ambient[2] * b * 0.5f;
+               diffusecolor[0] = ent->modellight_diffuse[0] * r * 0.5f;
+               diffusecolor[1] = ent->modellight_diffuse[1] * g * 0.5f;
+               diffusecolor[2] = ent->modellight_diffuse[2] * b * 0.5f;
+               if (VectorLength2(diffusecolor) > 0)
                {
-                       rsurface_lightmapcolor4f = varray_color4f;
-                       R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, surface->groupmesh->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, rsurface_lightmapcolor4f + 4 * surface->num_firstvertex);
+                       int numverts = surface->num_vertices;
+                       v = rsurface_vertex3f + 3 * surface->num_firstvertex;
+                       c2 = rsurface_normal3f + 3 * surface->num_firstvertex;
+                       c = varray_color4f + 4 * surface->num_firstvertex;
+                       // q3-style directional shading
+                       for (i = 0;i < numverts;i++, v += 3, c2 += 3, c += 4)
+                       {
+                               if ((f = DotProduct(c2, lightdir)) > 0)
+                               {
+                                       VectorMA(ambientcolor, f, diffusecolor, c);
+                                       c[3] = a;
+                               }
+                               else
+                                       VectorCopy4(ambientcolor, c);
+                       }
                        r = 1;
                        g = 1;
                        b = 1;
                        a = 1;
                        applycolor = false;
+                       rsurface_lightmapcolor4f = varray_color4f;
                }
                else
                {
-                       r = ambientcolor4f[0];
-                       g = ambientcolor4f[1];
-                       b = ambientcolor4f[2];
-                       a = ambientcolor4f[3];
+                       r = ambientcolor[0];
+                       g = ambientcolor[1];
+                       b = ambientcolor[2];
                        rsurface_lightmapcolor4f = NULL;
                }
        }
@@ -2447,16 +2575,7 @@ static void RSurf_DrawLightmap(const entity_render_t *ent, const texture_t *text
        }
        R_Mesh_ColorPointer(rsurface_lightmapcolor4f);
        GL_Color(r, g, b, a);
-       GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
-       GL_LockArrays(0, 0);
-}
-
-static void RSurf_Draw(const msurface_t *surface)
-{
-       GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
-       GL_LockArrays(0, 0);
+       RSurf_Draw(surface);
 }
 
 static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg)
@@ -2469,13 +2588,129 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
        rmeshstate_t m;
        if (texture->currentmaterialflags & MATERIALFLAG_NODRAW)
                return;
+       r_shadow_rtlight = NULL;
        renderstats.entities_surfaces += texturenumsurfaces;
        // FIXME: identify models using a better check than ent->model->brush.shadowmesh
        lightmode = ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh) ? 0 : 2;
        GL_DepthTest(!(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
        if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE))
                qglDisable(GL_CULL_FACE);
-       if (texture->currentnumlayers)
+       if (texture->currentmaterialflags & MATERIALFLAG_SKY)
+       {
+               // transparent sky would be ridiculous
+               if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
+               {
+                       GL_DepthMask(true);
+                       if (skyrendernow)
+                       {
+                               skyrendernow = false;
+                               if (skyrendermasked)
+                               {
+                                       R_Sky();
+                                       // restore entity matrix and GL_Color
+                                       R_Mesh_Matrix(&ent->matrix);
+                                       GL_Color(1,1,1,1);
+                               }
+                       }
+                       // LordHavoc: HalfLife maps have freaky skypolys...
+                       //if (!ent->model->brush.ishlbsp)
+                       {
+                               if (skyrendermasked)
+                               {
+                                       // depth-only (masking)
+                                       GL_ColorMask(0,0,0,0);
+                                       // just to make sure that braindead drivers don't draw anything
+                                       // despite that colormask...
+                                       GL_BlendFunc(GL_ZERO, GL_ONE);
+                               }
+                               else
+                               {
+                                       // fog sky
+                                       GL_BlendFunc(GL_ONE, GL_ZERO);
+                               }
+                               GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
+                               memset(&m, 0, sizeof(m));
+                               R_Mesh_State(&m);
+                               for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                               {
+                                       surface = texturesurfacelist[texturesurfaceindex];
+                                       RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, false);
+                                       RSurf_Draw(surface);
+                               }
+                               if (skyrendermasked)
+                                       GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
+                       }
+               }
+       }
+       else if (r_glsl.integer && gl_support_fragment_shader)
+       {
+               if (texture->currentmaterialflags & MATERIALFLAG_ADD)
+               {
+                       GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+                       GL_DepthMask(false);
+               }
+               else if (texture->currentmaterialflags & MATERIALFLAG_ALPHA)
+               {
+                       GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                       GL_DepthMask(false);
+               }
+               else
+               {
+                       GL_BlendFunc(GL_ONE, GL_ZERO);
+                       GL_DepthMask(true);
+               }
+
+               memset(&m, 0, sizeof(m));
+               R_Mesh_State(&m);
+               GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], texture->currentalpha);
+               R_SetupSurfaceShader(ent, texture, modelorg, vec3_origin, lightmode == 2);
+               if (!r_glsl_permutation)
+                       return;
+               if (lightmode == 2)
+               {
+                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                       {
+                               surface = texturesurfacelist[texturesurfaceindex];
+                               RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, true);
+                               R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
+                               R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f);
+                               R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f);
+                               R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f);
+                               RSurf_Draw(surface);
+                       }
+               }
+               else
+               {
+                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+                       {
+                               surface = texturesurfacelist[texturesurfaceindex];
+                               RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, true);
+                               R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
+                               R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f);
+                               R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f);
+                               R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f);
+                               R_Mesh_TexCoordPointer(4, 2, surface->groupmesh->data_texcoordlightmap2f);
+                               if (surface->lightmaptexture)
+                               {
+                                       R_Mesh_TexBind(7, R_GetTexture(surface->lightmaptexture));
+                                       if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
+                                               R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
+                                               //R_Mesh_TexBind(8, R_GetTexture(surface->deluxemaptexture));
+                                       R_Mesh_ColorPointer(NULL);
+                               }
+                               else
+                               {
+                                       R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
+                                       if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
+                                               R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
+                                       R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f);
+                               }
+                               RSurf_Draw(surface);
+                       }
+               }
+               qglUseProgramObjectARB(0);
+       }
+       else if (texture->currentnumlayers)
        {
                int layerindex;
                texturelayer_t *layer;
@@ -2506,46 +2741,6 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                        applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0;
                        switch (layer->type)
                        {
-                       case TEXTURELAYERTYPE_SKY:
-                               if (skyrendernow)
-                               {
-                                       skyrendernow = false;
-                                       if (skyrendermasked)
-                                       {
-                                               R_Sky();
-                                               // restore entity matrix and GL_Color
-                                               R_Mesh_Matrix(&ent->matrix);
-                                               GL_Color(layercolor[0], layercolor[1], layercolor[2], layercolor[3]);
-                                       }
-                               }
-                               // LordHavoc: HalfLife maps have freaky skypolys...
-                               //if (!ent->model->brush.ishlbsp)
-                               {
-                                       if (skyrendermasked)
-                                       {
-                                               // depth-only (masking)
-                                               GL_ColorMask(0,0,0,0);
-                                               // just to make sure that braindead drivers don't draw anything
-                                               // despite that colormask...
-                                               GL_BlendFunc(GL_ZERO, GL_ONE);
-                                       }
-                                       else
-                                       {
-                                               // fog sky
-                                               GL_BlendFunc(GL_ONE, GL_ZERO);
-                                       }
-                                       memset(&m, 0, sizeof(m));
-                                       R_Mesh_State(&m);
-                                       for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
-                                       {
-                                               surface = texturesurfacelist[texturesurfaceindex];
-                                               RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, false);
-                                               RSurf_Draw(surface);
-                                       }
-                                       if (skyrendermasked)
-                                               GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
-                               }
-                               break;
                        case TEXTURELAYERTYPE_LITTEXTURE_COMBINE:
                                memset(&m, 0, sizeof(m));
                                m.tex[1] = R_GetTexture(layer->texture);
@@ -2915,5 +3110,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
                R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
        if (!r_showtrispass)
                renderstats.entities_triangles += counttriangles;
+       if (gl_support_fragment_shader)
+               qglUseProgramObjectARB(0);
 }
 
index 79f4025..47cf815 100644 (file)
@@ -1052,6 +1052,7 @@ middle sample (the one which was requested)
 void Mod_Q1BSP_LightPoint(model_t *model, const vec3_t p, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal)
 {
        Mod_Q1BSP_LightPoint_RecursiveBSPNode(model, ambientcolor, diffusecolor, diffusenormal, model->brush.data_nodes + model->brushq1.hulls[0].firstclipnode, p[0], p[1], p[2], p[2] - 65536);
+       VectorSet(diffusenormal, 0, 0, -1);
 }
 
 static void Mod_Q1BSP_DecompressVis(const unsigned char *in, const unsigned char *inend, unsigned char *out, unsigned char *outend)
@@ -1517,68 +1518,6 @@ static void Mod_Q1BSP_LoadLighting(lump_t *l)
        }
 }
 
-static void Mod_Q1BSP_LoadLightList(void)
-{
-       int a, n, numlights;
-       char tempchar, *s, *t, *lightsstring, lightsfilename[1024];
-       mlight_t *e;
-
-       strlcpy (lightsfilename, loadmodel->name, sizeof (lightsfilename));
-       FS_StripExtension (lightsfilename, lightsfilename, sizeof(lightsfilename));
-       strlcat (lightsfilename, ".lights", sizeof (lightsfilename));
-       s = lightsstring = (char *) FS_LoadFile(lightsfilename, tempmempool, false, NULL);
-       if (s)
-       {
-               numlights = 0;
-               while (*s)
-               {
-                       while (*s && *s != '\n' && *s != '\r')
-                               s++;
-                       if (!*s)
-                       {
-                               Mem_Free(lightsstring);
-                               Con_Printf("lights file must end with a newline\n");
-                               return;
-                       }
-                       s++;
-                       numlights++;
-               }
-               loadmodel->brushq1.lights = (mlight_t *)Mem_Alloc(loadmodel->mempool, numlights * sizeof(mlight_t));
-               s = lightsstring;
-               n = 0;
-               while (*s && n < numlights)
-               {
-                       t = s;
-                       while (*s && *s != '\n' && *s != '\r')
-                               s++;
-                       if (!*s)
-                       {
-                               Con_Printf("misparsed lights file!\n");
-                               break;
-                       }
-                       e = loadmodel->brushq1.lights + n;
-                       tempchar = *s;
-                       *s = 0;
-                       a = sscanf(t, "%f %f %f %f %f %f %f %f %f %f %f %f %f %d", &e->origin[0], &e->origin[1], &e->origin[2], &e->falloff, &e->light[0], &e->light[1], &e->light[2], &e->subtract, &e->spotdir[0], &e->spotdir[1], &e->spotdir[2], &e->spotcone, &e->distbias, &e->style);
-                       *s = tempchar;
-                       if (a != 14)
-                       {
-                               Con_Printf("invalid lights file, found %d parameters on line %i, should be 14 parameters (origin[0] origin[1] origin[2] falloff light[0] light[1] light[2] subtract spotdir[0] spotdir[1] spotdir[2] spotcone distancebias style)\n", a, n + 1);
-                               break;
-                       }
-                       if (*s == '\r')
-                               s++;
-                       if (*s == '\n')
-                               s++;
-                       n++;
-               }
-               if (*s)
-                       Con_Printf("misparsed lights file!\n");
-               loadmodel->brushq1.numlights = numlights;
-               Mem_Free(lightsstring);
-       }
-}
-
 static void Mod_Q1BSP_LoadVisibility(lump_t *l)
 {
        loadmodel->brushq1.num_compressedpvs = 0;
@@ -3200,8 +3139,6 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
 
        mainmempool = mod->mempool;
 
-       Mod_Q1BSP_LoadLightList();
-
        // make a single combined shadow mesh to allow optimized shadow volume creation
        numshadowmeshtriangles = 0;
        for (j = 0, surface = loadmodel->data_surfaces;j < loadmodel->num_surfaces;j++, surface++)
index bf44b58..080daf0 100644 (file)
@@ -174,43 +174,6 @@ typedef struct svbspmesh_s
 }
 svbspmesh_t;
 
-typedef struct mlight_s
-{
-       // location of light
-       vec3_t origin;
-       // distance attenuation scale (smaller is a larger light)
-       float falloff;
-       // color and brightness combined
-       vec3_t light;
-       // brightness bias, used for limiting radius without a hard edge
-       float subtract;
-       // spotlight direction
-       vec3_t spotdir;
-       // cosine of spotlight cone angle (or 0 if not a spotlight)
-       float spotcone;
-       // distance bias (larger value is softer and darker)
-       float distbias;
-       // light style controlling this light
-       int style;
-       // maximum extent of the light for shading purposes
-       float lightradius;
-       // maximum extent of the light for culling purposes
-       float cullradius;
-       float cullradius2;
-       /*
-       // surfaces this shines on
-       int numsurfaces;
-       msurface_t **surfaces;
-       // lit area
-       vec3_t mins, maxs;
-       // precomputed shadow volume meshs
-       //svbspmesh_t *shadowvolume;
-       //vec3_t shadowvolumemins, shadowvolumemaxs;
-       shadowmesh_t *shadowvolume;
-       */
-}
-mlight_t;
-
 // Q2 bsp stuff
 
 #define Q2BSPVERSION   38
index e8bc24a..422b3c4 100644 (file)
@@ -144,7 +144,6 @@ shadowmesh_t;
 typedef enum texturelayertype_e
 {
        TEXTURELAYERTYPE_INVALID,
-       TEXTURELAYERTYPE_SKY,
        TEXTURELAYERTYPE_LITTEXTURE_COMBINE,
        TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS,
        TEXTURELAYERTYPE_LITTEXTURE_VERTEX,
@@ -210,6 +209,12 @@ typedef struct texture_s
        // current texture transform matrix (used for water scrolling)
        matrix4x4_t currenttexmatrix;
 
+       qboolean colormapping;
+       rtexture_t *basetexture;
+       rtexture_t *glosstexture;
+       float specularscale;
+       float specularpower;
+
        int currentnumlayers;
        texturelayer_t currentlayers[16];
 
@@ -418,9 +423,6 @@ typedef struct model_brushq1_s
        int                             num_lightdata;
        unsigned char                   *lightdata;
 
-       int                             numlights;
-       mlight_t                *lights;
-
        // lightmap update chains for light styles
        int                             light_styles;
        unsigned char                   *light_style;
index 572d6ed..343ac74 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -23,7 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "cl_collision.h"
 #include "r_shadow.h"
 
-cvar_t r_modellights = {CVAR_SAVE, "r_modellights", "4", "how many lights from a .lights file (produced by hlight) are worthy of directional shading on a model (others are applied to the whole model as ambient lighting)"};
 cvar_t r_coronas = {CVAR_SAVE, "r_coronas", "1", "brightness of corona flare effects around certain lights, 0 disables corona effects"};
 cvar_t gl_flashblend = {CVAR_SAVE, "gl_flashblend", "0", "render bright coronas for dynamic lights instead of actual lighting, fast but ugly"};
 
@@ -68,7 +67,6 @@ void r_light_newmap(void)
 
 void R_Light_Init(void)
 {
-       Cvar_RegisterVariable(&r_modellights);
        Cvar_RegisterVariable(&r_coronas);
        Cvar_RegisterVariable(&gl_flashblend);
        R_RegisterModule("R_Light", r_light_start, r_light_shutdown, r_light_newmap);
@@ -131,239 +129,18 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu
        else
                VectorSet(ambientcolor, 1, 1, 1);
 
-       // FIXME: this .lights related stuff needs to be ported into the Mod_Q1BSP code
-       if (r_refdef.worldmodel->brushq1.numlights)
-       {
-               int i;
-               vec3_t v;
-               float f;
-               mlight_t *sl;
-               for (i = 0;i < r_refdef.worldmodel->brushq1.numlights;i++)
-               {
-                       sl = r_refdef.worldmodel->brushq1.lights + i;
-                       if (r_refdef.lightstylevalue[sl->style] > 0)
-                       {
-                               VectorSubtract (p, sl->origin, v);
-                               f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract);
-                               if (f > 0 && CL_TraceBox(p, vec3_origin, vec3_origin, sl->origin, false, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
-                               {
-                                       f *= r_refdef.lightstylevalue[sl->style] * (1.0f / 65536.0f);
-                                       if (f > 0)
-                                               VectorMA(ambientcolor, f, sl->light, ambientcolor);
-                               }
-                       }
-               }
-       }
-
        if (dynamic)
        {
                int i;
                float f, v[3];
                dlight_t *light;
-               // FIXME: this really should handle dlights as diffusecolor/diffusenormal somehow
-               // FIXME: this should be updated to match rtlight falloff!
                for (i = 0;i < r_refdef.numlights;i++)
                {
                        light = r_refdef.lights[i];
-                       VectorSubtract(p, light->origin, v);
-                       f = DotProduct(v, v);
-                       if (f < light->rtlight.lightmap_cullradius2 && CL_TraceBox(p, vec3_origin, vec3_origin, light->origin, false, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
-                       {
-                               f = (1.0f / (f + LIGHTOFFSET)) - light->rtlight.lightmap_subtract;
-                               if (f > 0)
-                                       VectorMA(ambientcolor, f, light->rtlight.lightmap_light, ambientcolor);
-                       }
+                       Matrix4x4_Transform(&light->rtlight.matrix_worldtolight, p, v);
+                       f = 1 - VectorLength2(v);
+                       if (f > 0 && CL_TraceBox(p, vec3_origin, vec3_origin, light->origin, false, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
+                               VectorMA(ambientcolor, f, light->rtlight.currentcolor, ambientcolor);
                }
        }
 }
-
-typedef struct nearlight_s
-{
-       vec3_t origin;
-       //vec_t cullradius2;
-       vec3_t light;
-       // how much this light would contribute to ambient if replaced
-       vec3_t ambientlight;
-       vec_t subtract;
-       vec_t falloff;
-       vec_t offset;
-       // used for choosing only the brightest lights
-       vec_t intensity;
-}
-nearlight_t;
-
-static int nearlights;
-static nearlight_t nearlight[MAX_DLIGHTS];
-
-int R_LightModel(float *ambient4f, float *diffusecolor, float *diffusenormal, const entity_render_t *ent, float colorr, float colorg, float colorb, float colora, int worldcoords)
-{
-       int i, j, maxnearlights;
-       float v[3], f, mscale, stylescale, intensity, ambientcolor[3], tempdiffusenormal[3];
-       nearlight_t *nl;
-       mlight_t *sl;
-
-       nearlights = 0;
-       maxnearlights = r_modellights.integer;
-       ambient4f[0] = ambient4f[1] = ambient4f[2] = r_ambient.value * (2.0f / 128.0f);
-       VectorClear(diffusecolor);
-       VectorClear(diffusenormal);
-       if (!(ent->flags & RENDER_LIGHT))
-       {
-               // highly rare
-               VectorSet(ambient4f, 1, 1, 1);
-               maxnearlights = 0;
-       }
-       else if (r_lightmapintensity <= 0)
-               maxnearlights = 0;
-       else
-       {
-               if (r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
-               {
-                       r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, ent->origin, ambient4f, diffusecolor, tempdiffusenormal);
-                       Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, diffusenormal);
-                       VectorNormalize(diffusenormal);
-               }
-               else
-                       VectorSet(ambient4f, 1, 1, 1);
-       }
-
-       // scale of the model's coordinate space, to alter light attenuation to match
-       // make the mscale squared so it can scale the squared distance results
-       mscale = ent->scale * ent->scale;
-       // FIXME: no support for .lights on non-Q1BSP?
-       nl = &nearlight[0];
-       for (i = 0;i < ent->numentlights;i++)
-       {
-               sl = r_refdef.worldmodel->brushq1.lights + ent->entlights[i];
-               stylescale = r_refdef.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
-               {
-                       for (j = 0;j < maxnearlights;j++)
-                       {
-                               if (nearlight[j].intensity < intensity)
-                               {
-                                       if (nearlight[j].intensity > 0)
-                                               VectorAdd(ambient4f, nearlight[j].ambientlight, ambient4f);
-                                       break;
-                               }
-                       }
-               }
-               if (j >= maxnearlights)
-               {
-                       // this light is less significant than all others,
-                       // add it to ambient
-                       if (intensity > 0)
-                               VectorAdd(ambient4f, ambientcolor, ambient4f);
-               }
-               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;
-               }
-       }
-       ambient4f[0] *= colorr;
-       ambient4f[1] *= colorg;
-       ambient4f[2] *= colorb;
-       ambient4f[3] = colora;
-       diffusecolor[0] *= colorr;
-       diffusecolor[1] *= colorg;
-       diffusecolor[2] *= colorb;
-       return nearlights != 0 || DotProduct(diffusecolor, diffusecolor) > 0;
-}
-
-void R_LightModel_CalcVertexColors(const float *ambientcolor4f, const float *diffusecolor, const float *diffusenormal, int numverts, const float *vertex3f, const float *normal3f, float *color4f)
-{
-       int i, j, usediffuse;
-       float color[4], v[3], dot, dist2, f, dnormal[3];
-       nearlight_t *nl;
-       usediffuse = DotProduct(diffusecolor, diffusecolor) > 0;
-       // negate the diffuse normal to avoid the need to negate the
-       // dotproduct on each vertex
-       VectorNegate(diffusenormal, dnormal);
-       if (usediffuse)
-               VectorNormalize(dnormal);
-       // directional shading code here
-       for (i = 0;i < numverts;i++, vertex3f += 3, normal3f += 3, color4f += 4)
-       {
-               VectorCopy4(ambientcolor4f, color);
-
-               // silly directional diffuse shading
-               if (usediffuse)
-               {
-                       // we have to negate this result because it is the incoming light
-                       // direction, not simply the normal to dotproduct with.
-                       dot = DotProduct(normal3f, dnormal);
-                       if (dot < 0)
-                               VectorMA(color, -dot, diffusecolor, color);
-               }
-
-               // pretty good lighting
-               for (j = 0, nl = &nearlight[0];j < nearlights;j++, nl++)
-               {
-                       VectorSubtract(nl->origin, vertex3f, v);
-                       // first eliminate negative lighting (back side)
-                       dot = DotProduct(normal3f, v);
-                       if (dot > 0)
-                       {
-                               // we'll need this again later to normalize the dotproduct
-                               dist2 = DotProduct(v,v);
-                               // do the distance attenuation math
-                               f = (1.0f / (dist2 * nl->falloff + nl->offset)) - nl->subtract;
-                               if (f > 0)
-                               {
-                                       // we must divide dot by sqrt(dist2) to compensate for
-                                       // the fact we did not normalize v before doing the
-                                       // dotproduct, the result is in the range 0 to 1 (we
-                                       // eliminated negative numbers already)
-                                       f *= dot / sqrt(dist2);
-                                       // blend in the lighting
-                                       VectorMA(color, f, nl->light, color);
-                               }
-                       }
-               }
-               VectorCopy4(color, color4f);
-       }
-}
-
-void R_UpdateEntLights(entity_render_t *ent)
-{
-       int i;
-       const mlight_t *sl;
-       vec3_t v;
-       if (r_lightmapintensity <= 0)
-               return;
-       VectorSubtract(ent->origin, ent->entlightsorigin, v);
-       if (ent->entlightsframe != (r_framecount - 1) || (realtime > ent->entlightstime && DotProduct(v,v) >= 1.0f))
-       {
-               ent->entlightstime = realtime + 0.1;
-               VectorCopy(ent->origin, ent->entlightsorigin);
-               ent->numentlights = 0;
-               if (r_refdef.worldmodel)
-                       for (i = 0, sl = r_refdef.worldmodel->brushq1.lights;i < r_refdef.worldmodel->brushq1.numlights && ent->numentlights < MAXENTLIGHTS;i++, sl++)
-                               if (CL_TraceBox(ent->origin, vec3_origin, vec3_origin, sl->origin, false, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
-                                       ent->entlights[ent->numentlights++] = i;
-       }
-       ent->entlightsframe = r_framecount;
-}
-
index 84429ef..7af2aad 100644 (file)
--- a/r_light.h
+++ b/r_light.h
@@ -4,9 +4,6 @@
 
 void R_DrawCoronas(void);
 void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, int dynamic);
-int R_LightModel(float *ambient4f, float *diffusecolor, float *diffusenormal, const entity_render_t *ent, float colorr, float colorg, float colorb, float colora, int worldcoords);
-void R_LightModel_CalcVertexColors(const float *ambientcolor4f, const float *diffusecolor, const float *diffusenormal, int numverts, const float *vertex3f, const float *normal3f, float *color4f);
-void R_UpdateEntLights(entity_render_t *ent);
 
 #endif
 
index 5235137..cd2850b 100644 (file)
@@ -1293,7 +1293,7 @@ static void R_Shadow_RenderSurfacesLighting_Light_GLSL(const entity_render_t *en
 {
        // ARB2 GLSL shader path (GFFX5200, Radeon 9500)
        int surfacelistindex;
-       R_SetupSurfaceShader(ent, texture, lightcolorbase, lightcolorpants, lightcolorshirt, basetexture, pantstexture, shirttexture, normalmaptexture, glosstexture, specularscale, dopants, doshirt);
+       R_SetupSurfaceShader(ent, texture, r_shadow_entityeyeorigin, lightcolorbase, false);
        for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
        {
                const msurface_t *surface = surfacelist[surfacelistindex];
@@ -2172,47 +2172,20 @@ void R_Shadow_RenderSurfacesLighting(const entity_render_t *ent, const texture_t
 {
        // FIXME: support MATERIALFLAG_NODEPTHTEST
        vec3_t lightcolorbase, lightcolorpants, lightcolorshirt;
-       rtexture_t *basetexture;
-       rtexture_t *pantstexture;
-       rtexture_t *shirttexture;
-       rtexture_t *glosstexture;
-       float specularscale;
-       qboolean dopants, doshirt;
-       glosstexture = r_texture_black;
-       specularscale = 0;
-       if (r_shadow_gloss.integer > 0)
-       {
-               if (texture->skin.gloss)
-               {
-                       if (r_shadow_glossintensity.value > 0 && r_shadow_rtlight->specularscale > 0)
-                       {
-                               glosstexture = texture->skin.gloss;
-                               specularscale = r_shadow_rtlight->specularscale * r_shadow_glossintensity.value;
-                       }
-               }
-               else
-               {
-                       if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0 && r_shadow_glossintensity.value > 0 && r_shadow_rtlight->specularscale > 0)
-                       {
-                               glosstexture = r_texture_white;
-                               specularscale = r_shadow_rtlight->specularscale * r_shadow_gloss2intensity.value;
-                       }
-               }
-       }
        // calculate colors to render this texture with
        lightcolorbase[0] = r_shadow_rtlight->currentcolor[0] * ent->colormod[0] * texture->currentalpha;
        lightcolorbase[1] = r_shadow_rtlight->currentcolor[1] * ent->colormod[1] * texture->currentalpha;
        lightcolorbase[2] = r_shadow_rtlight->currentcolor[2] * ent->colormod[2] * texture->currentalpha;
-       if ((r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorbase) + specularscale * VectorLength2(lightcolorbase) < (1.0f / 1048576.0f))
+       if ((r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorbase) + (r_shadow_rtlight->specularscale * texture->specularscale) * VectorLength2(lightcolorbase) < (1.0f / 1048576.0f))
                return;
        if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE))
                qglDisable(GL_CULL_FACE);
        else
                qglEnable(GL_CULL_FACE);
-       dopants = texture->skin.pants != NULL && VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f);
-       doshirt = texture->skin.shirt != NULL && VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f);
-       if (dopants + doshirt)
+       if (texture->colormapping)
        {
+               qboolean dopants = texture->skin.pants != NULL && VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f);
+               qboolean doshirt = texture->skin.shirt != NULL && VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f);
                if (dopants)
                {
                        lightcolorpants[0] = lightcolorbase[0] * ent->colormap_pantscolor[0];
@@ -2220,35 +2193,28 @@ void R_Shadow_RenderSurfacesLighting(const entity_render_t *ent, const texture_t
                        lightcolorpants[2] = lightcolorbase[2] * ent->colormap_pantscolor[2];
                }
                else
-               {
-                       pantstexture = r_texture_black;
                        VectorClear(lightcolorpants);
-               }
                if (doshirt)
                {
-                       shirttexture = texture->skin.shirt;
                        lightcolorshirt[0] = lightcolorbase[0] * ent->colormap_shirtcolor[0];
                        lightcolorshirt[1] = lightcolorbase[1] * ent->colormap_shirtcolor[1];
                        lightcolorshirt[2] = lightcolorbase[2] * ent->colormap_shirtcolor[2];
                }
                else
-               {
-                       shirttexture = r_texture_black;
                        VectorClear(lightcolorshirt);
-               }
                switch (r_shadow_rendermode)
                {
                case R_SHADOW_RENDERMODE_VISIBLELIGHTING:
-                       R_Shadow_RenderSurfacesLighting_VisibleLighting(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, texture->skin.base, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, dopants, doshirt);
+                       R_Shadow_RenderSurfacesLighting_VisibleLighting(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, texture->basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, texture->glosstexture, r_shadow_rtlight->specularscale * texture->specularscale, dopants, doshirt);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_GLSL:
-                       R_Shadow_RenderSurfacesLighting_Light_GLSL(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, texture->skin.base, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, dopants, doshirt);
+                       R_Shadow_RenderSurfacesLighting_Light_GLSL(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, texture->basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, texture->glosstexture, r_shadow_rtlight->specularscale * texture->specularscale, dopants, doshirt);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_DOT3:
-                       R_Shadow_RenderSurfacesLighting_Light_Dot3(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, texture->skin.base, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, dopants, doshirt);
+                       R_Shadow_RenderSurfacesLighting_Light_Dot3(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, texture->basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, texture->glosstexture, r_shadow_rtlight->specularscale * texture->specularscale, dopants, doshirt);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
-                       R_Shadow_RenderSurfacesLighting_Light_Vertex(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, texture->skin.base, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, dopants, doshirt);
+                       R_Shadow_RenderSurfacesLighting_Light_Vertex(ent, texture, numsurfaces, surfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, texture->basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, texture->glosstexture, r_shadow_rtlight->specularscale * texture->specularscale, dopants, doshirt);
                        break;
                default:
                        Con_Printf("R_Shadow_RenderSurfacesLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode);
@@ -2257,20 +2223,19 @@ void R_Shadow_RenderSurfacesLighting(const entity_render_t *ent, const texture_t
        }
        else
        {
-               basetexture = texture->skin.merged ? texture->skin.merged : texture->skin.base;
                switch (r_shadow_rendermode)
                {
                case R_SHADOW_RENDERMODE_VISIBLELIGHTING:
-                       R_Shadow_RenderSurfacesLighting_VisibleLighting(ent, texture, numsurfaces, surfacelist, lightcolorbase, vec3_origin, vec3_origin, basetexture, r_texture_black, r_texture_black, texture->skin.nmap, glosstexture, specularscale, false, false);
+                       R_Shadow_RenderSurfacesLighting_VisibleLighting(ent, texture, numsurfaces, surfacelist, lightcolorbase, vec3_origin, vec3_origin, texture->basetexture, r_texture_black, r_texture_black, texture->skin.nmap, texture->glosstexture, r_shadow_rtlight->specularscale * texture->specularscale, false, false);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_GLSL:
-                       R_Shadow_RenderSurfacesLighting_Light_GLSL(ent, texture, numsurfaces, surfacelist, lightcolorbase, vec3_origin, vec3_origin, basetexture, r_texture_black, r_texture_black, texture->skin.nmap, glosstexture, specularscale, false, false);
+                       R_Shadow_RenderSurfacesLighting_Light_GLSL(ent, texture, numsurfaces, surfacelist, lightcolorbase, vec3_origin, vec3_origin, texture->basetexture, r_texture_black, r_texture_black, texture->skin.nmap, texture->glosstexture, r_shadow_rtlight->specularscale * texture->specularscale, false, false);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_DOT3:
-                       R_Shadow_RenderSurfacesLighting_Light_Dot3(ent, texture, numsurfaces, surfacelist, lightcolorbase, vec3_origin, vec3_origin, basetexture, r_texture_black, r_texture_black, texture->skin.nmap, glosstexture, specularscale, false, false);
+                       R_Shadow_RenderSurfacesLighting_Light_Dot3(ent, texture, numsurfaces, surfacelist, lightcolorbase, vec3_origin, vec3_origin, texture->basetexture, r_texture_black, r_texture_black, texture->skin.nmap, texture->glosstexture, r_shadow_rtlight->specularscale * texture->specularscale, false, false);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
-                       R_Shadow_RenderSurfacesLighting_Light_Vertex(ent, texture, numsurfaces, surfacelist, lightcolorbase, vec3_origin, vec3_origin, basetexture, r_texture_black, r_texture_black, texture->skin.nmap, glosstexture, specularscale, false, false);
+                       R_Shadow_RenderSurfacesLighting_Light_Vertex(ent, texture, numsurfaces, surfacelist, lightcolorbase, vec3_origin, vec3_origin, texture->basetexture, r_texture_black, r_texture_black, texture->skin.nmap, texture->glosstexture, r_shadow_rtlight->specularscale * texture->specularscale, false, false);
                        break;
                default:
                        Con_Printf("R_Shadow_RenderSurfacesLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode);
@@ -2319,11 +2284,6 @@ void R_RTLight_Update(dlight_t *light, int isstatic)
        for (k = 0;k < 3;k++)
                for (j = 0;j < 4;j++)
                        rtlight->matrix_worldtolight.m[k][j] *= scale;
-
-       rtlight->lightmap_cullradius = bound(0, rtlight->radius, 2048.0f);
-       rtlight->lightmap_cullradius2 = rtlight->lightmap_cullradius * rtlight->lightmap_cullradius;
-       VectorScale(rtlight->color, rtlight->radius * (rtlight->style >= 0 ? r_refdef.lightstylevalue[rtlight->style] : 128) * 0.125f, rtlight->lightmap_light);
-       rtlight->lightmap_subtract = 1.0f / rtlight->lightmap_cullradius2;
 }
 
 // compiles rtlight geometry
index bc0dde0..3f989a7 100644 (file)
--- a/render.h
+++ b/render.h
@@ -265,16 +265,18 @@ void R_UpdateAllTextureInfo(entity_render_t *ent);
 void R_QueueTextureSurfaceList(entity_render_t *ent, struct texture_s *texture, int texturenumsurfaces, const struct msurface_s **texturesurfacelist, const vec3_t modelorg);
 void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces);
 
-#define SHADERPERMUTATION_DELUXEMAPPING (1<<0) // (lightmap) use directional pixel shading
-#define SHADERPERMUTATION_LIGHTSOURCE (1<<1) // (lightsource) indicates this is lightsource rendering mode
-#define SHADERPERMUTATION_FOG (1<<2) // tint the color by fog color or black if using additive blend mode
-#define SHADERPERMUTATION_COLORMAPPING (1<<3) // indicates this is a colormapped skin
-#define SHADERPERMUTATION_SPECULAR (1<<4) // (lightsource or deluxemapping) render specular effects
-#define SHADERPERMUTATION_CUBEFILTER (1<<5) // (lightsource) use cubemap light filter
-#define SHADERPERMUTATION_OFFSETMAPPING (1<<6) // adjust texcoords to roughly simulate a displacement mapped surface
-#define SHADERPERMUTATION_SURFACENORMALIZE (1<<7) // (lightsource or deluxemapping) improved bumpmapping
-#define SHADERPERMUTATION_GEFORCEFX (1<<8) // use half vector types if available (NVIDIA specific)
-#define SHADERPERMUTATION_COUNT (1<<9) // how many permutations are possible
+#define SHADERPERMUTATION_MODE_LIGHTSOURCE (1<<0) // (lightsource) use directional pixel shading from light source (rtlight)
+#define SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP (1<<1) // (lightmap) use directional pixel shading from texture containing light directions (deluxemap)
+#define SHADERPERMUTATION_MODE_LIGHTDIRECTION (1<<2) // (lightmap) use directional pixel shading from fixed light direction (q3bsp)
+#define SHADERPERMUTATION_GLOW (1<<3) // (lightmap) blend in an additive glow texture
+#define SHADERPERMUTATION_FOG (1<<4) // tint the color by fog color or black if using additive blend mode
+#define SHADERPERMUTATION_COLORMAPPING (1<<5) // indicates this is a colormapped skin
+#define SHADERPERMUTATION_SPECULAR (1<<6) // (lightsource or deluxemapping) render specular effects
+#define SHADERPERMUTATION_CUBEFILTER (1<<7) // (lightsource) use cubemap light filter
+#define SHADERPERMUTATION_OFFSETMAPPING (1<<8) // adjust texcoords to roughly simulate a displacement mapped surface
+#define SHADERPERMUTATION_SURFACENORMALIZE (1<<9) // (lightsource or deluxemapping) improved bumpmapping
+#define SHADERPERMUTATION_GEFORCEFX (1<<10) // use half vector types if available (NVIDIA specific)
+#define SHADERPERMUTATION_COUNT (1<<11) // how many permutations are possible
 
 typedef struct r_glsl_permutation_s
 {
@@ -291,6 +293,7 @@ typedef struct r_glsl_permutation_s
        int loc_Texture_Shirt;
        int loc_Texture_Lightmap;
        int loc_Texture_Deluxemap;
+       int loc_Texture_Glow;
        int loc_FogColor;
        int loc_LightPosition;
        int loc_EyePosition;
@@ -304,6 +307,10 @@ typedef struct r_glsl_permutation_s
        int loc_SpecularPower;
        int loc_OffsetMapping_Scale;
        int loc_OffsetMapping_Bias;
+       int loc_AmbientColor;
+       int loc_DiffuseColor;
+       int loc_SpecularColor;
+       int loc_LightDir;
 }
 r_glsl_permutation_t;
 
@@ -313,7 +320,7 @@ extern r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_COUNT];
 r_glsl_permutation_t *r_glsl_permutation;
 
 void R_GLSL_CompilePermutation(int permutation);
-void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float specularscale, qboolean dopants, qboolean doshirt);
+void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture, const vec3_t modelorg, const vec3_t lightcolorbase, qboolean modellighting);
 
 #endif