X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=gl_rmain.c;h=7d5d2594eb5a935f8bde6b06b8c56d3e1faab2d9;hb=04ebd98618c773b10ada031f18b99f11020b559f;hp=637e2b1660331a3481b042757752b57de770757f;hpb=54b3bad79b60edd1c2b1be6c06c2dcc790274840;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index 637e2b16..7d5d2594 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -112,6 +112,12 @@ cvar_t gl_skyclip = {0, "gl_skyclip", "4608", "nehahra farclip distance - the re cvar_t r_texture_dds_load = {CVAR_SAVE, "r_texture_dds_load", "0", "load compressed dds/filename.dds texture instead of filename.tga, if the file exists (requires driver support)"}; cvar_t r_texture_dds_save = {CVAR_SAVE, "r_texture_dds_save", "0", "save compressed dds/filename.dds texture when filename.tga is loaded, so that it can be loaded instead next time"}; +cvar_t r_texture_convertsRGB_2d = {0, "r_texture_convertsRGB_2d", "0", "load textures as sRGB and convert to linear for proper shading"}; +cvar_t r_texture_convertsRGB_skin = {0, "r_texture_convertsRGB_skin", "0", "load textures as sRGB and convert to linear for proper shading"}; +cvar_t r_texture_convertsRGB_cubemap = {0, "r_texture_convertsRGB_cubemap", "0", "load textures as sRGB and convert to linear for proper shading"}; +cvar_t r_texture_convertsRGB_skybox = {0, "r_texture_convertsRGB_skybox", "0", "load textures as sRGB and convert to linear for proper shading"}; +cvar_t r_texture_convertsRGB_particles = {0, "r_texture_convertsRGB_particles", "0", "load textures as sRGB and convert to linear for proper shading"}; + cvar_t r_textureunits = {0, "r_textureunits", "32", "number of texture units to use in GL 1.1 and GL 1.3 rendering paths"}; static cvar_t gl_combine = {CVAR_READONLY, "gl_combine", "1", "indicates whether the OpenGL 1.3 rendering path is active"}; static cvar_t r_glsl = {CVAR_READONLY, "r_glsl", "1", "indicates whether the OpenGL 2.0 rendering path is active"}; @@ -162,6 +168,9 @@ cvar_t r_track_sprites = {CVAR_SAVE, "r_track_sprites", "1", "track SPR_LABEL* s cvar_t r_track_sprites_flags = {CVAR_SAVE, "r_track_sprites_flags", "1", "1: Rotate sprites accodringly, 2: Make it a continuous rotation"}; cvar_t r_track_sprites_scalew = {CVAR_SAVE, "r_track_sprites_scalew", "1", "width scaling of tracked sprites"}; cvar_t r_track_sprites_scaleh = {CVAR_SAVE, "r_track_sprites_scaleh", "1", "height scaling of tracked sprites"}; +cvar_t r_overheadsprites_perspective = {CVAR_SAVE, "r_overheadsprites_perspective", "0.15", "fake perspective effect for SPR_OVERHEAD sprites"}; +cvar_t r_overheadsprites_pushback = {CVAR_SAVE, "r_overheadsprites_pushback", "16", "how far to pull the SPR_OVERHEAD sprites toward the eye (used to avoid intersections with 3D models)"}; + cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"}; cvar_t r_framedatasize = {CVAR_SAVE, "r_framedatasize", "1", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"}; @@ -208,6 +217,18 @@ rtexture_t *r_texture_fogattenuation; rtexture_t *r_texture_gammaramps; unsigned int r_texture_gammaramps_serial; //rtexture_t *r_texture_fogintensity; +rtexture_t *r_texture_reflectcube; + +// TODO: hash lookups? +typedef struct cubemapinfo_s +{ + char basename[64]; + rtexture_t *texture; +} +cubemapinfo_t; + +int r_texture_numcubemaps; +cubemapinfo_t r_texture_cubemaps[MAX_CUBEMAPS]; unsigned int r_queries[MAX_OCCLUSION_QUERIES]; unsigned int r_numqueries; @@ -474,7 +495,7 @@ static const char *builtinshaderstring = "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n" "#define USELIGHTMAP\n" "#endif\n" -"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING)\n" +"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE)\n" "#define USEEYEVECTOR\n" "#endif\n" "\n" @@ -801,6 +822,7 @@ static const char *builtinshaderstring = " vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n" " //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n" " vec4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n" +" //SafeScreenTexCoord = gl_FragCoord.xyxy * vec4(1.0 / 1920.0, 1.0 / 1200.0, 1.0 / 1920.0, 1.0 / 1200.0);\n" " vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xyxy * DistortScaleRefractReflect;\n" " // FIXME temporary hack to detect the case that the reflection\n" " // gets blackened at edges due to leaving the area that contains actual\n" @@ -851,7 +873,7 @@ static const char *builtinshaderstring = "varying vec4 EyeVectorModelSpaceFogPlaneVertexDist;\n" "#endif\n" "\n" -"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY)\n" +"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY) || defined(USEREFLECTCUBE)\n" "varying vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n" "varying vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n" "varying vec3 VectorR; // direction of R texcoord (surface normal)\n" @@ -885,18 +907,14 @@ static const char *builtinshaderstring = "\n" "uniform sampler2D Texture_Normal;\n" "uniform sampler2D Texture_Color;\n" -"//#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n" "uniform sampler2D Texture_Gloss;\n" -"//#endif\n" "#ifdef USEGLOW\n" "uniform sampler2D Texture_Glow;\n" "#endif\n" "#ifdef USEVERTEXTEXTUREBLEND\n" "uniform sampler2D Texture_SecondaryNormal;\n" "uniform sampler2D Texture_SecondaryColor;\n" -"//#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n" "uniform sampler2D Texture_SecondaryGloss;\n" -"//#endif\n" "#ifdef USEGLOW\n" "uniform sampler2D Texture_SecondaryGlow;\n" "#endif\n" @@ -1278,11 +1296,13 @@ static const char *builtinshaderstring = "\n" "#ifdef USEVERTEXTEXTUREBLEND\n" " vec3 surfacenormal = mix(vec3(texture2D(Texture_SecondaryNormal, TexCoord2)), vec3(texture2D(Texture_Normal, TexCoord)), terrainblend) - vec3(0.5, 0.5, 0.5);\n" +" float a = mix(texture2D(Texture_SecondaryGloss, TexCoord2).a, texture2D(Texture_Gloss, TexCoord).a, terrainblend);\n" "#else\n" " vec3 surfacenormal = vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5, 0.5, 0.5);\n" +" float a = texture2D(Texture_Gloss, TexCoord).a;\n" "#endif\n" "\n" -" gl_FragColor = vec4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + vec3(0.5, 0.5, 0.5), 1);\n" +" gl_FragColor = vec4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + vec3(0.5, 0.5, 0.5), a);\n" "}\n" "#endif // FRAGMENT_SHADER\n" "#else // !MODE_DEFERREDGEOMETRY\n" @@ -1336,10 +1356,10 @@ static const char *builtinshaderstring = " // calculate directional shading\n" " vec3 eyevector = position * -1.0;\n" "# ifdef USEEXACTSPECULARMATH\n" -" myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower);\n" +" myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower * normalmap.a);\n" "# else\n" " myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(eyevector)));\n" -" myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" +" myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * normalmap.a);\n" "# endif\n" "#endif\n" "\n" @@ -1427,7 +1447,7 @@ static const char *builtinshaderstring = " EyeVectorModelSpaceFogPlaneVertexDist.w = dot(FogPlane, gl_Vertex);\n" "#endif\n" "\n" -"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n" +"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(USEREFLECTCUBE)\n" " VectorS = gl_MultiTexCoord1.xyz;\n" " VectorT = gl_MultiTexCoord2.xyz;\n" " VectorR = gl_MultiTexCoord3.xyz;\n" @@ -1465,6 +1485,11 @@ static const char *builtinshaderstring = "uniform vec4 ScreenCenterRefractReflect;\n" "uniform myhalf4 ReflectColor;\n" "#endif\n" +"#ifdef USEREFLECTCUBE\n" +"uniform mat4 ModelToReflectCube;\n" +"uniform sampler2D Texture_ReflectMask;\n" +"uniform samplerCube Texture_ReflectCube;\n" +"#endif\n" "#ifdef MODE_LIGHTDIRECTION\n" "uniform myhalf3 LightColor;\n" "#endif\n" @@ -1509,12 +1534,19 @@ static const char *builtinshaderstring = " myhalf3 diffusetex = color.rgb;\n" "#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n" "# ifdef USEVERTEXTEXTUREBLEND\n" -" myhalf3 glosstex = mix(myhalf3(texture2D(Texture_SecondaryGloss, TexCoord2)), myhalf3(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n" +" myhalf4 glosstex = mix(myhalf4(texture2D(Texture_SecondaryGloss, TexCoord2)), myhalf4(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n" "# else\n" -" myhalf3 glosstex = myhalf3(texture2D(Texture_Gloss, TexCoord));\n" +" myhalf4 glosstex = myhalf4(texture2D(Texture_Gloss, TexCoord));\n" "# endif\n" "#endif\n" "\n" +"#ifdef USEREFLECTCUBE\n" +" vec3 TangentReflectVector = reflect(-EyeVector, surfacenormal);\n" +" vec3 ModelReflectVector = TangentReflectVector.x * VectorS + TangentReflectVector.y * VectorT + TangentReflectVector.z * VectorR;\n" +" vec3 ReflectCubeTexCoord = vec3(ModelToReflectCube * vec4(ModelReflectVector, 0));\n" +" diffusetex += myhalf3(texture2D(Texture_ReflectMask, TexCoord)) * myhalf3(textureCube(Texture_ReflectCube, ReflectCubeTexCoord));\n" +"#endif\n" +"\n" "\n" "\n" "\n" @@ -1526,12 +1558,12 @@ static const char *builtinshaderstring = " color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n" "#ifdef USESPECULAR\n" "#ifdef USEEXACTSPECULARMATH\n" -" myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n" +" myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a);\n" "#else\n" " myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(EyeVector)));\n" -" myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" +" myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a);\n" "#endif\n" -" color.rgb += glosstex * (specular * Color_Specular);\n" +" color.rgb += glosstex.rgb * (specular * Color_Specular);\n" "#endif\n" "#else\n" " color.rgb = diffusetex * Color_Ambient;\n" @@ -1605,12 +1637,12 @@ static const char *builtinshaderstring = " myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n" "# ifdef USESPECULAR\n" "# ifdef USEEXACTSPECULARMATH\n" -" myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n" +" myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a);\n" "# else\n" " myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(EyeVector)));\n" -" myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" +" myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a);\n" "# endif\n" -" color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex * Color_Specular * specular) * lightcolor;\n" +" color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex.rgb * Color_Specular * specular) * lightcolor;\n" "# else\n" " color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n" "# endif\n" @@ -1622,7 +1654,7 @@ static const char *builtinshaderstring = "#ifdef USEDEFERREDLIGHTMAP\n" " vec2 ScreenTexCoord = gl_FragCoord.xy * PixelToScreenTexCoord;\n" " color.rgb += diffusetex * myhalf3(texture2D(Texture_ScreenDiffuse, ScreenTexCoord)) * DeferredMod_Diffuse;\n" -" color.rgb += glosstex * myhalf3(texture2D(Texture_ScreenSpecular, ScreenTexCoord)) * DeferredMod_Specular;\n" +" color.rgb += glosstex.rgb * myhalf3(texture2D(Texture_ScreenSpecular, ScreenTexCoord)) * DeferredMod_Specular;\n" "#endif\n" "\n" "#ifdef USEGLOW\n" @@ -1714,7 +1746,7 @@ const char *builtincgshaderstring = "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n" "#define USELIGHTMAP\n" "#endif\n" -"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING)\n" +"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE)\n" "#define USEEYEVECTOR\n" "#endif\n" "\n" @@ -2423,8 +2455,10 @@ const char *builtincgshaderstring = "#ifdef USEALPHAKILL\n" "uniform sampler2D Texture_Color,\n" "#endif\n" +"uniform sampler2D Texture_Gloss,\n" "#ifdef USEVERTEXTEXTUREBLEND\n" "uniform sampler2D Texture_SecondaryNormal,\n" +"uniform sampler2D Texture_SecondaryGloss,\n" "#endif\n" "#ifdef USEOFFSETMAPPING\n" "uniform float OffsetMapping_Scale,\n" @@ -2454,8 +2488,10 @@ const char *builtincgshaderstring = "\n" "#ifdef USEVERTEXTEXTUREBLEND\n" " float3 surfacenormal = lerp(float3(tex2D(Texture_SecondaryNormal, TexCoord2)), float3(tex2D(Texture_Normal, TexCoord)), terrainblend) - float3(0.5, 0.5, 0.5);\n" +" float a = lerp(tex2D(Texture_SecondaryGloss, TexCoord2), tex2D(Texture_Gloss, TexCoord).a, terrainblend);\n" "#else\n" " float3 surfacenormal = float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5, 0.5, 0.5);\n" +" float a = tex2D(Texture_Gloss, TexCoord).a;\n" "#endif\n" "\n" " gl_FragColor = float4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + float3(0.5, 0.5, 0.5), 1);\n" @@ -2562,10 +2598,10 @@ const char *builtincgshaderstring = " // calculate directional shading\n" " float3 eyevector = position * -1.0;\n" "# ifdef USEEXACTSPECULARMATH\n" -" half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower);\n" +" half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower * normalmap.a);\n" "# else\n" " half3 specularnormal = normalize(lightnormal + half3(normalize(eyevector)));\n" -" half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" +" half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * normalmap.a);\n" "# endif\n" "#endif\n" "\n" @@ -2663,7 +2699,7 @@ const char *builtincgshaderstring = "#ifdef MODE_LIGHTSOURCE\n" "out float3 CubeVector : TEXCOORD3,\n" "#endif\n" -"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY)\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" "out float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n" "out float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n" @@ -2765,7 +2801,7 @@ const char *builtincgshaderstring = "#ifdef MODE_DEFERREDLIGHTSOURCE\n" "float4 ModelViewPosition : TEXCOORD0,\n" "#endif\n" -"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY)\n" +"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY) || defined(USEREFLECTCUBE)\n" "float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n" "float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n" "float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n" @@ -2849,6 +2885,11 @@ const char *builtincgshaderstring = "uniform float4 ScreenCenterRefractReflect,\n" "uniform half4 ReflectColor,\n" "#endif\n" +"#ifdef USEREFLECTCUBE\n" +"uniform float4x4 ModelToReflectCube,\n" +"uniform sampler2D Texture_ReflectMask,\n" +"uniform samplerCUBE Texture_ReflectCube,\n" +"#endif\n" "#ifdef MODE_LIGHTDIRECTION\n" "uniform half3 LightColor,\n" "#endif\n" @@ -2937,12 +2978,19 @@ const char *builtincgshaderstring = " half3 diffusetex = color.rgb;\n" "#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n" "# ifdef USEVERTEXTEXTUREBLEND\n" -" half3 glosstex = half3(lerp(float3(tex2D(Texture_SecondaryGloss, TexCoord2)), float3(tex2D(Texture_Gloss, TexCoord)), terrainblend));\n" +" half4 glosstex = half4(lerp(float4(tex2D(Texture_SecondaryGloss, TexCoord2)), float4(tex2D(Texture_Gloss, TexCoord)), terrainblend));\n" "# else\n" -" half3 glosstex = half3(tex2D(Texture_Gloss, TexCoord));\n" +" half4 glosstex = half4(tex2D(Texture_Gloss, TexCoord));\n" "# endif\n" "#endif\n" "\n" +"#ifdef USEREFLECTCUBE\n" +" vec3 TangentReflectVector = reflect(-EyeVector, surfacenormal);\n" +" vec3 ModelReflectVector = TangentReflectVector.x * VectorS + TangentReflectVector.y * VectorT + TangentReflectVector.z * VectorR;\n" +" vec3 ReflectCubeTexCoord = float3(mul(ModelToReflectCube, float4(ModelReflectVector, 0)));\n" +" diffusetex += half3(tex2D(Texture_ReflectMask, TexCoord)) * half3(texCUBE(Texture_ReflectCube, ReflectCubeTexCoord));\n" +"#endif\n" +"\n" "\n" "\n" "\n" @@ -2954,12 +3002,12 @@ const char *builtincgshaderstring = " color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n" "#ifdef USESPECULAR\n" "#ifdef USEEXACTSPECULARMATH\n" -" half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n" +" half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a);\n" "#else\n" " half3 specularnormal = normalize(lightnormal + half3(normalize(EyeVector)));\n" -" half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" +" half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a);\n" "#endif\n" -" color.rgb += glosstex * (specular * Color_Specular);\n" +" color.rgb += glosstex.rgb * (specular * Color_Specular);\n" "#endif\n" "#else\n" " color.rgb = diffusetex * Color_Ambient;\n" @@ -3048,12 +3096,12 @@ const char *builtincgshaderstring = " half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n" "# ifdef USESPECULAR\n" "# ifdef USEEXACTSPECULARMATH\n" -" half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n" +" half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a);\n" "# else\n" " half3 specularnormal = normalize(lightnormal + half3(normalize(EyeVector)));\n" -" half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" +" half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a);\n" "# endif\n" -" color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex * Color_Specular * specular) * lightcolor;\n" +" color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex.rgb * Color_Specular * specular) * lightcolor;\n" "# else\n" " color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n" "# endif\n" @@ -3065,7 +3113,7 @@ const char *builtincgshaderstring = "#ifdef USEDEFERREDLIGHTMAP\n" " float2 ScreenTexCoord = Pixel * PixelToScreenTexCoord;\n" " color.rgb += diffusetex * half3(tex2D(Texture_ScreenDiffuse, ScreenTexCoord)) * DeferredMod_Diffuse;\n" -" color.rgb += glosstex * half3(tex2D(Texture_ScreenSpecular, ScreenTexCoord)) * DeferredMod_Specular;\n" +" color.rgb += glosstex.rgb * half3(tex2D(Texture_ScreenSpecular, ScreenTexCoord)) * DeferredMod_Specular;\n" "#endif\n" "\n" "#ifdef USEGLOW\n" @@ -3118,6 +3166,9 @@ const char *builtincgshaderstring = "#endif // !MODE_DEPTH_OR_SHADOW\n" ; +char *glslshaderstring = NULL; +char *cgshaderstring = NULL; + //======================================================================================================================================================= typedef struct shaderpermutationinfo_s @@ -3165,8 +3216,9 @@ typedef enum shaderpermutation_e SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<23, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<24, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping SHADERPERMUTATION_ALPHAKILL = 1<<25, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5 - SHADERPERMUTATION_LIMIT = 1<<26, ///< size of permutations array - SHADERPERMUTATION_COUNT = 26 ///< size of shaderpermutationinfo array + SHADERPERMUTATION_REFLECTCUBE = 1<<26, ///< fake reflections using global cubemap (not HDRI light probe) + SHADERPERMUTATION_LIMIT = 1<<27, ///< size of permutations array + SHADERPERMUTATION_COUNT = 27 ///< size of shaderpermutationinfo array } shaderpermutation_t; @@ -3199,6 +3251,7 @@ shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] = {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"}, {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"}, {"#define USEALPHAKILL\n", " alphakill"}, + {"#define USEREFLECTCUBE\n", " reflectcube"}, }; /// this enum is multiplied by SHADERPERMUTATION_MODEBASE @@ -3248,7 +3301,7 @@ shadermodeinfo_t cgshadermodeinfo[SHADERMODE_COUNT] = { {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_GENERIC\n", " generic"}, {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_POSTPROCESS\n", " postprocess"}, - {"cg/default.cg", NULL, NULL , "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"}, + {"cg/default.cg", NULL, NULL , "#define MODE_DEPTH_OR_SHADOW\n", " depth"}, {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_FLATCOLOR\n", " flatcolor"}, {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_VERTEXCOLOR\n", " vertexcolor"}, {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTMAP\n", " lightmap"}, @@ -3305,6 +3358,8 @@ typedef struct r_glsl_permutation_s int loc_Texture_ScreenNormalMap; int loc_Texture_ScreenDiffuse; int loc_Texture_ScreenSpecular; + int loc_Texture_ReflectMask; + int loc_Texture_ReflectCube; int loc_Alpha; int loc_BloomBlur_Parameters; int loc_ClientTime; @@ -3354,6 +3409,7 @@ typedef struct r_glsl_permutation_s int loc_ModelViewProjectionMatrix; int loc_ModelViewMatrix; int loc_PixelToScreenTexCoord; + int loc_ModelToReflectCube; } r_glsl_permutation_t; @@ -3396,6 +3452,20 @@ static char *R_GLSL_GetText(const char *filename, qboolean printfromdisknotice) char *shaderstring; if (!filename || !filename[0]) return NULL; + if (!strcmp(filename, "glsl/default.glsl")) + { + if (!glslshaderstring) + { + glslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL); + if (glslshaderstring) + Con_DPrintf("Loading shaders from file %s...\n", filename); + else + glslshaderstring = (char *)builtinshaderstring; + } + shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(glslshaderstring) + 1); + memcpy(shaderstring, glslshaderstring, strlen(glslshaderstring) + 1); + return shaderstring; + } shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL); if (shaderstring) { @@ -3403,11 +3473,6 @@ static char *R_GLSL_GetText(const char *filename, qboolean printfromdisknotice) Con_DPrintf("from disk %s... ", filename); return shaderstring; } - else if (!strcmp(filename, "glsl/default.glsl")) - { - shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(builtinshaderstring) + 1); - memcpy(shaderstring, builtinshaderstring, strlen(builtinshaderstring) + 1); - } return shaderstring; } @@ -3518,6 +3583,8 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode p->loc_Texture_ScreenNormalMap = qglGetUniformLocationARB(p->program, "Texture_ScreenNormalMap"); p->loc_Texture_ScreenDiffuse = qglGetUniformLocationARB(p->program, "Texture_ScreenDiffuse"); p->loc_Texture_ScreenSpecular = qglGetUniformLocationARB(p->program, "Texture_ScreenSpecular"); + p->loc_Texture_ReflectMask = qglGetUniformLocationARB(p->program, "Texture_ReflectMask"); + p->loc_Texture_ReflectCube = qglGetUniformLocationARB(p->program, "Texture_ReflectCube"); p->loc_Alpha = qglGetUniformLocationARB(p->program, "Alpha"); p->loc_BloomBlur_Parameters = qglGetUniformLocationARB(p->program, "BloomBlur_Parameters"); p->loc_ClientTime = qglGetUniformLocationARB(p->program, "ClientTime"); @@ -3567,6 +3634,7 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode p->loc_ModelViewMatrix = qglGetUniformLocationARB(p->program, "ModelViewMatrix"); p->loc_ModelViewProjectionMatrix = qglGetUniformLocationARB(p->program, "ModelViewProjectionMatrix"); p->loc_PixelToScreenTexCoord = qglGetUniformLocationARB(p->program, "PixelToScreenTexCoord"); + p->loc_ModelToReflectCube = qglGetUniformLocationARB(p->program, "ModelToReflectCube"); // initialize the samplers to refer to the texture units we use if (p->loc_Texture_First >= 0) qglUniform1iARB(p->loc_Texture_First , GL20TU_FIRST); if (p->loc_Texture_Second >= 0) qglUniform1iARB(p->loc_Texture_Second , GL20TU_SECOND); @@ -3596,6 +3664,8 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode if (p->loc_Texture_ScreenNormalMap >= 0) qglUniform1iARB(p->loc_Texture_ScreenNormalMap, GL20TU_SCREENNORMALMAP); if (p->loc_Texture_ScreenDiffuse >= 0) qglUniform1iARB(p->loc_Texture_ScreenDiffuse , GL20TU_SCREENDIFFUSE); if (p->loc_Texture_ScreenSpecular >= 0) qglUniform1iARB(p->loc_Texture_ScreenSpecular , GL20TU_SCREENSPECULAR); + if (p->loc_Texture_ReflectMask >= 0) qglUniform1iARB(p->loc_Texture_ReflectMask , GL20TU_REFLECTMASK); + if (p->loc_Texture_ReflectCube >= 0) qglUniform1iARB(p->loc_Texture_ReflectCube , GL20TU_REFLECTCUBE); CHECKGLERROR Con_DPrintf("^5GLSL shader %s compiled.\n", permutationname); } @@ -3652,6 +3722,7 @@ void R_SetupShader_SetPermutationGLSL(unsigned int mode, unsigned int permutatio } if (r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f); if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f); + if (r_glsl_permutation->loc_ClientTime >= 0) qglUniform1fARB(r_glsl_permutation->loc_ClientTime, cl.time); } #ifdef SUPPORTCG @@ -3708,6 +3779,8 @@ typedef struct r_cg_permutation_s CGparameter fp_Texture_ScreenNormalMap; CGparameter fp_Texture_ScreenDiffuse; CGparameter fp_Texture_ScreenSpecular; + CGparameter fp_Texture_ReflectMask; + CGparameter fp_Texture_ReflectCube; CGparameter fp_Alpha; CGparameter fp_BloomBlur_Parameters; CGparameter fp_ClientTime; @@ -3752,6 +3825,7 @@ typedef struct r_cg_permutation_s CGparameter fp_ViewTintColor; CGparameter fp_ViewToLight; CGparameter fp_PixelToScreenTexCoord; + CGparameter fp_ModelToReflectCube; } r_cg_permutation_t; @@ -3794,6 +3868,20 @@ static char *R_CG_GetText(const char *filename, qboolean printfromdisknotice) char *shaderstring; if (!filename || !filename[0]) return NULL; + if (!strcmp(filename, "cg/default.cg")) + { + if (!cgshaderstring) + { + cgshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL); + if (cgshaderstring) + Con_DPrintf("Loading shaders from file %s...\n", filename); + else + cgshaderstring = (char *)builtincgshaderstring; + } + shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(cgshaderstring) + 1); + memcpy(shaderstring, cgshaderstring, strlen(cgshaderstring) + 1); + return shaderstring; + } shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL); if (shaderstring) { @@ -3801,14 +3889,14 @@ static char *R_CG_GetText(const char *filename, qboolean printfromdisknotice) Con_DPrintf("from disk %s... ", filename); return shaderstring; } - else if (!strcmp(filename, "cg/default.cg")) - { - shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(builtincgshaderstring) + 1); - memcpy(shaderstring, builtincgshaderstring, strlen(builtincgshaderstring) + 1); - } return shaderstring; } +static void R_CG_CacheShader(r_cg_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring) +{ + // TODO: load or create .fp and .vp shader files +} + static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, unsigned int permutation) { int i; @@ -3823,6 +3911,7 @@ static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, un const char *geomstrings_list[32+3]; const char *fragstrings_list[32+3]; char permutationname[256]; + char cachename[256]; CGprofile vertexProfile; CGprofile fragmentProfile; @@ -3833,11 +3922,13 @@ static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, un p->fprogram = NULL; permutationname[0] = 0; + cachename[0] = 0; vertexstring = R_CG_GetText(modeinfo->vertexfilename, true); geometrystring = R_CG_GetText(modeinfo->geometryfilename, false); fragmentstring = R_CG_GetText(modeinfo->fragmentfilename, false); strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname)); + strlcat(cachename, "cg/", sizeof(cachename)); // the first pretext is which type of shader to compile as // (later these will all be bound together as a program object) @@ -3850,6 +3941,7 @@ static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, un geomstrings_list[geomstrings_count++] = modeinfo->pretext; fragstrings_list[fragstrings_count++] = modeinfo->pretext; strlcat(permutationname, modeinfo->name, sizeof(permutationname)); + strlcat(cachename, modeinfo->name, sizeof(cachename)); // now add all the permutation pretexts for (i = 0;i < SHADERPERMUTATION_COUNT;i++) @@ -3860,6 +3952,7 @@ static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, un geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext; fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext; strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname)); + strlcat(cachename, shaderpermutationinfo[i].name, sizeof(cachename)); } else { @@ -3870,6 +3963,11 @@ static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, un } } + // replace spaces in the cachename with _ characters + for (i = 0;cachename[i];i++) + if (cachename[i] == ' ') + cachename[i] = '_'; + // now append the shader text itself vertstrings_list[vertstrings_count++] = vertexstring; geomstrings_list[geomstrings_count++] = geometrystring; @@ -3915,130 +4013,117 @@ static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, un //cgSetAutoCompile(vid.cgcontext, CG_COMPILE_MANUAL);CHECKCGERROR CHECKGLERROR - // compile the vertex program - if (vertstring[0] && (p->vprogram = cgCreateProgram(vid.cgcontext, CG_SOURCE, vertstring, vertexProfile, NULL, NULL))) + // try to load the cached shader, or generate one + R_CG_CacheShader(p, cachename, vertstring, fragstring); + + // if caching failed, do a dynamic compile for now + CHECKCGERROR + if (vertstring[0] && !p->vprogram) + p->vprogram = cgCreateProgram(vid.cgcontext, CG_SOURCE, vertstring, vertexProfile, NULL, NULL); + CHECKCGERROR + if (fragstring[0] && !p->fprogram) + p->fprogram = cgCreateProgram(vid.cgcontext, CG_SOURCE, fragstring, fragmentProfile, NULL, NULL); + CHECKCGERROR + + // look up all the uniform variable names we care about, so we don't + // have to look them up every time we set them + if (p->vprogram) { CHECKCGERROR -#if 0 - cgCompileProgram(p->vprogram);CHECKCGERROR - if (!cgIsProgramCompiled(p->vprogram)) - { - CHECKCGERROR - cgDestroyProgram(p->vprogram);CHECKCGERROR - p->vprogram = 0; - } - else -#endif - { - cgGLLoadProgram(p->vprogram);CHECKCGERROR CHECKGLERROR - cgGLEnableProfile(vertexProfile);CHECKCGERROR CHECKGLERROR - // look up all the uniform variable names we care about, so we don't - // have to look them up every time we set them - CHECKCGERROR - p->vp_EyePosition = cgGetNamedParameter(p->vprogram, "EyePosition"); - p->vp_FogPlane = cgGetNamedParameter(p->vprogram, "FogPlane"); - p->vp_LightDir = cgGetNamedParameter(p->vprogram, "LightDir"); - p->vp_LightPosition = cgGetNamedParameter(p->vprogram, "LightPosition"); - p->vp_ModelToLight = cgGetNamedParameter(p->vprogram, "ModelToLight"); - p->vp_TexMatrix = cgGetNamedParameter(p->vprogram, "TexMatrix"); - p->vp_BackgroundTexMatrix = cgGetNamedParameter(p->vprogram, "BackgroundTexMatrix"); - p->vp_ModelViewProjectionMatrix = cgGetNamedParameter(p->vprogram, "ModelViewProjectionMatrix"); - p->vp_ModelViewMatrix = cgGetNamedParameter(p->vprogram, "ModelViewMatrix"); - CHECKCGERROR - } + cgGLLoadProgram(p->vprogram);CHECKCGERROR CHECKGLERROR + cgGLEnableProfile(vertexProfile);CHECKCGERROR CHECKGLERROR + p->vp_EyePosition = cgGetNamedParameter(p->vprogram, "EyePosition"); + p->vp_FogPlane = cgGetNamedParameter(p->vprogram, "FogPlane"); + p->vp_LightDir = cgGetNamedParameter(p->vprogram, "LightDir"); + p->vp_LightPosition = cgGetNamedParameter(p->vprogram, "LightPosition"); + p->vp_ModelToLight = cgGetNamedParameter(p->vprogram, "ModelToLight"); + p->vp_TexMatrix = cgGetNamedParameter(p->vprogram, "TexMatrix"); + p->vp_BackgroundTexMatrix = cgGetNamedParameter(p->vprogram, "BackgroundTexMatrix"); + p->vp_ModelViewProjectionMatrix = cgGetNamedParameter(p->vprogram, "ModelViewProjectionMatrix"); + p->vp_ModelViewMatrix = cgGetNamedParameter(p->vprogram, "ModelViewMatrix"); + CHECKCGERROR } - - // compile the fragment program - if (fragstring[0] && (p->fprogram = cgCreateProgram(vid.cgcontext, CG_SOURCE, fragstring, fragmentProfile, NULL, NULL))) + if (p->fprogram) { -#if 0 - cgCompileProgram(p->fprogram);CHECKCGERROR - if (!cgIsProgramCompiled(p->fprogram)) - { - CHECKCGERROR - cgDestroyProgram(p->fprogram);CHECKCGERROR - p->fprogram = 0; - } - else -#endif - { - cgGLLoadProgram(p->fprogram);CHECKCGERROR CHECKGLERROR - cgGLEnableProfile(fragmentProfile);CHECKCGERROR CHECKGLERROR - CHECKCGERROR - p->fp_Texture_First = cgGetNamedParameter(p->fprogram, "Texture_First"); - p->fp_Texture_Second = cgGetNamedParameter(p->fprogram, "Texture_Second"); - p->fp_Texture_GammaRamps = cgGetNamedParameter(p->fprogram, "Texture_GammaRamps"); - p->fp_Texture_Normal = cgGetNamedParameter(p->fprogram, "Texture_Normal"); - p->fp_Texture_Color = cgGetNamedParameter(p->fprogram, "Texture_Color"); - p->fp_Texture_Gloss = cgGetNamedParameter(p->fprogram, "Texture_Gloss"); - p->fp_Texture_Glow = cgGetNamedParameter(p->fprogram, "Texture_Glow"); - p->fp_Texture_SecondaryNormal = cgGetNamedParameter(p->fprogram, "Texture_SecondaryNormal"); - p->fp_Texture_SecondaryColor = cgGetNamedParameter(p->fprogram, "Texture_SecondaryColor"); - p->fp_Texture_SecondaryGloss = cgGetNamedParameter(p->fprogram, "Texture_SecondaryGloss"); - 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_FogMask = cgGetNamedParameter(p->fprogram, "Texture_FogMask"); - p->fp_Texture_Lightmap = cgGetNamedParameter(p->fprogram, "Texture_Lightmap"); - p->fp_Texture_Deluxemap = cgGetNamedParameter(p->fprogram, "Texture_Deluxemap"); - p->fp_Texture_Attenuation = cgGetNamedParameter(p->fprogram, "Texture_Attenuation"); - p->fp_Texture_Cube = cgGetNamedParameter(p->fprogram, "Texture_Cube"); - p->fp_Texture_Refraction = cgGetNamedParameter(p->fprogram, "Texture_Refraction"); - p->fp_Texture_Reflection = cgGetNamedParameter(p->fprogram, "Texture_Reflection"); - p->fp_Texture_ShadowMapRect = cgGetNamedParameter(p->fprogram, "Texture_ShadowMapRect"); - p->fp_Texture_ShadowMapCube = cgGetNamedParameter(p->fprogram, "Texture_ShadowMapCube"); - p->fp_Texture_ShadowMap2D = cgGetNamedParameter(p->fprogram, "Texture_ShadowMap2D"); - p->fp_Texture_CubeProjection = cgGetNamedParameter(p->fprogram, "Texture_CubeProjection"); - p->fp_Texture_ScreenDepth = cgGetNamedParameter(p->fprogram, "Texture_ScreenDepth"); - p->fp_Texture_ScreenNormalMap = cgGetNamedParameter(p->fprogram, "Texture_ScreenNormalMap"); - p->fp_Texture_ScreenDiffuse = cgGetNamedParameter(p->fprogram, "Texture_ScreenDiffuse"); - p->fp_Texture_ScreenSpecular = cgGetNamedParameter(p->fprogram, "Texture_ScreenSpecular"); - p->fp_Alpha = cgGetNamedParameter(p->fprogram, "Alpha"); - p->fp_BloomBlur_Parameters = cgGetNamedParameter(p->fprogram, "BloomBlur_Parameters"); - p->fp_ClientTime = cgGetNamedParameter(p->fprogram, "ClientTime"); - p->fp_Color_Ambient = cgGetNamedParameter(p->fprogram, "Color_Ambient"); - p->fp_Color_Diffuse = cgGetNamedParameter(p->fprogram, "Color_Diffuse"); - p->fp_Color_Specular = cgGetNamedParameter(p->fprogram, "Color_Specular"); - p->fp_Color_Glow = cgGetNamedParameter(p->fprogram, "Color_Glow"); - p->fp_Color_Pants = cgGetNamedParameter(p->fprogram, "Color_Pants"); - p->fp_Color_Shirt = cgGetNamedParameter(p->fprogram, "Color_Shirt"); - p->fp_DeferredColor_Ambient = cgGetNamedParameter(p->fprogram, "DeferredColor_Ambient"); - p->fp_DeferredColor_Diffuse = cgGetNamedParameter(p->fprogram, "DeferredColor_Diffuse"); - p->fp_DeferredColor_Specular = cgGetNamedParameter(p->fprogram, "DeferredColor_Specular"); - p->fp_DeferredMod_Diffuse = cgGetNamedParameter(p->fprogram, "DeferredMod_Diffuse"); - p->fp_DeferredMod_Specular = cgGetNamedParameter(p->fprogram, "DeferredMod_Specular"); - p->fp_DistortScaleRefractReflect = cgGetNamedParameter(p->fprogram, "DistortScaleRefractReflect"); - p->fp_EyePosition = cgGetNamedParameter(p->fprogram, "EyePosition"); - p->fp_FogColor = cgGetNamedParameter(p->fprogram, "FogColor"); - p->fp_FogHeightFade = cgGetNamedParameter(p->fprogram, "FogHeightFade"); - p->fp_FogPlane = cgGetNamedParameter(p->fprogram, "FogPlane"); - p->fp_FogPlaneViewDist = cgGetNamedParameter(p->fprogram, "FogPlaneViewDist"); - p->fp_FogRangeRecip = cgGetNamedParameter(p->fprogram, "FogRangeRecip"); - p->fp_LightColor = cgGetNamedParameter(p->fprogram, "LightColor"); - p->fp_LightDir = cgGetNamedParameter(p->fprogram, "LightDir"); - p->fp_LightPosition = cgGetNamedParameter(p->fprogram, "LightPosition"); - p->fp_OffsetMapping_Scale = cgGetNamedParameter(p->fprogram, "OffsetMapping_Scale"); - p->fp_PixelSize = cgGetNamedParameter(p->fprogram, "PixelSize"); - p->fp_ReflectColor = cgGetNamedParameter(p->fprogram, "ReflectColor"); - p->fp_ReflectFactor = cgGetNamedParameter(p->fprogram, "ReflectFactor"); - p->fp_ReflectOffset = cgGetNamedParameter(p->fprogram, "ReflectOffset"); - p->fp_RefractColor = cgGetNamedParameter(p->fprogram, "RefractColor"); - p->fp_Saturation = cgGetNamedParameter(p->fprogram, "Saturation"); - p->fp_ScreenCenterRefractReflect = cgGetNamedParameter(p->fprogram, "ScreenCenterRefractReflect"); - p->fp_ScreenScaleRefractReflect = cgGetNamedParameter(p->fprogram, "ScreenScaleRefractReflect"); - p->fp_ScreenToDepth = cgGetNamedParameter(p->fprogram, "ScreenToDepth"); - p->fp_ShadowMap_Parameters = cgGetNamedParameter(p->fprogram, "ShadowMap_Parameters"); - p->fp_ShadowMap_TextureScale = cgGetNamedParameter(p->fprogram, "ShadowMap_TextureScale"); - p->fp_SpecularPower = cgGetNamedParameter(p->fprogram, "SpecularPower"); - p->fp_UserVec1 = cgGetNamedParameter(p->fprogram, "UserVec1"); - p->fp_UserVec2 = cgGetNamedParameter(p->fprogram, "UserVec2"); - p->fp_UserVec3 = cgGetNamedParameter(p->fprogram, "UserVec3"); - p->fp_UserVec4 = cgGetNamedParameter(p->fprogram, "UserVec4"); - p->fp_ViewTintColor = cgGetNamedParameter(p->fprogram, "ViewTintColor"); - p->fp_ViewToLight = cgGetNamedParameter(p->fprogram, "ViewToLight"); - p->fp_PixelToScreenTexCoord = cgGetNamedParameter(p->fprogram, "PixelToScreenTexCoord"); - CHECKCGERROR - } + CHECKCGERROR + cgGLLoadProgram(p->fprogram);CHECKCGERROR CHECKGLERROR + cgGLEnableProfile(fragmentProfile);CHECKCGERROR CHECKGLERROR + p->fp_Texture_First = cgGetNamedParameter(p->fprogram, "Texture_First"); + p->fp_Texture_Second = cgGetNamedParameter(p->fprogram, "Texture_Second"); + p->fp_Texture_GammaRamps = cgGetNamedParameter(p->fprogram, "Texture_GammaRamps"); + p->fp_Texture_Normal = cgGetNamedParameter(p->fprogram, "Texture_Normal"); + p->fp_Texture_Color = cgGetNamedParameter(p->fprogram, "Texture_Color"); + p->fp_Texture_Gloss = cgGetNamedParameter(p->fprogram, "Texture_Gloss"); + p->fp_Texture_Glow = cgGetNamedParameter(p->fprogram, "Texture_Glow"); + p->fp_Texture_SecondaryNormal = cgGetNamedParameter(p->fprogram, "Texture_SecondaryNormal"); + p->fp_Texture_SecondaryColor = cgGetNamedParameter(p->fprogram, "Texture_SecondaryColor"); + p->fp_Texture_SecondaryGloss = cgGetNamedParameter(p->fprogram, "Texture_SecondaryGloss"); + 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_FogMask = cgGetNamedParameter(p->fprogram, "Texture_FogMask"); + p->fp_Texture_Lightmap = cgGetNamedParameter(p->fprogram, "Texture_Lightmap"); + p->fp_Texture_Deluxemap = cgGetNamedParameter(p->fprogram, "Texture_Deluxemap"); + p->fp_Texture_Attenuation = cgGetNamedParameter(p->fprogram, "Texture_Attenuation"); + p->fp_Texture_Cube = cgGetNamedParameter(p->fprogram, "Texture_Cube"); + p->fp_Texture_Refraction = cgGetNamedParameter(p->fprogram, "Texture_Refraction"); + p->fp_Texture_Reflection = cgGetNamedParameter(p->fprogram, "Texture_Reflection"); + p->fp_Texture_ShadowMapRect = cgGetNamedParameter(p->fprogram, "Texture_ShadowMapRect"); + p->fp_Texture_ShadowMapCube = cgGetNamedParameter(p->fprogram, "Texture_ShadowMapCube"); + p->fp_Texture_ShadowMap2D = cgGetNamedParameter(p->fprogram, "Texture_ShadowMap2D"); + p->fp_Texture_CubeProjection = cgGetNamedParameter(p->fprogram, "Texture_CubeProjection"); + p->fp_Texture_ScreenDepth = cgGetNamedParameter(p->fprogram, "Texture_ScreenDepth"); + p->fp_Texture_ScreenNormalMap = cgGetNamedParameter(p->fprogram, "Texture_ScreenNormalMap"); + p->fp_Texture_ScreenDiffuse = cgGetNamedParameter(p->fprogram, "Texture_ScreenDiffuse"); + p->fp_Texture_ScreenSpecular = cgGetNamedParameter(p->fprogram, "Texture_ScreenSpecular"); + p->fp_Texture_ReflectMask = cgGetNamedParameter(p->fprogram, "Texture_ReflectMask"); + p->fp_Texture_ReflectCube = cgGetNamedParameter(p->fprogram, "Texture_ReflectCube"); + p->fp_Alpha = cgGetNamedParameter(p->fprogram, "Alpha"); + p->fp_BloomBlur_Parameters = cgGetNamedParameter(p->fprogram, "BloomBlur_Parameters"); + p->fp_ClientTime = cgGetNamedParameter(p->fprogram, "ClientTime"); + p->fp_Color_Ambient = cgGetNamedParameter(p->fprogram, "Color_Ambient"); + p->fp_Color_Diffuse = cgGetNamedParameter(p->fprogram, "Color_Diffuse"); + p->fp_Color_Specular = cgGetNamedParameter(p->fprogram, "Color_Specular"); + p->fp_Color_Glow = cgGetNamedParameter(p->fprogram, "Color_Glow"); + p->fp_Color_Pants = cgGetNamedParameter(p->fprogram, "Color_Pants"); + p->fp_Color_Shirt = cgGetNamedParameter(p->fprogram, "Color_Shirt"); + p->fp_DeferredColor_Ambient = cgGetNamedParameter(p->fprogram, "DeferredColor_Ambient"); + p->fp_DeferredColor_Diffuse = cgGetNamedParameter(p->fprogram, "DeferredColor_Diffuse"); + p->fp_DeferredColor_Specular = cgGetNamedParameter(p->fprogram, "DeferredColor_Specular"); + p->fp_DeferredMod_Diffuse = cgGetNamedParameter(p->fprogram, "DeferredMod_Diffuse"); + p->fp_DeferredMod_Specular = cgGetNamedParameter(p->fprogram, "DeferredMod_Specular"); + p->fp_DistortScaleRefractReflect = cgGetNamedParameter(p->fprogram, "DistortScaleRefractReflect"); + p->fp_EyePosition = cgGetNamedParameter(p->fprogram, "EyePosition"); + p->fp_FogColor = cgGetNamedParameter(p->fprogram, "FogColor"); + p->fp_FogHeightFade = cgGetNamedParameter(p->fprogram, "FogHeightFade"); + p->fp_FogPlane = cgGetNamedParameter(p->fprogram, "FogPlane"); + p->fp_FogPlaneViewDist = cgGetNamedParameter(p->fprogram, "FogPlaneViewDist"); + p->fp_FogRangeRecip = cgGetNamedParameter(p->fprogram, "FogRangeRecip"); + p->fp_LightColor = cgGetNamedParameter(p->fprogram, "LightColor"); + p->fp_LightDir = cgGetNamedParameter(p->fprogram, "LightDir"); + p->fp_LightPosition = cgGetNamedParameter(p->fprogram, "LightPosition"); + p->fp_OffsetMapping_Scale = cgGetNamedParameter(p->fprogram, "OffsetMapping_Scale"); + p->fp_PixelSize = cgGetNamedParameter(p->fprogram, "PixelSize"); + p->fp_ReflectColor = cgGetNamedParameter(p->fprogram, "ReflectColor"); + p->fp_ReflectFactor = cgGetNamedParameter(p->fprogram, "ReflectFactor"); + p->fp_ReflectOffset = cgGetNamedParameter(p->fprogram, "ReflectOffset"); + p->fp_RefractColor = cgGetNamedParameter(p->fprogram, "RefractColor"); + p->fp_Saturation = cgGetNamedParameter(p->fprogram, "Saturation"); + p->fp_ScreenCenterRefractReflect = cgGetNamedParameter(p->fprogram, "ScreenCenterRefractReflect"); + p->fp_ScreenScaleRefractReflect = cgGetNamedParameter(p->fprogram, "ScreenScaleRefractReflect"); + p->fp_ScreenToDepth = cgGetNamedParameter(p->fprogram, "ScreenToDepth"); + p->fp_ShadowMap_Parameters = cgGetNamedParameter(p->fprogram, "ShadowMap_Parameters"); + p->fp_ShadowMap_TextureScale = cgGetNamedParameter(p->fprogram, "ShadowMap_TextureScale"); + p->fp_SpecularPower = cgGetNamedParameter(p->fprogram, "SpecularPower"); + p->fp_UserVec1 = cgGetNamedParameter(p->fprogram, "UserVec1"); + p->fp_UserVec2 = cgGetNamedParameter(p->fprogram, "UserVec2"); + p->fp_UserVec3 = cgGetNamedParameter(p->fprogram, "UserVec3"); + p->fp_UserVec4 = cgGetNamedParameter(p->fprogram, "UserVec4"); + p->fp_ViewTintColor = cgGetNamedParameter(p->fprogram, "ViewTintColor"); + p->fp_ViewToLight = cgGetNamedParameter(p->fprogram, "ViewToLight"); + p->fp_PixelToScreenTexCoord = cgGetNamedParameter(p->fprogram, "PixelToScreenTexCoord"); + p->fp_ModelToReflectCube = cgGetNamedParameter(p->fprogram, "ModelToReflectCube"); + CHECKCGERROR } if ((p->vprogram || !vertstring[0]) && (p->fprogram || !fragstring[0])) @@ -4126,6 +4211,7 @@ void R_SetupShader_SetPermutationCG(unsigned int mode, unsigned int permutation) CHECKCGERROR if (r_cg_permutation->vp_ModelViewProjectionMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewProjectionMatrix, gl_modelviewprojection16f);CHECKCGERROR if (r_cg_permutation->vp_ModelViewMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelview16f);CHECKCGERROR + if (r_cg_permutation->fp_ClientTime) cgGLSetParameter1f(r_cg_permutation->fp_ClientTime, cl.time);CHECKCGERROR } void CG_BindTexture(CGparameter param, rtexture_t *tex) @@ -4138,6 +4224,12 @@ void CG_BindTexture(CGparameter param, rtexture_t *tex) void R_GLSL_Restart_f(void) { unsigned int i, limit; + if (glslshaderstring && glslshaderstring != builtinshaderstring) + Mem_Free(glslshaderstring); + glslshaderstring = NULL; + if (cgshaderstring && cgshaderstring != builtincgshaderstring) + Mem_Free(cgshaderstring); + cgshaderstring = NULL; switch(vid.renderpath) { case RENDERPATH_GL20: @@ -4425,6 +4517,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, else if (r_shadow_shadowmappcf) permutation |= SHADERPERMUTATION_SHADOWMAPPCF; } + if (rsurface.texture->reflectmasktexture) + permutation |= SHADERPERMUTATION_REFLECTCUBE; R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); if (true || permutation & (SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_OFFSETMAPPING)) { @@ -4467,6 +4561,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_COLORMAPPING; if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) permutation |= SHADERPERMUTATION_REFLECTION; + if (rsurface.texture->reflectmasktexture) + permutation |= SHADERPERMUTATION_REFLECTCUBE; R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); if (true || permutation & (SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_OFFSETMAPPING)) { @@ -4517,6 +4613,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_REFLECTION; if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; + if (rsurface.texture->reflectmasktexture) + permutation |= SHADERPERMUTATION_REFLECTCUBE; R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); if (true || permutation & (SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_OFFSETMAPPING)) { @@ -4557,6 +4655,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_REFLECTION; if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; + if (rsurface.texture->reflectmasktexture) + permutation |= SHADERPERMUTATION_REFLECTCUBE; R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); if (true || permutation & (SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_OFFSETMAPPING)) { @@ -4596,6 +4696,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_REFLECTION; if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; + if (rsurface.texture->reflectmasktexture) + permutation |= SHADERPERMUTATION_REFLECTCUBE; if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping) { // deluxemapping (light direction texture) @@ -4670,6 +4772,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { case RENDERPATH_GL20: R_SetupShader_SetPermutationGLSL(mode, permutation); + if (r_glsl_permutation->loc_ModelToReflectCube >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelToReflectCube, 1, false, m16f);} if (mode == SHADERMODE_LIGHTSOURCE) { if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);} @@ -4767,6 +4870,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_glsl_permutation->loc_Texture_SecondaryGlow >= 0) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture ); if (r_glsl_permutation->loc_Texture_Pants >= 0) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture ); 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_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 ); @@ -4791,6 +4896,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, case RENDERPATH_CGGL: #ifdef SUPPORTCG R_SetupShader_SetPermutationCG(mode, permutation); + if (r_cg_permutation->fp_ModelToReflectCube) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->fp_ModelToReflectCube, m16f);}CHECKCGERROR if (mode == SHADERMODE_LIGHTSOURCE) { if (r_cg_permutation->vp_ModelToLight) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelToLight, m16f);}CHECKCGERROR @@ -4905,6 +5011,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_cg_permutation->fp_Texture_SecondaryGlow ) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryGlow , rsurface.texture->backgroundglowtexture );CHECKCGERROR if (r_cg_permutation->fp_Texture_Pants ) CG_BindTexture(r_cg_permutation->fp_Texture_Pants , rsurface.texture->pantstexture );CHECKCGERROR 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_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 @@ -5092,6 +5200,7 @@ void R_SkinFrame_Purge(void) R_PurgeTexture(s->gloss );s->gloss = NULL; R_PurgeTexture(s->glow );s->glow = NULL; R_PurgeTexture(s->fog );s->fog = NULL; + R_PurgeTexture(s->reflect);s->reflect = NULL; s->loadsequence = 0; } } @@ -5228,7 +5337,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole // check for DDS texture file first if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s.dds", basename), textureflags, &ddshasalpha, ddsavgcolor))) { - basepixels = loadimagepixelsbgra(name, complain, true); + basepixels = loadimagepixelsbgra(name, complain, true, r_texture_convertsRGB_skin.integer); if (basepixels == NULL) return NULL; } @@ -5248,6 +5357,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole skinframe->gloss = NULL; skinframe->glow = NULL; skinframe->fog = NULL; + skinframe->reflect = NULL; skinframe->hasalpha = false; if (ddsbase) @@ -5306,18 +5416,19 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_gloss.dds", skinframe->basename), textureflags, NULL, NULL); skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_pants.dds", skinframe->basename), textureflags, NULL, NULL); skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_shirt.dds", skinframe->basename), textureflags, NULL, NULL); + skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_reflect.dds", skinframe->basename), textureflags, NULL, NULL); } // _norm is the name used by tenebrae and has been adopted as standard if (r_loadnormalmap && skinframe->nmap == NULL) { - if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false)) != NULL) + if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false, false)) != NULL) { skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); Mem_Free(pixels); pixels = NULL; } - else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixelsbgra(va("%s_bump", skinframe->basename), false, false)) != NULL) + else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixelsbgra(va("%s_bump", skinframe->basename), false, false, false)) != NULL) { pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); Image_HeightmapToNormalmap_BGRA(bumppixels, pixels, image_width, image_height, false, r_shadow_bumpscale_bumpmap.value); @@ -5338,7 +5449,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole // _luma is supported only for tenebrae compatibility // _glow is the preferred name - if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false)))) + if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer)))) { skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->glow) @@ -5346,7 +5457,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole Mem_Free(pixels);pixels = NULL; } - if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false))) + if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer))) { skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss) @@ -5355,7 +5466,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole pixels = NULL; } - if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false))) + if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer))) { skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->pants) @@ -5364,7 +5475,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole pixels = NULL; } - if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false))) + if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer))) { skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->shirt) @@ -5373,6 +5484,15 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole pixels = NULL; } + if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va("%s_reflect", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer))) + { + skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va("%s_reflect", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_reflectmask.integer ? ~0 : ~TEXF_COMPRESS), NULL); + if (r_savedds && qglGetCompressedTexImageARB && skinframe->reflect) + R_SaveTextureDDSFile(skinframe->reflect, va("dds/%s_reflect.dds", skinframe->basename), true); + Mem_Free(pixels); + pixels = NULL; + } + if (basepixels) Mem_Free(basepixels); @@ -5403,6 +5523,7 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co skinframe->gloss = NULL; skinframe->glow = NULL; skinframe->fog = NULL; + skinframe->reflect = NULL; skinframe->hasalpha = false; // if no data was provided, then clearly the caller wanted to get a blank skinframe @@ -5471,6 +5592,7 @@ skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, i skinframe->gloss = NULL; skinframe->glow = NULL; skinframe->fog = NULL; + skinframe->reflect = NULL; skinframe->hasalpha = false; // if no data was provided, then clearly the caller wanted to get a blank skinframe @@ -5591,6 +5713,7 @@ skinframe_t *R_SkinFrame_LoadInternal8bit(const char *name, int textureflags, co skinframe->gloss = NULL; skinframe->glow = NULL; skinframe->fog = NULL; + skinframe->reflect = NULL; skinframe->hasalpha = false; // if no data was provided, then clearly the caller wanted to get a blank skinframe @@ -5638,6 +5761,7 @@ skinframe_t *R_SkinFrame_LoadMissing(void) skinframe->gloss = NULL; skinframe->glow = NULL; skinframe->fog = NULL; + skinframe->reflect = NULL; skinframe->hasalpha = false; skinframe->avgcolor[0] = rand() / RAND_MAX; @@ -5648,6 +5772,136 @@ skinframe_t *R_SkinFrame_LoadMissing(void) return skinframe; } +//static char *suffix[6] = {"ft", "bk", "rt", "lf", "up", "dn"}; +typedef struct suffixinfo_s +{ + char *suffix; + qboolean flipx, flipy, flipdiagonal; +} +suffixinfo_t; +static suffixinfo_t suffix[3][6] = +{ + { + {"px", false, false, false}, + {"nx", false, false, false}, + {"py", false, false, false}, + {"ny", false, false, false}, + {"pz", false, false, false}, + {"nz", false, false, false} + }, + { + {"posx", false, false, false}, + {"negx", false, false, false}, + {"posy", false, false, false}, + {"negy", false, false, false}, + {"posz", false, false, false}, + {"negz", false, false, false} + }, + { + {"rt", true, false, true}, + {"lf", false, true, true}, + {"ft", true, true, false}, + {"bk", false, false, false}, + {"up", true, false, true}, + {"dn", true, false, true} + } +}; + +static int componentorder[4] = {0, 1, 2, 3}; + +rtexture_t *R_LoadCubemap(const char *basename) +{ + int i, j, cubemapsize; + unsigned char *cubemappixels, *image_buffer; + rtexture_t *cubemaptexture; + char name[256]; + // must start 0 so the first loadimagepixels has no requested width/height + cubemapsize = 0; + cubemappixels = NULL; + cubemaptexture = NULL; + // keep trying different suffix groups (posx, px, rt) until one loads + for (j = 0;j < 3 && !cubemappixels;j++) + { + // load the 6 images in the suffix group + for (i = 0;i < 6;i++) + { + // generate an image name based on the base and and suffix + dpsnprintf(name, sizeof(name), "%s%s", basename, suffix[j][i].suffix); + // load it + if ((image_buffer = loadimagepixelsbgra(name, false, false, r_texture_convertsRGB_cubemap.integer))) + { + // an image loaded, make sure width and height are equal + if (image_width == image_height && (!cubemappixels || image_width == cubemapsize)) + { + // if this is the first image to load successfully, allocate the cubemap memory + if (!cubemappixels && image_width >= 1) + { + cubemapsize = image_width; + // note this clears to black, so unavailable sides are black + cubemappixels = (unsigned char *)Mem_Alloc(tempmempool, 6*cubemapsize*cubemapsize*4); + } + // copy the image with any flipping needed by the suffix (px and posx types don't need flipping) + if (cubemappixels) + Image_CopyMux(cubemappixels+i*cubemapsize*cubemapsize*4, image_buffer, cubemapsize, cubemapsize, suffix[j][i].flipx, suffix[j][i].flipy, suffix[j][i].flipdiagonal, 4, 4, componentorder); + } + else + Con_Printf("Cubemap image \"%s\" (%ix%i) is not square, OpenGL requires square cubemaps.\n", name, image_width, image_height); + // free the image + Mem_Free(image_buffer); + } + } + } + // if a cubemap loaded, upload it + if (cubemappixels) + { + if (developer_loading.integer) + Con_Printf("loading cubemap \"%s\"\n", basename); + + cubemaptexture = R_LoadTextureCubeMap(r_main_texturepool, basename, cubemapsize, cubemappixels, TEXTYPE_BGRA, (gl_texturecompression_lightcubemaps.integer ? TEXF_COMPRESS : 0) | TEXF_FORCELINEAR, NULL); + Mem_Free(cubemappixels); + } + else + { + Con_DPrintf("failed to load cubemap \"%s\"\n", basename); + if (developer_loading.integer) + { + Con_Printf("(tried tried images "); + for (j = 0;j < 3;j++) + for (i = 0;i < 6;i++) + Con_Printf("%s\"%s%s.tga\"", j + i > 0 ? ", " : "", basename, suffix[j][i].suffix); + Con_Print(" and was unable to find any of them).\n"); + } + } + return cubemaptexture; +} + +rtexture_t *R_GetCubemap(const char *basename) +{ + int i; + for (i = 0;i < r_texture_numcubemaps;i++) + if (!strcasecmp(r_texture_cubemaps[i].basename, basename)) + return r_texture_cubemaps[i].texture ? r_texture_cubemaps[i].texture : r_texture_whitecube; + if (i >= MAX_CUBEMAPS) + return r_texture_whitecube; + r_texture_numcubemaps++; + strlcpy(r_texture_cubemaps[i].basename, basename, sizeof(r_texture_cubemaps[i].basename)); + r_texture_cubemaps[i].texture = R_LoadCubemap(r_texture_cubemaps[i].basename); + return r_texture_cubemaps[i].texture; +} + +void R_FreeCubemaps(void) +{ + int i; + for (i = 0;i < r_texture_numcubemaps;i++) + { + if (developer_loading.integer) + Con_DPrintf("unloading cubemap \"%s\"\n", r_texture_cubemaps[i].basename); + if (r_texture_cubemaps[i].texture) + R_FreeTexture(r_texture_cubemaps[i].texture); + } + r_texture_numcubemaps = 0; +} + void R_Main_FreeViewCache(void) { if (r_refdef.viewcache.entityvisible) @@ -5711,6 +5965,7 @@ void gl_main_start(void) r_texture_normalizationcube = NULL; r_texture_fogattenuation = NULL; r_texture_gammaramps = NULL; + r_texture_numcubemaps = 0; r_loaddds = vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc && r_texture_dds_load.integer; r_savedds = vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc && r_texture_dds_save.integer; @@ -5774,9 +6029,11 @@ void gl_main_start(void) memset(&r_waterstate, 0, sizeof(r_waterstate)); memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash)); Mem_ExpandableArray_NewArray(&r_glsl_permutationarray, r_main_mempool, sizeof(r_glsl_permutation_t), 256); + glslshaderstring = NULL; #ifdef SUPPORTCG memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash)); Mem_ExpandableArray_NewArray(&r_cg_permutationarray, r_main_mempool, sizeof(r_cg_permutation_t), 256); + cgshaderstring = NULL; #endif memset(&r_svbsp, 0, sizeof (r_svbsp)); @@ -5817,6 +6074,7 @@ void gl_main_shutdown(void) r_texture_normalizationcube = NULL; r_texture_fogattenuation = NULL; r_texture_gammaramps = NULL; + r_texture_numcubemaps = 0; //r_texture_fogintensity = NULL; memset(&r_bloomstate, 0, sizeof(r_bloomstate)); memset(&r_waterstate, 0, sizeof(r_waterstate)); @@ -5929,6 +6187,11 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_transparentdepthmasking); Cvar_RegisterVariable(&r_texture_dds_load); Cvar_RegisterVariable(&r_texture_dds_save); + Cvar_RegisterVariable(&r_texture_convertsRGB_2d); + Cvar_RegisterVariable(&r_texture_convertsRGB_skin); + Cvar_RegisterVariable(&r_texture_convertsRGB_cubemap); + Cvar_RegisterVariable(&r_texture_convertsRGB_skybox); + Cvar_RegisterVariable(&r_texture_convertsRGB_particles); Cvar_RegisterVariable(&r_textureunits); Cvar_RegisterVariable(&gl_combine); Cvar_RegisterVariable(&r_glsl); @@ -5976,6 +6239,8 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_track_sprites_flags); Cvar_RegisterVariable(&r_track_sprites_scalew); Cvar_RegisterVariable(&r_track_sprites_scaleh); + Cvar_RegisterVariable(&r_overheadsprites_perspective); + Cvar_RegisterVariable(&r_overheadsprites_pushback); } extern void R_Textures_Init(void); @@ -6424,6 +6689,10 @@ static qboolean R_CanSeeBox(int numsamples, vec_t enlarge, vec3_t eye, vec3_t en boxmins[2] = (enlarge+1) * entboxmins[2] - enlarge * entboxmaxs[2]; boxmaxs[2] = (enlarge+1) * entboxmaxs[2] - enlarge * entboxmins[2]; + // return true if eye is inside enlarged box + if (BoxesOverlap(boxmins, boxmaxs, eye, eye)) + return true; + // try center VectorCopy(eye, start); VectorMAM(0.5f, boxmins, 0.5f, boxmaxs, end); @@ -6450,6 +6719,8 @@ static void R_View_UpdateEntityVisible (void) entity_render_t *ent; renderimask = r_refdef.envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : ((chase_active.integer || r_waterstate.renderingscene) ? RENDER_VIEWMODEL : RENDER_EXTERIORMODEL); + if (!r_drawviewmodel.integer) + renderimask |= RENDER_VIEWMODEL; if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs) { // worldmodel can check visibility @@ -7519,7 +7790,6 @@ static void R_BlendView(void) if (r_glsl_permutation->loc_Texture_Second >= 0) R_Mesh_TexBind(GL20TU_SECOND , r_bloomstate.texture_bloom ); if (r_glsl_permutation->loc_Texture_GammaRamps >= 0) R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps ); if (r_glsl_permutation->loc_ViewTintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]); - if (r_glsl_permutation->loc_ClientTime >= 0) qglUniform1fARB(r_glsl_permutation->loc_ClientTime , cl.time); if (r_glsl_permutation->loc_PixelSize >= 0) qglUniform2fARB(r_glsl_permutation->loc_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight); if (r_glsl_permutation->loc_UserVec1 >= 0) qglUniform4fARB(r_glsl_permutation->loc_UserVec1 , uservecs[0][0], uservecs[0][1], uservecs[0][2], uservecs[0][3]); if (r_glsl_permutation->loc_UserVec2 >= 0) qglUniform4fARB(r_glsl_permutation->loc_UserVec2 , uservecs[1][0], uservecs[1][1], uservecs[1][2], uservecs[1][3]); @@ -7535,7 +7805,6 @@ static void R_BlendView(void) if (r_cg_permutation->fp_Texture_Second ) CG_BindTexture(r_cg_permutation->fp_Texture_Second , r_bloomstate.texture_bloom );CHECKCGERROR if (r_cg_permutation->fp_Texture_GammaRamps) CG_BindTexture(r_cg_permutation->fp_Texture_GammaRamps, r_texture_gammaramps );CHECKCGERROR if (r_cg_permutation->fp_ViewTintColor ) cgGLSetParameter4f( r_cg_permutation->fp_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);CHECKCGERROR - if (r_cg_permutation->fp_ClientTime ) cgGLSetParameter1f( r_cg_permutation->fp_ClientTime , cl.time);CHECKCGERROR if (r_cg_permutation->fp_PixelSize ) cgGLSetParameter2f( r_cg_permutation->fp_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);CHECKCGERROR if (r_cg_permutation->fp_UserVec1 ) cgGLSetParameter4f( r_cg_permutation->fp_UserVec1 , uservecs[0][0], uservecs[0][1], uservecs[0][2], uservecs[0][3]);CHECKCGERROR if (r_cg_permutation->fp_UserVec2 ) cgGLSetParameter4f( r_cg_permutation->fp_UserVec2 , uservecs[1][0], uservecs[1][1], uservecs[1][2], uservecs[1][3]);CHECKCGERROR @@ -7770,6 +8039,7 @@ void R_RenderView(void) { if (r_timereport_active) R_TimeReport("start"); + r_textureframe++; // used only by R_GetCurrentTexture rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity if (!r_drawentities.integer) @@ -7829,7 +8099,11 @@ void R_RenderView(void) // this produces a bloom texture to be used in R_BlendView() later if (r_hdr.integer && r_bloomstate.bloomwidth) + { R_HDR_RenderBloomTexture(); + // we have to bump the texture frame again because r_refdef.view.colorscale is cached in the textures + r_textureframe++; // used only by R_GetCurrentTexture + } r_refdef.view.showdebug = true; @@ -7890,7 +8164,6 @@ extern qboolean r_shadow_usingdeferredprepass; void R_RenderScene(void) { r_refdef.stats.renders++; - r_textureframe++; // used only by R_GetCurrentTexture R_UpdateFogColor(); @@ -7923,8 +8196,11 @@ void R_RenderScene(void) if (skyrendermasked && skyrenderlater) { // we have to force off the water clipping plane while rendering sky + qboolean save = r_refdef.view.showdebug; R_SetupView(false); + r_refdef.view.showdebug = false; R_Sky(); + r_refdef.view.showdebug = save; R_SetupView(true); if (r_timereport_active) R_TimeReport("sky"); @@ -8584,7 +8860,7 @@ void R_LoadQWSkin(r_qwskincache_t *cache, const char *skinname) f = FS_LoadFile(name, tempmempool, true, &filesize); if (f) { - if (LoadPCX_QWSkin(f, filesize, pixels, 296, 194)) + if (LoadPCX_QWSkin(f, (int)filesize, pixels, 296, 194)) skinframe = R_SkinFrame_LoadInternalQuake(name, textureflags, true, r_fullbrights.integer, pixels, image_width, image_height); Mem_Free(f); } @@ -8722,6 +8998,7 @@ texture_t *R_GetCurrentTexture(texture_t *t) t->glosstexture = r_texture_black; t->glowtexture = t->currentskinframe->glow; t->fogtexture = t->currentskinframe->fog; + t->reflectmasktexture = t->currentskinframe->reflect; if (t->backgroundnumskinframes) { t->backgroundbasetexture = (!t->colormapping && t->backgroundcurrentskinframe->merged) ? t->backgroundcurrentskinframe->merged : t->backgroundcurrentskinframe->base; @@ -8775,6 +9052,7 @@ texture_t *R_GetCurrentTexture(texture_t *t) t->glosstexture = r_texture_black; t->glowtexture = NULL; t->fogtexture = NULL; + t->reflectmasktexture = NULL; t->backgroundbasetexture = NULL; t->backgroundnmaptexture = r_texture_blanknormalmap; t->backgroundglosstexture = r_texture_black; @@ -10317,12 +10595,14 @@ extern rtexture_t *r_shadow_prepasslightingdiffusetexture; extern rtexture_t *r_shadow_prepasslightingspeculartexture; static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass) { + if (r_waterstate.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION))) + return; RSurf_PrepareVerticesForBatch(true, true, texturenumsurfaces, texturesurfacelist); if (prepass) { // render screenspace normalmap to texture GL_DepthMask(true); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, prepass ? RSURFPASS_DEFERREDGEOMETRY : RSURFPASS_BASE); + R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_DEFERREDGEOMETRY); RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); } else if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION)) && !r_waterstate.renderingscene) @@ -10332,14 +10612,17 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BACKGROUND); RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist); GL_DepthMask(false); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, prepass ? RSURFPASS_DEFERREDGEOMETRY : RSURFPASS_BASE); - RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist); + R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE); + if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) + RSurf_DrawBatch_WithLightmapSwitching(texturenumsurfaces, texturesurfacelist); + else + RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); } else { // render surface normally GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, prepass ? RSURFPASS_DEFERREDGEOMETRY : RSURFPASS_BASE); + R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE); if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist); else if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) @@ -10398,7 +10681,7 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, const msurface { case TEXTURELAYERTYPE_LITTEXTURE: // single-pass lightmapped texture with 2x rgbscale - //R_Mesh_TexBind(0, r_texture_white); + R_Mesh_TexBind(0, r_texture_white); R_Mesh_TexMatrix(0, NULL); R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1); R_Mesh_TexCoordPointer(0, 2, rsurface.modeltexcoordlightmap2f, rsurface.modeltexcoordlightmap2f_bufferobject, rsurface.modeltexcoordlightmap2f_bufferoffset); @@ -10503,7 +10786,7 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, const msurface { // two-pass lit texture with 2x rgbscale // first the lightmap pass - //R_Mesh_TexBind(0, r_texture_white); + R_Mesh_TexBind(0, r_texture_white); R_Mesh_TexMatrix(0, NULL); R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1); R_Mesh_TexCoordPointer(0, 2, rsurface.modeltexcoordlightmap2f, rsurface.modeltexcoordlightmap2f_bufferobject, rsurface.modeltexcoordlightmap2f_bufferoffset); @@ -11153,7 +11436,6 @@ static void R_DecalSystem_SpawnTriangle(decalsystem_t *decalsystem, const float tridecal_t *decal; tridecal_t *decals; int i; - int maxdecals; // expand or initialize the system if (decalsystem->maxdecals <= decalsystem->numdecals) @@ -11180,7 +11462,6 @@ static void R_DecalSystem_SpawnTriangle(decalsystem_t *decalsystem, const float } // grab a decal and search for another free slot for the next one - maxdecals = decalsystem->maxdecals; decals = decalsystem->decals; decal = decalsystem->decals + (i = decalsystem->freedecal++); for (i = decalsystem->freedecal;i < decalsystem->numdecals && decals[i].color4ub[0][3];i++) @@ -11237,13 +11518,11 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor const msurface_t *surfaces; const int *surfacelist; const texture_t *texture; - int numvertices; int numtriangles; int numsurfacelist; int surfacelistindex; int surfaceindex; int triangleindex; - int decalsurfaceindex; int cornerindex; int index; int numpoints; @@ -11253,7 +11532,6 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor float localmins[3]; float localmaxs[3]; float localsize; - float ilocalsize; float v[9][3]; float tc[9][2]; float c[9][4]; @@ -11289,7 +11567,6 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor Matrix4x4_Transform3x3(&rsurface.inversematrix, worldnormal, localnormal); VectorNormalize(localnormal); localsize = worldsize*rsurface.inversematrixscale; - ilocalsize = 1.0f / localsize; localmins[0] = localorigin[0] - localsize; localmins[1] = localorigin[1] - localsize; localmins[2] = localorigin[2] - localsize; @@ -11350,16 +11627,15 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor { surfaceindex = surfacelist[surfacelistindex]; surface = surfaces + surfaceindex; + // check cull box first because it rejects more than any other check + if (!dynamic && !BoxesOverlap(surface->mins, surface->maxs, localmins, localmaxs)) + continue; // skip transparent surfaces texture = surface->texture; if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION)) continue; if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS) continue; - if (!dynamic && !BoxesOverlap(surface->mins, surface->maxs, localmins, localmaxs)) - continue; - decalsurfaceindex = ent == r_refdef.scene.worldentity ? surfaceindex : -1; - numvertices = surface->num_vertices; numtriangles = surface->num_triangles; for (triangleindex = 0, e = model->surfmesh.data_element3i + 3*surface->num_firsttriangle;triangleindex < numtriangles;triangleindex++, e += 3) { @@ -11469,7 +11745,6 @@ typedef struct r_decalsystem_splatqueue_s r_decalsystem_splatqueue_t; int r_decalsystem_numqueued = 0; -#define MAX_DECALSYSTEM_QUEUE 1024 r_decalsystem_splatqueue_t r_decalsystem_queue[MAX_DECALSYSTEM_QUEUE]; void R_DecalSystem_SplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize) @@ -11575,7 +11850,6 @@ static void R_DrawModelDecals_Entity(entity_render_t *ent) decalsystem_t *decalsystem = &ent->decalsystem; int numdecals; tridecal_t *decal; - float fadedelay; float faderate; float alpha; float *v3f; @@ -11609,7 +11883,6 @@ static void R_DrawModelDecals_Entity(entity_render_t *ent) decalsystem->lastupdatetime = cl.time; decal = decalsystem->decals; - fadedelay = cl_decals_time.value; faderate = 1.0f / max(0.001f, cl_decals_fadetime.value); // update vertex positions for animated models @@ -11755,7 +12028,6 @@ void R_DrawDebugModel(void) { entity_render_t *ent = rsurface.entity; int i, j, k, l, flagsmask; - const int *elements; q3mbrush_t *brush; const msurface_t *surface; dp_model_t *model = ent->model; @@ -11824,7 +12096,6 @@ void R_DrawDebugModel(void) GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, r_showtris.value); else GL_Color(0, r_refdef.view.colorscale, 0, r_showtris.value); - elements = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle); R_Mesh_VertexPointer(rsurface.vertex3f, 0, 0); R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_TexCoordPointer(0, 0, NULL, 0, 0); @@ -11899,8 +12170,7 @@ int r_maxsurfacelist = 0; const msurface_t **r_surfacelist = NULL; void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass) { - int i, j, endj, f, flagsmask; - texture_t *t; + int i, j, endj, flagsmask; dp_model_t *model = r_refdef.scene.worldmodel; msurface_t *surfaces; unsigned char *update; @@ -11946,8 +12216,6 @@ void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean dep return; } - f = 0; - t = NULL; rsurface.uselightmaptexture = false; rsurface.texture = NULL; rsurface.rtlight = NULL; @@ -11996,8 +12264,7 @@ void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean dep void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass) { - int i, j, endj, f, flagsmask; - texture_t *t; + int i, j, endj, flagsmask; dp_model_t *model = ent->model; msurface_t *surfaces; unsigned char *update; @@ -12067,8 +12334,6 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr return; } - f = 0; - t = NULL; rsurface.uselightmaptexture = false; rsurface.texture = NULL; rsurface.rtlight = NULL;