- Added support for defining the full color range of a special colormap.

SVN r1865 (trunk)
This commit is contained in:
Randy Heit 2009-09-22 02:54:19 +00:00
parent 79298285f7
commit 84a018f05a
23 changed files with 113 additions and 108 deletions

View file

@ -1,4 +1,8 @@
September 21, 2009
- Added support for defining the full color range of a special colormap.
- Moved the code for specialcolormap and colormapstyle in D3DFB::SetStyle()
at the end of the normally-colored block so that they get all the proper
texture format setup.
- Fixed: In letterbox modes, the clipping window needs to be adjusted down.
September 21, 2009 (Changes by Graf Zahl)

View file

@ -1823,10 +1823,6 @@ void R_DrawRemainingPlayerSprites()
{
// Yuck! There needs to be a better way to store colormaps in the vissprite... :(
ptrdiff_t specialmap = (vis->colormap - SpecialColormaps[0].Colormap) / sizeof(FSpecialColormap);
if (SpecialColormaps[specialmap].Inverted)
{
vis->RenderStyle.Flags ^= STYLEF_InvertSource;
}
special = &SpecialColormaps[specialmap];
}
else if (colormap->Color == PalEntry(255,255,255) &&

View file

@ -1608,7 +1608,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory)
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY_PREFIX(powerup, colormap, FFFI, Inventory)
DEFINE_CLASS_PROPERTY_PREFIX(powerup, colormap, FFFfff, Inventory)
{
PalEntry * pBlendColor;
@ -1626,14 +1626,27 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, colormap, FFFI, Inventory)
return;
}
PROP_FLOAT_PARM(r, 0);
PROP_FLOAT_PARM(g, 1);
PROP_FLOAT_PARM(b, 2);
PROP_INT_PARM(inv, 3);
*pBlendColor = MakeSpecialColormap(AddSpecialColormap(r, g, b, !!inv));
if (PROP_PARM_COUNT == 3)
{
PROP_FLOAT_PARM(r, 0);
PROP_FLOAT_PARM(g, 1);
PROP_FLOAT_PARM(b, 2);
*pBlendColor = MakeSpecialColormap(AddSpecialColormap(0, 0, 0, r, g, b));
}
else if (PROP_PARM_COUNT == 6)
{
PROP_FLOAT_PARM(r1, 0);
PROP_FLOAT_PARM(g1, 1);
PROP_FLOAT_PARM(b1, 2);
PROP_FLOAT_PARM(r2, 0);
PROP_FLOAT_PARM(g2, 1);
PROP_FLOAT_PARM(b2, 2);
*pBlendColor = MakeSpecialColormap(AddSpecialColormap(r1, g1, b1, r2, g2, b2));
}
else
{
I_Error("\"power.colormap\" must have either 3 or 6 parameters\n");
}
}
//==========================================================================

View file

