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);