- 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.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.
FTexture *pic = TexMan(maptex);

View file

@ -10,7 +10,6 @@ struct lightlist_t;
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_INGAME2D = -3, // ingame lighting mode for automap
CM_PLAIN2D = -2, // regular 2D drawing.
CM_INVALID=-1,
CM_DEFAULT=0, // untranslated

View file

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

View file

@ -159,8 +159,6 @@ bool FRenderState::ApplyShader()
glVertexAttrib4fv(VATTR_COLOR, mColor.vec);
glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec);
//activeShader->muObjectColor2.Set(mObjectColor2);
activeShader->muObjectColor2.Set(mObjectColor2);
activeShader->muDesaturation.Set(mDesaturation / 255.f);
activeShader->muFogEnabled.Set(fogset);
@ -171,6 +169,7 @@ bool FRenderState::ApplyShader()
activeShader->muLightParms.Set(mLightParms);
activeShader->muFogColor.Set(mFogColor);
activeShader->muObjectColor.Set(mObjectColor);
activeShader->muObjectColor2.Set(mObjectColor2);
activeShader->muDynLightColor.Set(mDynColor.vec);
activeShader->muInterpolationFactor.Set(mInterpolationFactor);
activeShader->muClipHeight.Set(mClipHeight);
@ -225,7 +224,28 @@ bool FRenderState::ApplyShader()
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;
activeShader->currentfixedcolormap = mColormapState;
@ -233,26 +253,6 @@ bool FRenderState::ApplyShader()
{
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)
{
if (FGLRenderBuffers::IsEnabled())

View file

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

View file

@ -200,6 +200,12 @@ public:
{
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

View file

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

View file

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

View file

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

View file

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

View file

@ -131,7 +131,6 @@ bool F2DDrawer::SetStyle(FTexture *tex, DrawParms &parms, PalEntry &vertexcolor,
}
SetColorOverlay(parms.colorOverlay, alpha, vertexcolor, quad.mColor1);
quad.mColorOverlay = parms.colorOverlay;
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.b = (uint8_t)(end[2] * (255 / 2));
}
else if (parms.colormapstyle != nullptr)
{
// 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;
}
quad.mDesaturate = parms.desaturate;
}
// 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);
@ -347,15 +331,21 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
poly.mType = DrawTypeTriangles;
poly.mTexture = texture;
poly.mRenderStyle = DefaultRenderStyle();
poly.mFlags |= DTF_Wrap | DTF_IngameLighting;
poly.mFlags |= DTF_Wrap;
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);
poly.mColor2.r = uint8_t(colormap.FadeColor.r * fadelevel);
poly.mColor2.g = uint8_t(colormap.FadeColor.g * fadelevel);
poly.mColor2.b = uint8_t(colormap.FadeColor.b * fadelevel);
color0.r = uint8_t(colormap.LightColor.r * invfade);
color0.g = uint8_t(colormap.LightColor.g * invfade);
color0.b = uint8_t(colormap.LightColor.b * invfade);
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;

View file

@ -35,7 +35,6 @@ public:
DTF_Wrap = 1,
DTF_Scissor = 2,
DTF_SpecialColormap = 4,
DTF_IngameLighting = 8
};
@ -79,7 +78,6 @@ public:
FTexture *mTexture;
FRemapTable *mTranslation;
int mScissor[4];
uint32_t mColorOverlay;
int mDesaturate;
FRenderStyle mRenderStyle;
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 &&
mTranslation == other.mTranslation &&
!memcmp(mScissor, other.mScissor, sizeof(mScissor)) &&
other.mColorOverlay == 0 && mColorOverlay == 0 &&
mDesaturate == other.mDesaturate &&
mRenderStyle == other.mRenderStyle &&
mDrawMode == other.mDrawMode &&

View file

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

View file

@ -110,8 +110,8 @@ enum
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_BilinearFilter, // bool: apply bilinear filtering to the image
DTA_SpecialColormap,// pointer to FSpecialColormapParameters (likely to be forever hardware-only)
DTA_ColormapStyle, // pointer to FColormapStyle (hardware-only)
DTA_SpecialColormap,// pointer to FSpecialColormapParameters
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.)
// floating point duplicates of some of the above:
@ -184,7 +184,7 @@ struct DrawParms
INTBOOL bilinear;
FRenderStyle style;
struct FSpecialColormap *specialcolormap;
struct FColormapStyle *colormapstyle;
int desaturate;
int scalex, scaley;
int cellx, celly;
int maxstrlen;

View file

@ -491,16 +491,10 @@ void main()
break;
}
case 4: // simple 2D
{
frag = uObjectColor + frag * vColor;
break;
}
case 5: // 2D with in-game lighting (for textured automap)
case 4: // simple 2D (reuses a uniform for the special colormap for the color overlay.)
{
frag = frag * vColor;
frag.rgb = uObjectColor.rgb + frag.rgb * uObjectColor2.aaa + uObjectColor2.rgb;
frag.rgb = frag.rgb + uFixedColormapStart.rgb;
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_Internal1,
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.)
// floating point duplicates of some of the above: