diff --git a/Source/Core/VideoCommon/FreeLookCamera.cpp b/Source/Core/VideoCommon/FreeLookCamera.cpp index 4e49496dfd..7c2647ba2e 100644 --- a/Source/Core/VideoCommon/FreeLookCamera.cpp +++ b/Source/Core/VideoCommon/FreeLookCamera.cpp @@ -204,6 +204,11 @@ Common::Matrix44 FreeLookCamera::GetView() return m_camera_controller->GetView(); } +Common::Vec2 FreeLookCamera::GetFieldOfView() const +{ + return Common::Vec2{m_fov_x, m_fov_y}; +} + void FreeLookCamera::MoveVertical(float amt) { m_camera_controller->MoveVertical(amt); @@ -228,9 +233,23 @@ void FreeLookCamera::Rotate(const Common::Vec3& amt) m_dirty = true; } +void FreeLookCamera::IncreaseFovX(float fov) +{ + m_fov_x += fov; + m_fov_x = std::clamp(m_fov_x, 0.1f, m_fov_x); +} + +void FreeLookCamera::IncreaseFovY(float fov) +{ + m_fov_y += fov; + m_fov_y = std::clamp(m_fov_y, 0.1f, m_fov_y); +} + void FreeLookCamera::Reset() { m_camera_controller->Reset(); + m_fov_x = 1.0f; + m_fov_y = 1.0f; m_dirty = true; } @@ -239,6 +258,8 @@ void FreeLookCamera::DoState(PointerWrap& p) if (p.mode == PointerWrap::MODE_WRITE || p.mode == PointerWrap::MODE_MEASURE) { p.Do(m_current_type); + p.Do(m_fov_x); + p.Do(m_fov_y); if (m_camera_controller) { m_camera_controller->DoState(p); diff --git a/Source/Core/VideoCommon/FreeLookCamera.h b/Source/Core/VideoCommon/FreeLookCamera.h index aaee69390c..cb8455e5ab 100644 --- a/Source/Core/VideoCommon/FreeLookCamera.h +++ b/Source/Core/VideoCommon/FreeLookCamera.h @@ -43,6 +43,7 @@ class FreeLookCamera public: void SetControlType(FreelookControlType type); Common::Matrix44 GetView(); + Common::Vec2 GetFieldOfView() const; void MoveVertical(float amt); void MoveHorizontal(float amt); @@ -51,6 +52,9 @@ public: void Rotate(const Common::Vec3& amt); + void IncreaseFovX(float fov); + void IncreaseFovY(float fov); + void Reset(); void DoState(PointerWrap& p); @@ -60,6 +64,8 @@ public: private: bool m_dirty = false; + float m_fov_x = 1.0f; + float m_fov_y = 1.0f; std::optional m_current_type; std::unique_ptr m_camera_controller; }; diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index 6c65a86efa..8666e7b311 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -355,14 +355,17 @@ void VertexShaderManager::SetConstants() switch (xfmem.projection.type) { case GX_PERSPECTIVE: - g_fProjectionMatrix[0] = rawProjection[0] * g_ActiveConfig.fAspectRatioHackW; + { + const Common::Vec2 fov = + g_ActiveConfig.bFreeLook ? g_freelook_camera.GetFieldOfView() : Common::Vec2{1, 1}; + g_fProjectionMatrix[0] = rawProjection[0] * g_ActiveConfig.fAspectRatioHackW * fov.x; g_fProjectionMatrix[1] = 0.0f; - g_fProjectionMatrix[2] = rawProjection[1] * g_ActiveConfig.fAspectRatioHackW; + g_fProjectionMatrix[2] = rawProjection[1] * g_ActiveConfig.fAspectRatioHackW * fov.x; g_fProjectionMatrix[3] = 0.0f; g_fProjectionMatrix[4] = 0.0f; - g_fProjectionMatrix[5] = rawProjection[2] * g_ActiveConfig.fAspectRatioHackH; - g_fProjectionMatrix[6] = rawProjection[3] * g_ActiveConfig.fAspectRatioHackH; + g_fProjectionMatrix[5] = rawProjection[2] * g_ActiveConfig.fAspectRatioHackH * fov.y; + g_fProjectionMatrix[6] = rawProjection[3] * g_ActiveConfig.fAspectRatioHackH * fov.y; g_fProjectionMatrix[7] = 0.0f; g_fProjectionMatrix[8] = 0.0f; @@ -377,9 +380,11 @@ void VertexShaderManager::SetConstants() g_fProjectionMatrix[15] = 0.0f; g_stats.gproj = g_fProjectionMatrix; - break; + } + break; case GX_ORTHOGRAPHIC: + { g_fProjectionMatrix[0] = rawProjection[0]; g_fProjectionMatrix[1] = 0.0f; g_fProjectionMatrix[2] = 0.0f; @@ -403,7 +408,8 @@ void VertexShaderManager::SetConstants() g_stats.g2proj = g_fProjectionMatrix; g_stats.proj = rawProjection; - break; + } + break; default: ERROR_LOG(VIDEO, "Unknown projection type: %d", xfmem.projection.type);