]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
Cleaned up reflection and refraction a bit; added Q3 shader parameters dp_reflect...
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 3 Oct 2007 15:21:48 +0000 (15:21 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 3 Oct 2007 15:21:48 +0000 (15:21 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7603 d7cf8633-e32d-0410-b094-e92efae38249

darkplaces.txt
gl_rmain.c
model_brush.c
model_shared.c
model_shared.h
render.h

index c5e96e89e63809ff2b8accccccfaae38e3096c74..6cf3f2d0e5ead8b193bc46010930f0dcf8a3e17a 100644 (file)
@@ -1308,3 +1308,15 @@ de-we for the great icons.
 |Rain| for running my favorite anynet IRC server and his bot feh (which although a bit antisocial never seems to grow tired of being my calculator).\r
 VorteX for the DP_QC_GETTAGINFO extension.\r
 Ludwig Nussel for the ~/.games/darkplaces/ user directory support on non-Windows platforms (allowing games to be installed in a non-writable system location as is the standard on UNIX but still save configs to the user's home directory).\r
+\r
+\r
+Shader parameters for DP's own features:\r
+- dp_reflect <factor> <r> <g> <b>\r
+  Makes surfaces of this shader reflective with r_glsl_water. Factor is a\r
+  reflectiveness factor from 0 to 1, the rest is the color of the reflection.\r
+  Unspecified values get set to 1 (that is, standard water parameters).\r
+- dp_refract <factor> <r> <g> <b>\r
+  Marks a surface as "water" for r_glsl_water, that is, add a refraction\r
+  component too. The factor defines how strong the distorts by the refraction\r
+  are (default: 1.0). Unspecified values get set to 1 (that is, standard water\r
+  parameters).\r
index da1bd813df1c7fb12b6f90f81dc3f5bf4dfe1110..b1f55d19284187c5ec3c524479924ce0f0fb4dea 100644 (file)
@@ -81,12 +81,6 @@ cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0
 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)"};
@@ -577,6 +571,7 @@ static const char *builtinshaderstring =
 "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"
@@ -784,14 +779,14 @@ static const char *builtinshaderstring =
 "      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"
@@ -951,6 +946,7 @@ void R_GLSL_CompilePermutation(const char *filename, int permutation)
                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);
@@ -1272,11 +1268,12 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
        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;
 }
@@ -1758,12 +1755,6 @@ void GL_Main_Init(void)
        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);
@@ -3826,9 +3817,17 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
        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;
index bbef49b523c6b482f1118a43990c5159e052c3e1..a2bac292786ef0a77ce0ba5fbe1ce00e114177f9 100644 (file)
@@ -1537,7 +1537,13 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                                if (strncmp(tx->name,"*lava",5)
                                 && strncmp(tx->name,"*teleport",9)
                                 && strncmp(tx->name,"*rift",5)) // Scourge of Armagon texture
-                                       tx->basematerialflags |= MATERIALFLAG_WATERALPHA | MATERIALFLAG_NOSHADOW;
+                                {
+                                       tx->basematerialflags |= MATERIALFLAG_WATERALPHA | MATERIALFLAG_NOSHADOW | MATERIALFLAG_WATERSHADER;
+                                       VectorSet(tx->reflectcolor, 1, 1, 1);
+                                       VectorSet(tx->refractcolor, 1, 1, 1);
+                                       tx->reflectfactor = 1;
+                                       tx->refractfactor = 1;
+                               }
                                tx->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_NOSHADOW;
                        }
                        else if (!strncmp(tx->name, "sky", 3))
index 3b381c58a903eaec14f8e87d74dd73a41ca92a99..655132e785c8ee5b8aa21e99750950e4afa17a04 100644 (file)
@@ -1133,7 +1133,13 @@ void Mod_LoadQ3Shaders(void)
                                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, "{"))
                        {
@@ -1490,6 +1496,22 @@ void Mod_LoadQ3Shaders(void)
                                        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;
@@ -1550,6 +1572,9 @@ void Mod_LoadQ3Shaders(void)
                                        shader->primarylayer = shader->layers + 1;
                                }
                        }
+                       // fix up multiple reflection types
+                       if(shader->textureflags & Q3TEXTUREFLAG_WATERSHADER)
+                               shader->textureflags &= ~Q3TEXTUREFLAG_REFLECTION;
                }
                Mem_Free(f);
        }
@@ -1605,6 +1630,10 @@ qboolean Mod_LoadTextureFromQ3Shader(texture_t *texture, const char *name, qbool
                        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)
@@ -1686,6 +1715,10 @@ nothing                GL_ZERO GL_ONE
                        }
                }
                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"))
        {
index 2c4be3756414f5400fa4008142079ea4855f5b81..c4b6fe912ad90857818f121771de51575a9b2614 100644 (file)
@@ -187,6 +187,8 @@ shadowmesh_t;
 #define Q3TEXTUREFLAG_TWOSIDED 1
 #define Q3TEXTUREFLAG_NOPICMIP 16
 #define Q3TEXTUREFLAG_POLYGONOFFSET 32
+#define Q3TEXTUREFLAG_REFLECTION 256
+#define Q3TEXTUREFLAG_WATERSHADER 512
 
 #define Q3PATHLENGTH 64
 #define TEXTURE_MAXFRAMES 64
@@ -362,6 +364,10 @@ typedef struct q3shaderinfo_s
        q3shaderinfo_layer_t layers[Q3SHADER_MAXLAYERS];
        char skyboxname[Q3PATHLENGTH];
        q3shaderinfo_deform_t deforms[Q3MAXDEFORMS];
+
+       vec3_t reflectcolor, refractcolor;
+       float reflectfactor; // amount of reflection (1.0 = full, can't be larger)
+       float refractfactor; // amount of refraction distort (1.0 = like the cvar specifies; note that reflection distort is not configurable because that's what the bumpmap should do)
 }
 q3shaderinfo_t;
 
@@ -474,6 +480,11 @@ typedef struct texture_s
        int supercontents;
        int surfaceparms;
        int textureflags;
+
+       // reflection
+       vec3_t reflectcolor, refractcolor;
+       float reflectfactor; // amount of reflection (1.0 = full, can't be larger)
+       float refractfactor; // amount of refraction distort (1.0 = like the cvar specifies; note that reflection distort is not configurable because that's what the bumpmap should do)
 }
 texture_t;
 
index 3fd24e9020205292794791c06fba0e64b72b863e..fa024207b144bc2d0c0de8c1da46c4c90ff187ae 100644 (file)
--- a/render.h
+++ b/render.h
@@ -427,6 +427,7 @@ typedef struct r_glsl_permutation_s
        int loc_ScreenCenterRefractReflect;
        int loc_RefractColor;
        int loc_ReflectColor;
+       int loc_ReflectFactor;
 }
 r_glsl_permutation_t;