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