From caa062c88c4a103513c1728648acba344e1db93d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Tue, 14 May 2024 23:06:22 +0200 Subject: [PATCH] Always clear window with black color instead of background color Always use black color to clear the window with all graphics backends, instead of using `cl_background_color` or `cl_background_entities_color`, respectively, as the clear color. The respective map background color is rendered using a quad in `CMapLayers` instead, so this should not affect appearance of maps. This does not have any noticeable effect on FPS. Previously, the unused part of the window (when it is resized smaller than 5:4 aspect ratio), was colored using the map background color, whereas now it will be cleared black consistently. The color parameters of the `IGraphics::Clear` function and of the `SCommand_Clear` command are removed, as we always expect the screen to be cleared black now. The parameter `ForceClearNow` of the `IGraphics::Clear` function was already unused previously and is also removed. --- .../client/backend/opengl/backend_opengl.cpp | 2 +- .../client/backend/opengl/backend_opengl3.cpp | 8 +--- .../client/backend/opengl/backend_opengl3.h | 2 - .../client/backend/vulkan/backend_vulkan.cpp | 38 ++++--------------- src/engine/client/client.cpp | 16 ++------ src/engine/client/graphics_threaded.cpp | 7 +--- src/engine/client/graphics_threaded.h | 4 +- src/engine/graphics.h | 3 +- src/game/client/components/maplayers.cpp | 17 +++++++++ src/game/client/gameclient.cpp | 4 +- src/game/editor/editor.cpp | 2 +- 11 files changed, 36 insertions(+), 67 deletions(-) diff --git a/src/engine/client/backend/opengl/backend_opengl.cpp b/src/engine/client/backend/opengl/backend_opengl.cpp index 2e3223871..d892ca472 100644 --- a/src/engine/client/backend/opengl/backend_opengl.cpp +++ b/src/engine/client/backend/opengl/backend_opengl.cpp @@ -937,7 +937,7 @@ void CCommandProcessorFragment_OpenGL::Cmd_Clear(const CCommandBuffer::SCommand_ { glDisable(GL_SCISSOR_TEST); } - glClearColor(pCommand->m_Color.r, pCommand->m_Color.g, pCommand->m_Color.b, 0.0f); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if(ClipWasEnabled) { diff --git a/src/engine/client/backend/opengl/backend_opengl3.cpp b/src/engine/client/backend/opengl/backend_opengl3.cpp index 3f4fb575a..b4e15dbb5 100644 --- a/src/engine/client/backend/opengl/backend_opengl3.cpp +++ b/src/engine/client/backend/opengl/backend_opengl3.cpp @@ -414,8 +414,6 @@ bool CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand m_vTextures.resize(CCommandBuffer::MAX_TEXTURES); - m_ClearColor.r = m_ClearColor.g = m_ClearColor.b = -1.f; - // fix the alignment to allow even 1byte changes, e.g. for alpha components glPixelStorei(GL_UNPACK_ALIGNMENT, 1); @@ -687,11 +685,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Clear(const CCommandBuffer::SComma { glDisable(GL_SCISSOR_TEST); } - if(pCommand->m_Color.r != m_ClearColor.r || pCommand->m_Color.g != m_ClearColor.g || pCommand->m_Color.b != m_ClearColor.b) - { - glClearColor(pCommand->m_Color.r, pCommand->m_Color.g, pCommand->m_Color.b, 0.0f); - m_ClearColor = pCommand->m_Color; - } + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); if(ClipWasEnabled) { diff --git a/src/engine/client/backend/opengl/backend_opengl3.h b/src/engine/client/backend/opengl/backend_opengl3.h index 05b82a4df..93e0347e6 100644 --- a/src/engine/client/backend/opengl/backend_opengl3.h +++ b/src/engine/client/backend/opengl/backend_opengl3.h @@ -67,8 +67,6 @@ protected: std::vector m_vBufferObjectIndices; - CCommandBuffer::SColorf m_ClearColor; - void InitPrimExProgram(CGLSLPrimitiveExProgram *pProgram, class CGLSLCompiler *pCompiler, class IStorage *pStorage, bool Textured, bool Rotationless); bool IsNewApi() override { return true; } diff --git a/src/engine/client/backend/vulkan/backend_vulkan.cpp b/src/engine/client/backend/vulkan/backend_vulkan.cpp index edc9eda4d..f16832b5d 100644 --- a/src/engine/client/backend/vulkan/backend_vulkan.cpp +++ b/src/engine/client/backend/vulkan/backend_vulkan.cpp @@ -1059,8 +1059,6 @@ private: SDL_Window *m_pWindow; - std::array m_aClearColor = {0, 0, 0, 0}; - struct SRenderCommandExecuteBuffer { CCommandBuffer::ECommandBufferCMD m_Command; @@ -1077,8 +1075,6 @@ private: VkBuffer m_IndexBuffer; - bool m_ClearColorInRenderThread = false; - bool m_HasDynamicState = false; VkViewport m_Viewport; VkRect2D m_Scissor; @@ -2445,7 +2441,7 @@ protected: RenderPassInfo.renderArea.offset = {0, 0}; RenderPassInfo.renderArea.extent = m_VKSwapImgAndViewportExtent.m_SwapImageViewport; - VkClearValue ClearColorVal = {{{m_aClearColor[0], m_aClearColor[1], m_aClearColor[2], m_aClearColor[3]}}}; + VkClearValue ClearColorVal = {{{0.0f, 0.0f, 0.0f, 0.0f}}}; RenderPassInfo.clearValueCount = 1; RenderPassInfo.pClearValues = &ClearColorVal; @@ -6715,37 +6711,19 @@ public: void Cmd_Clear_FillExecuteBuffer(SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand_Clear *pCommand) { - if(!pCommand->m_ForceClear) - { - bool ColorChanged = m_aClearColor[0] != pCommand->m_Color.r || m_aClearColor[1] != pCommand->m_Color.g || - m_aClearColor[2] != pCommand->m_Color.b || m_aClearColor[3] != pCommand->m_Color.a; - m_aClearColor[0] = pCommand->m_Color.r; - m_aClearColor[1] = pCommand->m_Color.g; - m_aClearColor[2] = pCommand->m_Color.b; - m_aClearColor[3] = pCommand->m_Color.a; - if(ColorChanged) - ExecBuffer.m_ClearColorInRenderThread = true; - } - else - { - ExecBuffer.m_ClearColorInRenderThread = true; - } ExecBuffer.m_EstimatedRenderCallCount = 0; } [[nodiscard]] bool Cmd_Clear(const SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand_Clear *pCommand) { - if(ExecBuffer.m_ClearColorInRenderThread) - { - std::array aAttachments = {VkClearAttachment{VK_IMAGE_ASPECT_COLOR_BIT, 0, VkClearValue{VkClearColorValue{{pCommand->m_Color.r, pCommand->m_Color.g, pCommand->m_Color.b, pCommand->m_Color.a}}}}}; - std::array aClearRects = {VkClearRect{{{0, 0}, m_VKSwapImgAndViewportExtent.m_SwapImageViewport}, 0, 1}}; + std::array aAttachments = {VkClearAttachment{VK_IMAGE_ASPECT_COLOR_BIT, 0, VkClearValue{VkClearColorValue{{0.0f, 0.0f, 0.0f, 0.0f}}}}}; + std::array aClearRects = {VkClearRect{{{0, 0}, m_VKSwapImgAndViewportExtent.m_SwapImageViewport}, 0, 1}}; - VkCommandBuffer *pCommandBuffer; - if(!GetGraphicCommandBuffer(pCommandBuffer, ExecBuffer.m_ThreadIndex)) - return false; - auto &CommandBuffer = *pCommandBuffer; - vkCmdClearAttachments(CommandBuffer, aAttachments.size(), aAttachments.data(), aClearRects.size(), aClearRects.data()); - } + VkCommandBuffer *pCommandBuffer; + if(!GetGraphicCommandBuffer(pCommandBuffer, ExecBuffer.m_ThreadIndex)) + return false; + auto &CommandBuffer = *pCommandBuffer; + vkCmdClearAttachments(CommandBuffer, aAttachments.size(), aAttachments.data(), aClearRects.size(), aClearRects.data()); return true; } diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 2665ee0c5..b6b870eb4 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -891,17 +891,7 @@ const char *CClient::ErrorString() const void CClient::Render() { - if(g_Config.m_ClOverlayEntities) - { - ColorRGBA bg = color_cast(ColorHSLA(g_Config.m_ClBackgroundEntitiesColor)); - Graphics()->Clear(bg.r, bg.g, bg.b); - } - else - { - ColorRGBA bg = color_cast(ColorHSLA(g_Config.m_ClBackgroundColor)); - Graphics()->Clear(bg.r, bg.g, bg.b); - } - + Graphics()->Clear(); GameClient()->OnRender(); DebugRender(); @@ -2728,7 +2718,7 @@ void CClient::Run() } // make sure the first frame just clears everything to prevent undesired colors when waiting for io - Graphics()->Clear(0, 0, 0); + Graphics()->Clear(); Graphics()->Swap(); // init sound, allowed to fail @@ -3783,7 +3773,7 @@ void CClient::UpdateAndSwap() { Input()->Update(); Graphics()->Swap(); - Graphics()->Clear(0, 0, 0); + Graphics()->Clear(); } void CClient::ServerBrowserUpdate() diff --git a/src/engine/client/graphics_threaded.cpp b/src/engine/client/graphics_threaded.cpp index ec2642fd6..8fbb1841d 100644 --- a/src/engine/client/graphics_threaded.cpp +++ b/src/engine/client/graphics_threaded.cpp @@ -833,14 +833,9 @@ void CGraphics_Threaded::TextureSet(CTextureHandle TextureId) m_State.m_Texture = TextureId.Id(); } -void CGraphics_Threaded::Clear(float r, float g, float b, bool ForceClearNow) +void CGraphics_Threaded::Clear() { CCommandBuffer::SCommand_Clear Cmd; - Cmd.m_Color.r = r; - Cmd.m_Color.g = g; - Cmd.m_Color.b = b; - Cmd.m_Color.a = 0; - Cmd.m_ForceClear = ForceClearNow; AddCmd(Cmd); } diff --git a/src/engine/client/graphics_threaded.h b/src/engine/client/graphics_threaded.h index 3255c67aa..adfb06779 100644 --- a/src/engine/client/graphics_threaded.h +++ b/src/engine/client/graphics_threaded.h @@ -213,8 +213,6 @@ public: { SCommand_Clear() : SCommand(CMD_CLEAR) {} - SColorf m_Color; - bool m_ForceClear; }; struct SCommand_Signal : public SCommand @@ -991,7 +989,7 @@ public: void TextureSet(CTextureHandle TextureId) override; - void Clear(float r, float g, float b, bool ForceClearNow = false) override; + void Clear() override; void QuadsBegin() override; void QuadsEnd() override; diff --git a/src/engine/graphics.h b/src/engine/graphics.h index 14017affd..7fd9bfc3a 100644 --- a/src/engine/graphics.h +++ b/src/engine/graphics.h @@ -306,8 +306,7 @@ public: virtual void WindowDestroyNtf(uint32_t WindowId) = 0; virtual void WindowCreateNtf(uint32_t WindowId) = 0; - // ForceClearNow forces the backend to trigger a clear, even at performance cost, else it might be delayed by one frame - virtual void Clear(float r, float g, float b, bool ForceClearNow = false) = 0; + virtual void Clear() = 0; virtual void ClipEnable(int x, int y, int w, int h) = 0; virtual void ClipDisable() = 0; diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp index 681e6d777..496f954da 100644 --- a/src/game/client/components/maplayers.cpp +++ b/src/game/client/components/maplayers.cpp @@ -1412,6 +1412,23 @@ void CMapLayers::OnRender() CUIRect Screen; Graphics()->GetScreen(&Screen.x, &Screen.y, &Screen.w, &Screen.h); + if(m_Type == TYPE_BACKGROUND || m_Type == TYPE_BACKGROUND_FORCE) + { + Graphics()->TextureClear(); + Graphics()->QuadsBegin(); + if(g_Config.m_ClOverlayEntities) + { + Graphics()->SetColor(color_cast(ColorHSLA(g_Config.m_ClBackgroundEntitiesColor))); + } + else + { + Graphics()->SetColor(color_cast(ColorHSLA(g_Config.m_ClBackgroundColor))); + } + IGraphics::CQuadItem QuadItem(Screen.x, Screen.y, Screen.w, Screen.h); + Graphics()->QuadsDrawTL(&QuadItem, 1); + Graphics()->QuadsEnd(); + } + vec2 Center = GetCurCamera()->m_Center; bool PassedGameLayer = false; diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index d41cd9607..9b30e7f8b 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -1092,12 +1092,12 @@ void CGameClient::RenderShutdownMessage() dbg_assert(false, "Invalid client state for quitting message"); // This function only gets called after the render loop has already terminated, so we have to call Swap manually. - Graphics()->Clear(0.0f, 0.0f, 0.0f); + Graphics()->Clear(); Ui()->MapScreen(); TextRender()->TextColor(TextRender()->DefaultTextColor()); Ui()->DoLabel(Ui()->Screen(), pMessage, 16.0f, TEXTALIGN_MC); Graphics()->Swap(); - Graphics()->Clear(0.0f, 0.0f, 0.0f); + Graphics()->Clear(); } void CGameClient::OnRconType(bool UsernameReq) diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index dd6ba9777..8b8ef2184 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -7718,7 +7718,7 @@ void CEditor::RenderMenubar(CUIRect MenuBar) void CEditor::Render() { // basic start - Graphics()->Clear(0.0f, 0.0f, 0.0f); + Graphics()->Clear(); CUIRect View = *Ui()->Screen(); Ui()->MapScreen(); m_CursorType = CURSOR_NORMAL;