From 31b960255dca7e1d73633901a1b7f7dce38976e3 Mon Sep 17 00:00:00 2001 From: myT <> Date: Mon, 15 Jan 2024 22:03:50 +0100 Subject: [PATCH] added a magnifier tool to the CRP --- code/renderer/crp_local.h | 11 +++ code/renderer/crp_magnifier.cpp | 97 +++++++++++++++++++ code/renderer/crp_main.cpp | 3 + code/renderer/shaders/crp/magnifier.hlsl | 64 ++++++++++++ code/shadercomp/shadercomp.cpp | 1 + makefiles/windows_vs2019/renderer.vcxproj | 4 + .../windows_vs2019/renderer.vcxproj.filters | 4 + makefiles/windows_vs2022/renderer.vcxproj | 4 + .../windows_vs2022/renderer.vcxproj.filters | 4 + 9 files changed, 192 insertions(+) create mode 100644 code/renderer/crp_magnifier.cpp create mode 100644 code/renderer/shaders/crp/magnifier.hlsl diff --git a/code/renderer/crp_local.h b/code/renderer/crp_local.h index 11ad82f..7f526af 100644 --- a/code/renderer/crp_local.h +++ b/code/renderer/crp_local.h @@ -218,6 +218,16 @@ private: uint32_t tileHeight; }; +struct Magnifier +{ + void Init(); + void Draw(); + void DrawGUI(); + +private: + HPipeline pipeline; +}; + struct BaseBufferId { enum Id @@ -325,6 +335,7 @@ struct CRP : IRenderPipeline GatherDepthOfField gatherDof; AccumDepthOfField accumDof; Fog fog; + Magnifier magnifier; }; extern CRP crp; diff --git a/code/renderer/crp_magnifier.cpp b/code/renderer/crp_magnifier.cpp new file mode 100644 index 0000000..4ccf2a4 --- /dev/null +++ b/code/renderer/crp_magnifier.cpp @@ -0,0 +1,97 @@ +/* +=========================================================================== +Copyright (C) 2024 Gian 'myT' Schellenbaum + +This file is part of Challenge Quake 3 (CNQ3). + +Challenge Quake 3 is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Challenge Quake 3 is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Challenge Quake 3. If not, see . +=========================================================================== +*/ +// Cinematic Rendering Pipeline - magnifier tool for pixel peeping + + +#include "crp_local.h" +#include "../client/cl_imgui.h" +#include "compshaders/crp/fullscreen.h" +#include "compshaders/crp/magnifier.h" + + +#pragma pack(push, 4) +struct MagnifierRC +{ + uint32_t colorTextureIndex; + uint32_t cursorIndexX; + uint32_t cursorIndexY; + uint32_t magnifierWidth; + uint32_t magnifierScale; + uint32_t edgeWidth; + uint32_t edgeColor; +}; +#pragma pack(pop) + +static bool s_magnifierActive = false; + + +void Magnifier::Init() +{ + GraphicsPipelineDesc desc("Magnifier"); + desc.shortLifeTime = true; + desc.vertexShader = ShaderByteCode(g_fullscreen_vs); + desc.pixelShader = ShaderByteCode(g_magnifier_ps); + desc.depthStencil.DisableDepth(); + desc.rasterizer.cullMode = CT_TWO_SIDED; + desc.AddRenderTarget(0, crp.renderTargetFormat); + pipeline = CreateGraphicsPipeline(desc); +} + +void Magnifier::Draw() +{ + if(r_debugUI->integer == 0 || !s_magnifierActive) + { + return; + } + + srp.renderMode = RenderMode::None; + + SCOPED_RENDER_PASS("Magnifier", 1.0f, 1.0f, 1.0f); + + CmdSetViewportAndScissor(0, 0, glConfig.vidWidth, glConfig.vidHeight); + + crp.SwapRenderTargets(); + + CmdBeginBarrier(); + CmdTextureBarrier(crp.GetReadRenderTarget(), ResourceStates::PixelShaderAccessBit); + CmdTextureBarrier(crp.GetWriteRenderTarget(), ResourceStates::RenderTargetBit); + CmdEndBarrier(); + + MagnifierRC rc = {}; + rc.colorTextureIndex = GetTextureIndexSRV(crp.GetReadRenderTarget()); + rc.cursorIndexX = ImGui::GetIO().MousePos.x; + rc.cursorIndexY = ImGui::GetIO().MousePos.y; + rc.magnifierWidth = 256; + rc.magnifierScale = 4; + rc.edgeWidth = 2; + rc.edgeColor = 0xFF00FFFF; + + CmdBindRenderTargets(1, &crp.renderTarget, NULL); + CmdBindPipeline(pipeline); + CmdSetGraphicsRootConstants(0, sizeof(rc), &rc); + CmdDraw(3, 0); +} + +void Magnifier::DrawGUI() +{ + ToggleBooleanWithShortcut(s_magnifierActive, ImGuiKey_M); + GUI_AddMainMenuItem(GUI_MainMenu::Tools, "Magnifier", "Ctrl+M", &s_magnifierActive); +} diff --git a/code/renderer/crp_main.cpp b/code/renderer/crp_main.cpp index 6d01742..7d79648 100644 --- a/code/renderer/crp_main.cpp +++ b/code/renderer/crp_main.cpp @@ -329,6 +329,7 @@ void CRP::Init() gatherDof.Init(); accumDof.Init(); fog.Init(); + magnifier.Init(); srp.firstInit = false; } @@ -367,8 +368,10 @@ void CRP::BeginFrame() void CRP::EndFrame() { srp.DrawGUI(); + magnifier.DrawGUI(); imgui.Draw(renderTarget); toneMap.DrawToneMap(); + magnifier.Draw(); BlitRenderTarget(GetSwapChainTexture(), "Blit to Swap Chain"); BlitRenderTarget(readbackRenderTarget, "Blit to Readback Texture"); srp.EndFrame(); diff --git a/code/renderer/shaders/crp/magnifier.hlsl b/code/renderer/shaders/crp/magnifier.hlsl new file mode 100644 index 0000000..32f9e41 --- /dev/null +++ b/code/renderer/shaders/crp/magnifier.hlsl @@ -0,0 +1,64 @@ +/* +=========================================================================== +Copyright (C) 2024 Gian 'myT' Schellenbaum + +This file is part of Challenge Quake 3 (CNQ3). + +Challenge Quake 3 is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Challenge Quake 3 is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Challenge Quake 3. If not, see . +=========================================================================== +*/ +// magnifier for pixel peeping + + +#include "common.hlsli" +#include "fullscreen.hlsli" + + +cbuffer RootConstants +{ + uint colorTextureIndex; + int cursorIndexX; + int cursorIndexY; + int magnifierWidth; + int magnifierScale; + int edgeWidth; + uint edgeColor; +}; + +float4 ps(VOut input) : SV_Target +{ + Texture2D colorTexture = ResourceDescriptorHeap[colorTextureIndex]; + int2 tc = int2(input.position.xy); + int2 tcCursor = int2(cursorIndexX, cursorIndexY); + int2 diff = tc - tcCursor; + int2 dist = abs(diff); + int distInner = magnifierWidth / 2; + int distOuter = distInner + edgeWidth; + if(all(dist <= distInner)) + { + // we need to map diff values -N..-1 to -1 and 0..N-1 to 0 after division + // hence the N-1 offset for negative diff values + int2 negOffset = int2(magnifierScale - 1, magnifierScale - 1); + diff -= diff < int2(0, 0) ? negOffset : int2(0, 0); + tc = tcCursor + diff / magnifierScale; + } + float3 color = colorTexture.Load(int3(tc.x, tc.y, 0)).rgb; + if(any(dist > distInner) && all(dist <= distOuter)) + { + color = UnpackColor(edgeColor).rgb; + } + float4 result = float4(color, 1.0); + + return result; +} diff --git a/code/shadercomp/shadercomp.cpp b/code/shadercomp/shadercomp.cpp index 86000ef..723a6d8 100644 --- a/code/shadercomp/shadercomp.cpp +++ b/code/shadercomp/shadercomp.cpp @@ -405,6 +405,7 @@ void ProcessCRP() CompilePixelShader("gatherdof_debug.h", "gatherdof_debug.hlsl", "debug"); CompileGraphics("fog_inside.h", "fog_inside.hlsl", "inside"); CompileGraphics("fog_outside.h", "fog_outside.hlsl", "outside"); + CompilePixelShader("magnifier.h", "magnifier.hlsl", "magnifier"); } int main(int /*argc*/, const char** argv) diff --git a/makefiles/windows_vs2019/renderer.vcxproj b/makefiles/windows_vs2019/renderer.vcxproj index 1f41d78..bc7d208 100644 --- a/makefiles/windows_vs2019/renderer.vcxproj +++ b/makefiles/windows_vs2019/renderer.vcxproj @@ -131,6 +131,7 @@ + @@ -217,6 +218,9 @@ true + + true + true diff --git a/makefiles/windows_vs2019/renderer.vcxproj.filters b/makefiles/windows_vs2019/renderer.vcxproj.filters index 34bdace..c429822 100644 --- a/makefiles/windows_vs2019/renderer.vcxproj.filters +++ b/makefiles/windows_vs2019/renderer.vcxproj.filters @@ -35,6 +35,7 @@ + @@ -121,6 +122,9 @@ shaders\crp + + shaders\crp + shaders\crp diff --git a/makefiles/windows_vs2022/renderer.vcxproj b/makefiles/windows_vs2022/renderer.vcxproj index 43727a7..a8a5a61 100644 --- a/makefiles/windows_vs2022/renderer.vcxproj +++ b/makefiles/windows_vs2022/renderer.vcxproj @@ -133,6 +133,7 @@ + @@ -219,6 +220,9 @@ true + + true + true diff --git a/makefiles/windows_vs2022/renderer.vcxproj.filters b/makefiles/windows_vs2022/renderer.vcxproj.filters index 34bdace..c429822 100644 --- a/makefiles/windows_vs2022/renderer.vcxproj.filters +++ b/makefiles/windows_vs2022/renderer.vcxproj.filters @@ -35,6 +35,7 @@ + @@ -121,6 +122,9 @@ shaders\crp + + shaders\crp + shaders\crp