From 99c8ba1288aaac3a3879406150536423dc76d83a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 7 Mar 2019 18:05:07 +0100 Subject: [PATCH 01/12] - use uAddColor instead of uObjectColor2 for the ending color of a special colormap range. Unlike uObjectColor2, this is more global state. uObjectColor2 is part of gradient calculation which may later be offloaded to a secondary buffer which already resulted in only conditionally setting it, resulting in broken special colormap application for the software renderer. --- src/rendering/gl/renderer/gl_renderstate.cpp | 2 +- src/rendering/hwrenderer/utility/hw_draw2d.cpp | 2 +- wadsrc/static/shaders/glsl/main.fp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rendering/gl/renderer/gl_renderstate.cpp b/src/rendering/gl/renderer/gl_renderstate.cpp index 18657e7487..57f20646ee 100644 --- a/src/rendering/gl/renderer/gl_renderstate.cpp +++ b/src/rendering/gl/renderer/gl_renderstate.cpp @@ -138,7 +138,7 @@ bool FGLRenderState::ApplyShader() activeShader->muLightIndex.Set(-1); activeShader->muClipSplit.Set(mClipSplit); activeShader->muSpecularMaterial.Set(mGlossiness, mSpecularLevel); - activeShader->muAddColor.Set(mAddColor); // Can this be done without a shader? + activeShader->muAddColor.Set(mAddColor); if (mGlowEnabled) { diff --git a/src/rendering/hwrenderer/utility/hw_draw2d.cpp b/src/rendering/hwrenderer/utility/hw_draw2d.cpp index 11baa5b15c..18955c2cd8 100644 --- a/src/rendering/hwrenderer/utility/hw_draw2d.cpp +++ b/src/rendering/hwrenderer/utility/hw_draw2d.cpp @@ -155,7 +155,7 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state) { state.SetTextureMode(TM_FIXEDCOLORMAP); state.SetObjectColor(cmd.mSpecialColormap[0]); - state.SetObjectColor2(cmd.mSpecialColormap[1]); + state.SetAddColor(cmd.mSpecialColormap[1]); } state.SetFog(cmd.mColor1, 0); state.SetColor(1, 1, 1, 1, cmd.mDesaturate); diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index ab4d16e918..84f044ef8c 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -588,7 +588,7 @@ void main() if (uTextureMode == 7) { float gray = grayscale(frag); - vec4 cm = (uObjectColor + gray * (uObjectColor2 - uObjectColor)) * 2; + vec4 cm = (uObjectColor + gray * (uAddColor - uObjectColor)) * 2; frag = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a); } frag = frag * ProcessLight(material, vColor); From d2475b68d0a1a0f82712422caeb749c6e3874692 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 7 Mar 2019 18:07:34 +0100 Subject: [PATCH 02/12] - removed unnecessary variable clear. --- src/p_user.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_user.cpp b/src/p_user.cpp index cd0699829c..1833641246 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -351,7 +351,6 @@ void player_t::CopyFrom(player_t &p, bool copyPSP) psprites = p.psprites; p.psprites = nullptr; } - else psprites = nullptr; } size_t player_t::PropagateMark() From 1a29d39355acb6e19583deb0fdef5db694ffd622 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 9 Mar 2019 12:10:50 +0100 Subject: [PATCH 03/12] - do not render player sprites to canvases in the software renderer. This applies to both savegame images and camera textures. --- src/rendering/swrenderer/scene/r_scene.cpp | 9 +++++---- src/rendering/swrenderer/scene/r_scene.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/rendering/swrenderer/scene/r_scene.cpp b/src/rendering/swrenderer/scene/r_scene.cpp index 57550231dc..5621561125 100644 --- a/src/rendering/swrenderer/scene/r_scene.cpp +++ b/src/rendering/swrenderer/scene/r_scene.cpp @@ -129,7 +129,7 @@ namespace swrenderer DrawerThreads::ResetDebugDrawPos(); } - RenderActorView(player->mo); + RenderActorView(player->mo, true, false); auto copyqueue = std::make_shared(MainThread()->FrameMemory.get()); copyqueue->Push(videobuffer, target->GetPixels(), target->GetWidth(), target->GetHeight(), target->GetPitch(), target->IsBgra() ? 4 : 1); @@ -140,7 +140,7 @@ namespace swrenderer DrawerWaitCycles.Unclock(); } - void RenderScene::RenderActorView(AActor *actor, bool dontmaplines) + void RenderScene::RenderActorView(AActor *actor, bool renderPlayerSprites, bool dontmaplines) { WallCycles.Reset(); PlaneCycles.Reset(); @@ -180,7 +180,8 @@ namespace swrenderer if (r_modelscene) MainThread()->Viewport->SetupPolyViewport(MainThread()); - RenderPSprites(); + if (renderPlayerSprites) + RenderPSprites(); MainThread()->Viewport->viewpoint.camera->renderflags = savedflags; } @@ -384,7 +385,7 @@ namespace swrenderer PolyTriangleDrawer::ResizeBuffers(viewport->RenderTarget); // Render: - RenderActorView(actor, dontmaplines); + RenderActorView(actor, false, dontmaplines); DrawerWaitCycles.Clock(); DrawerThreads::WaitForWorkers(); DrawerWaitCycles.Unclock(); diff --git a/src/rendering/swrenderer/scene/r_scene.h b/src/rendering/swrenderer/scene/r_scene.h index 1df9c292b5..cba2580563 100644 --- a/src/rendering/swrenderer/scene/r_scene.h +++ b/src/rendering/swrenderer/scene/r_scene.h @@ -56,7 +56,7 @@ namespace swrenderer RenderThread *MainThread() { return Threads.front().get(); } private: - void RenderActorView(AActor *actor, bool dontmaplines = false); + void RenderActorView(AActor *actor,bool renderplayersprite, bool dontmaplines); void RenderThreadSlices(); void RenderThreadSlice(RenderThread *thread); void RenderPSprites(); From 0ca7723c0e9c863ed0c22c10ed3b27e65418c91e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 9 Mar 2019 12:17:57 +0100 Subject: [PATCH 04/12] - disable player sprite drawing on canvases for the softpoly renderer. --- src/rendering/polyrenderer/poly_renderer.cpp | 10 ++++++---- src/rendering/polyrenderer/poly_renderer.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/rendering/polyrenderer/poly_renderer.cpp b/src/rendering/polyrenderer/poly_renderer.cpp index 5373d94327..b928979c5e 100644 --- a/src/rendering/polyrenderer/poly_renderer.cpp +++ b/src/rendering/polyrenderer/poly_renderer.cpp @@ -68,7 +68,7 @@ void PolyRenderer::RenderView(player_t *player, DCanvas *target, void *videobuff RenderTarget = target; RenderToCanvas = false; - RenderActorView(player->mo, false); + RenderActorView(player->mo, true, false); Threads.MainThread()->FlushDrawQueue(); @@ -102,7 +102,7 @@ void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int viewactive = true; // Render: - RenderActorView(actor, dontmaplines); + RenderActorView(actor, false, dontmaplines); Threads.MainThread()->FlushDrawQueue(); DrawerThreads::WaitForWorkers(); @@ -119,7 +119,7 @@ void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int RenderTarget = savedRenderTarget; } -void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) +void PolyRenderer::RenderActorView(AActor *actor, bool drawpsprites, bool dontmaplines) { PolyTotalBatches = 0; PolyTotalTriangles = 0; @@ -181,7 +181,9 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) mainViewpoint.StencilValue = GetNextStencilValue(); Scene.CurrentViewpoint = &mainViewpoint; Scene.Render(&mainViewpoint); - PlayerSprites.Render(Threads.MainThread()); + if (drawpsprites) + PlayerSprites.Render(Threads.MainThread()); + Scene.CurrentViewpoint = nullptr; if (Viewpoint.camera) diff --git a/src/rendering/polyrenderer/poly_renderer.h b/src/rendering/polyrenderer/poly_renderer.h index 949196af9c..4750d2b04d 100644 --- a/src/rendering/polyrenderer/poly_renderer.h +++ b/src/rendering/polyrenderer/poly_renderer.h @@ -71,7 +71,7 @@ public: FLevelLocals *Level; private: - void RenderActorView(AActor *actor, bool dontmaplines); + void RenderActorView(AActor *actor, bool drawpsprites, bool dontmaplines); void SetSceneViewport(); RenderPolyPlayerSprites PlayerSprites; From 2fa5a88701828ae6d99a75f7551ee97dde072cf8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 9 Mar 2019 12:34:10 +0100 Subject: [PATCH 05/12] - do not render player sprites to canvases in the hardware renderer. --- src/rendering/gl/renderer/gl_scene.cpp | 4 ++-- src/rendering/hwrenderer/scene/hw_bsp.cpp | 6 +++--- src/rendering/hwrenderer/scene/hw_drawinfo.cpp | 4 ++-- src/rendering/hwrenderer/scene/hw_drawinfo.h | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/rendering/gl/renderer/gl_scene.cpp b/src/rendering/gl/renderer/gl_scene.cpp index 764355d007..906d58dfbc 100644 --- a/src/rendering/gl/renderer/gl_scene.cpp +++ b/src/rendering/gl/renderer/gl_scene.cpp @@ -111,12 +111,12 @@ void FGLRenderer::DrawScene(HWDrawInfo *di, int drawmode) if (vp.camera != nullptr) { ActorRenderFlags savedflags = vp.camera->renderflags; - di->CreateScene(); + di->CreateScene(drawmode == DM_MAINVIEW); vp.camera->renderflags = savedflags; } else { - di->CreateScene(); + di->CreateScene(false); } glDepthMask(true); diff --git a/src/rendering/hwrenderer/scene/hw_bsp.cpp b/src/rendering/hwrenderer/scene/hw_bsp.cpp index cddf4db300..242154a26a 100644 --- a/src/rendering/hwrenderer/scene/hw_bsp.cpp +++ b/src/rendering/hwrenderer/scene/hw_bsp.cpp @@ -796,7 +796,7 @@ void HWDrawInfo::RenderBSPNode (void *node) DoSubsector ((subsector_t *)((uint8_t *)node - 1)); } -void HWDrawInfo::RenderBSP(void *node) +void HWDrawInfo::RenderBSP(void *node, bool drawpsprites) { Bsp.Clock(); @@ -829,6 +829,6 @@ void HWDrawInfo::RenderBSP(void *node) // Process all the sprites on the current portal's back side which touch the portal. if (mCurrentPortal != nullptr) mCurrentPortal->RenderAttached(this); - - PreparePlayerSprites(Viewpoint.sector, in_area); + if (drawpsprites) + PreparePlayerSprites(Viewpoint.sector, in_area); } diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp index 5d86051cc7..9997a17615 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp @@ -421,7 +421,7 @@ GLDecal *HWDrawInfo::AddDecal(bool onmirror) // //----------------------------------------------------------------------------- -void HWDrawInfo::CreateScene() +void HWDrawInfo::CreateScene(bool drawpsprites) { const auto &vp = Viewpoint; angle_t a1 = FrustumAngle(); @@ -436,7 +436,7 @@ void HWDrawInfo::CreateScene() screen->mVertexData->Map(); screen->mLights->Map(); - RenderBSP(Level->HeadNode()); + RenderBSP(Level->HeadNode(), drawpsprites); // And now the crappy hacks that have to be done to avoid rendering anomalies. // These cannot be multithreaded when the time comes because all these depend diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.h b/src/rendering/hwrenderer/scene/hw_drawinfo.h index 9738cbe443..c2f907acbb 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.h +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.h @@ -237,7 +237,7 @@ public: HWPortal * FindPortal(const void * src); void RenderBSPNode(void *node); - void RenderBSP(void *node); + void RenderBSP(void *node, bool drawpsprites); static HWDrawInfo *StartDrawInfo(FLevelLocals *lev, HWDrawInfo *parent, FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms); void StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms); @@ -246,7 +246,7 @@ public: void SetViewArea(); int SetFullbrightFlags(player_t *player); - void CreateScene(); + void CreateScene(bool drawpsprites); void RenderScene(FRenderState &state); void RenderTranslucent(FRenderState &state); void RenderPortal(HWPortal *p, FRenderState &state, bool usestencil); From 0e4a860c5ed0830341ca1ebc5a9575b8bb615226 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 9 Mar 2019 12:52:07 +0100 Subject: [PATCH 06/12] - fixed uninitialized screen flash color for savegame images in the software renderer. --- src/rendering/2d/v_draw.cpp | 25 +++++++++++++++++------ src/rendering/swrenderer/r_swrenderer.cpp | 3 +++ src/v_video.h | 3 ++- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/rendering/2d/v_draw.cpp b/src/rendering/2d/v_draw.cpp index 8030ba4c7d..fb66f4f5f9 100644 --- a/src/rendering/2d/v_draw.cpp +++ b/src/rendering/2d/v_draw.cpp @@ -1351,12 +1351,13 @@ void DFrameBuffer::DrawBorder (FTextureID picnum, int x1, int y1, int x2, int y2 } } -///========================================================================== +//========================================================================== // // Draws a blend over the entire view // //========================================================================== -void DFrameBuffer::DrawBlend(sector_t * viewsector) + +FVector4 DFrameBuffer::CalcBlend(sector_t * viewsector) { float blend[4] = { 0,0,0,0 }; PalEntry blendv = 0; @@ -1376,7 +1377,7 @@ void DFrameBuffer::DrawBlend(sector_t * viewsector) // don't draw sector based blends when any fullbright screen effect is active. if (!fullbright) { - const auto &vpp = r_viewpoint.Pos; + const auto &vpp = r_viewpoint.Pos; if (!viewsector->e->XFloor.ffloors.Size()) { if (viewsector->GetHeightSec()) @@ -1452,7 +1453,7 @@ void DFrameBuffer::DrawBlend(sector_t * viewsector) if (in->IsKindOf(torchtype)) { // The software renderer already bakes the torch flickering into its output, so this must be omitted here. - float r = vid_rendermode < 4? 1.f : (0.8f + (7 - player->fixedlightlevel) / 70.0f); + float r = vid_rendermode < 4 ? 1.f : (0.8f + (7 - player->fixedlightlevel) / 70.0f); if (r > 1.0f) r = 1.0f; int rr = (int)(r * 255); int b = rr; @@ -1488,8 +1489,20 @@ void DFrameBuffer::DrawBlend(sector_t * viewsector) const float br = clamp(blend[0] * 255.f, 0.f, 255.f); const float bg = clamp(blend[1] * 255.f, 0.f, 255.f); const float bb = clamp(blend[2] * 255.f, 0.f, 255.f); - const PalEntry bcolor(255, uint8_t(br), uint8_t(bg), uint8_t(bb)); - screen->Dim(bcolor, blend[3], 0, 0, screen->GetWidth(), screen->GetHeight()); + return { br, bg, bb, blend[3] }; +} + +//========================================================================== +// +// Draws a blend over the entire view +// +//========================================================================== + +void DFrameBuffer::DrawBlend(sector_t * viewsector) +{ + auto blend = CalcBlend(viewsector); + const PalEntry bcolor(255, uint8_t(blend.X), uint8_t(blend.Y), uint8_t(blend.Z)); + screen->Dim(bcolor, blend.W, 0, 0, screen->GetWidth(), screen->GetHeight()); } diff --git a/src/rendering/swrenderer/r_swrenderer.cpp b/src/rendering/swrenderer/r_swrenderer.cpp index 93802f4c81..41b071517b 100644 --- a/src/rendering/swrenderer/r_swrenderer.cpp +++ b/src/rendering/swrenderer/r_swrenderer.cpp @@ -230,6 +230,9 @@ void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int wi r_viewpoint = mScene.MainThread()->Viewport->viewpoint; r_viewwindow = mScene.MainThread()->Viewport->viewwindow; } + auto blend = screen->CalcBlend(r_viewpoint.sector); + const PalEntry bcolor(255, uint8_t(blend.X), uint8_t(blend.Y), uint8_t(blend.Z)); + screen->SetFlash(bcolor, int(blend.W * 256)); screen->GetFlashedPalette (palette); M_CreatePNG (file, pic.GetPixels(), palette, SS_PAL, width, height, pic.GetPitch(), Gamma); } diff --git a/src/v_video.h b/src/v_video.h index b56c4e7276..6ac2aaf203 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -352,7 +352,7 @@ private: protected: int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1; - PalEntry Flash; // Only needed to support some cruft in the interface that only makes sense for the software renderer + PalEntry Flash = 0; // Only needed to support some cruft in the interface that only makes sense for the software renderer PalEntry SourcePalette[256]; // This is where unpaletted textures get their palette from public: @@ -502,6 +502,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); + FVector4 CalcBlend(sector_t * viewsector); void DrawBlend(sector_t * viewsector); // Fill an area with a texture From f9d4ea842419e2ffebf81b1f7bc024e7dfb15554 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 9 Mar 2019 13:12:24 +0100 Subject: [PATCH 07/12] - missed the part that the blend function was still drawing multiplicative blends. This should be cleanly separated. --- src/rendering/2d/v_draw.cpp | 22 +++++++++++++++------- src/v_video.h | 2 +- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/rendering/2d/v_draw.cpp b/src/rendering/2d/v_draw.cpp index fb66f4f5f9..9f309cd3b7 100644 --- a/src/rendering/2d/v_draw.cpp +++ b/src/rendering/2d/v_draw.cpp @@ -1357,7 +1357,7 @@ void DFrameBuffer::DrawBorder (FTextureID picnum, int x1, int y1, int x2, int y2 // //========================================================================== -FVector4 DFrameBuffer::CalcBlend(sector_t * viewsector) +FVector4 DFrameBuffer::CalcBlend(sector_t * viewsector, PalEntry *modulateColor) { float blend[4] = { 0,0,0,0 }; PalEntry blendv = 0; @@ -1367,6 +1367,8 @@ FVector4 DFrameBuffer::CalcBlend(sector_t * viewsector) player_t *player = nullptr; bool fullbright = false; + if (modulateColor) *modulateColor = 0xffffffff; + if (players[consoleplayer].camera != nullptr) { player = players[consoleplayer].camera->player; @@ -1428,7 +1430,7 @@ FVector4 DFrameBuffer::CalcBlend(sector_t * viewsector) // 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]); + if (modulateColor) *modulateColor = blendv; } blendv = 0; } @@ -1468,9 +1470,9 @@ FVector4 DFrameBuffer::CalcBlend(sector_t * viewsector) } } } - if (color != 0xffffffff) - { - screen->Dim(color, 1, 0, 0, screen->GetWidth(), screen->GetHeight(), &LegacyRenderStyles[STYLE_Multiply]); + if (modulateColor) + { + *modulateColor = color; } } @@ -1500,9 +1502,15 @@ FVector4 DFrameBuffer::CalcBlend(sector_t * viewsector) void DFrameBuffer::DrawBlend(sector_t * viewsector) { - auto blend = CalcBlend(viewsector); + PalEntry modulateColor; + auto blend = CalcBlend(viewsector, &modulateColor); + if (modulateColor != 0xffffffff) + { + Dim(modulateColor, 1, 0, 0, GetWidth(), GetHeight(), &LegacyRenderStyles[STYLE_Multiply]); + } + const PalEntry bcolor(255, uint8_t(blend.X), uint8_t(blend.Y), uint8_t(blend.Z)); - screen->Dim(bcolor, blend.W, 0, 0, screen->GetWidth(), screen->GetHeight()); + Dim(bcolor, blend.W, 0, 0, GetWidth(), GetHeight()); } diff --git a/src/v_video.h b/src/v_video.h index 6ac2aaf203..d4fedf17c9 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -502,7 +502,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); - FVector4 CalcBlend(sector_t * viewsector); + FVector4 CalcBlend(sector_t * viewsector, PalEntry *modulateColor); void DrawBlend(sector_t * viewsector); // Fill an area with a texture From 29012a89c6fa1a4838f8f9c1520e070eacdd4af5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 9 Mar 2019 13:34:22 +0100 Subject: [PATCH 08/12] - for got to save this. --- src/rendering/swrenderer/r_swrenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendering/swrenderer/r_swrenderer.cpp b/src/rendering/swrenderer/r_swrenderer.cpp index 41b071517b..a2863ec717 100644 --- a/src/rendering/swrenderer/r_swrenderer.cpp +++ b/src/rendering/swrenderer/r_swrenderer.cpp @@ -230,7 +230,7 @@ void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int wi r_viewpoint = mScene.MainThread()->Viewport->viewpoint; r_viewwindow = mScene.MainThread()->Viewport->viewwindow; } - auto blend = screen->CalcBlend(r_viewpoint.sector); + auto blend = screen->CalcBlend(r_viewpoint.sector, nullptr); const PalEntry bcolor(255, uint8_t(blend.X), uint8_t(blend.Y), uint8_t(blend.Z)); screen->SetFlash(bcolor, int(blend.W * 256)); screen->GetFlashedPalette (palette); From 392ba7ed2e01af43e3a9a2a927a445c15d63bc06 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 9 Mar 2019 13:34:47 +0100 Subject: [PATCH 09/12] - properly construct the reply texts for Strife's merchants. --- wadsrc/static/zscript/ui/menu/conversationmenu.zs | 1 + 1 file changed, 1 insertion(+) diff --git a/wadsrc/static/zscript/ui/menu/conversationmenu.zs b/wadsrc/static/zscript/ui/menu/conversationmenu.zs index 58516bff72..1c5043512d 100644 --- a/wadsrc/static/zscript/ui/menu/conversationmenu.zs +++ b/wadsrc/static/zscript/ui/menu/conversationmenu.zs @@ -142,6 +142,7 @@ class ConversationMenu : Menu let trade = Stringtable.Localize("$TXT_TRADE"); let amount = String.Format("%u", reply.PrintAmount); trade.Replace("%u", amount); + ReplyText = ReplyText .. trade; } let ReplyLines = SmallFont.BreakLines (ReplyText, ReplyWidth); From b7d09c95ddb84f5c1aaf84877d7a059bfa607ca9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 9 Mar 2019 14:48:14 +0100 Subject: [PATCH 10/12] - cleanup of savegame picture code. * re-added screen blends for images from the hardware renderer. * moved all postprocessing of the image out of the renderers. * cleaned out a large piece of cruft for handling the palette in the frame buffer class. This was all a remnant of the old paletted backend that no longer exists. Nowadays the screen blend is just a postprocessing effect drawn over the 3D screen, there is no need to maintain any of it as global state anymore. * since the engine doesn't produce paletted screenshots anymore there is no need to have handling for it in the generation code. This depended on otherwise obsolete information so it got removed along with that information. --- src/c_console.cpp | 1 - src/d_main.cpp | 3 -- src/g_game.cpp | 50 +++++++++++++++++++++++ src/gamedata/textures/image.cpp | 2 +- src/intermission/intermission.cpp | 2 - src/m_misc.cpp | 10 +---- src/rendering/gl/renderer/gl_renderer.cpp | 8 +++- src/rendering/swrenderer/r_swrenderer.cpp | 9 ++-- src/v_framebuffer.cpp | 35 ---------------- src/v_palette.cpp | 23 ----------- src/v_palette.h | 17 -------- src/v_video.cpp | 3 -- src/v_video.h | 18 -------- src/wi_stuff.cpp | 1 - 14 files changed, 62 insertions(+), 120 deletions(-) diff --git a/src/c_console.cpp b/src/c_console.cpp index 12d76adba4..8da82d8521 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -1294,7 +1294,6 @@ void C_FullConsole () primaryLevel->Music = ""; S_Start (); P_FreeLevelData (); - V_SetBlend (0,0,0,0); } else { diff --git a/src/d_main.cpp b/src/d_main.cpp index 365b549388..ebb17e3d68 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1247,7 +1247,6 @@ void D_DoAdvanceDemo (void) return; } - V_SetBlend (0,0,0,0); players[consoleplayer].playerstate = PST_LIVE; // not reborn usergame = false; // no save / end game here paused = 0; @@ -2698,8 +2697,6 @@ void D_DoomMain (void) } else { - // let the renderer reinitialize some stuff if needed - screen->InitPalette(); // These calls from inside V_Init2 are still necessary C_NewModeAdjust(); D_StartTitle (); // start up intro loop diff --git a/src/g_game.cpp b/src/g_game.cpp index dd5e73e753..a3375b5ca9 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2100,6 +2100,56 @@ static void PutSaveComment (FSerializer &arc) arc.AddString("Comment", comment); } +void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown) +{ + PalEntry palette[256]; + PalEntry modulateColor; + auto blend = screen->CalcBlend(viewsector, &modulateColor); + int pixelsize = 1; + // Apply the screen blend, because the renderer does not provide this. + if (ssformat == SS_RGB) + { + int numbytes = width * height * 3; + pixelsize = 3; + if (modulateColor != 0xffffffff) + { + float r = modulateColor.r / 255.f; + float g = modulateColor.g / 255.f; + float b = modulateColor.b / 255.f; + for (int i = 0; i < numbytes; i += 3) + { + scr[i] = uint8_t(scr[i] * r); + scr[i + 1] = uint8_t(scr[i + 1] * g); + scr[i + 2] = uint8_t(scr[i + 2] * b); + } + } + float iblendfac = 1.f - blend.W; + blend.X *= blend.W; + blend.Y *= blend.W; + blend.Z *= blend.W; + for (int i = 0; i < numbytes; i += 3) + { + scr[i] = uint8_t(scr[i] * iblendfac + blend.X); + scr[i + 1] = uint8_t(scr[i + 1] * iblendfac + blend.Y); + scr[i + 2] = uint8_t(scr[i + 2] * iblendfac + blend.Z); + } + } + else + { + // Apply the screen blend to the palette. The colormap related parts get skipped here because these are already part of the image. + DoBlending(GPalette.BaseColors, palette, 256, uint8_t(blend.X), uint8_t(blend.Y), uint8_t(blend.Z), uint8_t(blend.W*255)); + } + + int pitch = width * pixelsize; + if (upsidedown) + { + scr += ((height - 1) * width * pixelsize); + pitch *= -1; + } + + M_CreatePNG(file, scr, ssformat == SS_PAL? palette : nullptr, ssformat, width, height, pitch, Gamma); +} + static void PutSavePic (FileWriter *file, int width, int height) { if (width <= 0 || height <= 0 || !storesavepic) diff --git a/src/gamedata/textures/image.cpp b/src/gamedata/textures/image.cpp index f047b8137b..bbc6216279 100644 --- a/src/gamedata/textures/image.cpp +++ b/src/gamedata/textures/image.cpp @@ -173,7 +173,7 @@ TArray FImageSource::GetPalettedPixels(int conversion) int FImageSource::CopyPixels(FBitmap *bmp, int conversion) { if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. - PalEntry *palette = screen->GetPalette(); + PalEntry *palette = GPalette.BaseColors; for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values auto ppix = CreatePalettedPixels(conversion); bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr); diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 9affb04ad8..f1dd8b9a08 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -211,7 +211,6 @@ int DIntermissionScreenFader::Responder (event_t *ev) { if (ev->type == EV_KeyDown) { - V_SetBlend(0,0,0,0); return -1; } return Super::Responder(ev); @@ -852,7 +851,6 @@ void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t s { DIntermissionController::CurrentIntermission->Destroy(); } - V_SetBlend (0,0,0,0); S_StopAllChannels (); gameaction = ga_nothing; gamestate = GS_FINALE; diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 2bf798b13c..4b3438bc49 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -612,12 +612,6 @@ void M_ScreenShot (const char *filename) auto buffer = screen->GetScreenshotBuffer(pitch, color_type, gamma); if (buffer.Size() > 0) { - PalEntry palette[256]; - - if (color_type == SS_PAL) - { - screen->GetFlashedPalette(palette); - } file = FileWriter::Open(autoname); if (file == NULL) { @@ -626,12 +620,12 @@ void M_ScreenShot (const char *filename) } if (writepcx) { - WritePCXfile(file, buffer.Data(), palette, color_type, + WritePCXfile(file, buffer.Data(), nullptr, color_type, screen->GetWidth(), screen->GetHeight(), pitch); } else { - WritePNGfile(file, buffer.Data(), palette, color_type, + WritePNGfile(file, buffer.Data(), nullptr, color_type, screen->GetWidth(), screen->GetHeight(), pitch, gamma); } delete file; diff --git a/src/rendering/gl/renderer/gl_renderer.cpp b/src/rendering/gl/renderer/gl_renderer.cpp index 38a0ad6043..662365724f 100644 --- a/src/rendering/gl/renderer/gl_renderer.cpp +++ b/src/rendering/gl/renderer/gl_renderer.cpp @@ -67,6 +67,8 @@ EXTERN_CVAR(Bool, cl_capfps) extern bool NoInterpolateView; +void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown); + namespace OpenGLRenderer { @@ -370,9 +372,11 @@ void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, i // strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers glFinish(); - uint8_t * scr = (uint8_t *)M_Malloc(width * height * 3); + int numpixels = width * height; + uint8_t * scr = (uint8_t *)M_Malloc(numpixels * 3); glReadPixels(0,0,width, height,GL_RGB,GL_UNSIGNED_BYTE,scr); - M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width * 3, Gamma); + + DoWriteSavePic(file, SS_RGB, scr, width, height, viewsector, true); M_Free(scr); // Switch back the screen render buffers diff --git a/src/rendering/swrenderer/r_swrenderer.cpp b/src/rendering/swrenderer/r_swrenderer.cpp index a2863ec717..cf153551f6 100644 --- a/src/rendering/swrenderer/r_swrenderer.cpp +++ b/src/rendering/swrenderer/r_swrenderer.cpp @@ -208,10 +208,11 @@ void FSoftwareRenderer::RenderView(player_t *player, DCanvas *target, void *vide }); } +void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown); + void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height) { DCanvas pic(width, height, false); - PalEntry palette[256]; // Take a snapshot of the player's view if (V_IsPolyRenderer()) @@ -230,11 +231,7 @@ void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int wi r_viewpoint = mScene.MainThread()->Viewport->viewpoint; r_viewwindow = mScene.MainThread()->Viewport->viewwindow; } - auto blend = screen->CalcBlend(r_viewpoint.sector, nullptr); - const PalEntry bcolor(255, uint8_t(blend.X), uint8_t(blend.Y), uint8_t(blend.Z)); - screen->SetFlash(bcolor, int(blend.W * 256)); - screen->GetFlashedPalette (palette); - M_CreatePNG (file, pic.GetPixels(), palette, SS_PAL, width, height, pic.GetPitch(), Gamma); + DoWriteSavePic(file, SS_PAL, pic.GetPixels(), width, height, r_viewpoint.sector, false); } void FSoftwareRenderer::DrawRemainingPlayerSprites() diff --git a/src/v_framebuffer.cpp b/src/v_framebuffer.cpp index 26a86623ae..c026133c0d 100644 --- a/src/v_framebuffer.cpp +++ b/src/v_framebuffer.cpp @@ -202,11 +202,6 @@ void DFrameBuffer::DrawRateStuff () // //========================================================================== -void DFrameBuffer::GetFlashedPalette(PalEntry pal[256]) -{ - DoBlending(SourcePalette, pal, 256, Flash.r, Flash.g, Flash.b, Flash.a); -} - void DFrameBuffer::Update() { CheckBench(); @@ -225,24 +220,6 @@ void DFrameBuffer::Update() } } -PalEntry *DFrameBuffer::GetPalette() -{ - return SourcePalette; -} - -bool DFrameBuffer::SetFlash(PalEntry rgb, int amount) -{ - Flash = PalEntry(amount, rgb.r, rgb.g, rgb.b); - return true; -} - -void DFrameBuffer::GetFlash(PalEntry &rgb, int &amount) -{ - rgb = Flash; - rgb.a = 0; - amount = Flash.a; -} - void DFrameBuffer::SetClearColor(int color) { PalEntry pe = GPalette.BaseColors[color]; @@ -293,18 +270,6 @@ FTexture *DFrameBuffer::WipeEndScreen() return nullptr; } -//========================================================================== -// -// DFrameBuffer :: InitPalette -// -//========================================================================== - -void DFrameBuffer::InitPalette() -{ - memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry) * 256); - UpdatePalette(); -} - //========================================================================== // // DFrameBuffer :: GetCaps diff --git a/src/v_palette.cpp b/src/v_palette.cpp index e598fa290b..0c3427cd36 100644 --- a/src/v_palette.cpp +++ b/src/v_palette.cpp @@ -443,29 +443,6 @@ void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, in } } -void V_SetBlend (int blendr, int blendg, int blendb, int blenda) -{ - // Don't do anything if the new blend is the same as the old - if (((blenda|BlendA) == 0) || - (blendr == BlendR && - blendg == BlendG && - blendb == BlendB && - blenda == BlendA)) - return; - - V_ForceBlend (blendr, blendg, blendb, blenda); -} - -void V_ForceBlend (int blendr, int blendg, int blendb, int blenda) -{ - BlendR = blendr; - BlendG = blendg; - BlendB = blendb; - BlendA = blenda; - - screen->SetFlash (PalEntry (BlendR, BlendG, BlendB), BlendA); -} - CCMD (testblend) { FString colorstring; diff --git a/src/v_palette.h b/src/v_palette.h index a9a7e476b9..7038916564 100644 --- a/src/v_palette.h +++ b/src/v_palette.h @@ -77,23 +77,6 @@ void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, in void ReadPalette(int lumpnum, uint8_t *buffer); void InitPalette (); -// V_SetBlend() -// input: blendr: red component of blend -// blendg: green component of blend -// blendb: blue component of blend -// blenda: alpha component of blend -// -// Applies the blend to all palettes with PALETTEF_BLEND flag -void V_SetBlend (int blendr, int blendg, int blendb, int blenda); - -// V_ForceBlend() -// -// Normally, V_SetBlend() does nothing if the new blend is the -// same as the old. This function will perform the blending -// even if the blend hasn't changed. -void V_ForceBlend (int blendr, int blendg, int blendb, int blenda); - - EXTERN_CVAR (Int, paletteflash) enum PaletteFlashFlags { diff --git a/src/v_video.cpp b/src/v_video.cpp index d82d18eb91..9d091a51ec 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -696,9 +696,6 @@ void V_Init (bool restart) // Update screen palette when restarting else { - PalEntry *palette = screen->GetPalette (); - for (int i = 0; i < 256; ++i) - *palette++ = GPalette.BaseColors[i]; screen->UpdatePalette(); } diff --git a/src/v_video.h b/src/v_video.h index d4fedf17c9..8265328538 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -352,9 +352,6 @@ private: protected: int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1; - PalEntry Flash = 0; // Only needed to support some cruft in the interface that only makes sense for the software renderer - PalEntry SourcePalette[256]; // This is where unpaletted textures get their palette from - public: // Hardware render state that needs to be exposed to the API independent part of the renderer. For ease of access this is stored in the base class. int hwcaps = 0; // Capability flags @@ -404,26 +401,12 @@ public: // Make the surface visible. virtual void Update (); - // Return a pointer to 256 palette entries that can be written to. - PalEntry *GetPalette (); - // Stores the palette with flash blended in into 256 dwords - void GetFlashedPalette (PalEntry palette[256]); - // Mark the palette as changed. It will be updated on the next Update(). virtual void UpdatePalette() {} virtual void SetGamma() {} - // Sets a color flash. RGB is the color, and amount is 0-256, with 256 - // being all flash and 0 being no flash. Returns false if the hardware - // does not support this. (Always true for now, since palettes can always - // be flashed.) - bool SetFlash (PalEntry rgb, int amount); - - // Converse of SetFlash - void GetFlash (PalEntry &rgb, int &amount); - // Returns true if running fullscreen. virtual bool IsFullscreen () = 0; virtual void ToggleFullscreen(bool yes) {} @@ -475,7 +458,6 @@ public: } // Report a game restart - void InitPalette(); void SetClearColor(int color); virtual uint32_t GetCaps(); virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height); diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 1849d471cf..dedda46027 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -761,7 +761,6 @@ void WI_Start(wbstartstruct_t *wbstartstruct) } } - V_SetBlend(0, 0, 0, 0); S_StopAllChannels(); for (auto Level : AllLevels()) { From bc6994151409b326c71118607cc2cef462b453f3 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 9 Mar 2019 16:34:28 +0200 Subject: [PATCH 11/12] - fixed compilation of Cocoa backend src/posix/cocoa/i_video.mm:297:2: error: use of undeclared identifier 'SetFlash' --- src/posix/cocoa/i_video.mm | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index 0c1abb8838..d18099ca10 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -294,8 +294,6 @@ SystemGLFrameBuffer::SystemGLFrameBuffer(void*, const bool fullscreen) , m_hiDPI(false) , m_window(CreateWindow(STYLE_MASK_WINDOWED)) { - SetFlash(0, 0); - NSOpenGLPixelFormat* pixelFormat = CreatePixelFormat(); if (nil == pixelFormat) From 784e0347c077a30ef1ad42be560c5ec7b271cfc3 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 9 Mar 2019 16:36:12 +0200 Subject: [PATCH 12/12] - removed excessive std::move() reported by Clang src/utility/xlsxread/xlsxio_read.cpp:69:27: warning: moving a temporary object prevents copy elision [-Wpessimizing-move] --- src/utility/xlsxread/xlsxio_read.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utility/xlsxread/xlsxio_read.cpp b/src/utility/xlsxread/xlsxio_read.cpp index 48f6de5d8b..8a3ee5263f 100644 --- a/src/utility/xlsxread/xlsxio_read.cpp +++ b/src/utility/xlsxread/xlsxio_read.cpp @@ -66,7 +66,7 @@ zip_file_t *zip_fopen(zip_t *zipfile, const char *filename) if (!zipfile || !filename) return NULL; auto lump = zipfile->FindLump(filename); if (!lump) return NULL; - return new FileReader(std::move(lump->NewReader())); + return new FileReader(lump->NewReader()); } void zip_fclose(zip_file_t *zippedfile)