@ -66,27 +66,26 @@ BYTE DesaturateColormap[31][256];
struct FSpecialColormapParameters
{
float Colorize[3];
bool Inverted;
float Start[3], End[3];
};
static FSpecialColormapParameters SpecialColormapParms[] =
{
// Doom invulnerability is an inverted grayscale.
// Strife uses it when firing the Sigil
{ { 1, 1, 1 }, true },
{ { 1, 1, 1 }, { 0, 0, 0 } },
// Heretic invulnerability is a golden shade.
{ { 1.5, 0.75, 0 }, false },
{ { 0, 0, 0 }, { 1.5, 0.75, 0 }, },
// [BC] Build the Doomsphere colormap. It is red!
{ { 1.5, 0, 0 }, false },
{ { 0, 0, 0 }, { 1.5, 0, 0 } },
// [BC] Build the Guardsphere colormap. It's a greenish-white kind of thing.
{ { 1.25, 1.5, 1 }, false },
{ { 0, 0, 0 }, { 1.25, 1.5, 1 } },
// Build a blue colormap.
{ { 0, 0, 1.5 }, false },
{{ 0, 0, 0 }, { 0, 0, 1.5 } },
};
static void FreeSpecialLights();
@ -361,14 +360,24 @@ static bool FixBuildPalette (BYTE *opal, int lump, bool blood)
return true;
}
int AddSpecialColormap(double r, double g, double b, bool inv)
int AddSpecialColormap(double r1, double g1, double b1, double r2, double g2, double b2)
{
// Clamp these in range for the hardware shader.
r1 = clamp(r1, 0.0, 2.0);
g1 = clamp(g1, 0.0, 2.0);
b1 = clamp(b1, 0.0, 2.0);
r2 = clamp(r2, 0.0, 2.0);
g2 = clamp(g2, 0.0, 2.0);
b2 = clamp(b2, 0.0, 2.0);
for(unsigned i=0; i<SpecialColormaps.Size(); i++)
{
if (SpecialColormaps[i].Colorize[0] == r &&
SpecialColormaps[i].Colorize[1] == g &&
SpecialColormaps[i].Colorize[2] == b &&
SpecialColormaps[i].Inverted == inv)
if (SpecialColormaps[i].ColorizeStart[0] == r1 &&
SpecialColormaps[i].ColorizeStart[1] == g1 &&
SpecialColormaps[i].ColorizeStart[2] == b1 &&
SpecialColormaps[i].ColorizeEnd[0] == r2 &&
SpecialColormaps[i].ColorizeEnd[1] == g2 &&
SpecialColormaps[i].ColorizeEnd[2] == b2)
{
return i; // The map already exists
}
@ -376,35 +385,34 @@ int AddSpecialColormap(double r, double g, double b, bool inv)
FSpecialColormap *cm = &SpecialColormaps[SpecialColormaps.Reserve(1)];
cm->Colorize[0] = float(r);
cm->Colorize[1] = float(g);
cm->Colorize[2] = float(b);
cm->Inverted = inv;
cm->ColorizeStart[0] = float(r1);
cm->ColorizeStart[1] = float(g1);
cm->ColorizeStart[2] = float(b1);
cm->ColorizeEnd[0] = float(r2);
cm->ColorizeEnd[1] = float(g2);
cm->ColorizeEnd[2] = float(b2);
r2 -= r1;
g2 -= g1;
b2 -= b1;
r1 *= 255;
g1 *= 255;
b1 *= 255;
for (int c = 0; c < 256; c++)
{
double intensity = (GPalette.BaseColors[c].r * 77 +
GPalette.BaseColors[c].g * 143 +
GPalette.BaseColors[c].b * 37) / 256.0;
if (inv)
{
intensity = 255 - intensity;
}
PalEntry pe = PalEntry( MIN(255, int(intensity*r)),
MIN(255, int(intensity*g)),
MIN(255, int(intensity*b)));
PalEntry pe = PalEntry( MIN(255, int(r1 + intensity*r2)),
MIN(255, int(g1 + intensity*g2)),
MIN(255, int(b1 + intensity*b2)));
cm->Colormap[c] = ColorMatcher.Pick(pe);
// This table is used by the texture composition code
for(int i = 0;i < 256; i++)
{
intensity = inv? 255-i : i;
cm->GrayscaleToColor[i] = PalEntry( MIN(255, int(intensity*r)),
MIN(255, int(intensity*g)),
MIN(255, int(intensity*b)));
}
cm->GrayscaleToColor[c] = pe;
}
return SpecialColormaps.Size() - 1;
}
@ -456,8 +464,9 @@ void InitPalette ()
for (int i = 0; i < countof(SpecialColormapParms); ++i)
{
AddSpecialColormap(SpecialColormapParms[i].Colorize[0], SpecialColormapParms[i].Colorize[1],
SpecialColormapParms[i].Colorize[2], SpecialColormapParms[i].Inverted);
AddSpecialColormap(SpecialColormapParms[i].Start[0], SpecialColormapParms[i].Start[1],
SpecialColormapParms[i].Start[2], SpecialColormapParms[i].End[0],
SpecialColormapParms[i].End[1], SpecialColormapParms[i].End[2]);
}
// desaturated colormaps
for(int m = 0; m < 31; m++)

View file

@ -97,8 +97,8 @@ enum
struct FSpecialColormap
{
float Colorize[3];
bool Inverted;
float ColorizeStart[3];
float ColorizeEnd[3];
BYTE Colormap[256];
PalEntry GrayscaleToColor[256];
};
@ -124,7 +124,7 @@ inline int GetSpecialColormap(int blend)
return IsSpecialColormap(blend) ? blend & 0xFFFF : NOFIXEDCOLORMAP;
}
int AddSpecialColormap(double r, double g, double b, bool inv);
int AddSpecialColormap(double r1, double g1, double b1, double r2, double g2, double b2);
@ -152,7 +152,7 @@ void V_SetBlend (int blendr, int blendg, int blendb, int blenda);
// V_ForceBlend()
//
// Normally, V_SetBlend() does nothing if the new blend is the
// same as the old. This function will performing the blending
// same as the old. This function will perform the blending
// even if the blend hasn't changed.
void V_ForceBlend (int blendr, int blendg, int blendb, int blenda);

View file

@ -224,9 +224,7 @@ const char *const D3DFB::ShaderNames[D3DFB::NUM_SHADERS] =
"VertexColor.pso",
"SpecialColormap.pso",
"SpecialColormapInv.pso",
"SpecialColorMapPal.pso",
"SpecialColorMapPalInv.pso",
"InGameColormap.pso",
"InGameColormapDesat.pso",
@ -2984,8 +2982,7 @@ void D3DFB::EndQuadBatch()
{
int select;
select = !!(quad->Flags & BQF_InvertSource);
select |= !!(quad->Flags & BQF_Paletted) << 1;
select = !!(quad->Flags & BQF_Paletted);
SetPixelShader(Shaders[SHADER_SpecialColormap + select]);
}
else if (quad->ShaderNum == BQS_InGameColormap)
@ -3115,47 +3112,7 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &
SetColorOverlay(parms.colorOverlay, alpha, color0, color1);
if (parms.specialcolormap != NULL)
{ // Emulate an invulnerability or similar colormap.
if (style.Flags & STYLEF_InvertSource)
{
quad.Flags |= BQF_InvertSource;
}
if (fmt == D3DFMT_L8)
{
quad.Flags |= BQF_GamePalette;
}
quad.ShaderNum = BQS_SpecialColormap;
color0 = D3DCOLOR_COLORVALUE(parms.specialcolormap->Colorize[0]/2,
parms.specialcolormap->Colorize[1]/2, parms.specialcolormap->Colorize[2]/2, 1);
color1 = D3DCOLOR_ARGB(255,0,0,0);
}
else if (parms.colormapstyle != NULL)
{ // Emulate the fading from an in-game colormap (colorized, faded, and desaturated)
if (style.Flags & STYLEF_InvertSource)
{
quad.Flags |= BQF_InvertSource;
}
if (fmt == D3DFMT_L8)
{
quad.Flags |= BQF_GamePalette;
}
if (parms.colormapstyle->Desaturate != 0)
{
quad.Flags |= BQF_Desaturated;
}
quad.ShaderNum = BQS_InGameColormap;
color0 = D3DCOLOR_ARGB(parms.colormapstyle->Desaturate,
parms.colormapstyle->Color.r,
parms.colormapstyle->Color.g,
parms.colormapstyle->Color.b);
double fadelevel = parms.colormapstyle->FadeLevel;
color1 = D3DCOLOR_ARGB(DWORD((1 - fadelevel) * 255),
DWORD(parms.colormapstyle->Fade.r * fadelevel),
DWORD(parms.colormapstyle->Fade.g * fadelevel),
DWORD(parms.colormapstyle->Fade.b * fadelevel));
}
else if (style.Flags & STYLEF_ColorIsFixed)
if (style.Flags & STYLEF_ColorIsFixed)
{
if (style.Flags & STYLEF_InvertSource)
{ // Since the source color is a constant, we can invert it now
@ -3219,10 +3176,42 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &
{
quad.Flags |= BQF_InvertSource;
}
if (parms.specialcolormap != NULL)
{ // Emulate an invulnerability or similar colormap.
float *start, *end;
start = parms.specialcolormap->ColorizeStart;
end = parms.specialcolormap->ColorizeEnd;
if (quad.Flags & BQF_InvertSource)
{
quad.Flags &= ~BQF_InvertSource;
swap(start, end);
}
quad.ShaderNum = BQS_SpecialColormap;
color0 = D3DCOLOR_RGBA(DWORD(start[0]/2*255), DWORD(start[1]/2*255), DWORD(start[2]/2*255), color0 >> 24);
color1 = D3DCOLOR_RGBA(DWORD(end[0]/2*255), DWORD(end[1]/2*255), DWORD(end[2]/2*255), color1 >> 24);
}
else if (parms.colormapstyle != NULL)
{ // Emulate the fading from an in-game colormap (colorized, faded, and desaturated)
if (parms.colormapstyle->Desaturate != 0)
{
quad.Flags |= BQF_Desaturated;
}
quad.ShaderNum = BQS_InGameColormap;
color0 = D3DCOLOR_ARGB(parms.colormapstyle->Desaturate,
parms.colormapstyle->Color.r,
parms.colormapstyle->Color.g,
parms.colormapstyle->Color.b);
double fadelevel = parms.colormapstyle->FadeLevel;
color1 = D3DCOLOR_ARGB(DWORD((1 - fadelevel) * 255),
DWORD(parms.colormapstyle->Fade.r * fadelevel),
DWORD(parms.colormapstyle->Fade.g * fadelevel),
DWORD(parms.colormapstyle->Fade.b * fadelevel));
}
}
// For unmasked images, force the alpha from the image data to be ignored.
if (!parms.masked)
if (!parms.masked && quad.ShaderNum != BQS_InGameColormap)
{
color0 = (color0 & D3DCOLOR_RGBA(255, 255, 255, 0)) | D3DCOLOR_COLORVALUE(0, 0, 0, alpha);
color1 &= D3DCOLOR_RGBA(255, 255, 255, 0);

View file

@ -310,9 +310,7 @@ private:
SHADER_VertexColor,
SHADER_SpecialColormap,
SHADER_SpecialColormapInv,
SHADER_SpecialColorMapPal,
SHADER_SpecialColorMapPalInv,
SHADER_InGameColormap,
SHADER_InGameColormapDesat,

View file

@ -59,13 +59,15 @@ float4 VertexColor(float4 color : COLOR0) : COLOR
// Emulate one of the special colormaps. (Invulnerability, gold, etc.)
float4 SpecialColormap(float2 tex_coord : TEXCOORD0, float4 icolor : COLOR0) : COLOR
float4 SpecialColormap(float2 tex_coord : TEXCOORD0, float4 start : COLOR0, float4 end : COLOR1) : COLOR
{
// We can't store values greater than 1.0 in a color register, so we multiply
// intensity by 2 and expect the caller to divide icolor by 2.
float4 color = SampleTexture(tex_coord);
float intensity = 2 * Grayscale(color);
color.rgb = icolor.rgb * intensity;
float4 range = end - start;
// We can't store values greater than 1.0 in a color register, so we multiply
// the final result by 2 and expect the caller to divide the start and end by 2.
color.rgb = 2 * (start + Grayscale(color) * range);
// Duplicate alpha semantics of NormalColor.
color.a = start.a + color.a * end.a;
return color;
}

View file

@ -9,9 +9,7 @@ fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ERedToAlpha -DINVERT=1 /FoRedToAlphaInv
fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EVertexColor /FoVertexColor.pso
fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ESpecialColormap -DPALTEX=0 -DINVERT=0 /FoSpecialColormap.pso
fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ESpecialColormap -DPALTEX=0 -DINVERT=1 /FoSpecialColormapInv.pso
fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ESpecialColormap -DPALTEX=1 -DINVERT=0 /FoSpecialColormapPal.pso
fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ESpecialColormap -DPALTEX=1 -DINVERT=1 /FoSpecialColormapPalInv.pso
fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=0 /FoInGameColormap.pso
fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=1 /FoInGameColormapDesat.pso

View file

@ -9,9 +9,7 @@ fxc ..\shaders.ps /Tps_2_0 /O3 /ERedToAlpha -DINVERT=1 /FoRedToAlphaInv.pso
fxc ..\shaders.ps /Tps_2_0 /O3 /EVertexColor /FoVertexColor.pso
fxc ..\shaders.ps /Tps_2_0 /O3 /ESpecialColormap -DPALTEX=0 -DINVERT=0 /FoSpecialColormap.pso
fxc ..\shaders.ps /Tps_2_0 /O3 /ESpecialColormap -DPALTEX=0 -DINVERT=1 /FoSpecialColormapInv.pso
fxc ..\shaders.ps /Tps_2_0 /O3 /ESpecialColormap -DPALTEX=1 -DINVERT=0 /FoSpecialColormapPal.pso
fxc ..\shaders.ps /Tps_2_0 /O3 /ESpecialColormap -DPALTEX=1 -DINVERT=1 /FoSpecialColormapPalInv.pso
fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=0 /FoInGameColormap.pso
fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=1 /FoInGameColormapDesat.pso

View file

@ -9,9 +9,7 @@ fxc ..\shaders.ps /Tps_3_0 /O3 /ERedToAlpha -DINVERT=1 /FoRedToAlphaInv.pso
fxc ..\shaders.ps /Tps_3_0 /O3 /EVertexColor /FoVertexColor.pso
fxc ..\shaders.ps /Tps_3_0 /O3 /ESpecialColormap -DPALTEX=0 -DINVERT=0 /FoSpecialColormap.pso
fxc ..\shaders.ps /Tps_3_0 /O3 /ESpecialColormap -DPALTEX=0 -DINVERT=1 /FoSpecialColormapInv.pso
fxc ..\shaders.ps /Tps_3_0 /O3 /ESpecialColormap -DPALTEX=1 -DINVERT=0 /FoSpecialColormapPal.pso
fxc ..\shaders.ps /Tps_3_0 /O3 /ESpecialColormap -DPALTEX=1 -DINVERT=1 /FoSpecialColormapPalInv.pso
fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=0 /FoInGameColormap.pso
fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=1 /FoInGameColormapDesat.pso