diff --git a/Runtime/Graphics/CGraphics.cpp b/Runtime/Graphics/CGraphics.cpp index 59c6dd10e..d0f70a406 100644 --- a/Runtime/Graphics/CGraphics.cpp +++ b/Runtime/Graphics/CGraphics.cpp @@ -28,6 +28,7 @@ zeus::CTransform CGraphics::g_GXViewPointMatrix; zeus::CTransform CGraphics::g_CameraMatrix; zeus::CVector2i CGraphics::g_ViewportResolution; zeus::CVector2i CGraphics::g_ViewportResolutionHalf; +SClipScreenRect CGraphics::g_CroppedViewport; int CGraphics::g_ViewportSamples = 1; bool CGraphics::g_IsGXModelMatrixIdentity = true; @@ -398,6 +399,9 @@ zeus::CVector3f CGraphics::ProjectModelPointToViewportSpace(const zeus::CVector3 void CGraphics::SetViewportResolution(const zeus::CVector2i& res) { g_ViewportResolution = res; + g_CroppedViewport = SClipScreenRect(); + g_CroppedViewport.xc_width = res.x; + g_CroppedViewport.x10_height = res.y; g_ViewportResolutionHalf = {res.x / 2, res.y / 2}; } diff --git a/Runtime/Graphics/CGraphics.hpp b/Runtime/Graphics/CGraphics.hpp index 673c814f6..5a85894ce 100644 --- a/Runtime/Graphics/CGraphics.hpp +++ b/Runtime/Graphics/CGraphics.hpp @@ -141,16 +141,31 @@ enum class ERglFogMode struct SClipScreenRect { - bool x0_valid; - int x4_left; - int x8_top; - int xc_width; - int x10_height; - int x14_dstWidth; - float x18_uvXMin; - float x1c_uvXMax; - float x20_uvYMin; - float x24_uvYMax; + bool x0_valid = false; + int x4_left = 0; + int x8_top = 0; + int xc_width = 0; + int x10_height = 0; + int x14_dstWidth = 0; + float x18_uvXMin = 0.f; + float x1c_uvXMax = 0.f; + float x20_uvYMin = 0.f; + float x24_uvYMax = 0.f; + + SClipScreenRect() = default; + SClipScreenRect(bool valid, int left, int top, int width, int height, int dstWidth, + float uvXMin, float uvXMax, float uvYMin, float uvYMax) + : x0_valid(valid), x4_left(left), x8_top(top), xc_width(width), x10_height(height), x14_dstWidth(dstWidth), + x18_uvXMin(uvXMin), x1c_uvXMax(uvXMax), x20_uvYMin(uvYMin), x24_uvYMax(uvYMax) {} + + SClipScreenRect(const boo::SWindowRect& rect) + { + x4_left = rect.location[0]; + x8_top = rect.location[1]; + xc_width = rect.size[0]; + x10_height = rect.size[1]; + x14_dstWidth = rect.size[0]; + } }; enum class ETexelFormat @@ -211,6 +226,7 @@ public: static zeus::CTransform g_CameraMatrix; static zeus::CVector2i g_ViewportResolution; static zeus::CVector2i g_ViewportResolutionHalf; + static SClipScreenRect g_CroppedViewport; static int g_ViewportSamples; static bool g_IsGXModelMatrixIdentity; diff --git a/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp b/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp index f530ac2d1..470d03786 100644 --- a/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp +++ b/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp @@ -8,18 +8,7 @@ CCameraBlurFilter::CCameraBlurFilter() { m_token = CGraphics::g_BooFactory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool { - struct Vert - { - zeus::CVector2f m_pos; - zeus::CVector2f m_uv; - } verts[4] = - { - {{-1.0, -1.0}, {0.0, 0.0}}, - {{-1.0, 1.0}, {0.0, 1.0}}, - {{ 1.0, -1.0}, {1.0, 0.0}}, - {{ 1.0, 1.0}, {1.0, 1.0}}, - }; - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, 32, 4); + m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 32, 4); m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); m_dataBind = TShader::BuildShaderDataBinding(ctx, *this); return true; @@ -35,7 +24,21 @@ void CCameraBlurFilter::draw(float amount) clipRect.xc_width = CGraphics::g_ViewportResolution.x; clipRect.x10_height = CGraphics::g_ViewportResolution.y; CGraphics::ResolveSpareTexture(clipRect); - float aspect = CGraphics::g_ViewportResolution.x / float(CGraphics::g_ViewportResolution.y); + float aspect = CGraphics::g_CroppedViewport.xc_width / float(CGraphics::g_CroppedViewport.x10_height); + + float xFac = CGraphics::g_CroppedViewport.xc_width / float(CGraphics::g_ViewportResolution.x); + float yFac = CGraphics::g_CroppedViewport.x10_height / float(CGraphics::g_ViewportResolution.y); + float xBias = CGraphics::g_CroppedViewport.x4_left / float(CGraphics::g_ViewportResolution.x); + float yBias = CGraphics::g_CroppedViewport.x8_top / float(CGraphics::g_ViewportResolution.y); + + Vert verts[4] = + { + {{-1.0, -1.0}, {xBias, yBias}}, + {{-1.0, 1.0}, {xBias, yBias + yFac}}, + {{ 1.0, -1.0}, {xBias + xFac, yBias}}, + {{ 1.0, 1.0}, {xBias + xFac, yBias + yFac}}, + }; + m_vbo->load(verts, sizeof(verts)); for (int i=0 ; i<6 ; ++i) { @@ -49,8 +52,8 @@ void CCameraBlurFilter::draw(float amount) float amtY = std::sin(tmp); amtY *= amount / 448.f; - m_uniform.m_uv[i][0] = amtX; - m_uniform.m_uv[i][1] = amtY; + m_uniform.m_uv[i][0] = amtX * xFac; + m_uniform.m_uv[i][1] = amtY * yFac; } m_uniform.m_opacity = std::min(amount / 2.f, 1.f); m_uniBuf->load(&m_uniform, sizeof(m_uniform)); diff --git a/Runtime/Graphics/Shaders/CCameraBlurFilter.hpp b/Runtime/Graphics/Shaders/CCameraBlurFilter.hpp index 3c62d4ef3..2b50345d8 100644 --- a/Runtime/Graphics/Shaders/CCameraBlurFilter.hpp +++ b/Runtime/Graphics/Shaders/CCameraBlurFilter.hpp @@ -15,13 +15,19 @@ class CCameraBlurFilter friend struct CCameraBlurFilterMetalDataBindingFactory; friend struct CCameraBlurFilterD3DDataBindingFactory; + struct Vert + { + zeus::CVector2f m_pos; + zeus::CVector2f m_uv; + }; + struct Uniform { zeus::CVector4f m_uv[6]; float m_opacity = 1.f; }; boo::GraphicsDataToken m_token; - boo::IGraphicsBufferS* m_vbo; + boo::IGraphicsBufferD* m_vbo; boo::IGraphicsBufferD* m_uniBuf; boo::IShaderDataBinding* m_dataBind = nullptr; Uniform m_uniform; diff --git a/Runtime/Graphics/Shaders/CColoredQuadFilter.cpp b/Runtime/Graphics/Shaders/CColoredQuadFilter.cpp index 188467500..3edd64d49 100644 --- a/Runtime/Graphics/Shaders/CColoredQuadFilter.cpp +++ b/Runtime/Graphics/Shaders/CColoredQuadFilter.cpp @@ -51,6 +51,37 @@ void CWideScreenFilter::draw(const zeus::CColor& color, float t) m_top.draw(color, rect); } } + +float CWideScreenFilter::SetViewportToMatch(float t) +{ + float aspect = CGraphics::g_ViewportResolution.x / float(CGraphics::g_ViewportResolution.y); + if (aspect < 1.7777f) + { + float targetHeight = CGraphics::g_ViewportResolution.x / 1.7777f; + float delta = (CGraphics::g_ViewportResolution.y - targetHeight) * t / 2.f; + boo::SWindowRect rect = {}; + rect.size[0] = CGraphics::g_ViewportResolution.x; + rect.size[1] = CGraphics::g_ViewportResolution.y - delta * 2.f; + rect.location[1] = delta; + CGraphics::g_CroppedViewport = rect; + CGraphics::g_BooMainCommandQueue->setViewport(rect); + return 1.7777f; + } + else + { + SetViewportToFull(); + return aspect; + } +} + +void CWideScreenFilter::SetViewportToFull() +{ + boo::SWindowRect rect = {}; + rect.size[0] = CGraphics::g_ViewportResolution.x; + rect.size[1] = CGraphics::g_ViewportResolution.y; + CGraphics::g_CroppedViewport = rect; + CGraphics::g_BooMainCommandQueue->setViewport(rect); +} const zeus::CRectangle CColoredQuadFilter::DefaultRect = {0.f, 0.f, 1.f, 1.f}; diff --git a/Runtime/Graphics/Shaders/CColoredQuadFilter.hpp b/Runtime/Graphics/Shaders/CColoredQuadFilter.hpp index 34627eaeb..9dcc0d557 100644 --- a/Runtime/Graphics/Shaders/CColoredQuadFilter.hpp +++ b/Runtime/Graphics/Shaders/CColoredQuadFilter.hpp @@ -45,6 +45,8 @@ public: CWideScreenFilter(CCameraFilterPass::EFilterType type) : m_top(type), m_bottom(type) {} void draw(const zeus::CColor& color, float t); + static float SetViewportToMatch(float t); + static void SetViewportToFull(); }; } diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp index aea3661f9..8b6e6259a 100644 --- a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp @@ -63,20 +63,21 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt) m_uniform.m_indXf[2][1] = 0.f; /* Warp effect is fixed at 192x192 rectangle in original (1/2.5 viewport height) */ + float aspect = CGraphics::g_CroppedViewport.xc_width / float(CGraphics::g_CroppedViewport.x10_height); m_uniform.m_matrix[1][1] = 1.f / 2.5f; - m_uniform.m_matrix[0][0] = m_uniform.m_matrix[1][1] / CGraphics::g_ProjAspect; + m_uniform.m_matrix[0][0] = m_uniform.m_matrix[1][1] / aspect; SClipScreenRect clipRect = {}; - clipRect.x4_left = ((pt[0] - m_uniform.m_matrix[0][0]) / 2.f + 0.5f) * CGraphics::g_ViewportResolution.x; - if (clipRect.x4_left >= CGraphics::g_ViewportResolution.x) + clipRect.x4_left = ((pt[0] - m_uniform.m_matrix[0][0]) / 2.f + 0.5f) * CGraphics::g_CroppedViewport.xc_width; + if (clipRect.x4_left >= CGraphics::g_CroppedViewport.xc_width) return; - clipRect.x8_top = ((pt[1] - m_uniform.m_matrix[1][1]) / 2.f + 0.5f) * CGraphics::g_ViewportResolution.y; - if (clipRect.x8_top >= CGraphics::g_ViewportResolution.y) + clipRect.x8_top = ((pt[1] - m_uniform.m_matrix[1][1]) / 2.f + 0.5f) * CGraphics::g_CroppedViewport.x10_height; + if (clipRect.x8_top >= CGraphics::g_CroppedViewport.x10_height) return; - clipRect.xc_width = CGraphics::g_ViewportResolution.x * m_uniform.m_matrix[0][0]; + clipRect.xc_width = CGraphics::g_CroppedViewport.xc_width * m_uniform.m_matrix[0][0]; if (clipRect.x4_left + clipRect.xc_width <= 0) return; - clipRect.x10_height = CGraphics::g_ViewportResolution.y * m_uniform.m_matrix[1][1]; + clipRect.x10_height = CGraphics::g_CroppedViewport.x10_height * m_uniform.m_matrix[1][1]; if (clipRect.x8_top + clipRect.x10_height <= 0) return; @@ -99,21 +100,21 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt) } float tmp = clipRect.x4_left + clipRect.xc_width; - if (tmp >= CGraphics::g_ViewportResolution.x) + if (tmp >= CGraphics::g_CroppedViewport.xc_width) { - clipRect.xc_width = CGraphics::g_ViewportResolution.x - clipRect.x4_left; + clipRect.xc_width = CGraphics::g_CroppedViewport.xc_width - clipRect.x4_left; m_uniform.m_indXf[0][0] = clipRect.xc_width / oldW; } tmp = clipRect.x8_top + clipRect.x10_height; - if (tmp >= CGraphics::g_ViewportResolution.y) + if (tmp >= CGraphics::g_CroppedViewport.x10_height) { - clipRect.x10_height = CGraphics::g_ViewportResolution.y - clipRect.x8_top; + clipRect.x10_height = CGraphics::g_CroppedViewport.x10_height - clipRect.x8_top; m_uniform.m_indXf[1][1] = clipRect.x10_height / oldH; } /* Transform UV coordinates of rectangle within viewport and sampled scene texels (clamped to viewport bounds) */ - zeus::CVector2f vp{float(CGraphics::g_ViewportResolution.x), float(CGraphics::g_ViewportResolution.y)}; + zeus::CVector2f vp{float(CGraphics::g_CroppedViewport.xc_width), float(CGraphics::g_CroppedViewport.x10_height)}; m_uniform.m_matrix[0][0] = clipRect.xc_width / vp.x; m_uniform.m_matrix[1][1] = clipRect.x10_height / vp.y; m_uniform.m_matrix[3][0] = pt.x + (1.f / vp.x); @@ -133,10 +134,13 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt) clipRect.x8_top -= 1; clipRect.x10_height += 1; } - if (clipRect.x4_left + clipRect.xc_width < CGraphics::g_ViewportResolution.x) + if (clipRect.x4_left + clipRect.xc_width < CGraphics::g_CroppedViewport.xc_width) clipRect.xc_width += 1; - if (clipRect.x8_top + clipRect.x10_height < CGraphics::g_ViewportResolution.y) + if (clipRect.x8_top + clipRect.x10_height < CGraphics::g_CroppedViewport.x10_height) clipRect.x10_height += 1; + + clipRect.x4_left += CGraphics::g_CroppedViewport.x4_left; + clipRect.x8_top += CGraphics::g_CroppedViewport.x8_top; CGraphics::ResolveSpareTexture(clipRect); m_uniform.m_strength.x = m_uniform.m_matrix[0][0] * m_strength * 0.5f * diff --git a/Runtime/Graphics/Shaders/CThermalColdFilter.cpp b/Runtime/Graphics/Shaders/CThermalColdFilter.cpp index 2d5139b89..605dd77dd 100644 --- a/Runtime/Graphics/Shaders/CThermalColdFilter.cpp +++ b/Runtime/Graphics/Shaders/CThermalColdFilter.cpp @@ -54,10 +54,7 @@ void CThermalColdFilter::setShift(unsigned shift) void CThermalColdFilter::draw() { - SClipScreenRect clipRect = {}; - clipRect.xc_width = CGraphics::g_ViewportResolution.x; - clipRect.x10_height = CGraphics::g_ViewportResolution.y; - CGraphics::ResolveSpareTexture(clipRect); + CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport); m_uniform.m_shiftTexMtx[0][0] = 80.f * (CGraphics::g_ProjAspect / 1.33f); m_uniform.m_shiftTexMtx[1][1] = 120.f; diff --git a/Runtime/Graphics/Shaders/CThermalHotFilter.cpp b/Runtime/Graphics/Shaders/CThermalHotFilter.cpp index 0c222a179..ea9afe093 100644 --- a/Runtime/Graphics/Shaders/CThermalHotFilter.cpp +++ b/Runtime/Graphics/Shaders/CThermalHotFilter.cpp @@ -28,10 +28,7 @@ CThermalHotFilter::CThermalHotFilter() void CThermalHotFilter::draw() { - SClipScreenRect clipRect = {}; - clipRect.xc_width = CGraphics::g_ViewportResolution.x; - clipRect.x10_height = CGraphics::g_ViewportResolution.y; - CGraphics::ResolveSpareTexture(clipRect); + CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport); //m_uniBuf->load(&m_uniform, sizeof(m_uniform)); diff --git a/Runtime/Graphics/Shaders/CXRayBlurFilter.cpp b/Runtime/Graphics/Shaders/CXRayBlurFilter.cpp index fdb85ac87..06e7fa869 100644 --- a/Runtime/Graphics/Shaders/CXRayBlurFilter.cpp +++ b/Runtime/Graphics/Shaders/CXRayBlurFilter.cpp @@ -31,10 +31,7 @@ CXRayBlurFilter::CXRayBlurFilter(TLockedToken& tex) void CXRayBlurFilter::draw(float amount) { - SClipScreenRect clipRect = {}; - clipRect.xc_width = CGraphics::g_ViewportResolution.x; - clipRect.x10_height = CGraphics::g_ViewportResolution.y; - CGraphics::ResolveSpareTexture(clipRect); + CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport); float blurL = amount * 0.0014f * 0.25f; float blurQ = amount * 0.0000525f * 0.25f; diff --git a/Runtime/World/CWorldTransManager.cpp b/Runtime/World/CWorldTransManager.cpp index cda8cf9a0..bdb508058 100644 --- a/Runtime/World/CWorldTransManager.cpp +++ b/Runtime/World/CWorldTransManager.cpp @@ -220,9 +220,10 @@ void CWorldTransManager::DrawSecondPass() void CWorldTransManager::DrawEnabled() { + float wsAspect = CWideScreenFilter::SetViewportToMatch(1.f); + g_Renderer->SetPerspective(CCameraManager::DefaultFirstPersonFOV(), - CGraphics::g_ViewportResolution.x / - float(CGraphics::g_ViewportResolution.y), + wsAspect, CCameraManager::DefaultNearPlane(), CCameraManager::DefaultFarPlane()); g_Renderer->x318_26_ = true; @@ -243,6 +244,7 @@ void CWorldTransManager::DrawEnabled() m_dissolve.draw(zeus::CColor{1.f, 1.f, 1.f, t}, 1.f); } + CWideScreenFilter::SetViewportToFull(); m_widescreen.draw(zeus::CColor::skBlack, 1.f); float ftbT = 0.f;