- 2D drawer implementation complete for hardware renderer.

This also replaces DTA_ColormapStyle with proper implementations of its components. As implemented it was a very awkward mixture of various effects that already existed in a separate form. As a result of its implementation it required additional but completely redundant shader support which could be removed now. As a side effect of this change a new DTA_Desaturate option was added.
This commit is contained in:
Christoph Oelckers 2018-03-29 16:21:21 +02:00
parent 077df87704
commit a40e085a46
16 changed files with 80 additions and 98 deletions

View file

@ -2191,6 +2191,11 @@ void AM_drawSubsectors()
(colormap.LightColor.b + 160) / 2); (colormap.LightColor.b + 160) / 2);
colormap.Desaturation = 255 - (255 - colormap.Desaturation) / 4; colormap.Desaturation = 255 - (255 - colormap.Desaturation) / 4;
} }
// make table based fog visible on the automap as well.
if (level.flags & LEVEL_HASFADETABLE)
{
colormap.FadeColor = PalEntry(0, 128, 128, 128);
}
// Draw the polygon. // Draw the polygon.
FTexture *pic = TexMan(maptex); FTexture *pic = TexMan(maptex);

View file

@ -10,7 +10,6 @@ struct lightlist_t;
enum EColorManipulation enum EColorManipulation
{ {
CM_SPECIAL2D = -3, // the special colormaps get passed as color pair from the 2D drawer so they need a different value here. CM_SPECIAL2D = -3, // the special colormaps get passed as color pair from the 2D drawer so they need a different value here.
CM_INGAME2D = -3, // ingame lighting mode for automap
CM_PLAIN2D = -2, // regular 2D drawing. CM_PLAIN2D = -2, // regular 2D drawing.
CM_INVALID=-1, CM_INVALID=-1,
CM_DEFAULT=0, // untranslated CM_DEFAULT=0, // untranslated

View file

@ -541,13 +541,8 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
} }
else else
{ {
gl_RenderState.SetObjectColor(cmd.mColor1); gl_RenderState.Set2DColors(cmd.mColor1, cmd.mColor2);
gl_RenderState.SetObjectColor2(cmd.mColor2); if (cmd.mFlags & F2DDrawer::DTF_SpecialColormap)
if (cmd.mFlags & F2DDrawer::DTF_IngameLighting)
{
gl_RenderState.SetFixedColormap(CM_INGAME2D);
}
else if (cmd.mFlags & F2DDrawer::DTF_SpecialColormap)
{ {
gl_RenderState.SetFixedColormap(CM_SPECIAL2D); gl_RenderState.SetFixedColormap(CM_SPECIAL2D);
} }

View file

@ -159,8 +159,6 @@ bool FRenderState::ApplyShader()
glVertexAttrib4fv(VATTR_COLOR, mColor.vec); glVertexAttrib4fv(VATTR_COLOR, mColor.vec);
glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec); glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec);
//activeShader->muObjectColor2.Set(mObjectColor2);
activeShader->muObjectColor2.Set(mObjectColor2);
activeShader->muDesaturation.Set(mDesaturation / 255.f); activeShader->muDesaturation.Set(mDesaturation / 255.f);
activeShader->muFogEnabled.Set(fogset); activeShader->muFogEnabled.Set(fogset);
@ -171,6 +169,7 @@ bool FRenderState::ApplyShader()
activeShader->muLightParms.Set(mLightParms); activeShader->muLightParms.Set(mLightParms);
activeShader->muFogColor.Set(mFogColor); activeShader->muFogColor.Set(mFogColor);
activeShader->muObjectColor.Set(mObjectColor); activeShader->muObjectColor.Set(mObjectColor);
activeShader->muObjectColor2.Set(mObjectColor2);
activeShader->muDynLightColor.Set(mDynColor.vec); activeShader->muDynLightColor.Set(mDynColor.vec);
activeShader->muInterpolationFactor.Set(mInterpolationFactor); activeShader->muInterpolationFactor.Set(mInterpolationFactor);
activeShader->muClipHeight.Set(mClipHeight); activeShader->muClipHeight.Set(mClipHeight);
@ -225,7 +224,28 @@ bool FRenderState::ApplyShader()
activeShader->currentcliplinestate = 0; activeShader->currentcliplinestate = 0;
} }
if (mColormapState != activeShader->currentfixedcolormap) if (mColormapState < -1) // 2D operations
{
if (mColormapState != CM_SPECIAL2D)
{
activeShader->muColormapStart.Set(m2DColors[0]);
activeShader->muFixedColormap.Set(4);
}
else
{
float startr = m2DColors[0].r / 255.f;
float startg = m2DColors[0].g / 255.f;
float startb = m2DColors[0].b / 255.f;
float ranger = m2DColors[1].r / 255.f - startr;
float rangeg = m2DColors[1].g / 255.f - startg;
float rangeb = m2DColors[1].b / 255.f - startb;
activeShader->muColormapStart.Set(startr, startg, startb, 0.f);
activeShader->muColormapRange.Set(ranger, rangeg, rangeb, 0.f);
activeShader->muFixedColormap.Set(1);
}
activeShader->currentfixedcolormap = mColormapState;
}
else if (mColormapState != activeShader->currentfixedcolormap)
{ {
float r, g, b; float r, g, b;
activeShader->currentfixedcolormap = mColormapState; activeShader->currentfixedcolormap = mColormapState;
@ -233,26 +253,6 @@ bool FRenderState::ApplyShader()
{ {
activeShader->muFixedColormap.Set(0); activeShader->muFixedColormap.Set(0);
} }
else if (mColormapState == CM_PLAIN2D)
{
activeShader->muFixedColormap.Set(4);
}
else if (mColormapState == CM_INGAME2D)
{
activeShader->muFixedColormap.Set(5);
}
else if (mColormapState == CM_SPECIAL2D)
{
activeShader->muFixedColormap.Set(1);
float startr = mObjectColor.r / 255;
float startg = mObjectColor.g / 255;
float startb = mObjectColor.b / 255;
float ranger = mObjectColor2.r / 255 - startr;
float rangeg = mObjectColor2.g / 255 - startg;
float rangeb = mObjectColor2.b / 255 - startb;
activeShader->muColormapStart.Set(startr, startg, startb, 0.f);
activeShader->muColormapRange.Set(ranger, rangeg, rangeb, 0.f);
}
else if (mColormapState > CM_DEFAULT && mColormapState < CM_MAXCOLORMAP) else if (mColormapState > CM_DEFAULT && mColormapState < CM_MAXCOLORMAP)
{ {
if (FGLRenderBuffers::IsEnabled()) if (FGLRenderBuffers::IsEnabled())

View file

@ -108,6 +108,7 @@ class FRenderState
PalEntry mFogColor; PalEntry mFogColor;
PalEntry mObjectColor; PalEntry mObjectColor;
PalEntry mObjectColor2; PalEntry mObjectColor2;
PalEntry m2DColors[2]; // in the shader these will reuse the colormap ramp uniforms.
FStateVec4 mDynColor; FStateVec4 mDynColor;
float mClipSplit[2]; float mClipSplit[2];
@ -392,6 +393,13 @@ public:
mObjectColor2 = pe; mObjectColor2 = pe;
} }
void Set2DColors(PalEntry pe, PalEntry pe2)
{
m2DColors[0] = pe;
m2DColors[1] = pe2;
}
void SetSpecular(float glossiness, float specularLevel) void SetSpecular(float glossiness, float specularLevel)
{ {
mGlossiness = glossiness; mGlossiness = glossiness;

View file

@ -200,6 +200,12 @@ public:
{ {
glUniform4f(mIndex, a, b, c, d); glUniform4f(mIndex, a, b, c, d);
} }
void Set(PalEntry newvalue)
{
glUniform4f(mIndex, newvalue.r / 255.f, newvalue.g / 255.f, newvalue.b / 255.f, newvalue.a / 255.f);
}
}; };
class FBufferedUniformPE class FBufferedUniformPE

View file

@ -179,7 +179,8 @@ void RenderPolyPlayerSprites::RenderRemainingSprites()
DTA_FillColor, sprite.FillColor, DTA_FillColor, sprite.FillColor,
DTA_SpecialColormap, sprite.special, DTA_SpecialColormap, sprite.special,
DTA_ColorOverlay, sprite.overlay.d, DTA_ColorOverlay, sprite.overlay.d,
DTA_ColormapStyle, sprite.usecolormapstyle ? &sprite.colormapstyle : nullptr, DTA_Color, sprite.LightColor,
DTA_Desaturate, sprite.Desaturate,
TAG_DONE); TAG_DONE);
} }
@ -441,19 +442,12 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p
{ {
accelSprite.special = PolyCameraLight::Instance()->ShaderColormap(); accelSprite.special = PolyCameraLight::Instance()->ShaderColormap();
} }
else if (colormap_to_use->Color == PalEntry(255, 255, 255) && else
colormap_to_use->Desaturate == 0)
{ {
accelSprite.overlay = colormap_to_use->Fade; accelSprite.overlay = colormap_to_use->Fade;
accelSprite.overlay.a = uint8_t(vis.Light.ColormapNum * 255 / NUMCOLORMAPS); accelSprite.overlay.a = uint8_t(vis.Light.ColormapNum * 255 / NUMCOLORMAPS);
} accelSprite.LightColor = colormap_to_use->Color;
else accelSprite.Desaturate = (uint8_t)clamp(colormap_to_use->Desaturate, 0, 255);
{
accelSprite.usecolormapstyle = true;
accelSprite.colormapstyle.Color = colormap_to_use->Color;
accelSprite.colormapstyle.Fade = colormap_to_use->Fade;
accelSprite.colormapstyle.Desaturate = colormap_to_use->Desaturate;
accelSprite.colormapstyle.FadeLevel = vis.Light.ColormapNum / float(NUMCOLORMAPS);
} }
AcceleratedSprites.Push(accelSprite); AcceleratedSprites.Push(accelSprite);

