"uniform sampler2D Texture_Normal;\n"
"uniform sampler2D Texture_Color;\n"
"uniform sampler2D Texture_Gloss;\n"
-"uniform samplerCube Texture_Cube;\n"
-"uniform sampler2D Texture_Attenuation;\n"
-"uniform sampler2D Texture_FogMask;\n"
+"uniform sampler2D Texture_Glow;\n"
+"uniform sampler2D Texture_SecondaryNormal;\n"
+"uniform sampler2D Texture_SecondaryColor;\n"
+"uniform sampler2D Texture_SecondaryGloss;\n"
+"uniform sampler2D Texture_SecondaryGlow;\n"
"uniform sampler2D Texture_Pants;\n"
"uniform sampler2D Texture_Shirt;\n"
+"uniform sampler2D Texture_FogMask;\n"
"uniform sampler2D Texture_Lightmap;\n"
"uniform sampler2D Texture_Deluxemap;\n"
-"uniform sampler2D Texture_Glow;\n"
-"uniform sampler2D Texture_Reflection;\n"
"uniform sampler2D Texture_Refraction;\n"
+"uniform sampler2D Texture_Reflection;\n"
+"uniform sampler2D Texture_Attenuation;\n"
+"uniform samplerCube Texture_Cube;\n"
"\n"
"uniform myhalf3 LightColor;\n"
"uniform myhalf3 AmbientColor;\n"
" vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
" //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
" vec4 ScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect + vec2(normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5))).xyxy * DistortScaleRefractReflect;\n"
-" float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 5.0) * ReflectFactor + ReflectOffset;\n"
+" float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * ReflectFactor + ReflectOffset;\n"
" gl_FragColor = mix(texture2D(Texture_Refraction, ScreenTexCoord.xy) * RefractColor, texture2D(Texture_Reflection, ScreenTexCoord.zw) * ReflectColor, Fresnel);\n"
"}\n"
"\n"
"#ifdef USECOLORMAPPING\n"
" color.rgb += myhalf3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + myhalf3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
"#endif\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+" myhalf terrainblend = clamp(myhalf(gl_Color.a) * color.a * 2.0 - 0.5, myhalf(0.0), myhalf(1.0));\n"
+" //myhalf terrainblend = min(myhalf(gl_Color.a) * color.a * 2.0, myhalf(1.0));\n"
+" //myhalf terrainblend = myhalf(gl_Color.a) * color.a > 0.5;\n"
+" color = mix(myhalf4(texture2D(Texture_SecondaryColor, TexCoord)), color, terrainblend);\n"
+" //color = mix(myhalf4(1, 0, 0, 1), color, terrainblend);\n"
+"#endif\n"
"\n"
+"#ifdef USEDIFFUSE\n"
+" // get the surface normal and the gloss color\n"
+"# ifdef USEVERTEXTEXTUREBLEND\n"
+" myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord)), myhalf3(texture2D(Texture_Normal, TexCoord)), terrainblend) - myhalf3(0.5, 0.5, 0.5));\n"
+"# ifdef USESPECULAR\n"
+" myhalf3 glosscolor = mix(myhalf3(texture2D(Texture_SecondaryGloss, TexCoord)), myhalf3(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n"
+"# endif\n"
+"# else\n"
+" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5));\n"
+"# ifdef USESPECULAR\n"
+" myhalf3 glosscolor = myhalf3(texture2D(Texture_Gloss, TexCoord));\n"
+"# endif\n"
+"# endif\n"
+"#endif\n"
"\n"
"\n"
"\n"
" // compute color intensity for the two textures (colormap and glossmap)\n"
" // scale by light color and attenuation as efficiently as possible\n"
" // (do as much scalar math as possible rather than vector math)\n"
-"# ifdef USESPECULAR\n"
-" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5));\n"
+"# ifdef USEDIFFUSE\n"
+" // get the light normal\n"
" myhalf3 diffusenormal = myhalf3(normalize(LightVector));\n"
+"# endif\n"
+"# ifdef USESPECULAR\n"
" myhalf3 specularnormal = normalize(diffusenormal + myhalf3(normalize(EyeVector)));\n"
"\n"
" // calculate directional shading\n"
-" color.rgb = LightColor * myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))) + (SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower)) * myhalf3(texture2D(Texture_Gloss, TexCoord)));\n"
+" color.rgb = myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))) + (SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower)) * glosscolor);\n"
"# else\n"
"# ifdef USEDIFFUSE\n"
-" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5));\n"
-" myhalf3 diffusenormal = myhalf3(normalize(LightVector));\n"
-"\n"
" // calculate directional shading\n"
-" color.rgb = color.rgb * LightColor * (myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))));\n"
+" color.rgb = color.rgb * (myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))));\n"
"# else\n"
" // calculate directionless shading\n"
-" color.rgb = color.rgb * LightColor * myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
+" color.rgb = color.rgb * myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
"# endif\n"
"# endif\n"
"\n"
"\n"
"#ifdef MODE_LIGHTDIRECTION\n"
" // directional model lighting\n"
-"# ifdef USESPECULAR\n"
-" // get the surface normal and light normal\n"
-" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5));\n"
+"# ifdef USEDIFFUSE\n"
+" // get the light normal\n"
" myhalf3 diffusenormal = myhalf3(LightVector);\n"
-"\n"
+"# endif\n"
+"# ifdef USESPECULAR\n"
" // calculate directional shading\n"
" color.rgb *= AmbientColor + DiffuseColor * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0));\n"
" myhalf3 specularnormal = normalize(diffusenormal + myhalf3(normalize(EyeVector)));\n"
" color.rgb += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
"# else\n"
"# ifdef USEDIFFUSE\n"
-" // get the surface normal and light normal\n"
-" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5));\n"
-" myhalf3 diffusenormal = myhalf3(LightVector);\n"
"\n"
" // calculate directional shading\n"
" color.rgb *= AmbientColor + DiffuseColor * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0));\n"
" color.rgb *= AmbientColor;\n"
"# endif\n"
"# endif\n"
-"\n"
-" color.a *= TintColor.a;\n"
"#endif // MODE_LIGHTDIRECTION\n"
"\n"
"\n"
"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
" // deluxemap lightmapping using light vectors in modelspace (evil q3map2)\n"
"\n"
-" // get the surface normal and light normal\n"
-" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5));\n"
-"\n"
+" // get the light normal\n"
" myhalf3 diffusenormal_modelspace = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - myhalf3(0.5);\n"
" myhalf3 diffusenormal = normalize(myhalf3(dot(diffusenormal_modelspace, myhalf3(VectorS)), dot(diffusenormal_modelspace, myhalf3(VectorT)), dot(diffusenormal_modelspace, myhalf3(VectorR))));\n"
" // calculate directional shading\n"
"\n"
" // apply lightmap color\n"
" color.rgb = color.rgb * AmbientScale + tempcolor * myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
-"\n"
-" color *= TintColor;\n"
"#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
"\n"
"\n"
"#ifdef MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
" // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n"
"\n"
-" // get the surface normal and light normal\n"
-" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5));\n"
-"\n"
+" // get the light normal\n"
" myhalf3 diffusenormal = normalize(myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - myhalf3(0.5));\n"
" // calculate directional shading\n"
" myhalf3 tempcolor = color.rgb * (DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0)));\n"
"\n"
" // apply lightmap color\n"
" color.rgb = color.rgb * AmbientScale + tempcolor * myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
-"\n"
-" color *= TintColor;\n"
"#endif // MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
"\n"
"\n"
"#ifdef MODE_LIGHTMAP\n"
" // apply lightmap color\n"
" color.rgb = color.rgb * myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap)) * DiffuseScale + color.rgb * AmbientScale;\n"
-"\n"
-" color *= TintColor;\n"
"#endif // MODE_LIGHTMAP\n"
"\n"
"\n"
"#ifdef MODE_VERTEXCOLOR\n"
" // apply lightmap color\n"
" color.rgb = color.rgb * myhalf3(gl_Color.rgb) * DiffuseScale + color.rgb * AmbientScale;\n"
-"\n"
-" color *= TintColor;\n"
"#endif // MODE_VERTEXCOLOR\n"
"\n"
"\n"
"\n"
"\n"
"#ifdef MODE_FLATCOLOR\n"
-" color *= TintColor;\n"
"#endif // MODE_FLATCOLOR\n"
"\n"
"\n"
"\n"
"\n"
"\n"
+" color *= TintColor;\n"
"\n"
"#ifdef USEGLOW\n"
" color.rgb += myhalf3(texture2D(Texture_Glow, TexCoord)) * GlowScale;\n"
typedef enum shaderpermutation_e
{
- SHADERPERMUTATION_COLORMAPPING = 1<<0, // indicates this is a colormapped skin
- SHADERPERMUTATION_CONTRASTBOOST = 1<<1, // r_glsl_contrastboost boosts the contrast at low color levels (similar to gamma)
- SHADERPERMUTATION_FOG = 1<<2, // tint the color by fog color or black if using additive blend mode
- SHADERPERMUTATION_CUBEFILTER = 1<<3, // (lightsource) use cubemap light filter
- SHADERPERMUTATION_GLOW = 1<<4, // (lightmap) blend in an additive glow texture
- SHADERPERMUTATION_DIFFUSE = 1<<5, // (lightsource) whether to use directional shading
- SHADERPERMUTATION_SPECULAR = 1<<6, // (lightsource or deluxemapping) render specular effects
- SHADERPERMUTATION_REFLECTION = 1<<7, // normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
- SHADERPERMUTATION_OFFSETMAPPING = 1<<8, // adjust texcoords to roughly simulate a displacement mapped surface
- SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<9, // adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
- SHADERPERMUTATION_LIMIT = 1<<10, // size of permutations array
- SHADERPERMUTATION_COUNT = 10 // size of shaderpermutationinfo array
+ SHADERPERMUTATION_DIFFUSE = 1<<0, // (lightsource) whether to use directional shading
+ SHADERPERMUTATION_VERTEXTEXTUREBLEND = 1<<1, // indicates this is a two-layer material blend based on vertex alpha (q3bsp)
+ SHADERPERMUTATION_COLORMAPPING = 1<<2, // indicates this is a colormapped skin
+ SHADERPERMUTATION_CONTRASTBOOST = 1<<3, // r_glsl_contrastboost boosts the contrast at low color levels (similar to gamma)
+ SHADERPERMUTATION_FOG = 1<<4, // tint the color by fog color or black if using additive blend mode
+ SHADERPERMUTATION_CUBEFILTER = 1<<5, // (lightsource) use cubemap light filter
+ SHADERPERMUTATION_GLOW = 1<<6, // (lightmap) blend in an additive glow texture
+ SHADERPERMUTATION_SPECULAR = 1<<7, // (lightsource or deluxemapping) render specular effects
+ SHADERPERMUTATION_REFLECTION = 1<<8, // normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
+ SHADERPERMUTATION_OFFSETMAPPING = 1<<9, // adjust texcoords to roughly simulate a displacement mapped surface
+ SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<10, // adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
+ SHADERPERMUTATION_LIMIT = 1<<11, // size of permutations array
+ SHADERPERMUTATION_COUNT = 11 // size of shaderpermutationinfo array
}
shaderpermutation_t;
// NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
{
+ {"#define USEDIFFUSE\n", " diffuse"},
+ {"#define USEVERTEXTEXTUREBLEND\n", " vertextextureblend"},
{"#define USECOLORMAPPING\n", " colormapping"},
{"#define USECONTRASTBOOST\n", " contrastboost"},
{"#define USEFOG\n", " fog"},
{"#define USECUBEFILTER\n", " cubefilter"},
{"#define USEGLOW\n", " glow"},
- {"#define USEDIFFUSE\n", " diffuse"},
{"#define USESPECULAR\n", " specular"},
{"#define USEREFLECTION\n", " reflection"},
{"#define USEOFFSETMAPPING\n", " offsetmapping"},
int loc_Texture_Normal;
int loc_Texture_Color;
int loc_Texture_Gloss;
- int loc_Texture_Cube;
- int loc_Texture_Attenuation;
- int loc_Texture_FogMask;
+ int loc_Texture_Glow;
+ int loc_Texture_SecondaryNormal;
+ int loc_Texture_SecondaryColor;
+ int loc_Texture_SecondaryGloss;
+ int loc_Texture_SecondaryGlow;
int loc_Texture_Pants;
int loc_Texture_Shirt;
+ int loc_Texture_FogMask;
int loc_Texture_Lightmap;
int loc_Texture_Deluxemap;
- int loc_Texture_Glow;
+ int loc_Texture_Attenuation;
+ int loc_Texture_Cube;
int loc_Texture_Refraction;
int loc_Texture_Reflection;
int loc_FogColor;
int loc_LightPosition;
int loc_EyePosition;
- int loc_LightColor;
int loc_Color_Pants;
int loc_Color_Shirt;
int loc_FogRangeRecip;
qglUseProgramObjectARB(p->program);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
- p->loc_Texture_Normal = qglGetUniformLocationARB(p->program, "Texture_Normal");
- p->loc_Texture_Color = qglGetUniformLocationARB(p->program, "Texture_Color");
- p->loc_Texture_Gloss = qglGetUniformLocationARB(p->program, "Texture_Gloss");
- p->loc_Texture_Cube = qglGetUniformLocationARB(p->program, "Texture_Cube");
- p->loc_Texture_Attenuation = qglGetUniformLocationARB(p->program, "Texture_Attenuation");
- p->loc_Texture_FogMask = qglGetUniformLocationARB(p->program, "Texture_FogMask");
- p->loc_Texture_Pants = qglGetUniformLocationARB(p->program, "Texture_Pants");
- p->loc_Texture_Shirt = qglGetUniformLocationARB(p->program, "Texture_Shirt");
- p->loc_Texture_Lightmap = qglGetUniformLocationARB(p->program, "Texture_Lightmap");
- p->loc_Texture_Deluxemap = qglGetUniformLocationARB(p->program, "Texture_Deluxemap");
- p->loc_Texture_Glow = qglGetUniformLocationARB(p->program, "Texture_Glow");
- p->loc_Texture_Refraction = qglGetUniformLocationARB(p->program, "Texture_Refraction");
- p->loc_Texture_Reflection = qglGetUniformLocationARB(p->program, "Texture_Reflection");
- p->loc_FogColor = qglGetUniformLocationARB(p->program, "FogColor");
- p->loc_LightPosition = qglGetUniformLocationARB(p->program, "LightPosition");
- p->loc_EyePosition = qglGetUniformLocationARB(p->program, "EyePosition");
- p->loc_LightColor = qglGetUniformLocationARB(p->program, "LightColor");
- p->loc_Color_Pants = qglGetUniformLocationARB(p->program, "Color_Pants");
- p->loc_Color_Shirt = qglGetUniformLocationARB(p->program, "Color_Shirt");
- p->loc_FogRangeRecip = qglGetUniformLocationARB(p->program, "FogRangeRecip");
- p->loc_AmbientScale = qglGetUniformLocationARB(p->program, "AmbientScale");
- p->loc_DiffuseScale = qglGetUniformLocationARB(p->program, "DiffuseScale");
- p->loc_SpecularPower = qglGetUniformLocationARB(p->program, "SpecularPower");
- p->loc_SpecularScale = qglGetUniformLocationARB(p->program, "SpecularScale");
- p->loc_GlowScale = qglGetUniformLocationARB(p->program, "GlowScale");
- p->loc_SceneBrightness = qglGetUniformLocationARB(p->program, "SceneBrightness");
- p->loc_OffsetMapping_Scale = qglGetUniformLocationARB(p->program, "OffsetMapping_Scale");
- p->loc_TintColor = qglGetUniformLocationARB(p->program, "TintColor");
- p->loc_AmbientColor = qglGetUniformLocationARB(p->program, "AmbientColor");
- p->loc_DiffuseColor = qglGetUniformLocationARB(p->program, "DiffuseColor");
- p->loc_SpecularColor = qglGetUniformLocationARB(p->program, "SpecularColor");
- p->loc_LightDir = qglGetUniformLocationARB(p->program, "LightDir");
- p->loc_ContrastBoostCoeff = qglGetUniformLocationARB(p->program, "ContrastBoostCoeff");
+ p->loc_Texture_Normal = qglGetUniformLocationARB(p->program, "Texture_Normal");
+ p->loc_Texture_Color = qglGetUniformLocationARB(p->program, "Texture_Color");
+ p->loc_Texture_Gloss = qglGetUniformLocationARB(p->program, "Texture_Gloss");
+ p->loc_Texture_Glow = qglGetUniformLocationARB(p->program, "Texture_Glow");
+ p->loc_Texture_SecondaryNormal = qglGetUniformLocationARB(p->program, "Texture_SecondaryNormal");
+ p->loc_Texture_SecondaryColor = qglGetUniformLocationARB(p->program, "Texture_SecondaryColor");
+ p->loc_Texture_SecondaryGloss = qglGetUniformLocationARB(p->program, "Texture_SecondaryGloss");
+ p->loc_Texture_SecondaryGlow = qglGetUniformLocationARB(p->program, "Texture_SecondaryGlow");
+ p->loc_Texture_FogMask = qglGetUniformLocationARB(p->program, "Texture_FogMask");
+ p->loc_Texture_Pants = qglGetUniformLocationARB(p->program, "Texture_Pants");
+ p->loc_Texture_Shirt = qglGetUniformLocationARB(p->program, "Texture_Shirt");
+ p->loc_Texture_Lightmap = qglGetUniformLocationARB(p->program, "Texture_Lightmap");
+ p->loc_Texture_Deluxemap = qglGetUniformLocationARB(p->program, "Texture_Deluxemap");
+ p->loc_Texture_Refraction = qglGetUniformLocationARB(p->program, "Texture_Refraction");
+ p->loc_Texture_Reflection = qglGetUniformLocationARB(p->program, "Texture_Reflection");
+ p->loc_Texture_Attenuation = qglGetUniformLocationARB(p->program, "Texture_Attenuation");
+ p->loc_Texture_Cube = qglGetUniformLocationARB(p->program, "Texture_Cube");
+ p->loc_FogColor = qglGetUniformLocationARB(p->program, "FogColor");
+ p->loc_LightPosition = qglGetUniformLocationARB(p->program, "LightPosition");
+ p->loc_EyePosition = qglGetUniformLocationARB(p->program, "EyePosition");
+ p->loc_Color_Pants = qglGetUniformLocationARB(p->program, "Color_Pants");
+ p->loc_Color_Shirt = qglGetUniformLocationARB(p->program, "Color_Shirt");
+ p->loc_FogRangeRecip = qglGetUniformLocationARB(p->program, "FogRangeRecip");
+ p->loc_AmbientScale = qglGetUniformLocationARB(p->program, "AmbientScale");
+ p->loc_DiffuseScale = qglGetUniformLocationARB(p->program, "DiffuseScale");
+ p->loc_SpecularPower = qglGetUniformLocationARB(p->program, "SpecularPower");
+ p->loc_SpecularScale = qglGetUniformLocationARB(p->program, "SpecularScale");
+ p->loc_GlowScale = qglGetUniformLocationARB(p->program, "GlowScale");
+ p->loc_SceneBrightness = qglGetUniformLocationARB(p->program, "SceneBrightness");
+ p->loc_OffsetMapping_Scale = qglGetUniformLocationARB(p->program, "OffsetMapping_Scale");
+ p->loc_TintColor = qglGetUniformLocationARB(p->program, "TintColor");
+ p->loc_AmbientColor = qglGetUniformLocationARB(p->program, "AmbientColor");
+ p->loc_DiffuseColor = qglGetUniformLocationARB(p->program, "DiffuseColor");
+ p->loc_SpecularColor = qglGetUniformLocationARB(p->program, "SpecularColor");
+ p->loc_LightDir = qglGetUniformLocationARB(p->program, "LightDir");
+ p->loc_ContrastBoostCoeff = qglGetUniformLocationARB(p->program, "ContrastBoostCoeff");
p->loc_DistortScaleRefractReflect = qglGetUniformLocationARB(p->program, "DistortScaleRefractReflect");
- p->loc_ScreenScaleRefractReflect = qglGetUniformLocationARB(p->program, "ScreenScaleRefractReflect");
+ p->loc_ScreenScaleRefractReflect = qglGetUniformLocationARB(p->program, "ScreenScaleRefractReflect");
p->loc_ScreenCenterRefractReflect = qglGetUniformLocationARB(p->program, "ScreenCenterRefractReflect");
- p->loc_RefractColor = qglGetUniformLocationARB(p->program, "RefractColor");
- p->loc_ReflectColor = qglGetUniformLocationARB(p->program, "ReflectColor");
- p->loc_ReflectFactor = qglGetUniformLocationARB(p->program, "ReflectFactor");
- p->loc_ReflectOffset = qglGetUniformLocationARB(p->program, "ReflectOffset");
+ p->loc_RefractColor = qglGetUniformLocationARB(p->program, "RefractColor");
+ p->loc_ReflectColor = qglGetUniformLocationARB(p->program, "ReflectColor");
+ p->loc_ReflectFactor = qglGetUniformLocationARB(p->program, "ReflectFactor");
+ p->loc_ReflectOffset = qglGetUniformLocationARB(p->program, "ReflectOffset");
// initialize the samplers to refer to the texture units we use
- if (p->loc_Texture_Normal >= 0) qglUniform1iARB(p->loc_Texture_Normal, 0);
- if (p->loc_Texture_Color >= 0) qglUniform1iARB(p->loc_Texture_Color, 1);
- if (p->loc_Texture_Gloss >= 0) qglUniform1iARB(p->loc_Texture_Gloss, 2);
- if (p->loc_Texture_Cube >= 0) qglUniform1iARB(p->loc_Texture_Cube, 3);
- if (p->loc_Texture_FogMask >= 0) qglUniform1iARB(p->loc_Texture_FogMask, 4);
- if (p->loc_Texture_Pants >= 0) qglUniform1iARB(p->loc_Texture_Pants, 5);
- if (p->loc_Texture_Shirt >= 0) qglUniform1iARB(p->loc_Texture_Shirt, 6);
- if (p->loc_Texture_Lightmap >= 0) qglUniform1iARB(p->loc_Texture_Lightmap, 7);
- if (p->loc_Texture_Deluxemap >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap, 8);
- if (p->loc_Texture_Glow >= 0) qglUniform1iARB(p->loc_Texture_Glow, 9);
- if (p->loc_Texture_Attenuation >= 0) qglUniform1iARB(p->loc_Texture_Attenuation, 10);
- if (p->loc_Texture_Refraction >= 0) qglUniform1iARB(p->loc_Texture_Refraction, 11);
- if (p->loc_Texture_Reflection >= 0) qglUniform1iARB(p->loc_Texture_Reflection, 12);
+ if (p->loc_Texture_Normal >= 0) qglUniform1iARB(p->loc_Texture_Normal , GL20TU_NORMAL);
+ if (p->loc_Texture_Color >= 0) qglUniform1iARB(p->loc_Texture_Color , GL20TU_COLOR);
+ if (p->loc_Texture_Gloss >= 0) qglUniform1iARB(p->loc_Texture_Gloss , GL20TU_GLOSS);
+ if (p->loc_Texture_Glow >= 0) qglUniform1iARB(p->loc_Texture_Glow , GL20TU_GLOW);
+ if (p->loc_Texture_SecondaryNormal >= 0) qglUniform1iARB(p->loc_Texture_SecondaryNormal, GL20TU_SECONDARY_NORMAL);
+ if (p->loc_Texture_SecondaryColor >= 0) qglUniform1iARB(p->loc_Texture_SecondaryColor , GL20TU_SECONDARY_COLOR);
+ if (p->loc_Texture_SecondaryGloss >= 0) qglUniform1iARB(p->loc_Texture_SecondaryGloss , GL20TU_SECONDARY_GLOSS);
+ if (p->loc_Texture_SecondaryGlow >= 0) qglUniform1iARB(p->loc_Texture_SecondaryGlow , GL20TU_SECONDARY_GLOW);
+ if (p->loc_Texture_Pants >= 0) qglUniform1iARB(p->loc_Texture_Pants , GL20TU_PANTS);
+ if (p->loc_Texture_Shirt >= 0) qglUniform1iARB(p->loc_Texture_Shirt , GL20TU_SHIRT);
+ if (p->loc_Texture_FogMask >= 0) qglUniform1iARB(p->loc_Texture_FogMask , GL20TU_FOGMASK);
+ if (p->loc_Texture_Lightmap >= 0) qglUniform1iARB(p->loc_Texture_Lightmap , GL20TU_LIGHTMAP);
+ if (p->loc_Texture_Deluxemap >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap , GL20TU_DELUXEMAP);
+ if (p->loc_Texture_Attenuation >= 0) qglUniform1iARB(p->loc_Texture_Attenuation , GL20TU_ATTENUATION);
+ if (p->loc_Texture_Cube >= 0) qglUniform1iARB(p->loc_Texture_Cube , GL20TU_CUBE);
+ if (p->loc_Texture_Refraction >= 0) qglUniform1iARB(p->loc_Texture_Refraction , GL20TU_REFRACTION);
+ if (p->loc_Texture_Reflection >= 0) qglUniform1iARB(p->loc_Texture_Reflection , GL20TU_REFLECTION);
CHECKGLERROR
qglUseProgramObjectARB(0);CHECKGLERROR
if (developer.integer)
FS_Print(file, "// #define VERTEX_SHADER\n// #define GEOMETRY_SHADER\n// #define FRAGMENT_SHADER\n");
for (i = 0;i < SHADERMODE_COUNT;i++)
FS_Printf(file, "// %s", shadermodeinfo[i].pretext);
- for (i = 0;i < SHADERPERMUTATION_LIMIT;i++)
+ for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
FS_Printf(file, "// %s", shaderpermutationinfo[i].pretext);
FS_Print(file, "\n");
FS_Print(file, builtinshaderstring);
{
// light source
mode = SHADERMODE_LIGHTSOURCE;
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
+ permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
permutation |= SHADERPERMUTATION_CUBEFILTER;
if (diffusescale > 0)
{
// unshaded geometry (fullbright or ambient model lighting)
mode = SHADERMODE_FLATCOLOR;
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
+ permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
if (rsurface.texture->currentskinframe->glow)
permutation |= SHADERPERMUTATION_GLOW;
if (r_refdef.fogenabled)
{
// directional model lighting
mode = SHADERMODE_LIGHTDIRECTION;
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
+ permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
if (rsurface.texture->currentskinframe->glow)
permutation |= SHADERPERMUTATION_GLOW;
permutation |= SHADERPERMUTATION_DIFFUSE;
{
// ambient model lighting
mode = SHADERMODE_LIGHTDIRECTION;
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
+ permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
if (rsurface.texture->currentskinframe->glow)
permutation |= SHADERPERMUTATION_GLOW;
if (r_refdef.fogenabled)
// ordinary vertex coloring (q3bsp)
mode = SHADERMODE_VERTEXCOLOR;
}
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
+ permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
if (rsurface.texture->currentskinframe->glow)
permutation |= SHADERPERMUTATION_GLOW;
if (r_refdef.fogenabled)
if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
if (permutation & SHADERPERMUTATION_DIFFUSE)
{
- if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
+ if (r_glsl_permutation->loc_TintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_TintColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2], rsurface.texture->lightmapcolor[3]);
if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, ambientscale);
if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, diffusescale);
if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, specularscale);
else
{
// ambient only is simpler
- if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0] * ambientscale, lightcolorbase[1] * ambientscale, lightcolorbase[2] * ambientscale);
+ if (r_glsl_permutation->loc_TintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_TintColor, lightcolorbase[0] * ambientscale, lightcolorbase[1] * ambientscale, lightcolorbase[2] * ambientscale, rsurface.texture->lightmapcolor[3]);
if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, 1);
if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, 0);
if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, 0);
}
- }
- else if (mode == SHADERMODE_LIGHTDIRECTION)
- {
- if (r_glsl_permutation->loc_AmbientColor >= 0)
- qglUniform3fARB(r_glsl_permutation->loc_AmbientColor , rsurface.modellight_ambient[0] * ambientscale * rsurface.texture->lightmapcolor[0] * 0.5f, rsurface.modellight_ambient[1] * ambientscale * rsurface.texture->lightmapcolor[1] * 0.5f, rsurface.modellight_ambient[2] * ambientscale * rsurface.texture->lightmapcolor[2] * 0.5f);
- if (r_glsl_permutation->loc_DiffuseColor >= 0)
- qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor , rsurface.modellight_diffuse[0] * diffusescale * rsurface.texture->lightmapcolor[0] * 0.5f, rsurface.modellight_diffuse[1] * diffusescale * rsurface.texture->lightmapcolor[1] * 0.5f, rsurface.modellight_diffuse[2] * diffusescale * rsurface.texture->lightmapcolor[2] * 0.5f);
- if (r_glsl_permutation->loc_SpecularColor >= 0)
- qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, rsurface.modellight_diffuse[0] * specularscale * rsurface.texture->lightmapcolor[0] * 0.5f, rsurface.modellight_diffuse[1] * specularscale * rsurface.texture->lightmapcolor[1] * 0.5f, rsurface.modellight_diffuse[2] * specularscale * rsurface.texture->lightmapcolor[2] * 0.5f);
- if (r_glsl_permutation->loc_LightDir >= 0)
- qglUniform3fARB(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
+ // additive passes are only darkened by fog, not tinted
+ if (r_glsl_permutation->loc_FogColor >= 0)
+ qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
}
else
{
- if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_ambient.value * 1.0f / 128.0f);
- if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_refdef.lightmapintensity);
- if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_refdef.lightmapintensity * specularscale);
+ if (mode == SHADERMODE_LIGHTDIRECTION)
+ {
+ if (r_glsl_permutation->loc_AmbientColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_AmbientColor , rsurface.modellight_ambient[0] * ambientscale * 0.5f, rsurface.modellight_ambient[1] * ambientscale * 0.5f, rsurface.modellight_ambient[2] * ambientscale * 0.5f);
+ if (r_glsl_permutation->loc_DiffuseColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor , rsurface.modellight_diffuse[0] * diffusescale * 0.5f, rsurface.modellight_diffuse[1] * diffusescale * 0.5f, rsurface.modellight_diffuse[2] * diffusescale * 0.5f);
+ if (r_glsl_permutation->loc_SpecularColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, rsurface.modellight_diffuse[0] * specularscale * 0.5f, rsurface.modellight_diffuse[1] * specularscale * 0.5f, rsurface.modellight_diffuse[2] * specularscale * 0.5f);
+ if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
+ }
+ else
+ {
+ if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_ambient.value * 1.0f / 128.0f);
+ if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_refdef.lightmapintensity);
+ if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_refdef.lightmapintensity * specularscale);
+ }
+ if (r_glsl_permutation->loc_TintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_TintColor, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2], rsurface.texture->lightmapcolor[3]);
+ if (r_glsl_permutation->loc_GlowScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_GlowScale, r_hdr_glowintensity.value);
+ // additive passes are only darkened by fog, not tinted
+ if (r_glsl_permutation->loc_FogColor >= 0)
+ {
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
+ qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
+ else
+ qglUniform3fARB(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
+ }
+ if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
+ if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
+ if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
+ if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_RefractColor, 1, rsurface.texture->refractcolor4f);
+ if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_ReflectColor, 1, rsurface.texture->reflectcolor4f);
+ if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
+ if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
}
- if (r_glsl_permutation->loc_TintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_TintColor, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2], rsurface.texture->lightmapcolor[3]);
- if (r_glsl_permutation->loc_GlowScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_GlowScale, r_hdr_glowintensity.value);
if (r_glsl_permutation->loc_ContrastBoostCoeff >= 0)
{
// The formula used is actually:
}
else
if (r_glsl_permutation->loc_SceneBrightness >= 0) qglUniform1fARB(r_glsl_permutation->loc_SceneBrightness, r_refdef.view.colorscale);
- if (r_glsl_permutation->loc_FogColor >= 0)
- {
- // additive passes are only darkened by fog, not tinted
- if (rsurface.rtlight || (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD))
- qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
- else
- qglUniform3fARB(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
- }
if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface.modelorg[0], rsurface.modelorg[1], rsurface.modelorg[2]);
if (r_glsl_permutation->loc_Color_Pants >= 0)
{
if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, r_refdef.fograngerecip);
if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower);
if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
- if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
- if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
- if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
- if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_RefractColor, 1, rsurface.texture->refractcolor4f);
- if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_ReflectColor, 1, rsurface.texture->reflectcolor4f);
- if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
- if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
CHECKGLERROR
return permutation;
}
{
int i;
double slopex, slopey;
+ vec3_t forward, left, up, origin;
- // break apart the view matrix into vectors for various purposes
- Matrix4x4_ToVectors(&r_refdef.view.matrix, r_refdef.view.forward, r_refdef.view.left, r_refdef.view.up, r_refdef.view.origin);
- VectorNegate(r_refdef.view.left, r_refdef.view.right);
+ // we can't trust r_refdef.view.forward and friends in reflected scenes
+ Matrix4x4_ToVectors(&r_refdef.view.matrix, forward, left, up, origin);
#if 0
r_refdef.view.frustum[0].normal[0] = 0 - 1.0 / r_refdef.view.frustum_x;
{
slopex = 1.0 / r_refdef.view.frustum_x;
slopey = 1.0 / r_refdef.view.frustum_y;
- VectorMA(r_refdef.view.forward, -slopex, r_refdef.view.left, r_refdef.view.frustum[0].normal);
- VectorMA(r_refdef.view.forward, slopex, r_refdef.view.left, r_refdef.view.frustum[1].normal);
- VectorMA(r_refdef.view.forward, -slopey, r_refdef.view.up , r_refdef.view.frustum[2].normal);
- VectorMA(r_refdef.view.forward, slopey, r_refdef.view.up , r_refdef.view.frustum[3].normal);
- VectorCopy(r_refdef.view.forward, r_refdef.view.frustum[4].normal);
+ VectorMA(forward, -slopex, left, r_refdef.view.frustum[0].normal);
+ VectorMA(forward, slopex, left, r_refdef.view.frustum[1].normal);
+ VectorMA(forward, -slopey, up , r_refdef.view.frustum[2].normal);
+ VectorMA(forward, slopey, up , r_refdef.view.frustum[3].normal);
+ VectorCopy(forward, r_refdef.view.frustum[4].normal);
// Leaving those out was a mistake, those were in the old code, and they
// fix a reproducable bug in this one: frustum culling got fucked up when viewmatrix was an identity matrix
VectorNormalize(r_refdef.view.frustum[3].normal);
// calculate frustum corners, which are used to calculate deformed frustum planes for shadow caster culling
- VectorMAMAMAM(1, r_refdef.view.origin, 1024, r_refdef.view.forward, -1024 * slopex, r_refdef.view.left, -1024 * slopey, r_refdef.view.up, r_refdef.view.frustumcorner[0]);
- VectorMAMAMAM(1, r_refdef.view.origin, 1024, r_refdef.view.forward, 1024 * slopex, r_refdef.view.left, -1024 * slopey, r_refdef.view.up, r_refdef.view.frustumcorner[1]);
- VectorMAMAMAM(1, r_refdef.view.origin, 1024, r_refdef.view.forward, -1024 * slopex, r_refdef.view.left, 1024 * slopey, r_refdef.view.up, r_refdef.view.frustumcorner[2]);
- VectorMAMAMAM(1, r_refdef.view.origin, 1024, r_refdef.view.forward, 1024 * slopex, r_refdef.view.left, 1024 * slopey, r_refdef.view.up, r_refdef.view.frustumcorner[3]);
+ VectorMAMAMAM(1, r_refdef.view.origin, 1024, forward, -1024 * slopex, left, -1024 * slopey, up, r_refdef.view.frustumcorner[0]);
+ VectorMAMAMAM(1, r_refdef.view.origin, 1024, forward, 1024 * slopex, left, -1024 * slopey, up, r_refdef.view.frustumcorner[1]);
+ VectorMAMAMAM(1, r_refdef.view.origin, 1024, forward, -1024 * slopex, left, 1024 * slopey, up, r_refdef.view.frustumcorner[2]);
+ VectorMAMAMAM(1, r_refdef.view.origin, 1024, forward, 1024 * slopex, left, 1024 * slopey, up, r_refdef.view.frustumcorner[3]);
r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[0].normal);
r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[1].normal);
}
else
{
- VectorScale(r_refdef.view.left, -r_refdef.view.ortho_x, r_refdef.view.frustum[0].normal);
- VectorScale(r_refdef.view.left, r_refdef.view.ortho_x, r_refdef.view.frustum[1].normal);
- VectorScale(r_refdef.view.up, -r_refdef.view.ortho_y, r_refdef.view.frustum[2].normal);
- VectorScale(r_refdef.view.up, r_refdef.view.ortho_y, r_refdef.view.frustum[3].normal);
- VectorCopy(r_refdef.view.forward, r_refdef.view.frustum[4].normal);
+ VectorScale(left, -r_refdef.view.ortho_x, r_refdef.view.frustum[0].normal);
+ VectorScale(left, r_refdef.view.ortho_x, r_refdef.view.frustum[1].normal);
+ VectorScale(up, -r_refdef.view.ortho_y, r_refdef.view.frustum[2].normal);
+ VectorScale(up, r_refdef.view.ortho_y, r_refdef.view.frustum[3].normal);
+ VectorCopy(forward, r_refdef.view.frustum[4].normal);
r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[0].normal) + r_refdef.view.ortho_x;
r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[1].normal) + r_refdef.view.ortho_x;
r_refdef.view.frustum[2].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[2].normal) + r_refdef.view.ortho_y;
// Quake2 has it disabled as well.
// rotate R_VIEWFORWARD right by FOV_X/2 degrees
- //RotatePointAroundVector( r_refdef.view.frustum[0].normal, r_refdef.view.up, r_refdef.view.forward, -(90 - r_refdef.fov_x / 2));
+ //RotatePointAroundVector( r_refdef.view.frustum[0].normal, up, forward, -(90 - r_refdef.fov_x / 2));
//r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, frustum[0].normal);
//PlaneClassify(&frustum[0]);
// rotate R_VIEWFORWARD left by FOV_X/2 degrees
- //RotatePointAroundVector( r_refdef.view.frustum[1].normal, r_refdef.view.up, r_refdef.view.forward, (90 - r_refdef.fov_x / 2));
+ //RotatePointAroundVector( r_refdef.view.frustum[1].normal, up, forward, (90 - r_refdef.fov_x / 2));
//r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, frustum[1].normal);
//PlaneClassify(&frustum[1]);
// rotate R_VIEWFORWARD up by FOV_X/2 degrees
- //RotatePointAroundVector( r_refdef.view.frustum[2].normal, r_refdef.view.left, r_refdef.view.forward, -(90 - r_refdef.fov_y / 2));
+ //RotatePointAroundVector( r_refdef.view.frustum[2].normal, left, forward, -(90 - r_refdef.fov_y / 2));
//r_refdef.view.frustum[2].dist = DotProduct (r_refdef.view.origin, frustum[2].normal);
//PlaneClassify(&frustum[2]);
// rotate R_VIEWFORWARD down by FOV_X/2 degrees
- //RotatePointAroundVector( r_refdef.view.frustum[3].normal, r_refdef.view.left, r_refdef.view.forward, (90 - r_refdef.fov_y / 2));
+ //RotatePointAroundVector( r_refdef.view.frustum[3].normal, left, forward, (90 - r_refdef.fov_y / 2));
//r_refdef.view.frustum[3].dist = DotProduct (r_refdef.view.origin, frustum[3].normal);
//PlaneClassify(&frustum[3]);
// nearclip plane
- //VectorCopy(r_refdef.view.forward, r_refdef.view.frustum[4].normal);
+ //VectorCopy(forward, r_refdef.view.frustum[4].normal);
//r_refdef.view.frustum[4].dist = DotProduct (r_refdef.view.origin, frustum[4].normal) + r_nearclip.value;
//PlaneClassify(&frustum[4]);
}
R_View_UpdateEntityVisible();
}
-void R_SetupView(void)
+void R_SetupView(qboolean allowwaterclippingplane)
{
if (!r_refdef.view.useperspective)
GL_SetupView_Mode_Ortho(-r_refdef.view.ortho_x, -r_refdef.view.ortho_y, r_refdef.view.ortho_x, r_refdef.view.ortho_y, -r_refdef.farclip, r_refdef.farclip);
GL_SetupView_Orientation_FromEntity(&r_refdef.view.matrix);
- if (r_refdef.view.useclipplane)
+ if (r_refdef.view.useclipplane && allowwaterclippingplane)
{
// LordHavoc: couldn't figure out how to make this approach the
vec_t dist = r_refdef.view.clipplane.dist - r_water_clippingplanebias.value;
// GL is weird because it's bottom to top, r_refdef.view.y is top to bottom
qglViewport(r_refdef.view.x, vid.height - (r_refdef.view.y + r_refdef.view.height), r_refdef.view.width, r_refdef.view.height);CHECKGLERROR
- R_SetupView();
+ R_SetupView(true);
GL_Scissor(r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height);
GL_Color(1, 1, 1, 1);
GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
{
// render reflected scene and copy into texture
Matrix4x4_Reflect(&r_refdef.view.matrix, p->plane.normal[0], p->plane.normal[1], p->plane.normal[2], p->plane.dist, -2);
+ // update the r_refdef.view.origin because otherwise the sky renders at the wrong location (amongst other problems)
+ Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, r_refdef.view.origin);
r_refdef.view.clipplane = p->plane;
// reverse the cullface settings for this render
r_refdef.view.cullface_front = GL_FRONT;
r_refdef.view.colorscale = r_hdr_scenebrightness.value;
+ // break apart the view matrix into vectors for various purposes
+ // it is important that this occurs outside the RenderScene function because that can be called from reflection renders, where the vectors come out wrong
+ // however the r_refdef.view.origin IS updated in RenderScene intentionally - otherwise the sky renders at the wrong origin, etc
+ Matrix4x4_ToVectors(&r_refdef.view.matrix, r_refdef.view.forward, r_refdef.view.left, r_refdef.view.up, r_refdef.view.origin);
+ VectorNegate(r_refdef.view.left, r_refdef.view.right);
+ // make an inverted copy of the view matrix for tracking sprites
+ Matrix4x4_Invert_Simple(&r_refdef.view.inverse_matrix, &r_refdef.view.matrix);
+
R_Shadow_UpdateWorldLightSelection();
R_Bloom_StartFrame();
static void R_DrawEntityBBoxes(void);
void R_RenderScene(qboolean addwaterplanes)
{
- Matrix4x4_Invert_Simple(&r_refdef.view.inverse_matrix, &r_refdef.view.matrix);
+ r_refdef.stats.renders++;
+
R_UpdateFogColor();
if (addwaterplanes)
}
else
GL_CullFace(r_refdef.view.cullface_back);
+ GL_CullFace(GL_NONE);
GL_DepthMask(false);
GL_DepthRange(0, depthshort ? 0.0625 : 1);
t->currentmaterialflags |= MATERIALFLAG_SHORTDEPTHRANGE;
if (ent->flags & RENDER_VIEWMODEL)
t->currentmaterialflags |= MATERIALFLAG_SHORTDEPTHRANGE;
- if (t->backgroundnumskinframes && !(t->currentmaterialflags & MATERIALFLAG_BLENDED))
+ if (t->backgroundnumskinframes)
t->currentmaterialflags |= MATERIALFLAG_VERTEXTEXTUREBLEND;
- if (t->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST))
- t->currentmaterialflags |= MATERIALFLAG_SORTTRANSPARENT;
- if (t->currentmaterialflags & (MATERIALFLAG_REFRACTION | MATERIALFLAG_WATER))
- t->currentmaterialflags &= ~MATERIALFLAG_SORTTRANSPARENT;
+ if (t->currentmaterialflags & MATERIALFLAG_BLENDED)
+ {
+ if (t->currentmaterialflags & (MATERIALFLAG_REFRACTION | MATERIALFLAG_WATERSHADER))
+ t->currentmaterialflags &= ~MATERIALFLAG_BLENDED;
+ }
+ else
+ t->currentmaterialflags &= ~(MATERIALFLAG_REFRACTION | MATERIALFLAG_WATERSHADER);
- // make sure that the waterscroll matrix is used on water surfaces when
// there is no tcmod
if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0)
t->currenttexmatrix = r_waterscrollmatrix;
static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, msurface_t **texturesurfacelist)
{
// transparent sky would be ridiculous
- if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SORTTRANSPARENT))
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
return;
if (rsurface.mode != RSURFMODE_SKY)
{
if (skyrendernow)
{
skyrendernow = false;
+ // we have to force off the water clipping plane while rendering sky
+ R_SetupView(false);
R_Sky();
+ R_SetupView(true);
// restore entity matrix
R_Mesh_Matrix(&rsurface.matrix);
}
}
R_Mesh_TexMatrix(0, &rsurface.texture->currenttexmatrix);
- R_Mesh_TexBind(0, R_GetTexture(rsurface.texture->currentskinframe->nmap));
- R_Mesh_TexBind(1, R_GetTexture(rsurface.texture->basetexture));
- R_Mesh_TexBind(2, R_GetTexture(rsurface.texture->glosstexture));
- R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation));
- R_Mesh_TexBind(5, R_GetTexture(rsurface.texture->currentskinframe->pants));
- R_Mesh_TexBind(6, R_GetTexture(rsurface.texture->currentskinframe->shirt));
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
- {
- R_Mesh_TexBind(7, R_GetTexture(r_texture_grey128));
- R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
- R_Mesh_ColorPointer(NULL, 0, 0);
- }
- else if (rsurface.uselightmaptexture)
- {
- R_Mesh_TexBind(7, R_GetTexture(texturesurfacelist[0]->lightmaptexture));
- R_Mesh_TexBind(8, R_GetTexture(texturesurfacelist[0]->deluxemaptexture));
+ R_Mesh_TexBind(GL20TU_NORMAL, R_GetTexture(rsurface.texture->currentskinframe->nmap));
+ R_Mesh_TexBind(GL20TU_COLOR, R_GetTexture(rsurface.texture->basetexture));
+ R_Mesh_TexBind(GL20TU_GLOSS, R_GetTexture(rsurface.texture->glosstexture));
+ R_Mesh_TexBind(GL20TU_GLOW, R_GetTexture(rsurface.texture->currentskinframe->glow));
+ if (rsurface.texture->backgroundcurrentskinframe)
+ {
+ R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL, R_GetTexture(rsurface.texture->backgroundcurrentskinframe->nmap));
+ R_Mesh_TexBind(GL20TU_SECONDARY_COLOR, R_GetTexture(rsurface.texture->backgroundbasetexture));
+ R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS, R_GetTexture(rsurface.texture->backgroundglosstexture));
+ R_Mesh_TexBind(GL20TU_SECONDARY_GLOW, R_GetTexture(rsurface.texture->backgroundcurrentskinframe->glow));
+ }
+ R_Mesh_TexBind(GL20TU_PANTS, R_GetTexture(rsurface.texture->currentskinframe->pants));
+ R_Mesh_TexBind(GL20TU_SHIRT, R_GetTexture(rsurface.texture->currentskinframe->shirt));
+ R_Mesh_TexBind(GL20TU_FOGMASK, R_GetTexture(r_texture_fogattenuation));
+ if ((rsurface.uselightmaptexture || (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND))
R_Mesh_ColorPointer(NULL, 0, 0);
- }
else
- {
- R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
- R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
R_Mesh_ColorPointer(rsurface.modellightmapcolor4f, rsurface.modellightmapcolor4f_bufferobject, rsurface.modellightmapcolor4f_bufferoffset);
- }
- R_Mesh_TexBind(9, R_GetTexture(rsurface.texture->currentskinframe->glow));
- R_Mesh_TexBind(11, R_GetTexture(r_texture_white)); // changed per surface
- R_Mesh_TexBind(12, R_GetTexture(r_texture_white)); // changed per surface
if (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
{
R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset);
R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset);
R_Mesh_TexCoordPointer(4, 2, rsurface.modeltexcoordlightmap2f, rsurface.modeltexcoordlightmap2f_bufferobject, rsurface.modeltexcoordlightmap2f_bufferoffset);
- RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist, -1, -1, r_glsl_permutation->loc_Texture_Refraction ? 11 : -1, r_glsl_permutation->loc_Texture_Reflection ? 12 : -1);
+ RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist, -1, -1, r_glsl_permutation->loc_Texture_Refraction >= 0 ? GL20TU_REFRACTION : -1, r_glsl_permutation->loc_Texture_Reflection >= 0 ? GL20TU_REFLECTION : -1);
}
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
GL_DepthMask(false);
GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
- {
- R_Mesh_TexBind(7, R_GetTexture(r_texture_grey128));
- R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
+ if ((rsurface.uselightmaptexture || (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND))
R_Mesh_ColorPointer(NULL, 0, 0);
- }
- else if (rsurface.uselightmaptexture)
- {
- R_Mesh_TexBind(7, R_GetTexture(texturesurfacelist[0]->lightmaptexture));
- R_Mesh_TexBind(8, R_GetTexture(texturesurfacelist[0]->deluxemaptexture));
- R_Mesh_ColorPointer(NULL, 0, 0);
- }
else
- {
- R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
- R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
R_Mesh_ColorPointer(rsurface.modellightmapcolor4f, rsurface.modellightmapcolor4f_bufferobject, rsurface.modellightmapcolor4f_bufferoffset);
- }
- R_Mesh_TexBind(11, R_GetTexture(r_texture_white)); // changed per surface
- R_Mesh_TexBind(12, R_GetTexture(r_texture_white)); // changed per surface
+ R_Mesh_TexBind(GL20TU_REFRACTION, R_GetTexture(r_texture_white)); // changed per surface
+ R_Mesh_TexBind(GL20TU_REFLECTION, R_GetTexture(r_texture_white)); // changed per surface
}
R_SetupSurfaceShader(vec3_origin, rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE);
if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
{
if (r_glsl_permutation->loc_Texture_Refraction >= 0 || r_glsl_permutation->loc_Texture_Reflection >= 0)
- RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist, 7, r_glsl_permutation->loc_Texture_Deluxemap >= 0 ? 8 : -1, r_glsl_permutation->loc_Texture_Refraction >= 0 ? 11 : -1, r_glsl_permutation->loc_Texture_Reflection >= 0 ? 12 : -1);
+ RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist, GL20TU_LIGHTMAP, r_glsl_permutation->loc_Texture_Deluxemap >= 0 ? GL20TU_DELUXEMAP : -1, r_glsl_permutation->loc_Texture_Refraction >= 0 ? GL20TU_REFRACTION : -1, r_glsl_permutation->loc_Texture_Reflection >= 0 ? GL20TU_REFLECTION : -1);
else
- RSurf_DrawBatch_WithLightmapSwitching(texturenumsurfaces, texturesurfacelist, 7, r_glsl_permutation->loc_Texture_Deluxemap >= 0 ? 8 : -1);
+ RSurf_DrawBatch_WithLightmapSwitching(texturenumsurfaces, texturesurfacelist, GL20TU_LIGHTMAP, r_glsl_permutation->loc_Texture_Deluxemap >= 0 ? GL20TU_DELUXEMAP : -1);
}
else
{
if (r_glsl_permutation->loc_Texture_Refraction >= 0 || r_glsl_permutation->loc_Texture_Reflection >= 0)
- RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist, -1, -1, r_glsl_permutation->loc_Texture_Refraction >= 0 ? 11 : -1, r_glsl_permutation->loc_Texture_Reflection >= 0 ? 12 : -1);
+ RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist, -1, -1, r_glsl_permutation->loc_Texture_Refraction >= 0 ? GL20TU_REFRACTION : -1, r_glsl_permutation->loc_Texture_Reflection >= 0 ? GL20TU_REFLECTION : -1);
else
RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
}
;
continue;
}
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_SORTTRANSPARENT)
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
{
// transparent surfaces get pushed off into the transparent queue
const msurface_t *surface = surfacelist[i];