cvar_t r_glsl_water = {CVAR_SAVE, "r_glsl_water", "0", "whether to use reflections and refraction on water surfaces (note: r_wateralpha must be set below 1)"};
cvar_t r_glsl_water_clippingplanebias = {CVAR_SAVE, "r_glsl_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"};
cvar_t r_glsl_water_resolutionmultiplier = {CVAR_SAVE, "r_glsl_water_resolutionmultiplier", "0.5", "multiplier for screen resolution when rendering refracted/reflected scenes, 1 is full quality, lower values are faster"};
-cvar_t r_glsl_water_refractcolor_r = {CVAR_SAVE, "r_glsl_water_refractcolor_r", "1", "water color tint for refraction"};
-cvar_t r_glsl_water_refractcolor_g = {CVAR_SAVE, "r_glsl_water_refractcolor_g", "1", "water color tint for refraction"};
-cvar_t r_glsl_water_refractcolor_b = {CVAR_SAVE, "r_glsl_water_refractcolor_b", "1", "water color tint for refraction"};
-cvar_t r_glsl_water_reflectcolor_r = {CVAR_SAVE, "r_glsl_water_reflectcolor_r", "1", "water color tint for reflection"};
-cvar_t r_glsl_water_reflectcolor_g = {CVAR_SAVE, "r_glsl_water_reflectcolor_g", "1", "water color tint for reflection"};
-cvar_t r_glsl_water_reflectcolor_b = {CVAR_SAVE, "r_glsl_water_reflectcolor_b", "1", "water color tint for reflection"};
cvar_t r_glsl_water_refractdistort = {CVAR_SAVE, "r_glsl_water_refractdistort", "0.01", "how much water refractions shimmer"};
cvar_t r_glsl_water_reflectdistort = {CVAR_SAVE, "r_glsl_water_reflectdistort", "0.01", "how much water reflections shimmer"};
cvar_t r_glsl_deluxemapping = {CVAR_SAVE, "r_glsl_deluxemapping", "1", "use per pixel lighting on deluxemap-compiled q3bsp maps (or a value of 2 forces deluxemap shading even without deluxemaps)"};
"uniform vec4 ScreenCenterRefractReflect;\n"
"uniform myhvec3 RefractColor;\n"
"uniform myhvec3 ReflectColor;\n"
+"uniform myhalf ReflectFactor;\n"
"//#else\n"
"//# ifdef USEREFLECTION\n"
"//uniform vec4 DistortScaleRefractReflect;\n"
" vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
" //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
" vec4 ScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect + vec3(normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5))).xyxy * DistortScaleRefractReflect;\n"
-" myhalf Fresnel = myhalf(pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0));\n"
+" myhalf Fresnel = myhalf(pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0)) * ReflectFactor;\n"
" color.rgb = mix(mix(myhvec3(texture2D(Texture_Refraction, ScreenTexCoord.xy)) * RefractColor, myhvec3(texture2D(Texture_Reflection, ScreenTexCoord.zw)) * ReflectColor, Fresnel), color.rgb, color.a);\n"
"# else\n"
"# ifdef USEREFLECTION\n"
" vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
" //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
" vec4 ScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect + vec3(normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5))).xyxy * DistortScaleRefractReflect;\n"
-" color.rgb += myhvec3(texture2D(Texture_Gloss, TexCoord)) * myhvec3(texture2D(Texture_Reflection, ScreenTexCoord.zw));\n"
+" color.rgb = mix(color.rgb, myhvec3(texture2D(Texture_Reflection, ScreenTexCoord.zw)), ReflectFactor);\n"
"# endif\n"
"# endif\n"
"#endif\n"
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");
// 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 (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_glsl_water_refractdistort.value, r_glsl_water_refractdistort.value, r_glsl_water_reflectdistort.value, r_glsl_water_reflectdistort.value);
+ if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_DistortScaleRefractReflect, r_glsl_water_refractdistort.value * rsurface.texture->refractfactor, r_glsl_water_refractdistort.value * rsurface.texture->refractfactor, r_glsl_water_reflectdistort.value, r_glsl_water_reflectdistort.value);
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) qglUniform3fARB(r_glsl_permutation->loc_RefractColor, r_glsl_water_refractcolor_r.value, r_glsl_water_refractcolor_g.value, r_glsl_water_refractcolor_b.value);
- if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_ReflectColor, r_glsl_water_reflectcolor_r.value, r_glsl_water_reflectcolor_g.value, r_glsl_water_reflectcolor_b.value);
+ if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform3fvARB(r_glsl_permutation->loc_RefractColor, 1, rsurface.texture->refractcolor);
+ if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform3fvARB(r_glsl_permutation->loc_ReflectColor, 1, rsurface.texture->reflectcolor);
+ if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectfactor);
CHECKGLERROR
return permutation;
}
Cvar_RegisterVariable(&r_glsl_water);
Cvar_RegisterVariable(&r_glsl_water_resolutionmultiplier);
Cvar_RegisterVariable(&r_glsl_water_clippingplanebias);
- Cvar_RegisterVariable(&r_glsl_water_refractcolor_r);
- Cvar_RegisterVariable(&r_glsl_water_refractcolor_g);
- Cvar_RegisterVariable(&r_glsl_water_refractcolor_b);
- Cvar_RegisterVariable(&r_glsl_water_reflectcolor_r);
- Cvar_RegisterVariable(&r_glsl_water_reflectcolor_g);
- Cvar_RegisterVariable(&r_glsl_water_reflectcolor_b);
Cvar_RegisterVariable(&r_glsl_water_refractdistort);
Cvar_RegisterVariable(&r_glsl_water_reflectdistort);
Cvar_RegisterVariable(&r_glsl_deluxemapping);
if (t->basematerialflags & MATERIALFLAG_WATERALPHA && (model->brush.supportwateralpha || r_novis.integer))
{
t->currentalpha *= r_wateralpha.value;
+ /*
+ * FIXME what is this supposed to do?
// if rendering refraction/reflection, disable transparency
if (r_waterstate.enabled && (t->currentalpha < 1 || (t->currentmaterialflags & MATERIALFLAG_ALPHA)))
t->currentmaterialflags |= MATERIALFLAG_WATERSHADER;
+ */
+ }
+ if(!r_waterstate.enabled)
+ {
+ t->currentmaterialflags &= ~MATERIALFLAG_WATERSHADER;
+ t->currentmaterialflags &= ~MATERIALFLAG_REFLECTION;
}
if (!(ent->flags & RENDER_LIGHT))
t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
break;
}
shader = q3shaders_shaders + q3shaders_numshaders++;
+
memset(shader, 0, sizeof(*shader));
+ VectorSet(shader->reflectcolor, 1, 1, 1);
+ VectorSet(shader->refractcolor, 1, 1, 1);
+ shader->reflectfactor = 1;
+ shader->refractfactor = 1;
+
strlcpy(shader->name, com_token, sizeof(shader->name));
if (!COM_ParseToken_QuakeC(&text, false) || strcasecmp(com_token, "{"))
{
shader->textureflags |= Q3TEXTUREFLAG_NOPICMIP;
else if (!strcasecmp(parameter[0], "polygonoffset"))
shader->textureflags |= Q3TEXTUREFLAG_POLYGONOFFSET;
+ else if (!strcasecmp(parameter[0], "dp_reflect"))
+ {
+ shader->textureflags |= Q3TEXTUREFLAG_REFLECTION;
+ if(numparameters >= 2)
+ shader->reflectfactor = atof(parameter[1]);
+ if(numparameters >= 5)
+ VectorSet(shader->reflectcolor, atof(parameter[2]), atof(parameter[3]), atof(parameter[4]));
+ }
+ else if (!strcasecmp(parameter[0], "dp_refract"))
+ {
+ shader->textureflags |= Q3TEXTUREFLAG_WATERSHADER;
+ if(numparameters >= 2)
+ shader->refractfactor = atof(parameter[1]);
+ if(numparameters >= 5)
+ VectorSet(shader->refractcolor, atof(parameter[2]), atof(parameter[3]), atof(parameter[4]));
+ }
else if (!strcasecmp(parameter[0], "deformvertexes") && numparameters >= 2)
{
int i, deformindex;
shader->primarylayer = shader->layers + 1;
}
}
+ // fix up multiple reflection types
+ if(shader->textureflags & Q3TEXTUREFLAG_WATERSHADER)
+ shader->textureflags &= ~Q3TEXTUREFLAG_REFLECTION;
}
Mem_Free(f);
}
texture->basematerialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_NOCULLFACE;
if (shader->textureflags & Q3TEXTUREFLAG_POLYGONOFFSET)
texture->basepolygonoffset -= 2;
+ if (shader->textureflags & Q3TEXTUREFLAG_REFLECTION)
+ texture->basematerialflags |= MATERIALFLAG_REFLECTION;
+ if (shader->textureflags & Q3TEXTUREFLAG_WATERSHADER)
+ texture->basematerialflags |= MATERIALFLAG_WATERSHADER;
texture->customblendfunc[0] = GL_ONE;
texture->customblendfunc[1] = GL_ZERO;
if (shader->numlayers > 0)
}
}
memcpy(texture->deforms, shader->deforms, sizeof(texture->deforms));
+ texture->reflectfactor = shader->reflectfactor;
+ texture->refractfactor = shader->refractfactor;
+ VectorCopy(shader->reflectcolor, texture->reflectcolor);
+ VectorCopy(shader->refractcolor, texture->refractcolor);
}
else if (!strcmp(texture->name, "noshader"))
{