]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
reenabled R_UpdateAllTextureInfo calls when lighting the world model
[xonotic/darkplaces.git] / gl_rmain.c
index fa7f2acd204ddb4522a5115705a25bac61b467fa..1a8a4999e737b4534602db2671382da3278e4174 100644 (file)
@@ -247,18 +247,24 @@ void FOG_clear(void)
                Cvar_Set("gl_fogblue", "0.3");
        }
        r_refdef.fog_density = r_refdef.fog_red = r_refdef.fog_green = r_refdef.fog_blue = 0.0f;
+       r_refdef.fog_start = 0;
+       r_refdef.fog_end = 1000000000;
 }
 
-float FogPoint_World(const vec3_t p)
+float FogForDistance(vec_t dist)
 {
-       unsigned int fogmasktableindex = (unsigned int)(VectorDistance((p), r_view.origin) * r_refdef.fogmasktabledistmultiplier);
+       unsigned int fogmasktableindex = (unsigned int)(bound(0, dist - r_refdef.fog_start, r_refdef.fog_end - r_refdef.fog_start) * r_refdef.fogmasktabledistmultiplier);
        return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
 }
 
+float FogPoint_World(const vec3_t p)
+{
+       return FogForDistance(VectorDistance((p), r_view.origin));
+}
+
 float FogPoint_Model(const vec3_t p)
 {
-       unsigned int fogmasktableindex = (unsigned int)(VectorDistance((p), rsurface.modelorg) * r_refdef.fogmasktabledistmultiplier);
-       return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
+       return FogForDistance(VectorDistance((p), rsurface.modelorg));
 }
 
 static void R_BuildBlankTextures(void)
@@ -384,7 +390,7 @@ static void R_BuildNormalizationCube(void)
 static void R_BuildFogTexture(void)
 {
        int x, b;
-#define FOGWIDTH 64
+#define FOGWIDTH 256
        unsigned char data1[FOGWIDTH][4];
        //unsigned char data2[FOGWIDTH][4];
        for (x = 0;x < FOGWIDTH;x++)
@@ -604,6 +610,8 @@ static const char *builtinshaderstring =
 "uniform float OffsetMapping_Scale;\n"
 "uniform float OffsetMapping_Bias;\n"
 "uniform float FogRangeRecip;\n"
+"uniform float FogStart;\n"
+"uniform float FogLength;\n"
 "\n"
 "uniform myhalf AmbientScale;\n"
 "uniform myhalf DiffuseScale;\n"
@@ -793,7 +801,7 @@ static const char *builtinshaderstring =
 "# endif\n"
 "\n"
 "      // apply lightmap color\n"
-"      color.rgb = tempcolor * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * myhvec3(gl_Color) + color * AmbientScale;\n"
+"      color.rgb = color.rgb * AmbientScale + tempcolor * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * myhvec3(gl_Color);\n"
 "      color.a *= myhalf(gl_Color.a);\n"
 "#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
 "\n"
@@ -815,7 +823,7 @@ static const char *builtinshaderstring =
 "# endif\n"
 "\n"
 "      // apply lightmap color\n"
-"      color.rgb = tempcolor * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * myhvec3(gl_Color) + color * AmbientScale;\n"
+"      color.rgb = color.rgb * AmbientScale + tempcolor * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * myhvec3(gl_Color);\n"
 "      color.a *= myhalf(gl_Color.a);\n"
 "#endif // MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
 "\n"
@@ -847,17 +855,18 @@ static const char *builtinshaderstring =
 "# endif\n"
 "#endif\n"
 "\n"
-"#ifdef USEFOG\n"
-"      // apply fog\n"
-"      color.rgb = mix(FogColor, color.rgb, myhalf(texture2D(Texture_FogMask, myhvec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0))));\n"
-"#endif\n"
-"\n"
 "#ifdef USECONTRASTBOOST\n"
 "      color.rgb = color.rgb / (ContrastBoostCoeff * color.rgb + myhvec3(1, 1, 1));\n"
 "#endif\n"
 "\n"
 "      color.rgb *= SceneBrightness;\n"
 "\n"
+"#ifdef USEFOG\n"
+"      // apply fog\n"
+"      color.rgb = mix(FogColor, color.rgb, myhalf(texture2D(Texture_FogMask, myhvec2(max(0.0, min(length(EyeVectorModelSpace) - FogStart, FogLength))*FogRangeRecip, 0.0))));\n"
+//"      color.rgb = mix(FogColor, color.rgb, myhalf(texture2D(Texture_FogMask, myhvec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0))));\n"
+"#endif\n"
+"\n"
 "      gl_FragColor = vec4(color);\n"
 "}\n"
 "#endif // MODE_REFRACTION\n"
@@ -950,6 +959,8 @@ typedef struct r_glsl_permutation_s
        int loc_Color_Pants;
        int loc_Color_Shirt;
        int loc_FogRangeRecip;
+       int loc_FogStart;
+       int loc_FogLength;
        int loc_AmbientScale;
        int loc_DiffuseScale;
        int loc_SpecularScale;
@@ -1081,6 +1092,8 @@ static void R_GLSL_CompilePermutation(const char *filename, int permutation, int
                p->loc_Color_Pants         = qglGetUniformLocationARB(p->program, "Color_Pants");
                p->loc_Color_Shirt         = qglGetUniformLocationARB(p->program, "Color_Shirt");
                p->loc_FogRangeRecip       = qglGetUniformLocationARB(p->program, "FogRangeRecip");
+               p->loc_FogStart            = qglGetUniformLocationARB(p->program, "FogStart");
+               p->loc_FogLength           = qglGetUniformLocationARB(p->program, "FogLength");
                p->loc_AmbientScale        = qglGetUniformLocationARB(p->program, "AmbientScale");
                p->loc_DiffuseScale        = qglGetUniformLocationARB(p->program, "DiffuseScale");
                p->loc_SpecularPower       = qglGetUniformLocationARB(p->program, "SpecularPower");
@@ -1356,11 +1369,11 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
        else if (mode == SHADERMODE_LIGHTDIRECTION)
        {
                if (r_glsl_permutation->loc_AmbientColor >= 0)
-                       qglUniform3fARB(r_glsl_permutation->loc_AmbientColor, rsurface.modellight_ambient[0] * ambientscale, rsurface.modellight_ambient[1] * ambientscale, rsurface.modellight_ambient[2] * ambientscale);
+                       qglUniform3fARB(r_glsl_permutation->loc_AmbientColor, rsurface.modellight_ambient[0] * ambientscale * r_refdef.lightmapintensity, rsurface.modellight_ambient[1] * ambientscale * r_refdef.lightmapintensity, rsurface.modellight_ambient[2] * ambientscale * r_refdef.lightmapintensity);
                if (r_glsl_permutation->loc_DiffuseColor >= 0)
-                       qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor, rsurface.modellight_diffuse[0] * diffusescale, rsurface.modellight_diffuse[1] * diffusescale, rsurface.modellight_diffuse[2] * diffusescale);
+                       qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor, rsurface.modellight_diffuse[0] * diffusescale * r_refdef.lightmapintensity, rsurface.modellight_diffuse[1] * diffusescale * r_refdef.lightmapintensity, rsurface.modellight_diffuse[2] * diffusescale * r_refdef.lightmapintensity);
                if (r_glsl_permutation->loc_SpecularColor >= 0)
-                       qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, rsurface.modellight_diffuse[0] * specularscale, rsurface.modellight_diffuse[1] * specularscale, rsurface.modellight_diffuse[2] * specularscale);
+                       qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, rsurface.modellight_diffuse[0] * specularscale * r_refdef.lightmapintensity, rsurface.modellight_diffuse[1] * specularscale * r_refdef.lightmapintensity, rsurface.modellight_diffuse[2] * specularscale * r_refdef.lightmapintensity);
                if (r_glsl_permutation->loc_LightDir >= 0)
                        qglUniform3fARB(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
        }
@@ -1393,21 +1406,6 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
                if (rsurface.rtlight || (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD))
                        qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
                else
-               /*
-               {
-                       vec3_t fogvec;
-                       //   color.rgb *= SceneBrightness;
-                       VectorScale(r_refdef.fogcolor, r_view.colorscale, fogvec);
-                       if(r_glsl_permutation->loc_ContrastBoostCoeff >= 0) // need to support contrast boost
-                       {
-                               //   color.rgb *= ContrastBoost / ((ContrastBoost - 1) * color.rgb + 1);
-                               fogvec[0] *= r_glsl_contrastboost.value / ((r_glsl_contrastboost.value - 1) * fogvec[0] + 1);
-                               fogvec[1] *= r_glsl_contrastboost.value / ((r_glsl_contrastboost.value - 1) * fogvec[1] + 1);
-                               fogvec[2] *= r_glsl_contrastboost.value / ((r_glsl_contrastboost.value - 1) * fogvec[2] + 1);
-                       }
-                       qglUniform3fARB(r_glsl_permutation->loc_FogColor, fogvec[0], fogvec[1], fogvec[2]);
-               }
-               */
                        qglUniform3fARB(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
        }
        if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface.modelorg[0], rsurface.modelorg[1], rsurface.modelorg[2]);
@@ -1426,6 +1424,8 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
                        qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
        }
        if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, r_refdef.fograngerecip);
+       if (r_glsl_permutation->loc_FogStart >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogStart, r_refdef.fog_start);
+       if (r_glsl_permutation->loc_FogLength >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogLength, r_refdef.fog_end - r_refdef.fog_start);
        if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.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_DistortScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
@@ -1825,10 +1825,10 @@ void gl_main_start(void)
        int x;
        double r, alpha;
 
-       r = (-1.0/256.0) * (FOGMASKTABLEWIDTH * FOGMASKTABLEWIDTH);
+       r = -16.0 / (1.0 * FOGMASKTABLEWIDTH * FOGMASKTABLEWIDTH);
        for (x = 0;x < FOGMASKTABLEWIDTH;x++)
        {
-               alpha = 1 - exp(r / ((double)x*(double)x));
+               alpha = exp(r * ((double)x*(double)x));
                if (x == FOGMASKTABLEWIDTH - 1)
                        alpha = 0;
                r_refdef.fogmasktable[x] = bound(0, alpha, 1);
@@ -2141,43 +2141,6 @@ int R_CullBoxCustomPlanes(const vec3_t mins, const vec3_t maxs, int numplanes, c
 
 //==================================================================================
 
-static void R_UpdateEntityLighting(entity_render_t *ent)
-{
-       vec3_t tempdiffusenormal;
-
-       // fetch the lighting from the worldmodel data
-       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(tempdiffusenormal);
-       if ((ent->flags & RENDER_LIGHT) && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
-       {
-               vec3_t org;
-               Matrix4x4_OriginFromMatrix(&ent->matrix, org);
-               r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, org, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
-       }
-       else // highly rare
-               VectorSet(ent->modellight_ambient, 1, 1, 1);
-
-       // move the light direction into modelspace coordinates for lighting code
-       Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
-       if(VectorLength2(ent->modellight_lightdir) > 0)
-       {
-               VectorNormalize(ent->modellight_lightdir);
-       }
-       else
-       {
-               VectorSet(ent->modellight_lightdir, 0, 0, 1); // have to set SOME valid vector here
-       }
-
-       // scale ambient and directional light contributions according to rendering variables
-       ent->modellight_ambient[0] *= ent->colormod[0] * r_refdef.lightmapintensity;
-       ent->modellight_ambient[1] *= ent->colormod[1] * r_refdef.lightmapintensity;
-       ent->modellight_ambient[2] *= ent->colormod[2] * r_refdef.lightmapintensity;
-       ent->modellight_diffuse[0] *= ent->colormod[0] * r_refdef.lightmapintensity;
-       ent->modellight_diffuse[1] *= ent->colormod[1] * r_refdef.lightmapintensity;
-       ent->modellight_diffuse[2] *= ent->colormod[2] * r_refdef.lightmapintensity;
-}
-
 static void R_View_UpdateEntityVisible (void)
 {
        int i, renderimask;
@@ -2220,10 +2183,6 @@ static void R_View_UpdateEntityVisible (void)
                        r_viewcache.entityvisible[i] = !(ent->flags & renderimask) && ((ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)) || !R_CullBox(ent->mins, ent->maxs));
                }
        }
-
-       // update entity lighting (even on hidden entities for r_shadows)
-       for (i = 0;i < r_refdef.numentities;i++)
-               R_UpdateEntityLighting(r_refdef.entities[i]);
 }
 
 // only used if skyrendermasked, and normally returns false
@@ -3111,6 +3070,8 @@ void R_Bloom_MakeTexture(void)
        }
 }
 
