From de15b589c095e5697b48b1c98da4b4a059fa2bb1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 5 May 2018 11:20:37 +0200 Subject: [PATCH] - moved the screen blending code out of the renderer. This is better be made part of the 2D interface. That would have been done long ago if it hadn't been for the totally incompatible way this was handled by the purely paletted software renderer. Now with that out of the way there is no point keeping this code this deeply embedded in the renderer. --- src/d_main.cpp | 4 +- src/g_statusbar/shared_sbar.cpp | 1 - src/gl/compatibility/gl_20.cpp | 9 +- src/gl/renderer/gl_renderer.cpp | 147 ++----------------------------- src/gl/renderer/gl_renderer.h | 3 +- src/gl/scene/gl_scene.cpp | 21 +---- src/gl/scene/gl_scenedrawer.h | 3 +- src/gl/scene/gl_swscene.cpp | 4 +- src/gl/scene/gl_swscene.h | 2 +- src/gl/system/gl_framebuffer.cpp | 5 +- src/gl/system/gl_framebuffer.h | 2 +- src/v_draw.cpp | 107 ++++++++++++++++++++++ src/v_video.h | 7 +- 13 files changed, 140 insertions(+), 175 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index aa81b9f5a..7c71d490c 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -652,6 +652,7 @@ CVAR(Bool, vid_activeinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) void D_Display () { bool wipe; + sector_t *viewsec; if (nodrawers || screen == NULL) return; // for comparative timing / profiling @@ -787,8 +788,9 @@ void D_Display () } else level.HasDynamicLights = false; // lights are off so effectively we have none. - screen->RenderView(&players[consoleplayer]); + viewsec = screen->RenderView(&players[consoleplayer]); screen->Begin2D(false); + screen->DrawBlend(viewsec); // returns with 2S mode set. if (automapactive) { diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 511449abd..6309ca65f 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -130,7 +130,6 @@ CUSTOM_CVAR(Int, am_showmaplabel, 2, CVAR_ARCHIVE) } CVAR (Bool, idmypos, false, 0); -CVAR(Float, underwater_fade_scalar, 1.0f, CVAR_ARCHIVE) // [Nash] user-settable underwater blend intensity //--------------------------------------------------------------------------- // diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index d6f06eda7..9f9fbf284 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -353,7 +353,14 @@ void FRenderState::ApplyFixedFunction() // //========================================================================== -void gl_FillScreen(); +void gl_FillScreen() +{ + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); + gl_RenderState.EnableTexture(false); + gl_RenderState.Apply(); + // The fullscreen quad is stored at index 4 in the main vertex buffer. + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4); +} void FRenderState::DrawColormapOverlay() { diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 45acc8b10..89d18185a 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -66,7 +66,6 @@ EXTERN_CVAR(Int, screenblocks) EXTERN_CVAR(Bool, cl_capfps) -EXTERN_CVAR(Float, underwater_fade_scalar) CVAR(Bool, gl_scale_viewport, true, CVAR_ARCHIVE); extern bool NoInterpolateView; @@ -401,15 +400,16 @@ void FGLRenderer::EndOffscreen() // //----------------------------------------------------------------------------- -void FGLRenderer::RenderView(player_t* player) +sector_t *FGLRenderer::RenderView(player_t* player) { gl_RenderState.SetVertexBuffer(mVBO); mVBO->Reset(); + sector_t *retsec; if (!V_IsHardwareRenderer()) { if (swdrawer == nullptr) swdrawer = new SWSceneDrawer; - swdrawer->RenderView(player); + retsec = swdrawer->RenderView(player); } else { @@ -451,10 +451,10 @@ void FGLRenderer::RenderView(player_t* player) drawer.SetFixedColormap(player); mShadowMap.Update(); - sector_t * viewsector = drawer.RenderViewpoint(player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true); + retsec = drawer.RenderViewpoint(player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true); } - All.Unclock(); + return retsec; } //=========================================================================== @@ -519,143 +519,6 @@ void FGLRenderer::BeginFrame() buffersActive = GLRenderer->mBuffers->Setup(GLRenderer->mScreenViewport.width, GLRenderer->mScreenViewport.height, GLRenderer->mSceneViewport.width, GLRenderer->mSceneViewport.height); } - - -void gl_FillScreen() -{ - gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); - gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(); - // The fullscreen quad is stored at index 4 in the main vertex buffer. - GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4); -} - -//========================================================================== -// -// Draws a blend over the entire view -// -//========================================================================== -void FGLRenderer::DrawBlend(sector_t * viewsector, bool FixedColormap, bool docolormap, bool in2d) -{ - float blend[4] = { 0,0,0,0 }; - PalEntry blendv = 0; - float extra_red; - float extra_green; - float extra_blue; - player_t *player = NULL; - - if (players[consoleplayer].camera != NULL) - { - player = players[consoleplayer].camera->player; - } - - // don't draw sector based blends when an invulnerability colormap is active - if (!FixedColormap) - { - if (!viewsector->e->XFloor.ffloors.Size()) - { - if (viewsector->GetHeightSec()) - { - auto s = viewsector->heightsec; - blendv = s->floorplane.PointOnSide(r_viewpoint.Pos) < 0? s->bottommap : s->ceilingplane.PointOnSide(r_viewpoint.Pos) < 0 ? s->topmap : s->midmap; - } - } - else - { - TArray & lightlist = viewsector->e->XFloor.lightlist; - - for (unsigned int i = 0; i < lightlist.Size(); i++) - { - double lightbottom; - if (i < lightlist.Size() - 1) - lightbottom = lightlist[i + 1].plane.ZatPoint(r_viewpoint.Pos); - else - lightbottom = viewsector->floorplane.ZatPoint(r_viewpoint.Pos); - - if (lightbottom < r_viewpoint.Pos.Z && (!lightlist[i].caster || !(lightlist[i].caster->flags&FF_FADEWALLS))) - { - // 3d floor 'fog' is rendered as a blending value - blendv = lightlist[i].blend; - // If this is the same as the sector's it doesn't apply! - if (blendv == viewsector->Colormap.FadeColor) blendv = 0; - // a little hack to make this work for Legacy maps. - if (blendv.a == 0 && blendv != 0) blendv.a = 128; - break; - } - } - } - - if (blendv.a == 0 && docolormap) - { - blendv = R_BlendForColormap(blendv); - } - - if (blendv.a == 255) - { - - extra_red = blendv.r / 255.0f; - extra_green = blendv.g / 255.0f; - extra_blue = blendv.b / 255.0f; - - // If this is a multiplicative blend do it separately and add the additive ones on top of it. - - // black multiplicative blends are ignored - if (extra_red || extra_green || extra_blue) - { - if (!in2d) - { - gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); - gl_RenderState.SetColor(extra_red, extra_green, extra_blue, 1.0f); - gl_FillScreen(); - } - else - { - screen->Dim(blendv, 1, 0, 0, screen->GetWidth(), screen->GetHeight(), &LegacyRenderStyles[STYLE_Multiply]); - } - } - blendv = 0; - } - else if (blendv.a) - { - // [Nash] allow user to set blend intensity - int cnt = blendv.a; - cnt = (int)(cnt * underwater_fade_scalar); - - V_AddBlend(blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, cnt / 255.0f, blend); - } - } - - if (player) - { - V_AddPlayerBlend(player, blend, 0.5, 175); - } - - if (players[consoleplayer].camera != NULL) - { - // except for fadeto effects - player_t *player = (players[consoleplayer].camera->player != NULL) ? players[consoleplayer].camera->player : &players[consoleplayer]; - V_AddBlend(player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend); - } - - if (!in2d) - { - gl_RenderState.SetTextureMode(TM_MODULATE); - gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - if (blend[3] > 0.0f) - { - gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]); - gl_FillScreen(); - } - gl_RenderState.ResetColor(); - gl_RenderState.EnableTexture(true); - } - else - { - screen->Dim(PalEntry(255, blend[0] * 255, blend[1] * 255, blend[2] * 255), blend[3], 0, 0, screen->GetWidth(), screen->GetHeight()); - } -} - - //=========================================================================== // // Vertex buffer for 2D drawer diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 2514992e4..51fa30276 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -190,8 +190,7 @@ public: void Draw2D(F2DDrawer *data); void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV); void WriteSavePic(player_t *player, FileWriter *file, int width, int height); - void RenderView(player_t *player); - void DrawBlend(sector_t * viewsector, bool FixedColormap, bool docolormap, bool in2d = false); + sector_t *RenderView(player_t *player); void BeginFrame(); bool StartOffscreen(); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index abee69818..e440e6d0b 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -558,10 +558,6 @@ void GLSceneDrawer::DrawEndScene2D(sector_t * viewsector) gl_RenderState.SetFixedColormap(CM_DEFAULT); gl_RenderState.SetSoftLightLevel(-1); - if (!FGLRenderBuffers::IsEnabled()) - { - DrawBlend(viewsector); - } // Restore standard rendering state gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -635,17 +631,6 @@ void GLSceneDrawer::SetFixedColormap (player_t *player) gl_RenderState.SetFixedColormap(FixedColormap); } -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -void GLSceneDrawer::DrawBlend(sector_t *viewsector) -{ - GLRenderer->DrawBlend(viewsector, !!FixedColormap, true); -} - //----------------------------------------------------------------------------- // // Renders one viewpoint in a scene @@ -727,8 +712,6 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f gl_RenderState.mProjectionMatrix.ortho(GLRenderer->mScreenViewport.left, GLRenderer->mScreenViewport.width, GLRenderer->mScreenViewport.height, GLRenderer->mScreenViewport.top, -1.0f, 1.0f); gl_RenderState.ApplyMatrices(); } - - DrawBlend(lviewsector); } FDrawInfo::EndDrawInfo(); GLRenderer->mDrawingScene2D = false; @@ -770,7 +753,9 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width, gl_RenderState.SetSoftLightLevel(-1); if (!FGLRenderBuffers::IsEnabled()) { - DrawBlend(viewsector); + // Since this doesn't do any of the 2D rendering it needs to draw the screen blend itself before extracting the image. + screen->DrawBlend(viewsector); + screen->Draw2D(); } GLRenderer->CopyToBackbuffer(&bounds, false); glFlush(); diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index fb66e2721..94b872c4f 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -60,12 +60,11 @@ public: void SetFixedColormap(player_t *player); void DrawScene(int drawmode); void ProcessScene(bool toscreen = false); - void DrawBlend(sector_t * viewsector); void EndDrawScene(sector_t * viewsector); void DrawEndScene2D(sector_t * viewsector); sector_t *RenderViewpoint(AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen); - void RenderView(player_t *player); + sector_t *RenderView(player_t *player); void WriteSavePic(player_t *player, FileWriter *file, int width, int height); void InitClipper(angle_t a1, angle_t a2) diff --git a/src/gl/scene/gl_swscene.cpp b/src/gl/scene/gl_swscene.cpp index 86915eec2..60209a517 100644 --- a/src/gl/scene/gl_swscene.cpp +++ b/src/gl/scene/gl_swscene.cpp @@ -97,7 +97,7 @@ SWSceneDrawer::~SWSceneDrawer() if (FBTexture != nullptr) delete FBTexture; } -void SWSceneDrawer::RenderView(player_t *player) +sector_t *SWSceneDrawer::RenderView(player_t *player) { DCanvas buffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor()); if (FBTexture == nullptr || FBTexture->SystemTexture[0] == nullptr || @@ -121,5 +121,5 @@ void SWSceneDrawer::RenderView(player_t *player) auto map = swrenderer::CameraLight::Instance()->ShaderColormap(); screen->DrawTexture(FBTexture, 0, 0, DTA_SpecialColormap, map, TAG_DONE); SWRenderer->DrawRemainingPlayerSprites(); - GLRenderer->DrawBlend(r_viewpoint.sector, !!map, V_IsTrueColor(), true); + return r_viewpoint.sector; } diff --git a/src/gl/scene/gl_swscene.h b/src/gl/scene/gl_swscene.h index f54b2f3ed..ef52c20c6 100644 --- a/src/gl/scene/gl_swscene.h +++ b/src/gl/scene/gl_swscene.h @@ -19,6 +19,6 @@ public: SWSceneDrawer(); ~SWSceneDrawer(); - void RenderView(player_t *player); + sector_t *RenderView(player_t *player); }; diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 75c4fd165..9d555f3ee 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -210,10 +210,11 @@ void OpenGLFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int wid // //=========================================================================== -void OpenGLFrameBuffer::RenderView(player_t *player) +sector_t *OpenGLFrameBuffer::RenderView(player_t *player) { if (GLRenderer != nullptr) - GLRenderer->RenderView(player); + return GLRenderer->RenderView(player); + return nullptr; } diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index 22d5f6e63..d2764419f 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -37,7 +37,7 @@ public: uint32_t GetCaps() override; void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) override; void WriteSavePic(player_t *player, FileWriter *file, int width, int height) override; - void RenderView(player_t *player) override; + sector_t *RenderView(player_t *player) override; void SetTextureFilterMode() override; IHardwareTexture *CreateHardwareTexture(FTexture *tex) override; FModelRenderer *CreateModelRenderer(int mli) override; diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 693c2b868..87e495242 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -44,11 +44,14 @@ #include "gi.h" #include "g_level.h" #include "sbar.h" +#include "d_player.h" #include "i_video.h" #include "g_levellocals.h" #include "vm.h" +CVAR(Float, underwater_fade_scalar, 1.0f, CVAR_ARCHIVE) // [Nash] user-settable underwater blend intensity + CUSTOM_CVAR(Int, uiscale, 0, CVAR_ARCHIVE | CVAR_NOINITCALL) { if (self < 0) @@ -1313,3 +1316,107 @@ void DFrameBuffer::RefreshViewBorder () } } +//========================================================================== +// +// Draws a blend over the entire view +// +//========================================================================== +void DFrameBuffer::DrawBlend(sector_t * viewsector) +{ + float blend[4] = { 0,0,0,0 }; + PalEntry blendv = 0; + float extra_red; + float extra_green; + float extra_blue; + player_t *player = nullptr; + bool fullbright = false; + + if (players[consoleplayer].camera != nullptr) + { + player = players[consoleplayer].camera->player; + fullbright = (player->fixedcolormap != NOFIXEDCOLORMAP || player->extralight == INT_MIN || player->fixedlightlevel != -1); + } + + // don't draw sector based blends when any fullbright screen effect is active. + if (!fullbright) + { + if (!viewsector->e->XFloor.ffloors.Size()) + { + if (viewsector->GetHeightSec()) + { + auto s = viewsector->heightsec; + blendv = s->floorplane.PointOnSide(r_viewpoint.Pos) < 0 ? s->bottommap : s->ceilingplane.PointOnSide(r_viewpoint.Pos) < 0 ? s->topmap : s->midmap; + } + } + else + { + TArray & lightlist = viewsector->e->XFloor.lightlist; + + for (unsigned int i = 0; i < lightlist.Size(); i++) + { + double lightbottom; + if (i < lightlist.Size() - 1) + lightbottom = lightlist[i + 1].plane.ZatPoint(r_viewpoint.Pos); + else + lightbottom = viewsector->floorplane.ZatPoint(r_viewpoint.Pos); + + if (lightbottom < r_viewpoint.Pos.Z && (!lightlist[i].caster || !(lightlist[i].caster->flags&FF_FADEWALLS))) + { + // 3d floor 'fog' is rendered as a blending value + blendv = lightlist[i].blend; + // If this is the same as the sector's it doesn't apply! + if (blendv == viewsector->Colormap.FadeColor) blendv = 0; + // a little hack to make this work for Legacy maps. + if (blendv.a == 0 && blendv != 0) blendv.a = 128; + break; + } + } + } + + if (blendv.a == 0 && V_IsTrueColor()) // The paletted software renderer uses the original colormap as this frame's palette, but in true color that isn't doable. + { + blendv = R_BlendForColormap(blendv); + } + + if (blendv.a == 255) + { + + extra_red = blendv.r / 255.0f; + extra_green = blendv.g / 255.0f; + extra_blue = blendv.b / 255.0f; + + // If this is a multiplicative blend do it separately and add the additive ones on top of it. + + // black multiplicative blends are ignored + if (extra_red || extra_green || extra_blue) + { + screen->Dim(blendv, 1, 0, 0, screen->GetWidth(), screen->GetHeight(), &LegacyRenderStyles[STYLE_Multiply]); + } + blendv = 0; + } + else if (blendv.a) + { + // [Nash] allow user to set blend intensity + int cnt = blendv.a; + cnt = (int)(cnt * underwater_fade_scalar); + + V_AddBlend(blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, cnt / 255.0f, blend); + } + } + + if (player) + { + V_AddPlayerBlend(player, blend, 0.5, 175); + } + + if (players[consoleplayer].camera != NULL) + { + // except for fadeto effects + player_t *player = (players[consoleplayer].camera->player != NULL) ? players[consoleplayer].camera->player : &players[consoleplayer]; + V_AddBlend(player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend); + } + + screen->Dim(PalEntry(255, uint8_t(blend[0] * 255), uint8_t(blend[1] * 255), uint8_t(blend[2] * 255)), blend[3], 0, 0, screen->GetWidth(), screen->GetHeight()); +} + + diff --git a/src/v_video.h b/src/v_video.h index 98903413f..3e563bdc5 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -44,6 +44,8 @@ #include "v_colortables.h" #include "v_2ddrawer.h" +struct sector_t; + enum EHWCaps { // [BB] Added texture compression flags. @@ -91,7 +93,7 @@ inline bool V_IsPolyRenderer() inline bool V_IsTrueColor() { - return vid_rendermode == 1 || vid_rendermode == 3; + return vid_rendermode == 1 || vid_rendermode == 3 || vid_rendermode == 4; } @@ -399,7 +401,7 @@ public: virtual uint32_t GetCaps(); virtual void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV); virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height); - virtual void RenderView(player_t *player) {} + virtual sector_t *RenderView(player_t *player) { return nullptr; } // Screen wiping virtual bool WipeStartScreen(int type); @@ -422,6 +424,7 @@ public: // Dim part of the canvas void Dim(PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle *style = nullptr); void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle *style = nullptr); + void DrawBlend(sector_t * viewsector); // Fill an area with a texture void FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin = false);