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"};
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;
"#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"
" 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"
"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"
"\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"
"\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"
" // 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"
" 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"
"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"
" 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"
" 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"
" 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"
"#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"
"#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"
"#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"
"\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"
" // 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"
"#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"
"#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"
"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"
" 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"
" 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"
" 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"
"#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"
"#endif // !MODE_DEPTH_OR_SHADOW\n"
;
+char *glslshaderstring = NULL;
+char *cgshaderstring = NULL;
+
//=======================================================================================================================================================
typedef struct shaderpermutationinfo_s
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;
{"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"},
{"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
{"#define USEALPHAKILL\n", " alphakill"},
+ {"#define USEREFLECTCUBE\n", " reflectcube"},
};
/// this enum is multiplied by SHADERPERMUTATION_MODEBASE
{
{"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"},
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;
int loc_ModelViewProjectionMatrix;
int loc_ModelViewMatrix;
int loc_PixelToScreenTexCoord;
+ int loc_ModelToReflectCube;
}
r_glsl_permutation_t;
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)
{
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;
}
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");
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);
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);
}
}
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
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;
CGparameter fp_ViewTintColor;
CGparameter fp_ViewToLight;
CGparameter fp_PixelToScreenTexCoord;
+ CGparameter fp_ModelToReflectCube;
}
r_cg_permutation_t;
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)
{
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;
const char *geomstrings_list[32+3];
const char *fragstrings_list[32+3];
char permutationname[256];
+ char cachename[256];
CGprofile vertexProfile;
CGprofile fragmentProfile;
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)
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++)
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
{
}
}
+ // 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;
//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]))
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)
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:
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))
{
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))
{
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))
{
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))
{
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)
{
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);}
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 );
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
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
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;
}
}
// 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;
}
skinframe->gloss = NULL;
skinframe->glow = NULL;
skinframe->fog = NULL;
+ skinframe->reflect = NULL;
skinframe->hasalpha = false;
if (ddsbase)
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);
// _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)
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)
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)
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)
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);
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
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
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
skinframe->gloss = NULL;
skinframe->glow = NULL;
skinframe->fog = NULL;
+ skinframe->reflect = NULL;
skinframe->hasalpha = false;
skinframe->avgcolor[0] = rand() / RAND_MAX;
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)
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;
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));
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));
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);
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);
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
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]);
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
{
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)
// 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;
void R_RenderScene(void)
{
r_refdef.stats.renders++;
- r_textureframe++; // used only by R_GetCurrentTexture
R_UpdateFogColor();
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");
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);
}
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;
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;
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)
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))
{
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);
{
// 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);
tridecal_t *decal;
tridecal_t *decals;
int i;
- int maxdecals;
// expand or initialize the system
if (decalsystem->maxdecals <= decalsystem->numdecals)
}
// 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++)
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;
float localmins[3];
float localmaxs[3];
float localsize;
- float ilocalsize;
float v[9][3];
float tc[9][2];
float c[9][4];
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;
{
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)
{
decalsystem_t *decalsystem = &ent->decalsystem;
int numdecals;
tridecal_t *decal;
- float fadedelay;
float faderate;
float alpha;
float *v3f;
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
{
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;
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);
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;
return;
}
- f = 0;
- t = NULL;
rsurface.uselightmaptexture = false;
rsurface.texture = NULL;
rsurface.rtlight = NULL;
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;
return;
}
- f = 0;
- t = NULL;
rsurface.uselightmaptexture = false;
rsurface.texture = NULL;
rsurface.rtlight = NULL;