From a40e085a4654d798c3a2e3898963e59648f0ba32 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 29 Mar 2018 16:21:21 +0200 Subject: [PATCH] - 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. --- src/am_map.cpp | 5 +++ src/gl/renderer/gl_colormap.h | 1 - src/gl/renderer/gl_renderer.cpp | 9 +--- src/gl/renderer/gl_renderstate.cpp | 46 ++++++++++---------- src/gl/renderer/gl_renderstate.h | 8 ++++ src/gl/shaders/gl_shader.h | 6 +++ src/polyrenderer/scene/poly_playersprite.cpp | 16 +++---- src/polyrenderer/scene/poly_playersprite.h | 4 +- src/swrenderer/things/r_playersprite.cpp | 16 +++---- src/swrenderer/things/r_playersprite.h | 4 +- src/v_2ddrawer.cpp | 36 ++++++--------- src/v_2ddrawer.h | 3 -- src/v_draw.cpp | 6 +-- src/v_video.h | 6 +-- wadsrc/static/shaders/glsl/main.fp | 10 +---- wadsrc/static/zscript/base.txt | 2 +- 16 files changed, 80 insertions(+), 98 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index f037ede34..00ced812b 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -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); diff --git a/src/gl/renderer/gl_colormap.h b/src/gl/renderer/gl_colormap.h index 0bdd7dd8c..33c1a8337 100644 --- a/src/gl/renderer/gl_colormap.h +++ b/src/gl/renderer/gl_colormap.h @@ -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 diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index b75a8949a..692dd10ca 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -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); } diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index d579a8aa2..2f6b11515 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -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()) diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 8c4425c5c..2489511ba 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -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; diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 8b119aec9..0ee867784 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -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 diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index 7da66b198..747f17e9a 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -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); diff --git a/src/polyrenderer/scene/poly_playersprite.h b/src/polyrenderer/scene/poly_playersprite.h index 8e3e9aa7a..010c1c7be 100644 --- a/src/polyrenderer/scene/poly_playersprite.h +++ b/src/polyrenderer/scene/poly_playersprite.h @@ -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 diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index b26870563..3fa68374d 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -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); } diff --git a/src/swrenderer/things/r_playersprite.h b/src/swrenderer/things/r_playersprite.h index 3dbfd6edb..64dd66172 100644 --- a/src/swrenderer/things/r_playersprite.h +++ b/src/swrenderer/things/r_playersprite.h @@ -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 diff --git a/src/v_2ddrawer.cpp b/src/v_2ddrawer.cpp index eedcc7a09..cbd827f72 100644 --- a/src/v_2ddrawer.cpp +++ b/src/v_2ddrawer.cpp @@ -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; diff --git a/src/v_2ddrawer.h b/src/v_2ddrawer.h index 6b4740365..a8785c129 100644 --- a/src/v_2ddrawer.h +++ b/src/v_2ddrawer.h @@ -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 && diff --git a/src/v_draw.cpp b/src/v_draw.cpp index aacaef7cb..6927b714a 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -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: diff --git a/src/v_video.h b/src/v_video.h index 8c69dbdc1..b4a2485c2 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -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; diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 2ca28cca3..096db0c8f 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -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; } diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 46e9e222e..2ebeba421 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -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: