diff --git a/source/graphics/Camera.cpp b/source/graphics/Camera.cpp index 86ee8cf38d..1166ac9c1a 100644 --- a/source/graphics/Camera.cpp +++ b/source/graphics/Camera.cpp @@ -35,7 +35,7 @@ #include "renderer/WaterManager.h" CCamera::CCamera() - : m_NearPlane(0.0f), m_FarPlane(0.0f), m_FOV(0.0f) + : m_NearPlane(0.0f), m_FarPlane(0.0f), m_FOV(0.0f), m_ProjType(CUSTOM) { // Set viewport to something anything should handle, but should be initialised // to window size before use. @@ -47,16 +47,27 @@ CCamera::CCamera() CCamera::~CCamera() = default; +void CCamera::SetProjection(const CMatrix3D& matrix) +{ + m_ProjType = CUSTOM; + m_ProjMat = matrix; +} + void CCamera::SetProjectionFromCamera(const CCamera& camera) { + m_ProjType = camera.m_ProjType; m_NearPlane = camera.m_NearPlane; m_FarPlane = camera.m_FarPlane; - m_FOV = camera.m_FOV; + if (m_ProjType == PERSPECTIVE) + { + m_FOV = camera.m_FOV; + } m_ProjMat = camera.m_ProjMat; } void CCamera::SetPerspectiveProjection(float nearp, float farp, float fov) { + m_ProjType = PERSPECTIVE; m_NearPlane = nearp; m_FarPlane = farp; m_FOV = fov; @@ -64,11 +75,6 @@ void CCamera::SetPerspectiveProjection(float nearp, float farp, float fov) m_ProjMat.SetPerspective(m_FOV, GetAspectRatio(), m_NearPlane, m_FarPlane); } -void CCamera::SetPerspectiveProjectionTile(int tiles, int tile_x, int tile_y) -{ - m_ProjMat.SetPerspectiveTile(m_FOV, GetAspectRatio(), m_NearPlane, m_FarPlane, tiles, tile_x, tile_y); -} - // Updates the frustum planes. Should be called // everytime the view or projection matrices are // altered. @@ -145,6 +151,7 @@ float CCamera::GetAspectRatio() const void CCamera::GetViewQuad(float dist, Quad& quad) const { + ENSURE(m_ProjType == PERSPECTIVE); const float y = dist * tanf(m_FOV * 0.5f); const float x = y * GetAspectRatio(); diff --git a/source/graphics/Camera.h b/source/graphics/Camera.h index fbe31b040f..3d7d6256ed 100644 --- a/source/graphics/Camera.h +++ b/source/graphics/Camera.h @@ -44,16 +44,22 @@ class CCamera // Represents camera viewport or frustum side in 3D space. using Quad = std::array; + enum ProjectionType + { + CUSTOM, + PERSPECTIVE, + }; + CCamera(); ~CCamera(); CMatrix3D& GetProjection() { return m_ProjMat; } const CMatrix3D& GetProjection() const { return m_ProjMat; } CMatrix3D GetViewProjection() const { return m_ProjMat * m_Orientation.GetInverse(); } - void SetProjection(const CMatrix3D& matrix) { m_ProjMat = matrix; } + void SetProjection(const CMatrix3D& matrix); void SetProjectionFromCamera(const CCamera& camera); void SetPerspectiveProjection(float nearp, float farp, float fov); - void SetPerspectiveProjectionTile(int tiles, int tile_x, int tile_y); + ProjectionType GetProjectionType() const { return m_ProjType; } CMatrix3D& GetOrientation() { return m_Orientation; } const CMatrix3D& GetOrientation() const { return m_Orientation; } @@ -113,10 +119,12 @@ class CCamera public: // This is the orientation matrix. The inverse of this // is the view matrix - CMatrix3D m_Orientation; + CMatrix3D m_Orientation; private: - CMatrix3D m_ProjMat; + CMatrix3D m_ProjMat; + ProjectionType m_ProjType; + float m_NearPlane; float m_FarPlane; diff --git a/source/graphics/tests/test_Camera.h b/source/graphics/tests/test_Camera.h index b081f1201f..c042768db7 100644 --- a/source/graphics/tests/test_Camera.h +++ b/source/graphics/tests/test_Camera.h @@ -43,6 +43,7 @@ public: CVector3D(0.0f, 1.0f, 0.0f) ); camera.SetPerspectiveProjection(1.0f, 101.0f, DEGTORAD(90.0f)); + TS_ASSERT_EQUALS(camera.GetProjectionType(), CCamera::PERSPECTIVE); camera.UpdateFrustum(); const float sqrt2 = sqrtf(2.0f) / 2.0f; @@ -75,6 +76,7 @@ public: CMatrix3D projection; projection.SetOrtho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 10.0f); camera.SetProjection(projection); + TS_ASSERT_EQUALS(camera.GetProjectionType(), CCamera::CUSTOM); camera.UpdateFrustum(); const std::vector expectedPlanes = { diff --git a/source/ps/Util.cpp b/source/ps/Util.cpp index 2446e91141..683bd622da 100644 --- a/source/ps/Util.cpp +++ b/source/ps/Util.cpp @@ -342,6 +342,8 @@ void WriteBigScreenshot(const VfsPath& extension, int tiles) ogl_WarnIfError(); + CCamera oldCamera = *g_Game->GetView()->GetCamera(); + // Resize various things so that the sizes and aspect ratios are correct { g_Renderer.Resize(tile_w, tile_h); @@ -366,12 +368,19 @@ void WriteBigScreenshot(const VfsPath& extension, int tiles) g_CursorName = L""; // Render each tile + CMatrix3D projection; + projection.SetIdentity(); + const CCamera& camera = *(g_Game->GetView()->GetCamera()); for (int tile_y = 0; tile_y < tiles; ++tile_y) { for (int tile_x = 0; tile_x < tiles; ++tile_x) { // Adjust the camera to render the appropriate region - g_Game->GetView()->GetCamera()->SetPerspectiveProjectionTile(tiles, tile_x, tile_y); + if (oldCamera.GetProjectionType() == CCamera::PERSPECTIVE) + { + projection.SetPerspectiveTile(oldCamera.GetFOV(), oldCamera.GetAspectRatio(), oldCamera.GetNearPlane(), oldCamera.GetFarPlane(), tiles, tile_x, tile_y); + } + g_Game->GetView()->GetCamera()->SetProjection(projection); RenderLogger(false); RenderGui(false); @@ -404,7 +413,7 @@ void WriteBigScreenshot(const VfsPath& extension, int tiles) g_Renderer.Resize(g_xres, g_yres); SViewPort vp = { 0, 0, g_xres, g_yres }; g_Game->GetView()->SetViewport(vp); - g_Game->GetView()->GetCamera()->SetPerspectiveProjectionTile(1, 0, 0); + g_Game->GetView()->GetCamera()->SetProjectionFromCamera(oldCamera); } if (tex_write(&t, filename) == INFO::OK) diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 18b189ff40..1a1ee11848 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -943,6 +943,7 @@ void CRenderer::ComputeReflectionCamera(CCamera& camera, const CBoundingBoxAlign { WaterManager& wm = m->waterManager; + ENSURE(m_ViewCamera.GetProjectionType() == CCamera::PERSPECTIVE); float fov = m_ViewCamera.GetFOV(); // Expand fov slightly since ripples can reflect parts of the scene that @@ -984,6 +985,7 @@ void CRenderer::ComputeRefractionCamera(CCamera& camera, const CBoundingBoxAlign { WaterManager& wm = m->waterManager; + ENSURE(m_ViewCamera.GetProjectionType() == CCamera::PERSPECTIVE); float fov = m_ViewCamera.GetFOV(); // Expand fov slightly since ripples can reflect parts of the scene that