View file

@ -83,8 +83,8 @@ public:
bool flip = false; bool flip = false;
FSpecialColormap *special = nullptr; FSpecialColormap *special = nullptr;
PalEntry overlay = 0; PalEntry overlay = 0;
FColormapStyle colormapstyle; PalEntry LightColor = 0xffffffff;
bool usecolormapstyle = false; uint8_t Desaturate = 0;
}; };
class RenderPolyPlayerSprites class RenderPolyPlayerSprites

View file

@ -444,19 +444,12 @@ namespace swrenderer
{ {
accelSprite.special = CameraLight::Instance()->ShaderColormap(); accelSprite.special = CameraLight::Instance()->ShaderColormap();
} }
else if (colormap_to_use->Color == PalEntry(255, 255, 255) && else
colormap_to_use->Desaturate == 0)
{ {
accelSprite.overlay = colormap_to_use->Fade; accelSprite.overlay = colormap_to_use->Fade;
accelSprite.overlay.a = uint8_t(vis.Light.ColormapNum * 255 / NUMCOLORMAPS); accelSprite.overlay.a = uint8_t(vis.Light.ColormapNum * 255 / NUMCOLORMAPS);
} accelSprite.LightColor = colormap_to_use->Color;
else accelSprite.Desaturate = (uint8_t)clamp(colormap_to_use->Desaturate, 0, 255);
{
accelSprite.usecolormapstyle = true;
accelSprite.colormapstyle.Color = colormap_to_use->Color;
accelSprite.colormapstyle.Fade = colormap_to_use->Fade;
accelSprite.colormapstyle.Desaturate = colormap_to_use->Desaturate;
accelSprite.colormapstyle.FadeLevel = vis.Light.ColormapNum / float(NUMCOLORMAPS);
} }
AcceleratedSprites.Push(accelSprite); AcceleratedSprites.Push(accelSprite);
@ -489,7 +482,8 @@ namespace swrenderer
DTA_FillColor, sprite.FillColor, DTA_FillColor, sprite.FillColor,
DTA_SpecialColormap, sprite.special, DTA_SpecialColormap, sprite.special,
DTA_ColorOverlay, sprite.overlay.d, DTA_ColorOverlay, sprite.overlay.d,
DTA_ColormapStyle, sprite.usecolormapstyle ? &sprite.colormapstyle : nullptr, DTA_Color, sprite.LightColor,
DTA_Desaturate, sprite.Desaturate,
TAG_DONE); TAG_DONE);
} }

