Cvar_Set("gl_fogblue", "0.3");
}
r_refdef.fog_density = r_refdef.fog_red = r_refdef.fog_green = r_refdef.fog_blue = 0.0f;
+ r_refdef.fog_start = 0;
+ r_refdef.fog_end = 1000000000;
}
-float FogPoint_World(const vec3_t p)
+float FogForDistance(vec_t dist)
{
- unsigned int fogmasktableindex = (unsigned int)(VectorDistance((p), r_view.origin) * r_refdef.fogmasktabledistmultiplier);
+ unsigned int fogmasktableindex = (unsigned int)(bound(0, dist - r_refdef.fog_start, r_refdef.fog_end - r_refdef.fog_start) * r_refdef.fogmasktabledistmultiplier);
return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
}
+float FogPoint_World(const vec3_t p)
+{
+ return FogForDistance(VectorDistance((p), r_view.origin));
+}
+
float FogPoint_Model(const vec3_t p)
{
- unsigned int fogmasktableindex = (unsigned int)(VectorDistance((p), rsurface.modelorg) * r_refdef.fogmasktabledistmultiplier);
- return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
+ return FogForDistance(VectorDistance((p), rsurface.modelorg));
}
static void R_BuildBlankTextures(void)
static void R_BuildFogTexture(void)
{
int x, b;
-#define FOGWIDTH 64
+#define FOGWIDTH 256
unsigned char data1[FOGWIDTH][4];
//unsigned char data2[FOGWIDTH][4];
for (x = 0;x < FOGWIDTH;x++)
"uniform float OffsetMapping_Scale;\n"
"uniform float OffsetMapping_Bias;\n"
"uniform float FogRangeRecip;\n"
+"uniform float FogStart;\n"
+"uniform float FogLength;\n"
"\n"
"uniform myhalf AmbientScale;\n"
"uniform myhalf DiffuseScale;\n"
"# endif\n"
"\n"
" // apply lightmap color\n"
-" color.rgb = myhvec4(tempcolor,1) * myhvec4(texture2D(Texture_Lightmap, TexCoordLightmap)) * myhvec4(gl_Color) + myhvec4(color.rgb * AmbientScale, 0);\n"
+" color.rgb = color.rgb * AmbientScale + tempcolor * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * myhvec3(gl_Color);\n"
+" color.a *= myhalf(gl_Color.a);\n"
"#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
"\n"
"\n"
"# endif\n"
"\n"
" // apply lightmap color\n"
-" color = myhvec4(tempcolor, 1) * myhvec4(texture2D(Texture_Lightmap, TexCoordLightmap)) * myhvec4(gl_Color) + myhvec4(color.rgb * AmbientScale, 0);\n"
+" color.rgb = color.rgb * AmbientScale + tempcolor * myhvec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * myhvec3(gl_Color);\n"
+" color.a *= myhalf(gl_Color.a);\n"
"#endif // MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
"\n"
"\n"
"# endif\n"
"#endif\n"
"\n"
-"#ifdef USEFOG\n"
-" // apply fog\n"
-" color.rgb = mix(FogColor, color.rgb, myhalf(texture2D(Texture_FogMask, myhvec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0))));\n"
-"#endif\n"
-"\n"
"#ifdef USECONTRASTBOOST\n"
" color.rgb = color.rgb / (ContrastBoostCoeff * color.rgb + myhvec3(1, 1, 1));\n"
"#endif\n"
"\n"
" color.rgb *= SceneBrightness;\n"
"\n"
+"#ifdef USEFOG\n"
+" // apply fog\n"
+" color.rgb = mix(FogColor, color.rgb, myhalf(texture2D(Texture_FogMask, myhvec2(max(0.0, min(length(EyeVectorModelSpace) - FogStart, FogLength))*FogRangeRecip, 0.0))));\n"
+//" color.rgb = mix(FogColor, color.rgb, myhalf(texture2D(Texture_FogMask, myhvec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0))));\n"
+"#endif\n"
+"\n"
" gl_FragColor = vec4(color);\n"
"}\n"
"#endif // MODE_REFRACTION\n"
int loc_Color_Pants;
int loc_Color_Shirt;
int loc_FogRangeRecip;
+ int loc_FogStart;
+ int loc_FogLength;
int loc_AmbientScale;
int loc_DiffuseScale;
int loc_SpecularScale;
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_FogStart = qglGetUniformLocationARB(p->program, "FogStart");
+ p->loc_FogLength = qglGetUniformLocationARB(p->program, "FogLength");
p->loc_AmbientScale = qglGetUniformLocationARB(p->program, "AmbientScale");
p->loc_DiffuseScale = qglGetUniformLocationARB(p->program, "DiffuseScale");
p->loc_SpecularPower = qglGetUniformLocationARB(p->program, "SpecularPower");
if (rsurface.rtlight || (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD))
qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
else
- /*
- {
- vec3_t fogvec;
- // color.rgb *= SceneBrightness;
- VectorScale(r_refdef.fogcolor, r_view.colorscale, fogvec);
- if(r_glsl_permutation->loc_ContrastBoostCoeff >= 0) // need to support contrast boost
- {
- // color.rgb *= ContrastBoost / ((ContrastBoost - 1) * color.rgb + 1);
- fogvec[0] *= r_glsl_contrastboost.value / ((r_glsl_contrastboost.value - 1) * fogvec[0] + 1);
- fogvec[1] *= r_glsl_contrastboost.value / ((r_glsl_contrastboost.value - 1) * fogvec[1] + 1);
- fogvec[2] *= r_glsl_contrastboost.value / ((r_glsl_contrastboost.value - 1) * fogvec[2] + 1);
- }
- qglUniform3fARB(r_glsl_permutation->loc_FogColor, fogvec[0], fogvec[1], fogvec[2]);
- }
- */
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]);
qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
}
if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, r_refdef.fograngerecip);
+ if (r_glsl_permutation->loc_FogStart >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogStart, r_refdef.fog_start);
+ if (r_glsl_permutation->loc_FogLength >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogLength, r_refdef.fog_end - r_refdef.fog_start);
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);
int x;
double r, alpha;
- r = (-1.0/256.0) * (FOGMASKTABLEWIDTH * FOGMASKTABLEWIDTH);
+ r = -16.0 / (1.0 * FOGMASKTABLEWIDTH * FOGMASKTABLEWIDTH);
for (x = 0;x < FOGMASKTABLEWIDTH;x++)
{
- alpha = 1 - exp(r / ((double)x*(double)x));
+ alpha = exp(r * ((double)x*(double)x));
if (x == FOGMASKTABLEWIDTH - 1)
alpha = 0;
r_refdef.fogmasktable[x] = bound(0, alpha, 1);
extern void R_Shadow_Init(void);
extern void R_Sky_Init(void);
extern void GL_Surf_Init(void);
-extern void R_Light_Init(void);
extern void R_Particles_Init(void);
extern void R_Explosion_Init(void);
extern void gl_backend_init(void);
R_Sky_Init();
GL_Surf_Init();
Sbar_Init();
- R_Light_Init();
R_Particles_Init();
R_Explosion_Init();
R_LightningBeams_Init();
for (i = 0;i < r_refdef.numentities;i++)
{
ent = r_refdef.entities[i];
- r_viewcache.entityvisible[i] = !(ent->flags & renderimask) && ((ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)) || !R_CullBox(ent->mins, ent->maxs)) && ((ent->effects & EF_NODEPTHTEST) || (ent->flags & RENDER_VIEWMODEL) || r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.worldmodel, r_viewcache.world_leafvisible, ent->mins, ent->maxs));
+ r_viewcache.entityvisible[i] = !(ent->flags & renderimask) && ((ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)) || !R_CullBox(ent->mins, ent->maxs)) && ((ent->effects & EF_NODEPTHTEST) || (ent->flags & RENDER_VIEWMODEL) || r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.worldmodel, r_viewcache.world_leafvisible, ent->mins, ent->maxs));
}
if(r_cullentities_trace.integer)
for (i = 0;i < r_refdef.numentities;i++)
{
ent = r_refdef.entities[i];
- r_viewcache.entityvisible[i] = !(ent->flags & renderimask) && ((ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)) || !R_CullBox(ent->mins, ent->maxs));
+ r_viewcache.entityvisible[i] = !(ent->flags & renderimask) && ((ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)) || !R_CullBox(ent->mins, ent->maxs));
}
}
{
int triangleindex, planeindex;
const int *e;
- vec_t f;
vec3_t vert[3];
vec3_t normal;
vec3_t center;
r_waterstate_waterplane_t *p;
// just use the first triangle with a valid normal for any decisions
VectorClear(normal);
- VectorClear(center);
for (triangleindex = 0, e = rsurface.modelelement3i + surface->num_firsttriangle * 3;triangleindex < surface->num_triangles;triangleindex++, e += 3)
{
Matrix4x4_Transform(&rsurface.matrix, rsurface.modelvertex3f + e[0]*3, vert[0]);
if (VectorLength2(normal) >= 0.001)
break;
}
- // now find the center of this surface
- for (triangleindex = 0, e = rsurface.modelelement3i + surface->num_firsttriangle * 3;triangleindex < surface->num_triangles*3;triangleindex++, e++)
- {
- Matrix4x4_Transform(&rsurface.matrix, rsurface.modelvertex3f + e[0]*3, vert[0]);
- VectorAdd(center, vert[0], center);
- }
- f = 1.0 / surface->num_triangles*3;
- VectorScale(center, f, center);
// find a matching plane if there is one
for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
// merge this surface's materialflags into the waterplane
p->materialflags |= surface->texture->currentframe->currentmaterialflags;
// merge this surface's PVS into the waterplane
- if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION) && r_refdef.worldmodel && r_refdef.worldmodel->brush.FatPVS)
+ VectorMAM(0.5f, surface->mins, 0.5f, surface->maxs, center);
+ if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION) && r_refdef.worldmodel && r_refdef.worldmodel->brush.FatPVS
+ && r_refdef.worldmodel->brush.PointInLeaf && r_refdef.worldmodel->brush.PointInLeaf(r_refdef.worldmodel, center)->clusterindex >= 0)
{
- r_refdef.worldmodel->brush.FatPVS(r_refdef.worldmodel, r_view.origin, 2, p->pvsbits, sizeof(p->pvsbits), p->pvsvalid);
+ r_refdef.worldmodel->brush.FatPVS(r_refdef.worldmodel, center, 2, p->pvsbits, sizeof(p->pvsbits), p->pvsvalid);
p->pvsvalid = true;
}
}
}
}
+static void R_UpdateFogColor(void); // needs to be called before HDR subrender too, as that changes colorscale!
+
void R_HDR_RenderBloomTexture(void)
{
int oldwidth, oldheight;
r_view.colorscale = r_bloom_colorscale.value * r_hdr_scenebrightness.value;
if (r_hdr.integer)
r_view.colorscale /= r_hdr_range.value;
+
+ R_UpdateFogColor();
+
r_waterstate.numwaterplanes = 0;
R_RenderScene(r_waterstate.enabled);
r_view.showdebug = true;
matrix4x4_t r_waterscrollmatrix;
+static void R_UpdateFogColor(void) // needs to be called before HDR subrender too, as that changes colorscale!
+{
+ if (r_refdef.fog_density)
+ {
+ r_refdef.fogcolor[0] = r_refdef.fog_red;
+ r_refdef.fogcolor[1] = r_refdef.fog_green;
+ r_refdef.fogcolor[2] = r_refdef.fog_blue;
+
+ {
+ vec3_t fogvec;
+ // color.rgb *= SceneBrightness;
+ VectorScale(r_refdef.fogcolor, r_view.colorscale, fogvec);
+ if(r_glsl.integer && (r_glsl_contrastboost.value > 1 || r_glsl_contrastboost.value < 0)) // need to support contrast boost
+ {
+ // color.rgb *= ContrastBoost / ((ContrastBoost - 1) * color.rgb + 1);
+ fogvec[0] *= r_glsl_contrastboost.value / ((r_glsl_contrastboost.value - 1) * fogvec[0] + 1);
+ fogvec[1] *= r_glsl_contrastboost.value / ((r_glsl_contrastboost.value - 1) * fogvec[1] + 1);
+ fogvec[2] *= r_glsl_contrastboost.value / ((r_glsl_contrastboost.value - 1) * fogvec[2] + 1);
+ }
+ r_refdef.fogcolor[0] = bound(0.0f, fogvec[0], 1.0f);
+ r_refdef.fogcolor[1] = bound(0.0f, fogvec[1], 1.0f);
+ r_refdef.fogcolor[2] = bound(0.0f, fogvec[2], 1.0f);
+ }
+ }
+}
+
void R_UpdateVariables(void)
{
R_Textures_Frame();
r_refdef.fog_blue = 0;
}
}
- if (r_refdef.fog_density)
+
+ if (r_refdef.fog_start >= r_refdef.fog_end || r_refdef.fog_start < 0)
{
- r_refdef.fogcolor[0] = bound(0.0f, r_refdef.fog_red , 1.0f);
- r_refdef.fogcolor[1] = bound(0.0f, r_refdef.fog_green, 1.0f);
- r_refdef.fogcolor[2] = bound(0.0f, r_refdef.fog_blue , 1.0f);
+ r_refdef.fog_start = 0;
+ r_refdef.fog_end = 1000000000;
+ // TODO update fog cvars here too
}
+
+ R_UpdateFogColor();
+
if (r_refdef.fog_density)
{
r_refdef.fogenabled = true;
// this is the point where the fog reaches 0.9986 alpha, which we
// consider a good enough cutoff point for the texture
// (0.9986 * 256 == 255.6)
- r_refdef.fogrange = 400 / r_refdef.fog_density;
+ r_refdef.fogrange = 16 / (r_refdef.fog_density * r_refdef.fog_density);
r_refdef.fograngerecip = 1.0f / r_refdef.fogrange;
r_refdef.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * r_refdef.fograngerecip;
// fog color was already set
R_Mesh_TexBind(0, R_GetTexture(fogtexture));
GL_BlendFunc(blendfunc1, GL_ONE);
fog = 1 - fog;
- GL_Color(r_refdef.fogcolor[0] * fog * r_view.colorscale, r_refdef.fogcolor[1] * fog * r_view.colorscale, r_refdef.fogcolor[2] * fog * r_view.colorscale, ca);
+ GL_Color(r_refdef.fogcolor[0] * fog, r_refdef.fogcolor[1] * fog, r_refdef.fogcolor[2] * fog, ca);
R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
}
}
if (t->backgroundnumskinframes && !(t->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED))
t->currentmaterialflags |= MATERIALFLAG_VERTEXTEXTUREBLEND;
+ // 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;
+
for (i = 0, tcmod = t->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++)
{
matrix4x4_t matrix;
// applied to the color
// FIXME: r_glsl 1 rendering doesn't support overbright lightstyles with this (the default light style is not overbright)
if (ent->model->type == mod_brushq3)
- colorscale *= r_refdef.lightstylevalue[0] * (1.0f / 256.0f);
+ colorscale *= r_refdef.rtlightstylevalue[0];
colorscale *= r_refdef.lightmapintensity;
R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, t->currentalpha);
if (r_ambient.value >= (1.0f/64.0f))
}
if (r_shownormals.value > 0)
{
- GL_Color(r_view.colorscale, 0, 0, r_shownormals.value);
qglBegin(GL_LINES);
for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
{
VectorCopy(rsurface.vertex3f + l * 3, v);
+ GL_Color(r_view.colorscale, 0, 0, 1);
qglVertex3f(v[0], v[1], v[2]);
- VectorMA(v, 8, rsurface.svector3f + l * 3, v);
+ VectorMA(v, r_shownormals.value, rsurface.svector3f + l * 3, v);
+ GL_Color(r_view.colorscale, 1, 1, 1);
qglVertex3f(v[0], v[1], v[2]);
}
qglEnd();
CHECKGLERROR
- GL_Color(0, 0, r_view.colorscale, r_shownormals.value);
qglBegin(GL_LINES);
for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
{
VectorCopy(rsurface.vertex3f + l * 3, v);
+ GL_Color(0, r_view.colorscale, 0, 1);
qglVertex3f(v[0], v[1], v[2]);
- VectorMA(v, 8, rsurface.tvector3f + l * 3, v);
+ VectorMA(v, r_shownormals.value, rsurface.tvector3f + l * 3, v);
+ GL_Color(r_view.colorscale, 1, 1, 1);
qglVertex3f(v[0], v[1], v[2]);
}
qglEnd();
CHECKGLERROR
- GL_Color(0, r_view.colorscale, 0, r_shownormals.value);
qglBegin(GL_LINES);
for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
{
VectorCopy(rsurface.vertex3f + l * 3, v);
+ GL_Color(0, 0, r_view.colorscale, 1);
qglVertex3f(v[0], v[1], v[2]);
- VectorMA(v, 8, rsurface.normal3f + l * 3, v);
+ VectorMA(v, r_shownormals.value, rsurface.normal3f + l * 3, v);
+ GL_Color(r_view.colorscale, 1, 1, 1);
qglVertex3f(v[0], v[1], v[2]);
}
qglEnd();
RSurf_ActiveWorldEntity();
// update light styles on this submodel
- if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.num_lightstyles)
+ if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0)
{
model_brush_lightstyleinfo_t *style;
for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++)
RSurf_ActiveModelEntity(ent, true, r_glsl.integer && gl_support_fragment_shader && !depthonly);
// update light styles
- if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.num_lightstyles)
+ if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0)
{
model_brush_lightstyleinfo_t *style;
for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++)