From b2d45dd172990008ff2fefa83cc24243b39cafae Mon Sep 17 00:00:00 2001 From: havoc Date: Tue, 9 Mar 2010 01:33:41 +0000 Subject: [PATCH] implemented a new type of height fog using a texture to describe multiple fog layers, some visual issues due to the method used. new command and worldspawn property - identical extra for a new texturename parameter at the end fixed some issues with shadowmapping in Cg shaders git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10044 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_main.c | 29 +++++- cl_parse.c | 11 +++ client.h | 9 ++ gl_rmain.c | 270 +++++++++++++++++++++++++++++++++++------------------ mathlib.h | 4 + r_shadow.c | 10 +- render.h | 5 +- 7 files changed, 241 insertions(+), 97 deletions(-) diff --git a/cl_main.c b/cl_main.c index abf851c5..66964ea4 100644 --- a/cl_main.c +++ b/cl_main.c @@ -1925,6 +1925,32 @@ static void CL_Fog_f (void) r_refdef.fog_fadedepth = atof(Cmd_Argv(9)); } +/* +====================== +CL_FogHeightTexture_f +====================== +*/ +static void CL_Fog_HeightTexture_f (void) +{ + if (Cmd_Argc () < 11) + { + Con_Printf("\"fog_heighttexture\" is \"%f %f %f %f %f %f %f %f %f %s\"\n", r_refdef.fog_density, r_refdef.fog_red, r_refdef.fog_green, r_refdef.fog_blue, r_refdef.fog_alpha, r_refdef.fog_start, r_refdef.fog_end, r_refdef.fog_height, r_refdef.fog_fadedepth, r_refdef.fog_height_texturename); + return; + } + FOG_clear(); // so missing values get good defaults + r_refdef.fog_density = atof(Cmd_Argv(1)); + r_refdef.fog_red = atof(Cmd_Argv(2)); + r_refdef.fog_green = atof(Cmd_Argv(3)); + r_refdef.fog_blue = atof(Cmd_Argv(4)); + r_refdef.fog_alpha = atof(Cmd_Argv(5)); + r_refdef.fog_start = atof(Cmd_Argv(6)); + r_refdef.fog_end = atof(Cmd_Argv(7)); + r_refdef.fog_height = atof(Cmd_Argv(8)); + r_refdef.fog_fadedepth = atof(Cmd_Argv(9)); + strlcpy(r_refdef.fog_height_texturename, Cmd_Argv(10), sizeof(r_refdef.fog_height_texturename)); +} + + /* ==================== CL_TimeRefresh_f @@ -2355,7 +2381,8 @@ void CL_Init (void) Cvar_RegisterVariable (&cl_autodemo); Cvar_RegisterVariable (&cl_autodemo_nameformat); - Cmd_AddCommand ("fog", CL_Fog_f, "set global fog parameters (density red green blue [alpha [mindist maxdist]])"); + Cmd_AddCommand ("fog", CL_Fog_f, "set global fog parameters (density red green blue [alpha [mindist [maxdist [top [fadedepth]]]]])"); + Cmd_AddCommand ("fog_heighttexture", CL_Fog_HeightTexture_f, "set global fog parameters (density red green blue alpha mindist maxdist top depth textures/mapname/fogheight.tga)"); // LordHavoc: added pausedemo Cmd_AddCommand ("pausedemo", CL_PauseDemo_f, "pause demo playback (can also safely pause demo recording if using QUAKE, QUAKEDP or NEHAHRAMOVIE protocol, useful for making movies)"); diff --git a/cl_parse.c b/cl_parse.c index 26cbc6fa..96109e54 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -389,6 +389,7 @@ void CL_ParseEntityLump(char *entdata) R_SetSkyBox(value); else if (!strcmp("fog", key)) { + FOG_clear(); // so missing values get good defaults r_refdef.fog_start = 0; r_refdef.fog_alpha = 1; r_refdef.fog_end = 16384; @@ -417,6 +418,16 @@ void CL_ParseEntityLump(char *entdata) r_refdef.fog_height = atof(value); else if (!strcmp("fog_fadedepth", key)) r_refdef.fog_fadedepth = atof(value); + else if (!strcmp("fog_heighttexture", key)) + { + FOG_clear(); // so missing values get good defaults +#if _MSC_VER >= 1400 + sscanf_s(value, "%f %f %f %f %f %f %f %f %f %s", &r_refdef.fog_density, &r_refdef.fog_red, &r_refdef.fog_green, &r_refdef.fog_blue, &r_refdef.fog_alpha, &r_refdef.fog_start, &r_refdef.fog_end, &r_refdef.fog_height, &r_refdef.fog_fadedepth, r_refdef.fog_height_texturename, (unsigned int)sizeof(r_refdef.fog_height_texturename)); +#else + sscanf(value, "%f %f %f %f %f %f %f %f %f %63s", &r_refdef.fog_density, &r_refdef.fog_red, &r_refdef.fog_green, &r_refdef.fog_blue, &r_refdef.fog_alpha, &r_refdef.fog_start, &r_refdef.fog_end, &r_refdef.fog_height, &r_refdef.fog_fadedepth, r_refdef.fog_height_texturename); +#endif + r_refdef.fog_height_texturename[63] = 0; + } } } diff --git a/client.h b/client.h index fe6c3b39..3c4ce0a6 100644 --- a/client.h +++ b/client.h @@ -1730,6 +1730,15 @@ typedef struct r_refdef_s qboolean fogenabled; qboolean oldgl_fogenable; + // new flexible texture height fog (overrides normal fog) + char fog_height_texturename[64]; // note: must be 64 for the sscanf code + unsigned char *fog_height_table1d; + unsigned char *fog_height_table2d; + int fog_height_tablesize; // enable + float fog_height_tablescale; + float fog_height_texcoordscale; + char fogheighttexturename[64]; // detects changes to active fog height texture + qboolean draw2dstage; // true during envmap command capture diff --git a/gl_rmain.c b/gl_rmain.c index ccc6e54d..80abf56d 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -218,6 +218,7 @@ rtexture_t *r_texture_notexture; rtexture_t *r_texture_whitecube; rtexture_t *r_texture_normalizationcube; rtexture_t *r_texture_fogattenuation; +rtexture_t *r_texture_fogheighttexture; rtexture_t *r_texture_gammaramps; unsigned int r_texture_gammaramps_serial; //rtexture_t *r_texture_fogintensity; @@ -304,6 +305,7 @@ void FOG_clear(void) r_refdef.fog_end = 16384; r_refdef.fog_height = 1<<30; r_refdef.fog_fadedepth = 128; + memset(r_refdef.fog_height_texturename, 0, sizeof(r_refdef.fog_height_texturename)); } static void R_BuildBlankTextures(void) @@ -484,6 +486,74 @@ static void R_BuildFogTexture(void) } } +static void R_BuildFogHeightTexture(void) +{ + unsigned char *inpixels; + int size; + int x; + int y; + int j; + float c[4]; + float f; + inpixels = NULL; + strlcpy(r_refdef.fogheighttexturename, r_refdef.fog_height_texturename, sizeof(r_refdef.fogheighttexturename)); + if (r_refdef.fogheighttexturename[0]) + inpixels = loadimagepixelsbgra(r_refdef.fogheighttexturename, true, false, false); + if (!inpixels) + { + r_refdef.fog_height_tablesize = 0; + if (r_texture_fogheighttexture) + R_FreeTexture(r_texture_fogheighttexture); + r_texture_fogheighttexture = NULL; + if (r_refdef.fog_height_table2d) + Mem_Free(r_refdef.fog_height_table2d); + r_refdef.fog_height_table2d = NULL; + if (r_refdef.fog_height_table1d) + Mem_Free(r_refdef.fog_height_table1d); + r_refdef.fog_height_table1d = NULL; + return; + } + size = image_width; + r_refdef.fog_height_tablesize = size; + r_refdef.fog_height_table1d = Mem_Alloc(r_main_mempool, size * 4); + r_refdef.fog_height_table2d = Mem_Alloc(r_main_mempool, size * size * 4); + memcpy(r_refdef.fog_height_table1d, inpixels, size * 4); + Mem_Free(inpixels); + // LordHavoc: now the magic - what is that table2d for? it is a cooked + // average fog color table accounting for every fog layer between a point + // and the camera. (Note: attenuation is handled separately!) + for (y = 0;y < size;y++) + { + for (x = 0;x < size;x++) + { + Vector4Clear(c); + f = 0; + if (x < y) + { + for (j = x;j <= y;j++) + { + Vector4Add(c, r_refdef.fog_height_table1d + j*4, c); + f++; + } + } + else + { + for (j = x;j >= y;j--) + { + Vector4Add(c, r_refdef.fog_height_table1d + j*4, c); + f++; + } + } + f = 1.0f / f; + r_refdef.fog_height_table2d[(y*size+x)*4+0] = (unsigned char)(c[0] * f); + r_refdef.fog_height_table2d[(y*size+x)*4+1] = (unsigned char)(c[1] * f); + r_refdef.fog_height_table2d[(y*size+x)*4+2] = (unsigned char)(c[2] * f); + r_refdef.fog_height_table2d[(y*size+x)*4+3] = (unsigned char)(c[3] * f); + } + } + r_texture_fogheighttexture = R_LoadTexture2D(r_main_texturepool, "fogheighttable", size, size, r_refdef.fog_height_table2d, TEXTYPE_BGRA, TEXF_ALPHA | TEXF_CLAMP, NULL); +} + //======================================================================================================================================================= static const char *builtinshaderstring = @@ -491,7 +561,7 @@ static const char *builtinshaderstring = "// written by Forest 'LordHavoc' Hale\n" "// shadowmapping enhancements by Lee 'eihrul' Salzman\n" "\n" -"#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE)\n" +"#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE) || defined(USEFOGHEIGHTTEXTURE)\n" "# define USEFOG\n" "#endif\n" "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n" @@ -930,6 +1000,9 @@ static const char *builtinshaderstring = "uniform sampler2D Texture_Shirt;\n" "#endif\n" "#ifdef USEFOG\n" +"#ifdef USEFOGHEIGHTTEXTURE\n" +"uniform sampler2D Texture_FogHeightTexture;\n" +"#endif\n" "uniform sampler2D Texture_FogMask;\n" "#endif\n" "#ifdef USELIGHTMAP\n" @@ -959,17 +1032,23 @@ static const char *builtinshaderstring = "uniform float FogRangeRecip;\n" "uniform float FogPlaneViewDist;\n" "uniform float FogHeightFade;\n" -"float FogVertex(void)\n" +"vec3 FogVertex(vec3 surfacecolor)\n" "{\n" " vec3 EyeVectorModelSpace = EyeVectorModelSpaceFogPlaneVertexDist.xyz;\n" " float FogPlaneVertexDist = EyeVectorModelSpaceFogPlaneVertexDist.w;\n" " float fogfrac;\n" -"#ifdef USEFOGOUTSIDE\n" -" fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n" +"#ifdef USEFOGHEIGHTTEXTURE\n" +" vec4 fogheightpixel = texture2D(Texture_FogHeightTexture, vec2(1,1) + vec2(FogPlaneVertexDist, FogPlaneViewDist) * (-2.0 * FogHeightFade));\n" +" fogfrac = fogheightpixel.a;\n" +" return mix(fogheightpixel.rgb * FogColor, surfacecolor, texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n" "#else\n" +"# ifdef USEFOGOUTSIDE\n" +" fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n" +"# else\n" " fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n" +"# endif\n" +" return mix(FogColor, surfacecolor, texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n" "#endif\n" -" return float(texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)));\n" "}\n" "#endif\n" "\n" @@ -1684,11 +1763,7 @@ static const char *builtinshaderstring = "#endif\n" "\n" "#ifdef USEFOG\n" -"#ifdef MODE_LIGHTSOURCE\n" -" color.rgb *= myhalf(FogVertex());\n" -"#else\n" -" color.rgb = mix(FogColor, color.rgb, FogVertex());\n" -"#endif\n" +" color.rgb = FogVertex(color.rgb);\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" @@ -1758,7 +1833,12 @@ const char *builtincgshaderstring = "// written by Forest 'LordHavoc' Hale\n" "// shadowmapping enhancements by Lee 'eihrul' Salzman\n" "\n" -"#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE)\n" +"// FIXME: we need to get rid of ModelViewProjectionPosition to make room for the texcoord for this\n" +"#if defined(USEREFLECTION)\n" +"#undef USESHADOWMAPORTHO\n" +"#endif\n" +"\n" +"#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE) || defined(USEFOGHEIGHTTEXTURE)\n" "# define USEFOG\n" "#endif\n" "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n" @@ -1768,6 +1848,10 @@ const char *builtincgshaderstring = "#define USEEYEVECTOR\n" "#endif\n" "\n" +"#ifdef FRAGMENT_SHADER\n" +"#define texDepth2D(tex,texcoord) tex2D(tex,texcoord).r\n" +"#endif\n" +"\n" "#ifdef MODE_DEPTH_OR_SHADOW\n" "#ifdef VERTEX_SHADER\n" "void main\n" @@ -2145,15 +2229,21 @@ const char *builtincgshaderstring = "#ifdef FRAGMENT_SHADER\n" "\n" "#ifdef USEFOG\n" -"float FogVertex(float3 EyeVectorModelSpace, float FogPlaneVertexDist, float FogRangeRecip, float FogPlaneViewDist, float FogHeightFade, sampler2D Texture_FogMask)\n" +"float3 FogVertex(float3 surfacecolor, float3 FogColor, float3 EyeVectorModelSpace, float FogPlaneVertexDist, float FogRangeRecip, float FogPlaneViewDist, float FogHeightFade, sampler2D Texture_FogMask, sampler2D Texture_FogHeightTexture)\n" "{\n" " float fogfrac;\n" -"#ifdef USEFOGOUTSIDE\n" -" fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n" +"#ifdef USEFOGHEIGHTTEXTURE\n" +" float4 fogheightpixel = tex2D(Texture_FogHeightTexture, float2(1,1) + float2(FogPlaneVertexDist, FogPlaneViewDist) * (-2.0 * FogHeightFade));\n" +" fogfrac = fogheightpixel.a;\n" +" return lerp(fogheightpixel.rgb * FogColor, surfacecolor, tex2D(Texture_FogMask, float2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n" "#else\n" +"# ifdef USEFOGOUTSIDE\n" +" fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n" +"# else\n" " fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n" +"# endif\n" +" return lerp(FogColor, surfacecolor, tex2D(Texture_FogMask, float2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n" "#endif\n" -" return float(tex2D(Texture_FogMask, half2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)));\n" "}\n" "#endif\n" "\n" @@ -2234,7 +2324,7 @@ const char *builtincgshaderstring = "float4 GetShadowMapTCCube(float3 dir, float4 ShadowMap_Parameters)\n" "{\n" " float3 adir = abs(dir);\n" -" return float4(dir, ShadowMap_Parameters.w + ShadowMap_Parameters.y / max(max(adir.x, adir.y), adir.z));\n" +" return float4(dir, ShadowMap_Parameters.z + ShadowMap_Parameters.w / max(max(adir.x, adir.y), adir.z));\n" "}\n" "#endif\n" "\n" @@ -2320,40 +2410,19 @@ const char *builtincgshaderstring = "# ifdef USESHADOWMAPPCF\n" "# if defined(GL_ARB_texture_gather) || defined(GL_AMD_texture_texture4)\n" "# ifdef GL_ARB_texture_gather\n" -"# define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, ivec2(x, y))\n" -"# else\n" -"# define texval(x, y) texture4(Texture_ShadowMap2D, center + float2(x, y)*ShadowMap_TextureScale)\n" -"# endif\n" -" float2 offset = frac(shadowmaptc.xy - 0.5), center = (shadowmaptc.xy - offset)*ShadowMap_TextureScale;\n" -"# if USESHADOWMAPPCF > 1\n" -" float4 group1 = step(shadowmaptc.z, texval(-2.0, -2.0));\n" -" float4 group2 = step(shadowmaptc.z, texval( 0.0, -2.0));\n" -" float4 group3 = step(shadowmaptc.z, texval( 2.0, -2.0));\n" -" float4 group4 = step(shadowmaptc.z, texval(-2.0, 0.0));\n" -" float4 group5 = step(shadowmaptc.z, texval( 0.0, 0.0));\n" -" float4 group6 = step(shadowmaptc.z, texval( 2.0, 0.0));\n" -" float4 group7 = step(shadowmaptc.z, texval(-2.0, 2.0));\n" -" float4 group8 = step(shadowmaptc.z, texval( 0.0, 2.0));\n" -" float4 group9 = step(shadowmaptc.z, texval( 2.0, 2.0));\n" -" float4 locols = float4(group1.ab, group3.ab);\n" -" float4 hicols = float4(group7.rg, group9.rg);\n" -" locols.yz += group2.ab;\n" -" hicols.yz += group8.rg;\n" -" float4 midcols = float4(group1.rg, group3.rg) + float4(group7.ab, group9.ab) +\n" -" float4(group4.rg, group6.rg) + float4(group4.ab, group6.ab) +\n" -" lerp(locols, hicols, offset.y);\n" -" float4 cols = group5 + float4(group2.rg, group8.ab);\n" -" cols.xyz += lerp(midcols.xyz, midcols.yzw, offset.x);\n" -" f = dot(cols, float4(1.0/25.0));\n" +"# define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, ivec(x, y))\n" "# else\n" -" float4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n" -" float4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n" -" float4 group3 = step(shadowmaptc.z, texval(-1.0, 1.0));\n" -" float4 group4 = step(shadowmaptc.z, texval( 1.0, 1.0));\n" -" float4 cols = float4(group1.rg, group2.rg) + float4(group3.ab, group4.ab) +\n" -" lerp(float4(group1.ab, group2.ab), float4(group3.rg, group4.rg), offset.y);\n" -" f = dot(lerp(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n" +"# define texval(x, y) texture4(Texture_ShadowMap2D, center + float2(x,y)*ShadowMap_TextureScale)\n" "# endif\n" +" float2 center = shadowmaptc.xy - 0.5, offset = frac(center);\n" +" center *= ShadowMap_TextureScale;\n" +" float4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n" +" float4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n" +" float4 group3 = step(shadowmaptc.z, texval(-1.0, 1.0));\n" +" float4 group4 = step(shadowmaptc.z, texval( 1.0, 1.0));\n" +" float4 cols = float4(group1.rg, group2.rg) + float4(group3.ab, group4.ab) +\n" +" lerp(float4(group1.ab, group2.ab), float4(group3.rg, group4.rg), offset.y);\n" +" f = dot(lerp(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n" "# else\n" "# define texval(x, y) texDepth2D(Texture_ShadowMap2D, center + float2(x, y)*ShadowMap_TextureScale) \n" "# if USESHADOWMAPPCF > 1\n" @@ -2553,6 +2622,10 @@ const char *builtincgshaderstring = "uniform sampler2D Texture_ScreenDepth,\n" "uniform sampler2D Texture_ScreenNormalMap,\n" "\n" +"#ifdef USECUBEFILTER\n" +"uniform samplerCUBE Texture_Cube,\n" +"#endif\n" +"\n" "#ifdef USESHADOWMAPRECT\n" "# ifdef USESHADOWSAMPLER\n" "uniform samplerRECTShadow Texture_ShadowMapRect,\n" @@ -2592,7 +2665,7 @@ const char *builtincgshaderstring = "{\n" " // calculate viewspace pixel position\n" " float2 ScreenTexCoord = Pixel * PixelToScreenTexCoord;\n" -" ScreenTexCoord.y = ScreenTexCoord.y * -1 + 1; // Cg is opposite?\n" +" //ScreenTexCoord.y = ScreenTexCoord.y * -1 + 1; // Cg is opposite?\n" " float3 position;\n" " position.z = ScreenToDepth.y / (texDepth2D(Texture_ScreenDepth, ScreenTexCoord) + ScreenToDepth.x);\n" " position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n" @@ -2713,10 +2786,10 @@ const char *builtincgshaderstring = "out float4 EyeVectorModelSpaceFogPlaneVertexDist : TEXCOORD4,\n" "#endif\n" "#if defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)\n" -"out float3 LightVector : TEXCOORD1,\n" +"out float3 LightVector : TEXCOORD5,\n" "#endif\n" "#ifdef MODE_LIGHTSOURCE\n" -"out float3 CubeVector : TEXCOORD3,\n" +"out float3 CubeVector : TEXCOORD6,\n" "#endif\n" "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY) || defined(USEREFLECTCUBE)\n" "out float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n" @@ -2724,7 +2797,7 @@ const char *builtincgshaderstring = "out float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n" "#endif\n" "#ifdef USESHADOWMAPORTHO\n" -"out float3 ShadowMapTC : TEXCOORD8,\n" +"out float3 ShadowMapTC : TEXCOORD3, // CONFLICTS WITH USEREFLECTION!\n" "#endif\n" "out float4 gl_Position : POSITION\n" ")\n" @@ -2776,7 +2849,7 @@ const char *builtincgshaderstring = " EyeVectorModelSpaceFogPlaneVertexDist.w = dot(FogPlane, gl_Vertex);\n" "#endif\n" "\n" -"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(USEREFLECTCUBE)\n" +"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n" " VectorS = gl_MultiTexCoord1.xyz;\n" " VectorT = gl_MultiTexCoord2.xyz;\n" " VectorR = gl_MultiTexCoord3.xyz;\n" @@ -2819,10 +2892,10 @@ const char *builtincgshaderstring = "float4 EyeVectorModelSpaceFogPlaneVertexDist : TEXCOORD4,\n" "#endif\n" "#if defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)\n" -"float3 LightVector : TEXCOORD1,\n" +"float3 LightVector : TEXCOORD5,\n" "#endif\n" "#ifdef MODE_LIGHTSOURCE\n" -"float3 CubeVector : TEXCOORD3,\n" +"float3 CubeVector : TEXCOORD6,\n" "#endif\n" "#ifdef MODE_DEFERREDLIGHTSOURCE\n" "float4 ModelViewPosition : TEXCOORD0,\n" @@ -2833,7 +2906,7 @@ const char *builtincgshaderstring = "float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n" "#endif\n" "#ifdef USESHADOWMAPORTHO\n" -"float3 ShadowMapTC : TEXCOORD8,\n" +"float3 ShadowMapTC : TEXCOORD3, // CONFLICTS WITH USEREFLECTION!\n" "#endif\n" "\n" "uniform sampler2D Texture_Normal,\n" @@ -2859,6 +2932,7 @@ const char *builtincgshaderstring = "uniform sampler2D Texture_Shirt,\n" "#endif\n" "#ifdef USEFOG\n" +"uniform sampler2D Texture_FogHeightTexture,\n" "uniform sampler2D Texture_FogMask,\n" "#endif\n" "#ifdef USELIGHTMAP\n" @@ -3168,11 +3242,7 @@ const char *builtincgshaderstring = "#endif\n" "\n" "#ifdef USEFOG\n" -"#ifdef MODE_LIGHTSOURCE\n" -" color.rgb *= half(FogVertex(EyeVectorModelSpaceFogPlaneVertexDist.xyz, EyeVectorModelSpaceFogPlaneVertexDist.w, FogRangeRecip, FogPlaneViewDist, FogHeightFade, Texture_FogMask));\n" -"#else\n" -" color.rgb = lerp(FogColor, float3(color.rgb), FogVertex(EyeVectorModelSpaceFogPlaneVertexDist.xyz, EyeVectorModelSpaceFogPlaneVertexDist.w, FogRangeRecip, FogPlaneViewDist, FogHeightFade, Texture_FogMask));\n" -"#endif\n" +" color.rgb = FogVertex(color.rgb, FogColor, EyeVectorModelSpaceFogPlaneVertexDist.xyz, EyeVectorModelSpaceFogPlaneVertexDist.w, FogRangeRecip, FogPlaneViewDist, FogHeightFade, Texture_FogMask, Texture_FogHeightTexture);\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" @@ -3240,29 +3310,30 @@ typedef enum shaderpermutation_e SHADERPERMUTATION_SATURATION = 1<<4, ///< saturation (postprocessing only) SHADERPERMUTATION_FOGINSIDE = 1<<5, ///< tint the color by fog color or black if using additive blend mode SHADERPERMUTATION_FOGOUTSIDE = 1<<6, ///< tint the color by fog color or black if using additive blend mode - SHADERPERMUTATION_GAMMARAMPS = 1<<7, ///< gamma (postprocessing only) - SHADERPERMUTATION_CUBEFILTER = 1<<8, ///< (lightsource) use cubemap light filter - SHADERPERMUTATION_GLOW = 1<<9, ///< (lightmap) blend in an additive glow texture - SHADERPERMUTATION_BLOOM = 1<<10, ///< bloom (postprocessing only) - SHADERPERMUTATION_SPECULAR = 1<<11, ///< (lightsource or deluxemapping) render specular effects - SHADERPERMUTATION_POSTPROCESSING = 1<<12, ///< user defined postprocessing (postprocessing only) - SHADERPERMUTATION_EXACTSPECULARMATH = 1<<13, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation - SHADERPERMUTATION_REFLECTION = 1<<14, ///< normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface - SHADERPERMUTATION_OFFSETMAPPING = 1<<15, ///< adjust texcoords to roughly simulate a displacement mapped surface - SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<16, ///< adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!) - SHADERPERMUTATION_SHADOWMAPRECT = 1<<17, ///< (lightsource) use shadowmap rectangle texture as light filter - SHADERPERMUTATION_SHADOWMAPCUBE = 1<<18, ///< (lightsource) use shadowmap cubemap texture as light filter - SHADERPERMUTATION_SHADOWMAP2D = 1<<19, ///< (lightsource) use shadowmap rectangle texture as light filter - SHADERPERMUTATION_SHADOWMAPPCF = 1<<20, ///< (lightsource) use percentage closer filtering on shadowmap test results - SHADERPERMUTATION_SHADOWMAPPCF2 = 1<<21, ///< (lightsource) use higher quality percentage closer filtering on shadowmap test results - SHADERPERMUTATION_SHADOWSAMPLER = 1<<22, ///< (lightsource) use hardware shadowmap test - SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<23, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing - SHADERPERMUTATION_SHADOWMAPORTHO = 1<<24, //< (lightsource) use orthographic shadowmap projection - SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<25, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping - SHADERPERMUTATION_ALPHAKILL = 1<<26, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5 - SHADERPERMUTATION_REFLECTCUBE = 1<<27, ///< fake reflections using global cubemap (not HDRI light probe) - SHADERPERMUTATION_LIMIT = 1<<28, ///< size of permutations array - SHADERPERMUTATION_COUNT = 28 ///< size of shaderpermutationinfo array + SHADERPERMUTATION_FOGHEIGHTTEXTURE = 1<<7, ///< fog color and density determined by texture mapped on vertical axis + SHADERPERMUTATION_GAMMARAMPS = 1<<8, ///< gamma (postprocessing only) + SHADERPERMUTATION_CUBEFILTER = 1<<9, ///< (lightsource) use cubemap light filter + SHADERPERMUTATION_GLOW = 1<<10, ///< (lightmap) blend in an additive glow texture + SHADERPERMUTATION_BLOOM = 1<<11, ///< bloom (postprocessing only) + SHADERPERMUTATION_SPECULAR = 1<<12, ///< (lightsource or deluxemapping) render specular effects + SHADERPERMUTATION_POSTPROCESSING = 1<<13, ///< user defined postprocessing (postprocessing only) + SHADERPERMUTATION_EXACTSPECULARMATH = 1<<14, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation + SHADERPERMUTATION_REFLECTION = 1<<15, ///< normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface + SHADERPERMUTATION_OFFSETMAPPING = 1<<16, ///< adjust texcoords to roughly simulate a displacement mapped surface + SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<17, ///< adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!) + SHADERPERMUTATION_SHADOWMAPRECT = 1<<18, ///< (lightsource) use shadowmap rectangle texture as light filter + SHADERPERMUTATION_SHADOWMAPCUBE = 1<<19, ///< (lightsource) use shadowmap cubemap texture as light filter + SHADERPERMUTATION_SHADOWMAP2D = 1<<20, ///< (lightsource) use shadowmap rectangle texture as light filter + SHADERPERMUTATION_SHADOWMAPPCF = 1<<21, ///< (lightsource) use percentage closer filtering on shadowmap test results + SHADERPERMUTATION_SHADOWMAPPCF2 = 1<<22, ///< (lightsource) use higher quality percentage closer filtering on shadowmap test results + SHADERPERMUTATION_SHADOWSAMPLER = 1<<23, ///< (lightsource) use hardware shadowmap test + SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<24, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing + SHADERPERMUTATION_SHADOWMAPORTHO = 1<<25, //< (lightsource) use orthographic shadowmap projection + SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<26, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping + SHADERPERMUTATION_ALPHAKILL = 1<<27, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5 + SHADERPERMUTATION_REFLECTCUBE = 1<<28, ///< fake reflections using global cubemap (not HDRI light probe) + SHADERPERMUTATION_LIMIT = 1<<29, ///< size of permutations array + SHADERPERMUTATION_COUNT = 29 ///< size of shaderpermutationinfo array } shaderpermutation_t; @@ -3276,6 +3347,7 @@ shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] = {"#define USESATURATION\n", " saturation"}, {"#define USEFOGINSIDE\n", " foginside"}, {"#define USEFOGOUTSIDE\n", " fogoutside"}, + {"#define USEFOGHEIGHTTEXTURE\n", " fogheighttexture"}, {"#define USEGAMMARAMPS\n", " gammaramps"}, {"#define USECUBEFILTER\n", " cubefilter"}, {"#define USEGLOW\n", " glow"}, @@ -3388,6 +3460,7 @@ typedef struct r_glsl_permutation_s int loc_Texture_SecondaryGlow; int loc_Texture_Pants; int loc_Texture_Shirt; + int loc_Texture_FogHeightTexture; int loc_Texture_FogMask; int loc_Texture_Lightmap; int loc_Texture_Deluxemap; @@ -3614,6 +3687,7 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode p->loc_Texture_SecondaryGlow = qglGetUniformLocationARB(p->program, "Texture_SecondaryGlow"); p->loc_Texture_Pants = qglGetUniformLocationARB(p->program, "Texture_Pants"); p->loc_Texture_Shirt = qglGetUniformLocationARB(p->program, "Texture_Shirt"); + p->loc_Texture_FogHeightTexture = qglGetUniformLocationARB(p->program, "Texture_FogHeightTexture"); p->loc_Texture_FogMask = qglGetUniformLocationARB(p->program, "Texture_FogMask"); p->loc_Texture_Lightmap = qglGetUniformLocationARB(p->program, "Texture_Lightmap"); p->loc_Texture_Deluxemap = qglGetUniformLocationARB(p->program, "Texture_Deluxemap"); @@ -3696,6 +3770,7 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode if (p->loc_Texture_SecondaryGlow >= 0) qglUniform1iARB(p->loc_Texture_SecondaryGlow , GL20TU_SECONDARY_GLOW); if (p->loc_Texture_Pants >= 0) qglUniform1iARB(p->loc_Texture_Pants , GL20TU_PANTS); if (p->loc_Texture_Shirt >= 0) qglUniform1iARB(p->loc_Texture_Shirt , GL20TU_SHIRT); + if (p->loc_Texture_FogHeightTexture>= 0) qglUniform1iARB(p->loc_Texture_FogHeightTexture, GL20TU_FOGHEIGHTTEXTURE); if (p->loc_Texture_FogMask >= 0) qglUniform1iARB(p->loc_Texture_FogMask , GL20TU_FOGMASK); if (p->loc_Texture_Lightmap >= 0) qglUniform1iARB(p->loc_Texture_Lightmap , GL20TU_LIGHTMAP); if (p->loc_Texture_Deluxemap >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap , GL20TU_DELUXEMAP); @@ -3812,6 +3887,7 @@ typedef struct r_cg_permutation_s CGparameter fp_Texture_SecondaryGlow; CGparameter fp_Texture_Pants; CGparameter fp_Texture_Shirt; + CGparameter fp_Texture_FogHeightTexture; CGparameter fp_Texture_FogMask; CGparameter fp_Texture_Lightmap; CGparameter fp_Texture_Deluxemap; @@ -4110,6 +4186,7 @@ static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, un p->fp_Texture_SecondaryGlow = cgGetNamedParameter(p->fprogram, "Texture_SecondaryGlow"); p->fp_Texture_Pants = cgGetNamedParameter(p->fprogram, "Texture_Pants"); p->fp_Texture_Shirt = cgGetNamedParameter(p->fprogram, "Texture_Shirt"); + p->fp_Texture_FogHeightTexture = cgGetNamedParameter(p->fprogram, "Texture_FogHeightTexture"); p->fp_Texture_FogMask = cgGetNamedParameter(p->fprogram, "Texture_FogMask"); p->fp_Texture_Lightmap = cgGetNamedParameter(p->fprogram, "Texture_Lightmap"); p->fp_Texture_Deluxemap = cgGetNamedParameter(p->fprogram, "Texture_Deluxemap"); @@ -4566,7 +4643,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_EXACTSPECULARMATH; } if (r_refdef.fogenabled) - permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE; + permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); if (rsurface.texture->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; if (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d || r_shadow_usingshadowmapcube) @@ -4633,7 +4710,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) permutation |= SHADERPERMUTATION_GLOW; if (r_refdef.fogenabled) - permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE; + permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); if (rsurface.texture->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)) @@ -4705,7 +4782,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_EXACTSPECULARMATH; } if (r_refdef.fogenabled) - permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE; + permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); if (rsurface.texture->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)) @@ -4769,7 +4846,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) permutation |= SHADERPERMUTATION_GLOW; if (r_refdef.fogenabled) - permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE; + permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); if (rsurface.texture->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)) @@ -4832,7 +4909,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) permutation |= SHADERPERMUTATION_GLOW; if (r_refdef.fogenabled) - permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE; + permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); if (rsurface.texture->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)) @@ -5032,6 +5109,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_glsl_permutation->loc_Texture_Shirt >= 0) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture ); if (r_glsl_permutation->loc_Texture_ReflectMask >= 0) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture ); if (r_glsl_permutation->loc_Texture_ReflectCube >= 0) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube); + if (r_glsl_permutation->loc_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture ); if (r_glsl_permutation->loc_Texture_FogMask >= 0) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation ); if (r_glsl_permutation->loc_Texture_Lightmap >= 0) R_Mesh_TexBind(GL20TU_LIGHTMAP , r_texture_white ); if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) R_Mesh_TexBind(GL20TU_LIGHTMAP , r_texture_blanknormalmap ); @@ -5177,6 +5255,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_cg_permutation->fp_Texture_Shirt ) CG_BindTexture(r_cg_permutation->fp_Texture_Shirt , rsurface.texture->shirttexture );CHECKCGERROR if (r_cg_permutation->fp_Texture_ReflectMask ) CG_BindTexture(r_cg_permutation->fp_Texture_ReflectMask , rsurface.texture->reflectmasktexture );CHECKCGERROR if (r_cg_permutation->fp_Texture_ReflectCube ) CG_BindTexture(r_cg_permutation->fp_Texture_ReflectCube , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);CHECKCGERROR + if (r_cg_permutation->fp_Texture_FogHeightTexture) CG_BindTexture(r_cg_permutation->fp_Texture_FogHeightTexture, r_texture_fogheighttexture );CHECKCGERROR if (r_cg_permutation->fp_Texture_FogMask ) CG_BindTexture(r_cg_permutation->fp_Texture_FogMask , r_texture_fogattenuation );CHECKCGERROR if (r_cg_permutation->fp_Texture_Lightmap ) CG_BindTexture(r_cg_permutation->fp_Texture_Lightmap , r_texture_white );CHECKCGERROR if (r_cg_permutation->fp_Texture_Deluxemap ) CG_BindTexture(r_cg_permutation->fp_Texture_Deluxemap , r_texture_blanknormalmap );CHECKCGERROR @@ -6131,6 +6210,7 @@ void gl_main_start(void) r_texture_whitecube = NULL; r_texture_normalizationcube = NULL; r_texture_fogattenuation = NULL; + r_texture_fogheighttexture = NULL; r_texture_gammaramps = NULL; r_texture_numcubemaps = 0; @@ -6190,6 +6270,7 @@ void gl_main_start(void) R_BuildNormalizationCube(); } r_texture_fogattenuation = NULL; + r_texture_fogheighttexture = NULL; r_texture_gammaramps = NULL; //r_texture_fogintensity = NULL; memset(&r_bloomstate, 0, sizeof(r_bloomstate)); @@ -6242,6 +6323,7 @@ void gl_main_shutdown(void) r_texture_whitecube = NULL; r_texture_normalizationcube = NULL; r_texture_fogattenuation = NULL; + r_texture_fogheighttexture = NULL; r_texture_gammaramps = NULL; r_texture_numcubemaps = 0; //r_texture_fogintensity = NULL; @@ -8224,10 +8306,14 @@ void R_UpdateVariables(void) 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; + if (strcmp(r_refdef.fogheighttexturename, r_refdef.fog_height_texturename)) + R_BuildFogHeightTexture(); // 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(); + r_refdef.fog_height_texcoordscale = 1.0f / max(0.125f, r_refdef.fog_fadedepth); + r_refdef.fog_height_tablescale = r_refdef.fog_height_tablesize * r_refdef.fog_height_texcoordscale; } else r_refdef.fogenabled = false; @@ -10382,9 +10468,9 @@ static void RSurf_BindReflectionForSurface(const msurface_t *surface) { case RENDERPATH_CGGL: #ifdef SUPPORTCG - if (r_cg_permutation->fp_Texture_Refraction) CG_BindTexture(r_cg_permutation->fp_Texture_Refraction, bestp ? bestp->texture_refraction : r_texture_black);CHECKCGERROR - else if (r_cg_permutation->fp_Texture_First) CG_BindTexture(r_cg_permutation->fp_Texture_First, bestp ? bestp->texture_camera : r_texture_black);CHECKCGERROR - if (r_cg_permutation->fp_Texture_Reflection) CG_BindTexture(r_cg_permutation->fp_Texture_Reflection, bestp ? bestp->texture_reflection : r_texture_black);CHECKCGERROR + if (r_cg_permutation->fp_Texture_Refraction) {CG_BindTexture(r_cg_permutation->fp_Texture_Refraction, bestp ? bestp->texture_refraction : r_texture_black);CHECKCGERROR} + else if (r_cg_permutation->fp_Texture_First) {CG_BindTexture(r_cg_permutation->fp_Texture_First, bestp ? bestp->texture_camera : r_texture_black);CHECKCGERROR} + if (r_cg_permutation->fp_Texture_Reflection) {CG_BindTexture(r_cg_permutation->fp_Texture_Reflection, bestp ? bestp->texture_reflection : r_texture_black);CHECKCGERROR} #endif break; case RENDERPATH_GL20: diff --git a/mathlib.h b/mathlib.h index 52c71113..64139365 100644 --- a/mathlib.h +++ b/mathlib.h @@ -92,6 +92,10 @@ unsigned int CeilPowerOf2(unsigned int value); #define Vector4Negate(a,b) ((b)[0]=-((a)[0]),(b)[1]=-((a)[1]),(b)[2]=-((a)[2]),(b)[3]=-((a)[3])) #define Vector4Set(a,b,c,d,e) ((a)[0]=(b),(a)[1]=(c),(a)[2]=(d),(a)[3]=(e)) #define Vector4Normalize2(v,dest) {float ilength = (float) sqrt(DotProduct4((v),(v)));if (ilength) ilength = 1.0f / ilength;dest[0] = (v)[0] * ilength;dest[1] = (v)[1] * ilength;dest[2] = (v)[2] * ilength;dest[3] = (v)[3] * ilength;} +#define Vector4Subtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2],(c)[3]=(a)[3]-(b)[3]) +#define Vector4Add(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2],(c)[3]=(a)[3]+(b)[3]) +#define Vector4Multiply(a,b,c) ((c)[0]=(a)[0]*(b)[0],(c)[1]=(a)[1]*(b)[1],(c)[2]=(a)[2]*(b)[2],(c)[3]=(a)[3]*(b)[3]) +#define Vector4MA(a, scale, b, c) ((c)[0] = (a)[0] + (scale) * (b)[0],(c)[1] = (a)[1] + (scale) * (b)[1],(c)[2] = (a)[2] + (scale) * (b)[2],(c)[3] = (a)[3] + (scale) * (b)[3]) #define VectorNegate(a,b) ((b)[0]=-((a)[0]),(b)[1]=-((a)[1]),(b)[2]=-((a)[2])) #define VectorSet(a,b,c,d) ((a)[0]=(b),(a)[1]=(c),(a)[2]=(d)) diff --git a/r_shadow.c b/r_shadow.c index 8a23ca0e..e4f4c101 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -373,7 +373,7 @@ skinframe_t *r_editlights_sprselection; void R_Shadow_SetShadowMode(void) { r_shadow_shadowmapmaxsize = bound(1, r_shadow_shadowmapping_maxsize.integer, (int)vid.maxtexturesize_2d / 4); - r_shadow_shadowmapvsdct = r_shadow_shadowmapping_vsdct.integer != 0; + r_shadow_shadowmapvsdct = r_shadow_shadowmapping_vsdct.integer && !vid.cgcontext; r_shadow_shadowmapfilterquality = r_shadow_shadowmapping_filterquality.integer; r_shadow_shadowmaptexturetype = r_shadow_shadowmapping_texturetype.integer; r_shadow_shadowmapdepthbits = r_shadow_shadowmapping_depthbits.integer; @@ -442,6 +442,12 @@ void R_Shadow_SetShadowMode(void) r_shadow_shadowmode = R_SHADOW_SHADOWMODE_SHADOWMAP2D; break; } + // Cg has very little choice in depth texture sampling + if (vid.cgcontext) + { + r_shadow_shadowmapsampler = true; + r_shadow_shadowmode = R_SHADOW_SHADOWMODE_SHADOWMAP2D; + } } break; case RENDERPATH_GL13: @@ -4069,7 +4075,7 @@ void R_Shadow_PrepareLights(void) if (r_shadow_shadowmapmaxsize != bound(1, r_shadow_shadowmapping_maxsize.integer, (int)vid.maxtexturesize_2d / 4) || (r_shadow_shadowmode != R_SHADOW_SHADOWMODE_STENCIL) != (r_shadow_shadowmapping.integer || r_shadow_deferred.integer) || - r_shadow_shadowmapvsdct != (r_shadow_shadowmapping_vsdct.integer != 0) || + r_shadow_shadowmapvsdct != (r_shadow_shadowmapping_vsdct.integer && !vid.cgcontext) || r_shadow_shadowmaptexturetype != r_shadow_shadowmapping_texturetype.integer || r_shadow_shadowmapfilterquality != r_shadow_shadowmapping_filterquality.integer || r_shadow_shadowmapdepthbits != r_shadow_shadowmapping_depthbits.integer || diff --git a/render.h b/render.h index aa84b231..a6bc2079 100644 --- a/render.h +++ b/render.h @@ -211,7 +211,7 @@ extern rtexture_t *r_texture_notexture; extern rtexture_t *r_texture_whitecube; extern rtexture_t *r_texture_normalizationcube; extern rtexture_t *r_texture_fogattenuation; -//extern rtexture_t *r_texture_fogintensity; +extern rtexture_t *r_texture_fogheighttexture; extern unsigned int r_queries[MAX_OCCLUSION_QUERIES]; extern unsigned int r_numqueries; @@ -463,7 +463,8 @@ typedef enum gl20_texunit_e GL20TU_SCREENSPECULAR = 12, // fake reflections GL20TU_REFLECTMASK = 5, - GL20TU_REFLECTCUBE = 6 + GL20TU_REFLECTCUBE = 6, + GL20TU_FOGHEIGHTTEXTURE = 14 } gl20_texunit; -- 2.39.2