View file

@ -75,8 +75,8 @@ namespace swrenderer
bool flip = false; bool flip = false;
FSpecialColormap *special = nullptr; FSpecialColormap *special = nullptr;
PalEntry overlay = 0; PalEntry overlay = 0;
FColormapStyle colormapstyle; PalEntry LightColor = 0xffffffff;
bool usecolormapstyle = false; uint8_t Desaturate = 0;
}; };
class RenderPlayerSprites class RenderPlayerSprites

View file

@ -131,7 +131,6 @@ bool F2DDrawer::SetStyle(FTexture *tex, DrawParms &parms, PalEntry &vertexcolor,
} }
SetColorOverlay(parms.colorOverlay, alpha, vertexcolor, quad.mColor1); SetColorOverlay(parms.colorOverlay, alpha, vertexcolor, quad.mColor1);
quad.mColorOverlay = parms.colorOverlay;
if (style.Flags & STYLEF_ColorIsFixed) if (style.Flags & STYLEF_ColorIsFixed)
{ {
@ -186,22 +185,7 @@ bool F2DDrawer::SetStyle(FTexture *tex, DrawParms &parms, PalEntry &vertexcolor,
quad.mColor2.g = (uint8_t)(end[1] * (255 / 2)); quad.mColor2.g = (uint8_t)(end[1] * (255 / 2));
quad.mColor2.b = (uint8_t)(end[2] * (255 / 2)); quad.mColor2.b = (uint8_t)(end[2] * (255 / 2));
} }
else if (parms.colormapstyle != nullptr) quad.mDesaturate = parms.desaturate;
{
// Emulate the fading from an in-game colormap (colorized, faded, and desaturated)
// This only gets used to render the weapon sprite for the software renderer.
quad.mDesaturate = parms.colormapstyle->Desaturate;
vertexcolor.r = parms.colormapstyle->Color.r;
vertexcolor.g = parms.colormapstyle->Color.g;
vertexcolor.b = parms.colormapstyle->Color.b;
// fade uses premultiplied alpha. This uses mColor2 so that it can be combined with color overlays.
double fadelevel = parms.colormapstyle->FadeLevel;
quad.mColor2.r = uint8_t(parms.colormapstyle->Fade.r * fadelevel);
quad.mColor2.g = uint8_t(parms.colormapstyle->Fade.g * fadelevel);
quad.mColor2.b = uint8_t(parms.colormapstyle->Fade.b * fadelevel);
quad.mFlags |= DTF_IngameLighting;
}
} }
// apply the element's own color. This is being blended with anything that came before. // apply the element's own color. This is being blended with anything that came before.
vertexcolor = PalEntry((vertexcolor.a * parms.color.a) / 255, (vertexcolor.r * parms.color.r) / 255, (vertexcolor.g * parms.color.g) / 255, (vertexcolor.b * parms.color.b) / 255); vertexcolor = PalEntry((vertexcolor.a * parms.color.a) / 255, (vertexcolor.r * parms.color.r) / 255, (vertexcolor.g * parms.color.g) / 255, (vertexcolor.b * parms.color.b) / 255);
@ -347,15 +331,21 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
poly.mType = DrawTypeTriangles; poly.mType = DrawTypeTriangles;
poly.mTexture = texture; poly.mTexture = texture;
poly.mRenderStyle = DefaultRenderStyle(); poly.mRenderStyle = DefaultRenderStyle();
poly.mFlags |= DTF_Wrap | DTF_IngameLighting; poly.mFlags |= DTF_Wrap;
poly.mDesaturate = colormap.Desaturation; poly.mDesaturate = colormap.Desaturation;
PalEntry color0 = colormap.LightColor; color0.a = 255; PalEntry color0;
double invfade = 1. - fadelevel;
poly.mColor2.a = uint8_t((1 - fadelevel) * 255); color0.r = uint8_t(colormap.LightColor.r * invfade);
poly.mColor2.r = uint8_t(colormap.FadeColor.r * fadelevel); color0.g = uint8_t(colormap.LightColor.g * invfade);
poly.mColor2.g = uint8_t(colormap.FadeColor.g * fadelevel); color0.b = uint8_t(colormap.LightColor.b * invfade);
poly.mColor2.b = uint8_t(colormap.FadeColor.b * fadelevel); color0.a = 255;
poly.mColor1.a = 0;
poly.mColor1.r = uint8_t(colormap.FadeColor.r * fadelevel);
poly.mColor1.g = uint8_t(colormap.FadeColor.g * fadelevel);
poly.mColor1.b = uint8_t(colormap.FadeColor.b * fadelevel);
bool dorotate = rotation != 0; bool dorotate = rotation != 0;

View file

@ -35,7 +35,6 @@ public:
DTF_Wrap = 1, DTF_Wrap = 1,
DTF_Scissor = 2, DTF_Scissor = 2,
DTF_SpecialColormap = 4, DTF_SpecialColormap = 4,
DTF_IngameLighting = 8
}; };
@ -79,7 +78,6 @@ public:
FTexture *mTexture; FTexture *mTexture;
FRemapTable *mTranslation; FRemapTable *mTranslation;
int mScissor[4]; int mScissor[4];
uint32_t mColorOverlay;
int mDesaturate; int mDesaturate;
FRenderStyle mRenderStyle; FRenderStyle mRenderStyle;
PalEntry mColor1, mColor2; // Can either be the overlay color or the special colormap ramp. Both features can not be combined. PalEntry mColor1, mColor2; // Can either be the overlay color or the special colormap ramp. Both features can not be combined.
@ -98,7 +96,6 @@ public:
mType == other.mType && mType == other.mType &&
mTranslation == other.mTranslation && mTranslation == other.mTranslation &&
!memcmp(mScissor, other.mScissor, sizeof(mScissor)) && !memcmp(mScissor, other.mScissor, sizeof(mScissor)) &&
other.mColorOverlay == 0 && mColorOverlay == 0 &&
mDesaturate == other.mDesaturate && mDesaturate == other.mDesaturate &&
mRenderStyle == other.mRenderStyle && mRenderStyle == other.mRenderStyle &&
mDrawMode == other.mDrawMode && mDrawMode == other.mDrawMode &&

