diff --git a/qrenderdoc/Windows/BufferViewer.cpp b/qrenderdoc/Windows/BufferViewer.cpp index 085c73007..4c1cecdac 100644 --- a/qrenderdoc/Windows/BufferViewer.cpp +++ b/qrenderdoc/Windows/BufferViewer.cpp @@ -39,7 +39,7 @@ class CameraWrapper public: virtual ~CameraWrapper() {} virtual bool Update(QRect winSize) = 0; - virtual Camera *camera() = 0; + virtual ICamera *camera() = 0; virtual void MouseWheel(QWheelEvent *e) = 0; @@ -122,12 +122,12 @@ private: class ArcballWrapper : public CameraWrapper { public: - ArcballWrapper() { m_Cam = Camera_InitArcball(); } - virtual ~ArcballWrapper() { Camera_Shutdown(m_Cam); } - Camera *camera() override { return m_Cam; } + ArcballWrapper() { m_Cam = RENDERDOC_InitCamera(CameraType::Arcball); } + virtual ~ArcballWrapper() { m_Cam->Shutdown(); } + ICamera *camera() override { return m_Cam; } void Reset(FloatVector pos, float dist) { - Camera_ResetArcball(m_Cam); + m_Cam->ResetArcball(); setLookAtPos(pos); SetDistance(dist); @@ -136,7 +136,7 @@ public: void SetDistance(float dist) { m_Distance = qAbs(dist); - Camera_SetArcballDistance(m_Cam, m_Distance); + m_Cam->SetArcballDistance(m_Distance); } bool Update(QRect size) override @@ -165,8 +165,8 @@ public: xdelta *= qMax(1.0f, m_Distance); ydelta *= qMax(1.0f, m_Distance); - FloatVector pos, fwd, right, up; - Camera_GetBasis(m_Cam, &pos, &fwd, &right, &up); + FloatVector right = m_Cam->GetRight(); + FloatVector up = m_Cam->GetUp(); m_LookAt.x -= right.x * xdelta; m_LookAt.y -= right.y * xdelta; @@ -176,7 +176,7 @@ public: m_LookAt.y += up.y * ydelta; m_LookAt.z += up.z * ydelta; - Camera_SetPosition(m_Cam, m_LookAt.x, m_LookAt.y, m_LookAt.z); + m_Cam->SetPosition(m_LookAt.x, m_LookAt.y, m_LookAt.z); } else if(e->buttons() == Qt::LeftButton) { @@ -191,11 +191,11 @@ public: void setLookAtPos(const FloatVector &v) { m_LookAt = v; - Camera_SetPosition(m_Cam, v.x, v.y, v.z); + m_Cam->SetPosition(v.x, v.y, v.z); } private: - Camera *m_Cam; + ICamera *m_Cam; QRect m_WinSize; @@ -222,29 +222,29 @@ private: ay = -ay; by = -by; - Camera_RotateArcball(m_Cam, ax, ay, bx, by); + m_Cam->RotateArcball(ax, ay, bx, by); } }; class FlycamWrapper : public CameraWrapper { public: - FlycamWrapper() { m_Cam = Camera_InitFPSLook(); } - virtual ~FlycamWrapper() { Camera_Shutdown(m_Cam); } - Camera *camera() override { return m_Cam; } + FlycamWrapper() { m_Cam = RENDERDOC_InitCamera(CameraType::FPSLook); } + virtual ~FlycamWrapper() { m_Cam->Shutdown(); } + ICamera *camera() override { return m_Cam; } void Reset(FloatVector pos) { m_Position = pos; m_Rotation = FloatVector(); - Camera_SetPosition(m_Cam, m_Position.x, m_Position.y, m_Position.z); - Camera_SetFPSRotation(m_Cam, m_Rotation.x, m_Rotation.y, m_Rotation.z); + m_Cam->SetPosition(m_Position.x, m_Position.y, m_Position.z); + m_Cam->SetFPSRotation(m_Rotation.x, m_Rotation.y, m_Rotation.z); } bool Update(QRect size) override { - FloatVector pos, fwd, right, up; - Camera_GetBasis(m_Cam, &pos, &fwd, &right, &up); + FloatVector fwd = m_Cam->GetForward(); + FloatVector right = m_Cam->GetRight(); float speed = currentSpeed(); @@ -277,7 +277,7 @@ public: if(horizMove || vertMove || fwdMove) { - Camera_SetPosition(m_Cam, m_Position.x, m_Position.y, m_Position.z); + m_Cam->SetPosition(m_Position.x, m_Position.y, m_Position.z); return true; } @@ -292,14 +292,14 @@ public: m_Rotation.y -= (float)(e->pos().x() - dragStartPos().x()) / 300.0f; m_Rotation.x -= (float)(e->pos().y() - dragStartPos().y()) / 300.0f; - Camera_SetFPSRotation(m_Cam, m_Rotation.x, m_Rotation.y, m_Rotation.z); + m_Cam->SetFPSRotation(m_Rotation.x, m_Rotation.y, m_Rotation.z); } CameraWrapper::MouseMove(e); } private: - Camera *m_Cam; + ICamera *m_Cam; FloatVector m_Position, m_Rotation; }; diff --git a/renderdoc/api/replay/control_types.h b/renderdoc/api/replay/control_types.h index 7f04fc8ed..3c2bfb007 100644 --- a/renderdoc/api/replay/control_types.h +++ b/renderdoc/api/replay/control_types.h @@ -104,7 +104,7 @@ struct MeshFormat DECLARE_REFLECTION_STRUCT(MeshFormat); -class Camera; +struct ICamera; DOCUMENT(R"( Describes how to render a mesh preview of one or more meshes. Describes the camera configuration as @@ -119,8 +119,8 @@ struct MeshDisplay DOCUMENT("The :class:`MeshDataStage` where this mesh data comes from."); MeshDataStage type; - DOCUMENT("The ``Camera`` to use when rendering all of the meshes."); - Camera *cam; + DOCUMENT("The :class:`Camera` to use when rendering all of the meshes."); + ICamera *cam; DOCUMENT( "``True`` if the projection matrix to use when unprojecting vertex positions is " diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 852e9f74b..fc5d5b18e 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -1075,7 +1075,7 @@ without opening the capture for analysis. )") struct ICaptureFile { - DOCUMENT("Closes the handle."); + DOCUMENT("Closes the file handle."); virtual void Shutdown() = 0; DOCUMENT(R"(Retrieves the status of the handle. @@ -1152,27 +1152,97 @@ protected: // camera ////////////////////////////////////////////////////////////////////////// -class Camera; +DOCUMENT(R"(A handle to a camera controller, used for user interaction and controlling a view of a +3D scene. +)") +struct ICamera +{ + DOCUMENT("Closes the camera handle."); + virtual void Shutdown() = 0; -// TODO expose the actual Camera class. -DOCUMENT(""); -extern "C" RENDERDOC_API Camera *RENDERDOC_CC Camera_InitArcball(); -extern "C" RENDERDOC_API Camera *RENDERDOC_CC Camera_InitFPSLook(); -extern "C" RENDERDOC_API void RENDERDOC_CC Camera_Shutdown(Camera *c); + DOCUMENT(R"(Sets the position for the camera, either arcball or FPS. -extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetPosition(Camera *c, float x, float y, float z); +For arcball cameras, this sets the lookat position at the centre of the arcball. -extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetFPSRotation(Camera *c, float x, float y, - float z); +For FPS look cameras, this sets the position of the camera in space. -extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetArcballDistance(Camera *c, float dist); -extern "C" RENDERDOC_API void RENDERDOC_CC Camera_ResetArcball(Camera *c); -extern "C" RENDERDOC_API void RENDERDOC_CC Camera_RotateArcball(Camera *c, float ax, float ay, - float bx, float by); +:param float x: The X co-ordinate of the position. +:param float y: The Y co-ordinate of the position. +:param float z: The Z co-ordinate of the position. +)"); + virtual void SetPosition(float x, float y, float z) = 0; -extern "C" RENDERDOC_API void RENDERDOC_CC Camera_GetBasis(Camera *c, FloatVector *pos, - FloatVector *fwd, FloatVector *right, - FloatVector *up); + DOCUMENT(R"(Sets the rotation for an FPS camera. + +It is invalid to call this function for arcball cameras. + +:param float x: The rotation around the X axis (pitch). +:param float y: The rotation around the Y axis (yaw). +:param float z: The rotation around the Z axis (roll). +)"); + virtual void SetFPSRotation(float x, float y, float z) = 0; + + DOCUMENT(R"(Sets the distance in units the arcball camera sits away from the lookat position. + +:param float dist: The distance of the camera from the lookat position. +)"); + virtual void SetArcballDistance(float dist) = 0; + + DOCUMENT("Reset the arcball to defaults."); + virtual void ResetArcball() = 0; + + DOCUMENT(R"(Rotates the arcball based on relative window co-ordinates. + +The co-ordinates are in pixels and represent the old/new co-ordinates of the mouse cursor over the +drag. + +:param float ax: The X co-ordinate of the previous mouse position. +:param float ay: The Y co-ordinate of the previous mouse position. +:param float bx: The X co-ordinate of the new mouse position. +:param float by: The Y co-ordinate of the new mouse position. +)"); + virtual void RotateArcball(float ax, float ay, float bx, float by) = 0; + + DOCUMENT(R"(Retrieves the position of the camera + +:return: The position vector of the camera. W is set to 1 +:rtype: FloatVector +)"); + virtual FloatVector GetPosition() = 0; + + DOCUMENT(R"(Retrieves the forward vector of the camera, in the positive Z direction. + +:return: The forward vector of the camera. W is set to 1 +:rtype: FloatVector +)"); + virtual FloatVector GetForward() = 0; + + DOCUMENT(R"(Retrieves the right vector of the camera, in the positive X direction. + +:return: The right vector of the camera. W is set to 1 +:rtype: FloatVector +)"); + virtual FloatVector GetRight() = 0; + + DOCUMENT(R"(Retrieves the up vector of the camera, in the positive Y direction. + +:return: The up vector of the camera. W is set to 1 +:rtype: FloatVector +)"); + virtual FloatVector GetUp() = 0; + +protected: + ICamera() = default; + ~ICamera() = default; +}; + +DOCUMENT(R"(Create a new camera of a given type. + +:param CameraType type: The type of controls to use +:return: The handle to the new camera. +:rtype: Camera +)"); +extern "C" RENDERDOC_API ICamera *RENDERDOC_CC RENDERDOC_InitCamera(CameraType type); ////////////////////////////////////////////////////////////////////////// // Maths/format/misc related exports diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index f7c7d4da4..480132044 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -2994,6 +2994,22 @@ enum class CounterUnit : uint32_t Cycles, }; +DOCUMENT(R"(The type of camera controls for an :class:`Camera`. + +.. data:: Arcball + + Arcball controls that rotate and zoom around the origin point. + +.. data:: FPSLook + + Traditional FPS style controls with movement in each axis relative to the current look direction. +)"); +enum class CameraType : uint32_t +{ + Arcball = 0, + FPSLook, +}; + DOCUMENT(R"(How supported a given API is on a particular replay instance. .. data:: Unsupported diff --git a/renderdoc/driver/d3d11/d3d11_analyse.cpp b/renderdoc/driver/d3d11/d3d11_analyse.cpp index 749c0e942..20b7d8fc2 100644 --- a/renderdoc/driver/d3d11/d3d11_analyse.cpp +++ b/renderdoc/driver/d3d11/d3d11_analyse.cpp @@ -2355,7 +2355,7 @@ uint32_t D3D11DebugManager::PickVertex(uint32_t eventID, const MeshDisplay &cfg, Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(GetWidth()) / float(GetHeight())); - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + Matrix4f camMat = cfg.cam ? ((Camera *)cfg.cam)->GetMatrix() : Matrix4f::Identity(); Matrix4f pickMVP = projMat.Mul(camMat); diff --git a/renderdoc/driver/d3d11/d3d11_debug.cpp b/renderdoc/driver/d3d11/d3d11_debug.cpp index c22dd8444..11feb53d7 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.cpp +++ b/renderdoc/driver/d3d11/d3d11_debug.cpp @@ -4771,7 +4771,7 @@ void D3D11DebugManager::RenderMesh(uint32_t eventID, const vector &s Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(GetWidth()) / float(GetHeight())); - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + Matrix4f camMat = cfg.cam ? ((Camera *)cfg.cam)->GetMatrix() : Matrix4f::Identity(); Matrix4f guessProjInv; vertexData.ModelViewProj = projMat.Mul(camMat); diff --git a/renderdoc/driver/d3d12/d3d12_debug.cpp b/renderdoc/driver/d3d12/d3d12_debug.cpp index 0375e4ddf..fcd691406 100644 --- a/renderdoc/driver/d3d12/d3d12_debug.cpp +++ b/renderdoc/driver/d3d12/d3d12_debug.cpp @@ -2479,7 +2479,7 @@ uint32_t D3D12DebugManager::PickVertex(uint32_t eventID, const MeshDisplay &cfg, Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(GetWidth()) / float(GetHeight())); - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + Matrix4f camMat = cfg.cam ? ((Camera *)cfg.cam)->GetMatrix() : Matrix4f::Identity(); Matrix4f pickMVP = projMat.Mul(camMat); @@ -5460,7 +5460,7 @@ void D3D12DebugManager::RenderMesh(uint32_t eventID, const vector &s Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, viewport.Width / viewport.Height); Matrix4f InvProj = projMat.Inverse(); - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + Matrix4f camMat = cfg.cam ? ((Camera *)cfg.cam)->GetMatrix() : Matrix4f::Identity(); Matrix4f guessProjInv; diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index d7439b07e..456b790cc 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -1185,7 +1185,7 @@ uint32_t GLReplay::PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, DebugData.outWidth / DebugData.outHeight); - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + Matrix4f camMat = cfg.cam ? ((Camera *)cfg.cam)->GetMatrix() : Matrix4f::Identity(); Matrix4f pickMVP = projMat.Mul(camMat); ResourceFormat resFmt; @@ -4733,7 +4733,7 @@ void GLReplay::RenderMesh(uint32_t eventID, const vector &secondaryD Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, DebugData.outWidth / DebugData.outHeight); - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + Matrix4f camMat = cfg.cam ? ((Camera *)cfg.cam)->GetMatrix() : Matrix4f::Identity(); Matrix4f ModelViewProj = projMat.Mul(camMat); Matrix4f guessProjInv; diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index cb5de2e46..44d197ed3 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -3910,7 +3910,7 @@ uint32_t VulkanDebugManager::PickVertex(uint32_t eventID, const MeshDisplay &cfg Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(w) / float(h)); - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + Matrix4f camMat = cfg.cam ? ((Camera *)cfg.cam)->GetMatrix() : Matrix4f::Identity(); Matrix4f pickMVP = projMat.Mul(camMat); ResourceFormat resFmt; diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 1f5bc58af..6096ff9fd 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1750,7 +1750,7 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector &second Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(m_DebugWidth) / float(m_DebugHeight)); Matrix4f InvProj = projMat.Inverse(); - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + Matrix4f camMat = cfg.cam ? ((Camera *)cfg.cam)->GetMatrix() : Matrix4f::Identity(); Matrix4f ModelViewProj = projMat.Mul(camMat); Matrix4f guessProjInv; diff --git a/renderdoc/maths/camera.cpp b/renderdoc/maths/camera.cpp index 4c484fe80..443cd24e8 100644 --- a/renderdoc/maths/camera.cpp +++ b/renderdoc/maths/camera.cpp @@ -37,10 +37,13 @@ void Camera::ResetArcball() } // https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Arcball -void Camera::RotateArcball(const Vec2f &from, const Vec2f &to) +void Camera::RotateArcball(float ax, float ay, float bx, float by) { Vec3f a, b; + Vec2f from(ax, ay); + Vec2f to(bx, by); + float az = from.x * from.x + from.y * from.y; float bz = to.x * to.x + to.y * to.y; @@ -84,7 +87,7 @@ void Camera::Update() if(!dirty) return; - if(type == eType_FPSLook) + if(type == CameraType::FPSLook) { Matrix4f p = Matrix4f::Translation(-pos); Matrix4f r = Matrix4f::RotationXYZ(-angles); @@ -108,22 +111,25 @@ const Matrix4f Camera::GetMatrix() return mat; } -const Vec3f Camera::GetPosition() +FloatVector Camera::GetPosition() { - return pos; + return FloatVector(pos.x, pos.y, pos.z, 1.0f); } -const Vec3f Camera::GetForward() +FloatVector Camera::GetForward() { - return basis.GetForward(); + Vec3f fwd = basis.GetForward(); + return FloatVector(fwd.x, fwd.y, fwd.z, 1.0f); } -const Vec3f Camera::GetRight() +FloatVector Camera::GetRight() { - return basis.GetRight(); + Vec3f right = basis.GetRight(); + return FloatVector(right.x, right.y, right.z, 1.0f); } -const Vec3f Camera::GetUp() +FloatVector Camera::GetUp() { - return basis.GetUp(); + Vec3f up = basis.GetUp(); + return FloatVector(up.x, up.y, up.z, 1.0f); } diff --git a/renderdoc/maths/camera.h b/renderdoc/maths/camera.h index b4d59c3fd..8ec4dec63 100644 --- a/renderdoc/maths/camera.h +++ b/renderdoc/maths/camera.h @@ -25,25 +25,22 @@ #pragma once +#include "api/replay/renderdoc_replay.h" #include "quat.h" #include "vec.h" class Matrix4f; -class Camera +class Camera : public ICamera { public: - enum CameraType - { - eType_Arcball = 0, - eType_FPSLook, - }; - Camera(CameraType t) : type(t), dirty(true), pos(), dist(0.0f), angles() { ResetArcball(); } - void SetPosition(const Vec3f &p) + virtual ~Camera() {} + void Shutdown() { delete this; } + void SetPosition(float x, float y, float z) { dirty = true; - pos = p; + pos = Vec3f(x, y, z); } // Arcball functions @@ -53,19 +50,19 @@ public: dirty = true; dist = d; } - void RotateArcball(const Vec2f &from, const Vec2f &to); + void RotateArcball(float ax, float ay, float bx, float by); // FPS look functions - void SetFPSRotation(const Vec3f &rot) + void SetFPSRotation(float x, float y, float z) { dirty = true; - angles = rot; + angles = Vec3f(x, y, z); } - const Vec3f GetPosition(); - const Vec3f GetForward(); - const Vec3f GetRight(); - const Vec3f GetUp(); + FloatVector GetPosition(); + FloatVector GetForward(); + FloatVector GetRight(); + FloatVector GetUp(); const Matrix4f GetMatrix(); private: diff --git a/renderdoc/replay/entry_points.cpp b/renderdoc/replay/entry_points.cpp index 7ad63ced2..fa54b5f8d 100644 --- a/renderdoc/replay/entry_points.cpp +++ b/renderdoc/replay/entry_points.cpp @@ -167,27 +167,27 @@ extern "C" RENDERDOC_API uint16_t RENDERDOC_CC RENDERDOC_FloatToHalf(float f) extern "C" RENDERDOC_API Camera *RENDERDOC_CC Camera_InitArcball() { - return new Camera(Camera::eType_Arcball); + return new Camera(CameraType::Arcball); } extern "C" RENDERDOC_API Camera *RENDERDOC_CC Camera_InitFPSLook() { - return new Camera(Camera::eType_FPSLook); + return new Camera(CameraType::FPSLook); } extern "C" RENDERDOC_API void RENDERDOC_CC Camera_Shutdown(Camera *c) { - delete c; + c->Shutdown(); } extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetPosition(Camera *c, float x, float y, float z) { - c->SetPosition(Vec3f(x, y, z)); + c->SetPosition(x, y, z); } extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetFPSRotation(Camera *c, float x, float y, float z) { - c->SetFPSRotation(Vec3f(x, y, z)); + c->SetFPSRotation(x, y, z); } extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetArcballDistance(Camera *c, float dist) @@ -203,33 +203,22 @@ extern "C" RENDERDOC_API void RENDERDOC_CC Camera_ResetArcball(Camera *c) extern "C" RENDERDOC_API void RENDERDOC_CC Camera_RotateArcball(Camera *c, float ax, float ay, float bx, float by) { - c->RotateArcball(Vec2f(ax, ay), Vec2f(bx, by)); + c->RotateArcball(ax, ay, bx, by); } extern "C" RENDERDOC_API void RENDERDOC_CC Camera_GetBasis(Camera *c, FloatVector *pos, FloatVector *fwd, FloatVector *right, FloatVector *up) { - Vec3f p = c->GetPosition(); - Vec3f f = c->GetForward(); - Vec3f r = c->GetRight(); - Vec3f u = c->GetUp(); + *pos = c->GetPosition(); + *fwd = c->GetForward(); + *right = c->GetRight(); + *up = c->GetUp(); +} - pos->x = p.x; - pos->y = p.y; - pos->z = p.z; - - fwd->x = f.x; - fwd->y = f.y; - fwd->z = f.z; - - right->x = r.x; - right->y = r.y; - right->z = r.z; - - up->x = u.x; - up->y = u.y; - up->z = u.z; +extern "C" RENDERDOC_API ICamera *RENDERDOC_CC RENDERDOC_InitCamera(CameraType type) +{ + return new Camera(type); } extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetVersionString()