X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=gl_rmain.c;h=18cf387c0bfceee22e42288415916cc1f33b798e;hb=0229fbee95a0110d1a9eb293be4bbfd4f31ec7a5;hp=50026747f8413cbc06f147772fe5f6a744d299fc;hpb=4eddff1519f73d32d72031d3b1011c72dfdd9802;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index 50026747..18cf387c 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -64,6 +64,7 @@ cvar_t r_shadows_throwdistance = {CVAR_SAVE, "r_shadows_throwdistance", "500", " cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"}; cvar_t r_polygonoffset_submodel_factor = {0, "r_polygonoffset_submodel_factor", "0", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"}; cvar_t r_polygonoffset_submodel_offset = {0, "r_polygonoffset_submodel_offset", "2", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"}; +cvar_t r_fog_exp2 = {0, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rather than realistic GL_EXP fog"}; cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"}; cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"}; @@ -72,6 +73,7 @@ cvar_t gl_foggreen = {0, "gl_foggreen","0.3", "nehahra fog color green value (fo cvar_t gl_fogblue = {0, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"}; cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"}; cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"}; +cvar_t gl_skyclip = {0, "gl_skyclip", "4608", "nehahra farclip distance - the real fog end (for Nehahra compatibility only)"}; cvar_t r_textureunits = {0, "r_textureunits", "32", "number of hardware texture units reported by driver (note: setting this to 1 turns off gl_combine)"}; @@ -246,14 +248,18 @@ void FOG_clear(void) Cvar_Set("gl_foggreen", "0.3"); 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_density = 0; + r_refdef.fog_red = 0; + r_refdef.fog_green = 0; + r_refdef.fog_blue = 0; + r_refdef.fog_alpha = 1; r_refdef.fog_start = 0; - r_refdef.fog_end = 1000000000; + r_refdef.fog_end = 0; } float FogForDistance(vec_t dist) { - unsigned int fogmasktableindex = (unsigned int)(bound(0, dist - r_refdef.fog_start, r_refdef.fog_end - r_refdef.fog_start) * r_refdef.fogmasktabledistmultiplier); + unsigned int fogmasktableindex = (unsigned int)(dist * r_refdef.fogmasktabledistmultiplier); return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)]; } @@ -393,6 +399,29 @@ static void R_BuildFogTexture(void) #define FOGWIDTH 256 unsigned char data1[FOGWIDTH][4]; //unsigned char data2[FOGWIDTH][4]; + double d, r, alpha; + + r_refdef.fogmasktable_start = r_refdef.fog_start; + r_refdef.fogmasktable_alpha = r_refdef.fog_alpha; + r_refdef.fogmasktable_range = r_refdef.fogrange; + r_refdef.fogmasktable_density = r_refdef.fog_density; + + r = r_refdef.fogmasktable_range / FOGMASKTABLEWIDTH; + for (x = 0;x < FOGMASKTABLEWIDTH;x++) + { + d = (x * r - r_refdef.fogmasktable_start); + Con_Printf("%f ", d); + d = max(0, d); + if (r_fog_exp2.integer) + alpha = exp(-r_refdef.fogmasktable_density * r_refdef.fogmasktable_density * 0.0001 * d * d); + else + alpha = exp(-r_refdef.fogmasktable_density * 0.004 * d); + Con_Printf(" : %f ", alpha); + alpha = 1 - (1 - alpha) * r_refdef.fogmasktable_alpha; + Con_Printf(" = %f\n", alpha); + r_refdef.fogmasktable[x] = bound(0, alpha, 1); + } + for (x = 0;x < FOGWIDTH;x++) { b = (int)(r_refdef.fogmasktable[x * (FOGMASKTABLEWIDTH - 1) / (FOGWIDTH - 1)] * 255); @@ -405,8 +434,16 @@ static void R_BuildFogTexture(void) //data2[x][2] = 255 - b; //data2[x][3] = 255; } - r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, NULL); - //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL); + if (r_texture_fogattenuation) + { + R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, FOGWIDTH, 1); + //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, FOGWIDTH, 1); + } + else + { + r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, NULL); + //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL); + } } static const char *builtinshaderstring = @@ -574,6 +611,9 @@ static const char *builtinshaderstring = "uniform myhvec3 Color_Shirt;\n" "uniform myhvec3 FogColor;\n" "\n" +"uniform myhvec4 TintColor;\n" +"\n" +"\n" "//#ifdef MODE_WATER\n" "uniform vec4 DistortScaleRefractReflect;\n" "uniform vec4 ScreenScaleRefractReflect;\n" @@ -610,8 +650,6 @@ 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" @@ -749,7 +787,6 @@ static const char *builtinshaderstring = " //color.rgb *= normalize(CubeVector) * 0.5 + 0.5;//vec3(textureCube(Texture_Cube, CubeVector));\n" " color.rgb *= myhvec3(textureCube(Texture_Cube, CubeVector));\n" "# endif\n" -" color *= myhvec4(gl_Color);\n" "#endif // MODE_LIGHTSOURCE\n" "\n" "\n" @@ -779,7 +816,7 @@ static const char *builtinshaderstring = "# endif\n" "# endif\n" "\n" -" color *= myhvec4(gl_Color);\n" +" color.a *= TintColor.a;\n" "#endif // MODE_LIGHTDIRECTION\n" "\n" "\n" @@ -801,8 +838,9 @@ static const char *builtinshaderstring = "# endif\n" "\n" " // apply lightmap color\n" -" color.rgb = color.rgb * AmbientScale + tempcolor * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * myhvec3(gl_Color);\n" -" color.a *= myhalf(gl_Color.a);\n" +" color.rgb = color.rgb * AmbientScale + tempcolor * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap));\n" +"\n" +" color *= TintColor;\n" "#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n" "\n" "\n" @@ -823,8 +861,9 @@ static const char *builtinshaderstring = "# endif\n" "\n" " // apply lightmap color\n" -" color.rgb = color.rgb * AmbientScale + tempcolor * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * myhvec3(gl_Color);\n" -" color.a *= myhalf(gl_Color.a);\n" +" color.rgb = color.rgb * AmbientScale + tempcolor * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap));\n" +"\n" +" color *= TintColor;\n" "#endif // MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n" "\n" "\n" @@ -832,12 +871,31 @@ static const char *builtinshaderstring = "\n" "#ifdef MODE_LIGHTMAP\n" " // apply lightmap color\n" -" color *= myhvec4(texture2D(Texture_Lightmap, TexCoordLightmap)) * myhvec4(gl_Color) * myhvec4(myhvec3(DiffuseScale), 1) + myhvec4(myhvec3(AmbientScale), 0);\n" +" color.rgb = color.rgb * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * DiffuseScale + color.rgb * AmbientScale;\n" +"\n" +" color *= TintColor;\n" "#endif // MODE_LIGHTMAP\n" "\n" "\n" "\n" "\n" +"#ifdef MODE_VERTEXCOLOR\n" +" // apply lightmap color\n" +" color.rgb = color.rgb * myhvec3(gl_Color.rgb) * DiffuseScale + color.rgb * AmbientScale;\n" +"\n" +" color *= TintColor;\n" +"#endif // MODE_VERTEXCOLOR\n" +"\n" +"\n" +"\n" +"\n" +"#ifdef MODE_FLATCOLOR\n" +" color *= TintColor;\n" +"#endif // MODE_FLATCOLOR\n" +"\n" +"\n" +"\n" +"\n" "\n" "\n" "\n" @@ -846,25 +904,23 @@ static const char *builtinshaderstring = " color.rgb += myhvec3(texture2D(Texture_Glow, TexCoord)) * GlowScale;\n" "#endif\n" "\n" -"#ifndef MODE_LIGHTSOURCE\n" -"# ifdef USEREFLECTION\n" -" vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n" -" //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n" -" vec4 ScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect + vec3(normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5))).xyxy * DistortScaleRefractReflect;\n" -" color.rgb = mix(color.rgb, myhvec3(texture2D(Texture_Reflection, ScreenTexCoord.zw)) * ReflectColor.rgb, ReflectColor.a);\n" -"# endif\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" +" // apply fog after Contrastboost/SceneBrightness because its color is already modified appropriately\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" +" color.rgb = mix(FogColor, color.rgb, myhalf(texture2D(Texture_FogMask, myhvec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0))));\n" +"#endif\n" +"\n" +" // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n" +"#ifdef USEREFLECTION\n" +" vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n" +" //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n" +" vec4 ScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect + vec3(normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5))).xyxy * DistortScaleRefractReflect;\n" +" color.rgb = mix(color.rgb, myhvec3(texture2D(Texture_Reflection, ScreenTexCoord.zw)) * ReflectColor.rgb, ReflectColor.a);\n" "#endif\n" "\n" " gl_FragColor = vec4(color);\n" @@ -906,9 +962,11 @@ const char *shaderpermutationinfo[][2] = // this enum is multiplied by SHADERPERMUTATION_MODEBASE typedef enum shadermode_e { - SHADERMODE_LIGHTMAP, // (lightmap) use directional pixel shading from fixed light direction (q3bsp) - SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE, // (lightmap) use directional pixel shading from texture containing modelspace light directions (deluxemap) - SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE, // (lightmap) use directional pixel shading from texture containing tangentspace light directions (deluxemap) + SHADERMODE_FLATCOLOR, // (lightmap) modulate texture by uniform color (q1bsp, q3bsp) + SHADERMODE_VERTEXCOLOR, // (lightmap) modulate texture by vertex colors (q3bsp) + SHADERMODE_LIGHTMAP, // (lightmap) modulate texture by lightmap texture (q1bsp, q3bsp) + SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE, // (lightmap) use directional pixel shading from texture containing modelspace light directions (q3bsp deluxemap) + SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE, // (lightmap) use directional pixel shading from texture containing tangentspace light directions (q1bsp deluxemap) SHADERMODE_LIGHTDIRECTION, // (lightmap) use directional pixel shading from fixed light direction (q3bsp) SHADERMODE_LIGHTSOURCE, // (lightsource) use directional pixel shading from light source (rtlight) SHADERMODE_REFRACTION, // refract background (the material is rendered normally after this pass) @@ -920,6 +978,8 @@ shadermode_t; // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS! const char *shadermodeinfo[][2] = { + {"#define MODE_FLATCOLOR\n", " flatcolor"}, + {"#define MODE_VERTEXCOLOR\n", " vertexcolor"}, {"#define MODE_LIGHTMAP\n", " lightmap"}, {"#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"}, {"#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"}, @@ -959,8 +1019,6 @@ 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; @@ -968,6 +1026,7 @@ typedef struct r_glsl_permutation_s int loc_GlowScale; int loc_SceneBrightness; // or: Scenebrightness * ContrastBoost int loc_OffsetMapping_Scale; + int loc_TintColor; int loc_AmbientColor; int loc_DiffuseColor; int loc_SpecularColor; @@ -1092,8 +1151,6 @@ 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"); @@ -1101,6 +1158,7 @@ static void R_GLSL_CompilePermutation(const char *filename, int permutation, int p->loc_GlowScale = qglGetUniformLocationARB(p->program, "GlowScale"); p->loc_SceneBrightness = qglGetUniformLocationARB(p->program, "SceneBrightness"); p->loc_OffsetMapping_Scale = qglGetUniformLocationARB(p->program, "OffsetMapping_Scale"); + p->loc_TintColor = qglGetUniformLocationARB(p->program, "TintColor"); p->loc_AmbientColor = qglGetUniformLocationARB(p->program, "AmbientColor"); p->loc_DiffuseColor = qglGetUniformLocationARB(p->program, "DiffuseColor"); p->loc_SpecularColor = qglGetUniformLocationARB(p->program, "SpecularColor"); @@ -1223,13 +1281,11 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl permutation |= SHADERPERMUTATION_COLORMAPPING; if(r_glsl_contrastboost.value > 1 || r_glsl_contrastboost.value < 0) permutation |= SHADERPERMUTATION_CONTRASTBOOST; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) - permutation |= SHADERPERMUTATION_REFLECTION; } else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) { // unshaded geometry (fullbright or ambient model lighting) - mode = SHADERMODE_LIGHTMAP; + mode = SHADERMODE_FLATCOLOR; if (rsurface.texture->currentskinframe->glow) permutation |= SHADERPERMUTATION_GLOW; if (r_refdef.fogenabled) @@ -1300,11 +1356,16 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl if (specularscale > 0) permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; } - else + else if (rsurface.uselightmaptexture) { - // ordinary lightmapping + // ordinary lightmapping (q1bsp, q3bsp) mode = SHADERMODE_LIGHTMAP; } + else + { + // ordinary vertex coloring (q3bsp) + mode = SHADERMODE_VERTEXCOLOR; + } if (rsurface.texture->currentskinframe->glow) permutation |= SHADERPERMUTATION_GLOW; if (r_refdef.fogenabled) @@ -1369,20 +1430,21 @@ 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 * rsurface.texture->lightmapcolor[0] * 0.5f, rsurface.modellight_ambient[1] * ambientscale * rsurface.texture->lightmapcolor[1] * 0.5f, rsurface.modellight_ambient[2] * ambientscale * rsurface.texture->lightmapcolor[2] * 0.5f); 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 * rsurface.texture->lightmapcolor[0] * 0.5f, rsurface.modellight_diffuse[1] * diffusescale * rsurface.texture->lightmapcolor[1] * 0.5f, rsurface.modellight_diffuse[2] * diffusescale * rsurface.texture->lightmapcolor[2] * 0.5f); 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 * rsurface.texture->lightmapcolor[0] * 0.5f, rsurface.modellight_diffuse[1] * specularscale * rsurface.texture->lightmapcolor[1] * 0.5f, rsurface.modellight_diffuse[2] * specularscale * rsurface.texture->lightmapcolor[2] * 0.5f); 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]); } 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_refdef.lightmapintensity * 2.0f); - if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_refdef.lightmapintensity * specularscale * 2.0f); + if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_ambient.value * 1.0f / 128.0f); + if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_refdef.lightmapintensity); + if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_refdef.lightmapintensity * specularscale); } + if (r_glsl_permutation->loc_TintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_TintColor, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2], rsurface.texture->lightmapcolor[3]); if (r_glsl_permutation->loc_GlowScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_GlowScale, r_hdr_glowintensity.value); if (r_glsl_permutation->loc_ContrastBoostCoeff >= 0) { @@ -1424,8 +1486,6 @@ 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); @@ -1521,7 +1581,7 @@ skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewid skinframe_t *item; int hashindex; char basename[MAX_QPATH]; - + Image_StripImageExtension(name, basename, sizeof(basename)); hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1); @@ -1543,7 +1603,7 @@ skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewid item->comparewidth = comparewidth; item->compareheight = compareheight; item->comparecrc = comparecrc; - item->next = r_skinframe.hash[hashindex]; + item->next = r_skinframe.hash[hashindex]; r_skinframe.hash[hashindex] = item; } else if( item->base == NULL ) @@ -1822,18 +1882,6 @@ skinframe_t *R_SkinFrame_LoadMissing(void) void gl_main_start(void) { - int x; - double r, alpha; - - r = -16.0 / (1.0 * FOGMASKTABLEWIDTH * FOGMASKTABLEWIDTH); - for (x = 0;x < FOGMASKTABLEWIDTH;x++) - { - alpha = exp(r * ((double)x*(double)x)); - if (x == FOGMASKTABLEWIDTH - 1) - alpha = 0; - r_refdef.fogmasktable[x] = bound(0, alpha, 1); - } - memset(r_qwskincache, 0, sizeof(r_qwskincache)); memset(r_qwskincache_skinframe, 0, sizeof(r_qwskincache_skinframe)); @@ -1850,11 +1898,14 @@ void gl_main_start(void) R_BuildWhiteCube(); R_BuildNormalizationCube(); } - R_BuildFogTexture(); + r_texture_fogattenuation = NULL; + //r_texture_fogintensity = NULL; memset(&r_bloomstate, 0, sizeof(r_bloomstate)); memset(&r_waterstate, 0, sizeof(r_waterstate)); memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations)); memset(&r_svbsp, 0, sizeof (r_svbsp)); + + r_refdef.fogmasktable_density = 0; } void gl_main_shutdown(void) @@ -1876,6 +1927,8 @@ void gl_main_shutdown(void) r_texture_black = NULL; r_texture_whitecube = NULL; r_texture_normalizationcube = NULL; + r_texture_fogattenuation = NULL; + //r_texture_fogintensity = NULL; memset(&r_bloomstate, 0, sizeof(r_bloomstate)); memset(&r_waterstate, 0, sizeof(r_waterstate)); R_GLSL_Restart_f(); @@ -1922,6 +1975,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable (&gl_fogblue); Cvar_RegisterVariable (&gl_fogstart); Cvar_RegisterVariable (&gl_fogend); + Cvar_RegisterVariable (&gl_skyclip); } Cvar_RegisterVariable(&r_depthfirst); Cvar_RegisterVariable(&r_nearclip); @@ -1952,6 +2006,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_q1bsp_skymasking); Cvar_RegisterVariable(&r_polygonoffset_submodel_factor); Cvar_RegisterVariable(&r_polygonoffset_submodel_offset); + Cvar_RegisterVariable(&r_fog_exp2); Cvar_RegisterVariable(&r_textureunits); Cvar_RegisterVariable(&r_glsl); Cvar_RegisterVariable(&r_glsl_offsetmapping); @@ -2141,43 +2196,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 +2238,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 @@ -2405,7 +2419,7 @@ static void R_View_SetFrustum(void) VectorMA(r_view.forward, -slopey, r_view.up , r_view.frustum[2].normal); VectorMA(r_view.forward, slopey, r_view.up , r_view.frustum[3].normal); VectorCopy(r_view.forward, r_view.frustum[4].normal); - + // Leaving those out was a mistake, those were in the old code, and they // fix a reproducable bug in this one: frustum culling got fucked up when viewmatrix was an identity matrix // I couldn't reproduce it after adding those normalizations. --blub @@ -2831,7 +2845,7 @@ static void R_Water_ProcessPlanes(void) } R_ResetViewRendering3D(); - R_ClearScreen(); + R_ClearScreen(r_refdef.fogenabled); if (r_timereport_active) R_TimeReport("viewclear"); @@ -2843,7 +2857,7 @@ static void R_Water_ProcessPlanes(void) qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view.x, vid.height - (r_view.y + r_view.height), r_view.width, r_view.height);CHECKGLERROR R_ResetViewRendering3D(); - R_ClearScreen(); + R_ClearScreen(r_refdef.fogenabled); if (r_timereport_active) R_TimeReport("viewclear"); } @@ -3114,7 +3128,9 @@ void R_Bloom_MakeTexture(void) void R_HDR_RenderBloomTexture(void) { int oldwidth, oldheight; + float oldcolorscale; + oldcolorscale = r_view.colorscale; oldwidth = r_view.width; oldheight = r_view.height; r_view.width = r_bloomstate.bloomwidth; @@ -3125,9 +3141,12 @@ void R_HDR_RenderBloomTexture(void) // TODO: add fp16 framebuffer support r_view.showdebug = false; - r_view.colorscale = r_bloom_colorscale.value * r_hdr_scenebrightness.value; - if (r_hdr.integer) - r_view.colorscale /= r_hdr_range.value; + r_view.colorscale *= r_bloom_colorscale.value / bound(1, r_hdr_range.value, 16); + + R_ClearScreen(r_refdef.fogenabled); + if (r_timereport_active) + R_TimeReport("HDRclear"); + r_waterstate.numwaterplanes = 0; R_RenderScene(r_waterstate.enabled); r_view.showdebug = true; @@ -3137,15 +3156,16 @@ void R_HDR_RenderBloomTexture(void) R_Bloom_CopyHDRTexture(); R_Bloom_MakeTexture(); + // restore the view settings + r_view.width = oldwidth; + r_view.height = oldheight; + r_view.colorscale = oldcolorscale; + R_ResetViewRendering3D(); - R_ClearScreen(); + R_ClearScreen(r_refdef.fogenabled); if (r_timereport_active) R_TimeReport("viewclear"); - - // restore the view settings - r_view.width = oldwidth; - r_view.height = oldheight; } static void R_BlendView(void) @@ -3216,6 +3236,33 @@ void R_RenderScene(qboolean addwaterplanes); matrix4x4_t r_waterscrollmatrix; +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; + VectorCopy(r_refdef.fogcolor, fogvec); + // color.rgb *= SceneBrightness; + 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); + } + VectorScale(fogvec, r_view.colorscale, fogvec); + 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(); @@ -3255,6 +3302,9 @@ void R_UpdateVariables(void) r_refdef.fog_red = gl_fogred.value; r_refdef.fog_green = gl_foggreen.value; r_refdef.fog_blue = gl_fogblue.value; + r_refdef.fog_alpha = 1; + r_refdef.fog_start = 0; + r_refdef.fog_end = gl_skyclip.value; } else if (r_refdef.oldgl_fogenable) { @@ -3263,37 +3313,17 @@ void R_UpdateVariables(void) r_refdef.fog_red = 0; r_refdef.fog_green = 0; r_refdef.fog_blue = 0; + r_refdef.fog_alpha = 0; + r_refdef.fog_start = 0; + r_refdef.fog_end = 0; } } - 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); - } - } + r_refdef.fog_alpha = bound(0, r_refdef.fog_alpha, 1); + r_refdef.fog_start = max(0, r_refdef.fog_start); + r_refdef.fog_end = max(r_refdef.fog_start + 0.01, r_refdef.fog_end); - if (r_refdef.fog_start >= r_refdef.fog_end || r_refdef.fog_start < 0) - { - r_refdef.fog_start = 0; - r_refdef.fog_end = 1000000000; - // TODO update fog cvars here too - } + // R_UpdateFogColor(); // why? R_RenderScene does it anyway if (r_refdef.fog_density) { @@ -3301,10 +3331,17 @@ void R_UpdateVariables(void) // 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 = 16 / (r_refdef.fog_density * r_refdef.fog_density); + if (r_fog_exp2.integer) + r_refdef.fogrange = 32 / (r_refdef.fog_density * r_refdef.fog_density) + r_refdef.fog_start; + else + r_refdef.fogrange = 2048 / r_refdef.fog_density + r_refdef.fog_start; + r_refdef.fogrange = bound(r_refdef.fog_start, r_refdef.fogrange, r_refdef.fog_end); r_refdef.fograngerecip = 1.0f / r_refdef.fogrange; r_refdef.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * r_refdef.fograngerecip; // fog color was already set + // update the fog texture + if (r_refdef.fogmasktable_start != r_refdef.fog_start || r_refdef.fogmasktable_alpha != r_refdef.fog_alpha || r_refdef.fogmasktable_density != r_refdef.fog_density || r_refdef.fogmasktable_range != r_refdef.fogrange) + R_BuildFogTexture(); } else r_refdef.fogenabled = false; @@ -3320,6 +3357,8 @@ void R_RenderView(void) if (!r_refdef.entities/* || !r_refdef.worldmodel*/) return; //Host_Error ("R_RenderView: NULL worldmodel"); + r_view.colorscale = r_hdr_scenebrightness.value; + R_Shadow_UpdateWorldLightSelection(); R_Bloom_StartFrame(); @@ -3331,9 +3370,9 @@ void R_RenderView(void) R_ResetViewRendering3D(); - if (r_view.clear) + if (r_view.clear || r_refdef.fogenabled) { - R_ClearScreen(); + R_ClearScreen(r_refdef.fogenabled); if (r_timereport_active) R_TimeReport("viewclear"); } @@ -3345,7 +3384,6 @@ void R_RenderView(void) if (r_hdr.integer) R_HDR_RenderBloomTexture(); - r_view.colorscale = r_hdr_scenebrightness.value; r_waterstate.numwaterplanes = 0; R_RenderScene(r_waterstate.enabled); @@ -3366,6 +3404,8 @@ static void R_DrawLocs(void); static void R_DrawEntityBBoxes(void); void R_RenderScene(qboolean addwaterplanes) { + R_UpdateFogColor(); + if (addwaterplanes) { R_ResetViewRendering3D(); @@ -4187,17 +4227,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)) @@ -4255,6 +4284,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) if (ent->model->type == mod_brushq3) colorscale *= r_refdef.rtlightstylevalue[0]; colorscale *= r_refdef.lightmapintensity; + Vector4Set(t->lightmapcolor, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, t->currentalpha); R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, t->currentalpha); if (r_ambient.value >= (1.0f/64.0f)) R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * r_ambient.value * (1.0f / 64.0f), ent->colormod[1] * r_ambient.value * (1.0f / 64.0f), ent->colormod[2] * r_ambient.value * (1.0f / 64.0f), t->currentalpha); @@ -4286,7 +4316,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) // were darkened by fog already, and we should not add fog color // (because the background was not darkened, there is no fog color // that was lost behind it). - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->currentskinframe->fog, &identitymatrix, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], t->currentalpha); + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->currentskinframe->fog, &identitymatrix, r_refdef.fogcolor[0] / r_view.colorscale, r_refdef.fogcolor[1] / r_view.colorscale, r_refdef.fogcolor[2] / r_view.colorscale, t->currentalpha); } } } @@ -4361,6 +4391,8 @@ void RSurf_ActiveWorldEntity(void) rsurface.frameblend[2].lerp = 0; rsurface.frameblend[3].frame = 0; rsurface.frameblend[3].lerp = 0; + rsurface.basepolygonfactor = r_refdef.polygonfactor; + rsurface.basepolygonoffset = r_refdef.polygonoffset; rsurface.modelvertex3f = model->surfmesh.data_vertex3f; rsurface.modelvertex3f_bufferobject = model->surfmesh.vbo; rsurface.modelvertex3f_bufferoffset = model->surfmesh.vbooffset_vertex3f; @@ -4414,7 +4446,12 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q rsurface.inversematrix = ent->inversematrix; R_Mesh_Matrix(&rsurface.matrix); Matrix4x4_Transform(&rsurface.inversematrix, r_view.origin, rsurface.modelorg); - VectorCopy(ent->modellight_ambient, rsurface.modellight_ambient); + rsurface.modellight_ambient[0] = ent->modellight_ambient[0] * ent->colormod[0]; + rsurface.modellight_ambient[1] = ent->modellight_ambient[1] * ent->colormod[1]; + rsurface.modellight_ambient[2] = ent->modellight_ambient[2] * ent->colormod[2]; + rsurface.modellight_diffuse[0] = ent->modellight_diffuse[0] * ent->colormod[0]; + rsurface.modellight_diffuse[1] = ent->modellight_diffuse[1] * ent->colormod[1]; + rsurface.modellight_diffuse[2] = ent->modellight_diffuse[2] * ent->colormod[2]; VectorCopy(ent->modellight_diffuse, rsurface.modellight_diffuse); VectorCopy(ent->modellight_lightdir, rsurface.modellight_lightdir); VectorCopy(ent->colormap_pantscolor, rsurface.colormap_pantscolor); @@ -4423,6 +4460,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) @@ -5354,12 +5398,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 @@ -5405,12 +5450,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; @@ -5443,10 +5496,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 @@ -5456,7 +5506,7 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, msurface_t **te // level, so don't use it then either. if (r_refdef.worldmodel && r_refdef.worldmodel->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_viewcache.world_novis) { - GL_Color(r_refdef.fogcolor[0] * r_view.colorscale, r_refdef.fogcolor[1] * r_view.colorscale, r_refdef.fogcolor[2] * r_view.colorscale, 1); + GL_Color(r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], 1); R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); if (skyrendermasked) @@ -5488,6 +5538,7 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, msurface_t **t { rsurface.mode = RSURFMODE_GLSL; R_Mesh_ResetTextureState(); + GL_Color(1, 1, 1, 1); } R_Mesh_TexMatrix(0, &rsurface.texture->currenttexmatrix); @@ -5576,7 +5627,6 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, msurface_t **t R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset); R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset); R_Mesh_TexCoordPointer(4, 2, rsurface.modeltexcoordlightmap2f, rsurface.modeltexcoordlightmap2f_bufferobject, rsurface.modeltexcoordlightmap2f_bufferoffset); - GL_Color(rsurface.texture->currentlayers[0].color[0], rsurface.texture->currentlayers[0].color[1], rsurface.texture->currentlayers[0].color[2], rsurface.texture->currentlayers[0].color[3]); if (r_glsl_permutation->loc_Texture_Refraction >= 0) { @@ -5886,9 +5936,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); @@ -5910,10 +5958,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); @@ -5957,10 +6003,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);