View file

@ -475,7 +475,7 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3
parms->masked = true; parms->masked = true;
parms->bilinear = false; parms->bilinear = false;
parms->specialcolormap = NULL; parms->specialcolormap = NULL;
parms->colormapstyle = NULL; parms->desaturate = 0;
parms->cleanmode = DTA_Base; parms->cleanmode = DTA_Base;
parms->scalex = parms->scaley = 1; parms->scalex = parms->scaley = 1;
parms->cellx = parms->celly = 0; parms->cellx = parms->celly = 0;
@ -817,8 +817,8 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3
parms->specialcolormap = ListGetSpecialColormap(tags); parms->specialcolormap = ListGetSpecialColormap(tags);
break; break;
case DTA_ColormapStyle: case DTA_Desaturate:
parms->colormapstyle = ListGetColormapStyle(tags); parms->desaturate = ListGetInt(tags);
break; break;
case DTA_TextLen: case DTA_TextLen:

View file

@ -110,8 +110,8 @@ enum
DTA_RenderStyle, // same as render style for actors DTA_RenderStyle, // same as render style for actors
DTA_ColorOverlay, // uint32_t: ARGB to overlay on top of image; limited to black for software DTA_ColorOverlay, // uint32_t: ARGB to overlay on top of image; limited to black for software
DTA_BilinearFilter, // bool: apply bilinear filtering to the image DTA_BilinearFilter, // bool: apply bilinear filtering to the image
DTA_SpecialColormap,// pointer to FSpecialColormapParameters (likely to be forever hardware-only) DTA_SpecialColormap,// pointer to FSpecialColormapParameters
DTA_ColormapStyle, // pointer to FColormapStyle (hardware-only) DTA_Desaturate, // explicit desaturation factor (does not do anything in Legacy OpenGL)
DTA_Fullscreen, // Draw image fullscreen (same as DTA_VirtualWidth/Height with graphics size.) DTA_Fullscreen, // Draw image fullscreen (same as DTA_VirtualWidth/Height with graphics size.)
// floating point duplicates of some of the above: // floating point duplicates of some of the above:
@ -184,7 +184,7 @@ struct DrawParms
INTBOOL bilinear; INTBOOL bilinear;
FRenderStyle style; FRenderStyle style;
struct FSpecialColormap *specialcolormap; struct FSpecialColormap *specialcolormap;
struct FColormapStyle *colormapstyle; int desaturate;
int scalex, scaley; int scalex, scaley;
int cellx, celly; int cellx, celly;
int maxstrlen; int maxstrlen;

View file

@ -491,16 +491,10 @@ void main()
break; break;
} }
case 4: // simple 2D case 4: // simple 2D (reuses a uniform for the special colormap for the color overlay.)
{
frag = uObjectColor + frag * vColor;
break;
}
case 5: // 2D with in-game lighting (for textured automap)
{ {
frag = frag * vColor; frag = frag * vColor;
frag.rgb = uObjectColor.rgb + frag.rgb * uObjectColor2.aaa + uObjectColor2.rgb; frag.rgb = frag.rgb + uFixedColormapStart.rgb;
break; break;
} }

View file

@ -138,7 +138,7 @@ enum DrawTextureTags
DTA_ColorOverlay, // DWORD: ARGB to overlay on top of image; limited to black for software DTA_ColorOverlay, // DWORD: ARGB to overlay on top of image; limited to black for software
DTA_Internal1, DTA_Internal1,
DTA_Internal2, DTA_Internal2,
DTA_Internal3, DTA_Desaturate, // explicit desaturation factor (does not do anything in Legacy OpenGL)
DTA_Fullscreen, // Draw image fullscreen (same as DTA_VirtualWidth/Height with graphics size.) DTA_Fullscreen, // Draw image fullscreen (same as DTA_VirtualWidth/Height with graphics size.)
// floating point duplicates of some of the above: // floating point duplicates of some of the above: