--- /dev/null
+use strict;
+use warnings;
+
+# generates the blendfunc flags function in gl_rmain.c
+
+my %blendfuncs =
+(
+ GL_ONE => sub { (1, 1); },
+ GL_ZERO => sub { (0, 0); },
+ GL_SRC_COLOR => sub { ($_[0], $_[1]); },
+ GL_ONE_MINUS_SRC_COLOR => sub { (1-$_[0], 1-$_[1]); },
+ GL_SRC_ALPHA => sub { ($_[1], $_[1]); },
+ GL_ONE_MINUS_SRC_ALPHA => sub { (1-$_[1], 1-$_[1]); },
+ GL_DST_COLOR => sub { ($_[2], $_[3]); },
+ GL_ONE_MINUS_DST_COLOR => sub { (1-$_[2], 1-$_[3]); },
+ GL_DST_ALPHA => sub { ($_[3], $_[3]); },
+ GL_ONE_MINUS_DST_ALPHA => sub { (1-$_[3], 1-$_[3]); },
+);
+
+sub evalblend($$$$$$)
+{
+ my ($fs, $fd, $s, $sa, $d, $da) = @_;
+ my @fs = $fs->($s, $sa, $d, $da);
+ my @fd = $fd->($s, $sa, $d, $da);
+ return (
+ $fs[0] * $s + $fd[0] * $d,
+ $fs[1] * $sa + $fd[1] * $da
+ );
+}
+
+sub isinvariant($$$$)
+{
+ my ($fs, $fd, $s, $sa) = @_;
+ my ($d, $da) = (0.7823, 0.3289);
+ my ($out, $outa) = evalblend $fs, $fd, $s, $sa, $d, $da;
+ return abs($out - $d) < 0.001 && abs($outa - $da) < 0.001;
+}
+
+sub isfogfriendly($$$$$)
+{
+ my ($fs, $fd, $s, $sa, $foghack) = @_;
+ my ($d, $da) = (0.7823, 0.3289);
+ my $fogamount = 0.3237;
+ my $fogcolor = 0.8612;
+
+ # compare:
+ # 1. blend(fog(s), sa, fog(d), da)
+ # 2. fog(blend(s, sa, d, da))
+
+ my ($out1, $out1a) = evalblend $fs, $fd, $s + ((defined $foghack ? $foghack < 0 ? $s : $foghack : $fogcolor) - $s) * $fogamount, $sa, $d + ($fogcolor - $d) * $fogamount, $da;
+ my ($out2, $out2a) = evalblend $fs, $fd, $s, $sa, $d, $da;
+ $out2 = $out2 + ($fogcolor - $out2) * $fogamount;
+
+ return abs($out1 - $out2) < 0.001 && abs($out1a - $out2a) < 0.001;
+}
+
+#die isfogfriendly $blendfuncs{GL_ONE}, $blendfuncs{GL_ONE}, 1, 0, 0;
+# out1 = 0 + fog($d)
+# out2 = fog(1 + $d)
+
+sub willitblend($$)
+{
+ my ($fs, $fd) = @_;
+ for my $s(0, 0.25, 0.5, 0.75, 1)
+ {
+ for my $sa(0, 0.25, 0.5, 0.75, 1)
+ {
+ if(isinvariant($fs, $fd, $s, $sa))
+ {
+ if(!isinvariant($fs, $fd, 0, $sa))
+ {
+ return 0; # no colormod possible
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+sub willitfog($$)
+{
+ my ($fs, $fd) = @_;
+
+ FOGHACK:
+ for my $foghack(undef, 0, 1, -1)
+ {
+ for my $s(0, 0.25, 0.5, 0.75, 1)
+ {
+ for my $sa(0, 0.25, 0.5, 0.75, 1)
+ {
+ if(!isfogfriendly($fs, $fd, $s, $sa, $foghack))
+ {
+ next FOGHACK;
+ }
+ }
+ }
+ return (1, $foghack);
+ }
+ return (0, undef);
+}
+
+print "\tr |= BLENDFUNC_ALLOWS_COLORMOD;\n";
+for my $s(sort keys %blendfuncs)
+{
+ for my $d(sort keys %blendfuncs)
+ {
+ if(!willitblend $blendfuncs{$s}, $blendfuncs{$d})
+ {
+ print "\tif(src == $s && dst == $d) r &= ~BLENDFUNC_ALLOWS_COLORMOD;\n";
+ }
+ my ($result, $h) = willitfog $blendfuncs{$s}, $blendfuncs{$d};
+ if($result)
+ {
+ if(defined $h)
+ {
+ print "\tif(src == $s && dst == $d) r |= BLENDFUNC_ALLOWS_FOG_HACK$h;\n";
+ }
+ else
+ {
+ print "\tif(src == $s && dst == $d) r |= BLENDFUNC_ALLOWS_FOG;\n";
+ }
+ }
+ }
+}
+
extern rtexture_t *r_shadow_prepassgeometrydepthcolortexture;
extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
extern rtexture_t *r_shadow_prepasslightingspeculartexture;
-static qboolean R_BlendFuncAllowsColormod(int src, int dst)
+
+#define BLENDFUNC_ALLOWS_COLORMOD 1
+#define BLENDFUNC_ALLOWS_FOG 2
+#define BLENDFUNC_ALLOWS_FOG_HACK0 4
+#define BLENDFUNC_ALLOWS_ANYFOG 6
+static int R_BlendFuncFlags(int src, int dst)
{
+ int r = 0;
+
// a blendfunc allows colormod if:
// a) it can never keep the destination pixel invariant, or
// b) it can keep the destination pixel invariant, and still can do so if colormodded
// this is to prevent unintended side effects from colormod
- // in formulas:
- // IF there is a (s, sa) for which for all (d, da),
- // s * src(s, d, sa, da) + d * dst(s, d, sa, da) == d
- // THEN, for this (s, sa) and all (colormod, d, da):
- // s*colormod * src(s*colormod, d, sa, da) + d * dst(s*colormod, d, sa, da) == d
- // OBVIOUSLY, this means that
- // s*colormod * src(s*colormod, d, sa, da) = 0
- // dst(s*colormod, d, sa, da) = 1
-
- // note: not caring about GL_SRC_ALPHA_SATURATE and following here, these are unused in DP code
-
- // main condition to leave dst color invariant:
- // s * src(s, d, sa, da) + d * dst(s, d, sa, da) == d
- // src == GL_ZERO:
- // s * 0 + d * dst(s, d, sa, da) == d
- // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod is a problem for GL_SRC_COLOR only
- // src == GL_ONE:
- // s + d * dst(s, d, sa, da) == d
- // => s == 0
- // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod is never problematic for these
- // src == GL_SRC_COLOR:
- // s*s + d * dst(s, d, sa, da) == d
- // => s == 0
- // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod is never problematic for these
- // src == GL_ONE_MINUS_SRC_COLOR:
- // s*(1-s) + d * dst(s, d, sa, da) == d
- // => s == 0 or s == 1
- // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod is a problem for GL_SRC_COLOR only
- // src == GL_DST_COLOR
- // s*d + d * dst(s, d, sa, da) == d
- // => s == 1
- // => dst == GL_ZERO/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod is always a problem
- // or
- // => s == 0
- // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod is never problematic for these
- // => BUT, we do not know s! We must assume it is problematic
- // then... except in GL_ONE case, where we know all invariant
- // cases are fine
- // src == GL_ONE_MINUS_DST_COLOR
- // s*(1-d) + d * dst(s, d, sa, da) == d
- // => s == 0 (1-d is impossible to handle for our desired result)
- // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod is never problematic for these
- // src == GL_SRC_ALPHA
- // s*sa + d * dst(s, d, sa, da) == d
- // => s == 0, or sa == 0
- // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod breaks in the case GL_SRC_COLOR only
- // src == GL_ONE_MINUS_SRC_ALPHA
- // s*(1-sa) + d * dst(s, d, sa, da) == d
- // => s == 0, or sa == 1
- // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod breaks in the case GL_SRC_COLOR only
- // src == GL_DST_ALPHA
- // s*da + d * dst(s, d, sa, da) == d
- // => s == 0
- // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod is never problematic for these
-
- switch(src)
- {
- case GL_ZERO:
- case GL_ONE_MINUS_SRC_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- if(dst == GL_SRC_COLOR)
- return false;
- return true;
- case GL_ONE:
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- return true;
- case GL_DST_COLOR:
- if(dst == GL_ONE)
- return true;
- return false;
- default:
- return false;
- }
-}
-static qboolean R_BlendFuncAllowsFog(int src, int dst)
-{
// a blendfunc allows fog if:
- // a) it can never keep the destination pixel invariant, or
- // b) it can keep the destination pixel invariant, and still can do so if fogged
- // this is to prevent unintended side effects from colormod
-
- // main condition to leave dst color invariant:
- // s * src(s, d, sa, da) + d * dst(s, d, sa, da) == d
- // src == GL_ZERO:
- // s * 0 + d * dst(s, d, sa, da) == d
- // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => fog is a problem for GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR only
- // src == GL_ONE:
- // s + d * dst(s, d, sa, da) == d
- // => s == 0
- // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => fog is a problem for all of them, because we require s == 0
- // src == GL_SRC_COLOR:
- // s*s + d * dst(s, d, sa, da) == d
- // => s == 0
- // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => fog is a problem for all of them, because we require s == 0
- // src == GL_ONE_MINUS_SRC_COLOR:
- // s*(1-s) + d * dst(s, d, sa, da) == d
- // => s == 0 or s == 1
- // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => fog is a problem for all of them, because we require s == 0 or s == 1
- // src == GL_DST_COLOR
- // s*d + d * dst(s, d, sa, da) == d
- // => s == 1
- // => dst == GL_ZERO/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => fog is a problem for all of them, because we require s == 1
- // or
- // => s == 0
- // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod is never problematic for these
- // => BUT, we do not know s! We must assume it is problematic
- // then... except in GL_ONE case, where we know all invariant
- // cases are fine
- // => fog is a problem for all of them, because we require s == 0 or s == 1
- // src == GL_ONE_MINUS_DST_COLOR
- // s*(1-d) + d * dst(s, d, sa, da) == d
- // => s == 0 (1-d is impossible to handle for our desired result)
- // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod is never problematic for these
- // => fog is a problem for all of them, because we require s == 0
- // src == GL_SRC_ALPHA
- // s*sa + d * dst(s, d, sa, da) == d
- // => s == 0, or sa == 0
- // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => fog breaks in the case GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR only
- // src == GL_ONE_MINUS_SRC_ALPHA
- // s*(1-sa) + d * dst(s, d, sa, da) == d
- // => s == 0, or sa == 1
- // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => colormod breaks in the case GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR only
- // src == GL_DST_ALPHA
- // s*da + d * dst(s, d, sa, da) == d
- // => s == 0
- // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
- // => fog is a problem for all of them, because we require s == 0
-
- switch(src)
- {
- case GL_ZERO:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- if(dst == GL_SRC_COLOR || dst == GL_ONE_MINUS_SRC_COLOR)
- return false;
- return true;
- case GL_ONE_MINUS_SRC_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- if(dst == GL_ONE || dst == GL_SRC_COLOR || dst == GL_ONE_MINUS_SRC_COLOR || dst == GL_SRC_ALPHA || dst == GL_ONE_MINUS_SRC_ALPHA)
- return false;
- return true;
- case GL_ONE:
- case GL_SRC_COLOR:
- case GL_DST_ALPHA:
- if(dst == GL_ONE || dst == GL_ONE_MINUS_SRC_COLOR || dst == GL_SRC_ALPHA || dst == GL_ONE_MINUS_SRC_ALPHA)
- return false;
- return true;
- case GL_DST_COLOR:
- if(dst == GL_ZERO || dst == GL_ONE_MINUS_SRC_COLOR || dst == GL_SRC_ALPHA || dst == GL_ONE_MINUS_SRC_ALPHA)
- return false;
- return true;
- case GL_ONE_MINUS_DST_ALPHA:
- return true;
- default:
- return false;
- }
+ // blend(fog(src), fog(dst)) == fog(blend(src, dst))
+ // this is to prevent unintended side effects from fog
+
+ // these checks are the output of fogeval.pl
+
+ r |= BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
+ if(src == GL_DST_ALPHA && dst == GL_ONE_MINUS_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_DST_COLOR && dst == GL_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_DST_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_DST_COLOR && dst == GL_ZERO) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_ONE && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
+ if(src == GL_ONE && dst == GL_ZERO) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
+ if(src == GL_ONE_MINUS_DST_COLOR && dst == GL_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
+ if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_ONE_MINUS_SRC_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
+ if(src == GL_SRC_ALPHA && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_ZERO && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_ZERO && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+
+ return r;
}
+
void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *surfacewaterplane)
{
// select a permutation of the lighting shader appropriate to this
// fragment shader on features that are not being used
unsigned int permutation = 0;
unsigned int mode = 0;
- qboolean allow_colormod;
- qboolean allow_fog;
+ int blendfuncflags;
static float dummy_colormod[3] = {1, 1, 1};
float *colormod = rsurface.colormod;
float m16f[16];
{
// this is the right thing to do for wateralpha
GL_BlendFunc(GL_ONE, GL_ZERO);
- allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
- allow_fog = R_BlendFuncAllowsFog(GL_ONE, GL_ZERO);
+ blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
}
else
{
// this is the right thing to do for entity alpha
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- allow_fog = R_BlendFuncAllowsFog(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
}
else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
{
mode = SHADERMODE_REFRACTION;
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- allow_fog = R_BlendFuncAllowsFog(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else
{
mode = SHADERMODE_GENERIC;
permutation |= SHADERPERMUTATION_DIFFUSE;
GL_BlendFunc(GL_ONE, GL_ZERO);
- allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
- allow_fog = R_BlendFuncAllowsFog(GL_ONE, GL_ZERO);
+ blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
}
}
else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
GL_BlendFunc(GL_ONE, GL_ZERO);
- allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
- allow_fog = R_BlendFuncAllowsFog(GL_ONE, GL_ZERO);
+ blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
}
else if (rsurfacepass == RSURFPASS_RTLIGHT)
{
if (rsurface.texture->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE);
- allow_fog = R_BlendFuncAllowsFog(GL_SRC_ALPHA, GL_ONE);
+ blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE);
}
else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
{
if (rsurface.texture->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- allow_fog = R_BlendFuncAllowsFog(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
}
else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
{
if (r_shadow_bouncegridtexture)
permutation |= SHADERPERMUTATION_BOUNCEGRID;
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- allow_fog = R_BlendFuncAllowsFog(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
}
else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
{
if (r_shadow_bouncegridtexture)
permutation |= SHADERPERMUTATION_BOUNCEGRID;
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- allow_fog = R_BlendFuncAllowsFog(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
}
else
{
if (r_shadow_bouncegridtexture)
permutation |= SHADERPERMUTATION_BOUNCEGRID;
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- allow_fog = R_BlendFuncAllowsFog(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
}
- if(!allow_colormod)
+ if(!(blendfuncflags & BLENDFUNC_ALLOWS_COLORMOD))
colormod = dummy_colormod;
- if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
- allow_fog = allow_colormod; // we actually implement fog by colormodding with a color (f,f,f) for some f
- if(!allow_fog)
+ if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG))
permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE);
switch(vid.renderpath)
{
hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
}
// additive passes are only darkened by fog, not tinted
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
+ if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
else
hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
// additive passes are only darkened by fog, not tinted
if (r_glsl_permutation->loc_FogColor >= 0)
{
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
+ if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
else
qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
}
// additive passes are only darkened by fog, not tinted
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
+ if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
else
DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
blendfunc2 = GL_ZERO;
}
// don't colormod evilblend textures
- if(!R_BlendFuncAllowsColormod(blendfunc1, blendfunc2))
+ if(!R_BlendFuncFlags(blendfunc1, blendfunc2) & BLENDFUNC_ALLOWS_COLORMOD)
VectorSet(t->lightmapcolor, 1, 1, 1);
depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED);
if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)