+static void R_UpdateFogColor(void); // needs to be called before HDR subrender too, as that changes colorscale!
+
 void R_HDR_RenderBloomTexture(void)
 {
        int oldwidth, oldheight;
@@ -3128,6 +3089,9 @@ void R_HDR_RenderBloomTexture(void)
        r_view.colorscale = r_bloom_colorscale.value * r_hdr_scenebrightness.value;
        if (r_hdr.integer)
                r_view.colorscale /= r_hdr_range.value;
+
+       R_UpdateFogColor();
+
        r_waterstate.numwaterplanes = 0;
        R_RenderScene(r_waterstate.enabled);
        r_view.showdebug = true;
@@ -3216,6 +3180,32 @@ void R_RenderScene(qboolean addwaterplanes);
 
 matrix4x4_t r_waterscrollmatrix;
 
+static void R_UpdateFogColor(void) // needs to be called before HDR subrender too, as that changes colorscale!
+{
+       if (r_refdef.fog_density)
+       {
+               r_refdef.fogcolor[0] = r_refdef.fog_red;
+               r_refdef.fogcolor[1] = r_refdef.fog_green;
+               r_refdef.fogcolor[2] = r_refdef.fog_blue;
+
+               {
+                       vec3_t fogvec;
+                       //   color.rgb *= SceneBrightness;
+                       VectorScale(r_refdef.fogcolor, r_view.colorscale, fogvec);
+                       if(r_glsl.integer && (r_glsl_contrastboost.value > 1 || r_glsl_contrastboost.value < 0)) // need to support contrast boost
+                       {
+                               //   color.rgb *= ContrastBoost / ((ContrastBoost - 1) * color.rgb + 1);
+                               fogvec[0] *= r_glsl_contrastboost.value / ((r_glsl_contrastboost.value - 1) * fogvec[0] + 1);
+                               fogvec[1] *= r_glsl_contrastboost.value / ((r_glsl_contrastboost.value - 1) * fogvec[1] + 1);
+                               fogvec[2] *= r_glsl_contrastboost.value / ((r_glsl_contrastboost.value - 1) * fogvec[2] + 1);
+                       }
+                       r_refdef.fogcolor[0] = bound(0.0f, fogvec[0], 1.0f);
+                       r_refdef.fogcolor[1] = bound(0.0f, fogvec[1], 1.0f);
+                       r_refdef.fogcolor[2] = bound(0.0f, fogvec[2], 1.0f);
+               }
+       }
+}
+
 void R_UpdateVariables(void)
 {
        R_Textures_Frame();
@@ -3265,19 +3255,23 @@ void R_UpdateVariables(void)
                        r_refdef.fog_blue = 0;
                }
        }
-       if (r_refdef.fog_density)
+
+       if (r_refdef.fog_start >= r_refdef.fog_end || r_refdef.fog_start < 0)
        {
-               r_refdef.fogcolor[0] = bound(0.0f, r_refdef.fog_red  , 1.0f);
-               r_refdef.fogcolor[1] = bound(0.0f, r_refdef.fog_green, 1.0f);
-               r_refdef.fogcolor[2] = bound(0.0f, r_refdef.fog_blue , 1.0f);
+               r_refdef.fog_start = 0;
+               r_refdef.fog_end = 1000000000;
+               // TODO update fog cvars here too
        }
+
+       R_UpdateFogColor();
+
        if (r_refdef.fog_density)
        {
                r_refdef.fogenabled = true;
                // this is the point where the fog reaches 0.9986 alpha, which we
                // consider a good enough cutoff point for the texture
                // (0.9986 * 256 == 255.6)
-               r_refdef.fogrange = 400 / r_refdef.fog_density;
+               r_refdef.fogrange = 16 / (r_refdef.fog_density * r_refdef.fog_density);
                r_refdef.fograngerecip = 1.0f / r_refdef.fogrange;
                r_refdef.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * r_refdef.fograngerecip;
                // fog color was already set
@@ -3826,7 +3820,7 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_
                R_Mesh_TexBind(0, R_GetTexture(fogtexture));
                GL_BlendFunc(blendfunc1, GL_ONE);
                fog = 1 - fog;
-               GL_Color(r_refdef.fogcolor[0] * fog * r_view.colorscale, r_refdef.fogcolor[1] * fog * r_view.colorscale, r_refdef.fogcolor[2] * fog * r_view.colorscale, ca);
+               GL_Color(r_refdef.fogcolor[0] * fog, r_refdef.fogcolor[1] * fog, r_refdef.fogcolor[2] * fog, ca);
                R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
        }
 }
@@ -4163,17 +4157,6 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
                t->specularscale = 0;
        }
 
-       t->currentpolygonfactor = r_refdef.polygonfactor + t->basepolygonfactor;
-       t->currentpolygonoffset = r_refdef.polygonoffset + t->basepolygonoffset;
-       // submodels are biased to avoid z-fighting with world surfaces that they
-       // may be exactly overlapping (avoids z-fighting artifacts on certain
-       // doors and things in Quake maps)
-       if (ent->model->brush.submodel)
-       {
-               t->currentpolygonfactor += r_polygonoffset_submodel_factor.value;
-               t->currentpolygonoffset += r_polygonoffset_submodel_offset.value;
-       }
-
        VectorClear(t->dlightcolor);
        t->currentnumlayers = 0;
        if (!(t->currentmaterialflags & MATERIALFLAG_NODRAW))
@@ -4399,6 +4382,13 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q
        rsurface.frameblend[1] = ent->frameblend[1];
        rsurface.frameblend[2] = ent->frameblend[2];
        rsurface.frameblend[3] = ent->frameblend[3];
+       rsurface.basepolygonfactor = r_refdef.polygonfactor;
+       rsurface.basepolygonoffset = r_refdef.polygonoffset;
+       if (ent->model->brush.submodel)
+       {
+               rsurface.basepolygonfactor += r_polygonoffset_submodel_factor.value;
+               rsurface.basepolygonoffset += r_polygonoffset_submodel_offset.value;
+       }
        if (model->surfmesh.isanimated && (rsurface.frameblend[0].lerp != 1 || rsurface.frameblend[0].frame != 0))
        {
                if (wanttangents)
@@ -5330,12 +5320,13 @@ static void RSurf_DrawBatch_GL11_VertexShade(int texturenumsurfaces, msurface_t
        // TODO: optimize
        // model lighting
        VectorCopy(rsurface.modellight_lightdir, lightdir);
-       ambientcolor[0] = rsurface.modellight_ambient[0] * r * 0.5f;
-       ambientcolor[1] = rsurface.modellight_ambient[1] * g * 0.5f;
-       ambientcolor[2] = rsurface.modellight_ambient[2] * b * 0.5f;
-       diffusecolor[0] = rsurface.modellight_diffuse[0] * r * 0.5f;
-       diffusecolor[1] = rsurface.modellight_diffuse[1] * g * 0.5f;
-       diffusecolor[2] = rsurface.modellight_diffuse[2] * b * 0.5f;
+       f = 0.5f * r_refdef.lightmapintensity;
+       ambientcolor[0] = rsurface.modellight_ambient[0] * r * f;
+       ambientcolor[1] = rsurface.modellight_ambient[1] * g * f;
+       ambientcolor[2] = rsurface.modellight_ambient[2] * b * f;
+       diffusecolor[0] = rsurface.modellight_diffuse[0] * r * f;
+       diffusecolor[1] = rsurface.modellight_diffuse[1] * g * f;
+       diffusecolor[2] = rsurface.modellight_diffuse[2] * b * f;
        if (VectorLength2(diffusecolor) > 0)
        {
                // generate color arrays for the surfaces in this list
@@ -5381,12 +5372,20 @@ static void RSurf_DrawBatch_GL11_VertexShade(int texturenumsurfaces, msurface_t
        RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
 }
 
-static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, msurface_t **texturesurfacelist)
+void RSurf_SetupDepthAndCulling(void)
 {
+       // submodels are biased to avoid z-fighting with world surfaces that they
+       // may be exactly overlapping (avoids z-fighting artifacts on certain
+       // doors and things in Quake maps)
        GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
-       GL_PolygonOffset(rsurface.texture->currentpolygonfactor, rsurface.texture->currentpolygonoffset);
+       GL_PolygonOffset(rsurface.basepolygonfactor + rsurface.texture->biaspolygonfactor, rsurface.basepolygonoffset + rsurface.texture->biaspolygonoffset);
        GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
        GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_view.cullface_back);
+}
+
+static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, msurface_t **texturesurfacelist)
+{
+       RSurf_SetupDepthAndCulling();
        if (rsurface.mode != RSURFMODE_SHOWSURFACES)
        {
                rsurface.mode = RSURFMODE_SHOWSURFACES;
@@ -5419,10 +5418,7 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, msurface_t **te
                // restore entity matrix
                R_Mesh_Matrix(&rsurface.matrix);
        }
-       GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
-       GL_PolygonOffset(rsurface.texture->currentpolygonfactor, rsurface.texture->currentpolygonoffset);
-       GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
-       GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_view.cullface_back);
+       RSurf_SetupDepthAndCulling();
        GL_DepthMask(true);
        // LordHavoc: HalfLife maps have freaky skypolys so don't use
        // skymasking on them, and Quake3 never did sky masking (unlike
@@ -5862,9 +5858,7 @@ static void R_DrawTextureSurfaceList(int texturenumsurfaces, msurface_t **textur
                        GL_ColorMask(0,0,0,0);
                        GL_Color(1,1,1,1);
                }
-               GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
-               GL_PolygonOffset(rsurface.texture->currentpolygonfactor, rsurface.texture->currentpolygonoffset);
-               GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_view.cullface_back);
+               RSurf_SetupDepthAndCulling();
                GL_DepthTest(true);
                GL_BlendFunc(GL_ONE, GL_ZERO);
                GL_DepthMask(true);
@@ -5886,10 +5880,8 @@ static void R_DrawTextureSurfaceList(int texturenumsurfaces, msurface_t **textur
        {
                if (rsurface.mode != RSURFMODE_MULTIPASS)
                        rsurface.mode = RSURFMODE_MULTIPASS;
-               GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
-               GL_PolygonOffset(rsurface.texture->currentpolygonfactor, rsurface.texture->currentpolygonoffset);
+               RSurf_SetupDepthAndCulling();
                GL_DepthTest(true);
-               GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_view.cullface_back);
                GL_BlendFunc(GL_ONE, GL_ZERO);
                GL_DepthMask(writedepth);
                GL_Color(1,1,1,1);
@@ -5933,10 +5925,7 @@ static void R_DrawTextureSurfaceList(int texturenumsurfaces, msurface_t **textur
                // write depth for anything we skipped on the depth-only pass earlier
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
                        writedepth = true;
-               GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
-               GL_PolygonOffset(rsurface.texture->currentpolygonfactor, rsurface.texture->currentpolygonoffset);
-               GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
-               GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_view.cullface_back);
+               RSurf_SetupDepthAndCulling();
                GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
                GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
                GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
@@ -6211,35 +6200,38 @@ void R_DrawDebugModel(entity_render_t *ent)
                                }
                                if (r_shownormals.value > 0)
                                {
-                                       GL_Color(r_view.colorscale, 0, 0, r_shownormals.value);
                                        qglBegin(GL_LINES);
                                        for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
                                        {
                                                VectorCopy(rsurface.vertex3f + l * 3, v);
+                                               GL_Color(r_view.colorscale, 0, 0, 1);
                                                qglVertex3f(v[0], v[1], v[2]);
-                                               VectorMA(v, 8, rsurface.svector3f + l * 3, v);
+                                               VectorMA(v, r_shownormals.value, rsurface.svector3f + l * 3, v);
+                                               GL_Color(r_view.colorscale, 1, 1, 1);
                                                qglVertex3f(v[0], v[1], v[2]);
                                        }
                                        qglEnd();
                                        CHECKGLERROR
-                                       GL_Color(0, 0, r_view.colorscale, r_shownormals.value);
                                        qglBegin(GL_LINES);
                                        for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
                                        {
                                                VectorCopy(rsurface.vertex3f + l * 3, v);
+                                               GL_Color(0, r_view.colorscale, 0, 1);
                                                qglVertex3f(v[0], v[1], v[2]);
-                                               VectorMA(v, 8, rsurface.tvector3f + l * 3, v);
+                                               VectorMA(v, r_shownormals.value, rsurface.tvector3f + l * 3, v);
+                                               GL_Color(r_view.colorscale, 1, 1, 1);
                                                qglVertex3f(v[0], v[1], v[2]);
                                        }
                                        qglEnd();
                                        CHECKGLERROR
-                                       GL_Color(0, r_view.colorscale, 0, r_shownormals.value);
                                        qglBegin(GL_LINES);
                                        for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
                                        {
                                                VectorCopy(rsurface.vertex3f + l * 3, v);
+                                               GL_Color(0, 0, r_view.colorscale, 1);
                                                qglVertex3f(v[0], v[1], v[2]);
-                                               VectorMA(v, 8, rsurface.normal3f + l * 3, v);
+                                               VectorMA(v, r_shownormals.value, rsurface.normal3f + l * 3, v);
+                                               GL_Color(r_view.colorscale, 1, 1, 1);
                                                qglVertex3f(v[0], v[1], v[2]);
                                        }
                                        qglEnd();