diff --git a/renderdoc/api/replay/control_types.h b/renderdoc/api/replay/control_types.h index 7d2bc04f4..2836ee2c0 100644 --- a/renderdoc/api/replay/control_types.h +++ b/renderdoc/api/replay/control_types.h @@ -75,6 +75,10 @@ struct MeshDisplay FloatVector prevMeshColour; FloatVector currentMeshColour; + FloatVector minBounds; + FloatVector maxBounds; + bool32 showBBox; + SolidShadeMode solidShadeMode; bool32 wireframeDraw; }; diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 6fed6e234..f5647e7a6 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -214,8 +214,8 @@ extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC RemoteRenderer_CreatePr extern "C" RENDERDOC_API float RENDERDOC_CC Maths_HalfToFloat(uint16_t half); extern "C" RENDERDOC_API uint16_t RENDERDOC_CC Maths_FloatToHalf(float f); -extern "C" RENDERDOC_API void RENDERDOC_CC Maths_CameraArcball(float dist, const FloatVector &rot, FloatVector *pos, FloatVector *fwd, FloatVector *right); -extern "C" RENDERDOC_API void RENDERDOC_CC Maths_CameraFPSLook(const FloatVector &lookpos, const FloatVector &rot, FloatVector *pos, FloatVector *fwd, FloatVector *right); +extern "C" RENDERDOC_API void RENDERDOC_CC Maths_CameraArcball(const FloatVector &lookat, float dist, const FloatVector &rot, FloatVector *pos, FloatVector *fwd, FloatVector *right, FloatVector *up); +extern "C" RENDERDOC_API void RENDERDOC_CC Maths_CameraFPSLook(const FloatVector &lookpos, const FloatVector &rot, FloatVector *pos, FloatVector *fwd, FloatVector *right, FloatVector *up); ////////////////////////////////////////////////////////////////////////// // Create a replay renderer, for playback and analysis. diff --git a/renderdoc/driver/d3d11/d3d11_debug.cpp b/renderdoc/driver/d3d11/d3d11_debug.cpp index f1295219d..3db00a43f 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.cpp +++ b/renderdoc/driver/d3d11/d3d11_debug.cpp @@ -1425,7 +1425,7 @@ bool D3D11DebugManager::InitStreamOut() D3D11_BUFFER_DESC bdesc; bdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; bdesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - bdesc.ByteWidth = sizeof(Vec4f)*16; + bdesc.ByteWidth = sizeof(Vec4f)*24; bdesc.MiscFlags = 0; bdesc.Usage = D3D11_USAGE_DYNAMIC; @@ -4559,7 +4559,7 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, uint32_t eventID, const vec Camera cam; if(cfg.arcballCamera) - cam.Arcball(cfg.cameraPos.x, Vec3f(cfg.cameraRot.x, cfg.cameraRot.y, cfg.cameraRot.z)); + cam.Arcball(Vec3f(cfg.cameraPos.x, cfg.cameraPos.y, cfg.cameraPos.z), cfg.cameraPos.w, Vec3f(cfg.cameraRot.x, cfg.cameraRot.y, cfg.cameraRot.z)); else cam.fpsLook(Vec3f(cfg.cameraPos.x, cfg.cameraPos.y, cfg.cameraPos.z), Vec3f(cfg.cameraRot.x, cfg.cameraRot.y, cfg.cameraRot.z)); @@ -5356,6 +5356,70 @@ void D3D11DebugManager::RenderMesh(uint32_t frameID, uint32_t eventID, const vec m_pImmediateContext->VSSetShader(m_DebugRender.WireframeVS, NULL, 0); } + // bounding box + if(cfg.showBBox) + { + UINT strides[] = { sizeof(Vec4f) }; + UINT offsets[] = { 0 }; + D3D11_MAPPED_SUBRESOURCE mapped; + + vertexData.SpriteSize = Vec2f(); + vertexData.ModelViewProj = projMat.Mul(camMat); + FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); + + HRESULT hr = m_pImmediateContext->Map(m_TriHighlightHelper, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + + Vec4f a = Vec4f(cfg.minBounds.x, cfg.minBounds.y, cfg.minBounds.z, cfg.minBounds.w); + Vec4f b = Vec4f(cfg.maxBounds.x, cfg.maxBounds.y, cfg.maxBounds.z, cfg.maxBounds.w); + + Vec4f TLN = Vec4f(a.x, b.y, a.z, 1.0f); // TopLeftNear, etc... + Vec4f TRN = Vec4f(b.x, b.y, a.z, 1.0f); + Vec4f BLN = Vec4f(a.x, a.y, a.z, 1.0f); + Vec4f BRN = Vec4f(b.x, a.y, a.z, 1.0f); + + Vec4f TLF = Vec4f(a.x, b.y, b.z, 1.0f); + Vec4f TRF = Vec4f(b.x, b.y, b.z, 1.0f); + Vec4f BLF = Vec4f(a.x, a.y, b.z, 1.0f); + Vec4f BRF = Vec4f(b.x, a.y, b.z, 1.0f); + + // 12 frustum lines => 24 verts + Vec4f bbox[24] = + { + TLN, TRN, + TRN, BRN, + BRN, BLN, + BLN, TLN, + + TLN, TLF, + TRN, TRF, + BLN, BLF, + BRN, BRF, + + TLF, TRF, + TRF, BRF, + BRF, BLF, + BLF, TLF, + }; + + memcpy(mapped.pData, bbox, sizeof(bbox)); + + m_pImmediateContext->Unmap(m_TriHighlightHelper, 0); + + // we want this to clip + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.LEqualDepthState, 0); + + m_pImmediateContext->IASetVertexBuffers(0, 1, &m_TriHighlightHelper, (UINT *)&strides, (UINT *)&offsets); + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); + m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericLayout); + + pixelData.WireframeColour = Vec3f(0.2f, 0.2f, 1.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + + m_pImmediateContext->Draw(24, 0); + + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.NoDepthState, 0); + } + // 'fake' helper frustum if(cfg.position.unproject) { diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index 57656130b..18bd184ce 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -490,7 +490,7 @@ void GLReplay::InitDebugData() gl.glGenBuffers(1, &DebugData.triHighlightBuffer); gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.triHighlightBuffer); - gl.glNamedBufferStorageEXT(DebugData.triHighlightBuffer, sizeof(Vec4f)*16, NULL, GL_DYNAMIC_STORAGE_BIT); + gl.glNamedBufferStorageEXT(DebugData.triHighlightBuffer, sizeof(Vec4f)*24, NULL, GL_DYNAMIC_STORAGE_BIT); gl.glVertexAttribPointer(0, 4, eGL_FLOAT, GL_FALSE, sizeof(Vec4f), NULL); gl.glEnableVertexAttribArray(0); @@ -3118,7 +3118,7 @@ void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector 24 verts + Vec4f bbox[24] = + { + TLN, TRN, + TRN, BRN, + BRN, BLN, + BLN, TLN, + + TLN, TLF, + TRN, TRF, + BLN, BLF, + BRN, BRF, + + TLF, TRF, + TRF, BRF, + BRF, BLF, + BLF, TLF, + }; + + gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.triHighlightBuffer); + gl.glBufferSubData(eGL_ARRAY_BUFFER, 0, sizeof(bbox), &bbox[0]); + + gl.glBindVertexArray(DebugData.triHighlightVAO); + + float wireCol[] = { 0.2f, 0.2f, 1.0f, 1.0f }; + gl.glUniform4fv(colLoc, 1, wireCol); + + Matrix4f mvpMat = projMat.Mul(camMat); + + gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, mvpMat.Data()); + + // we want this to clip + gl.glDepthFunc(eGL_LESS); + + gl.glDrawArrays(eGL_LINES, 0, 24); + + gl.glDepthFunc(eGL_ALWAYS); + } + // draw axis helpers if(!cfg.position.unproject) { diff --git a/renderdoc/maths/camera.cpp b/renderdoc/maths/camera.cpp index 57db27b71..fc35babc1 100644 --- a/renderdoc/maths/camera.cpp +++ b/renderdoc/maths/camera.cpp @@ -29,11 +29,12 @@ #include "camera.h" #include "matrix.h" -void Camera::Arcball(float dist, const Vec3f &rot) +void Camera::Arcball(const Vec3f &p, float d, const Vec3f &rot) { - pos = Vec3f(0.0f, 0.0f, dist); + pos = p; + dist = d; - order = ORDER_ROT_TRANS; + type = eType_Arcball; angles.x = rot.x; angles.y = rot.y; @@ -46,18 +47,26 @@ void Camera::fpsLook(const Vec3f &p, const Vec3f &rot) angles.x = -rot.x; angles.y = -rot.y; - order = ORDER_TRANS_ROT; + type = eType_FPSLook; } const Matrix4f Camera::GetMatrix() const { - Matrix4f p = Matrix4f::Translation(pos); - Matrix4f r = Matrix4f::RotationXYZ(angles); + if(type == eType_FPSLook) + { + Matrix4f p = Matrix4f::Translation(pos); + Matrix4f r = Matrix4f::RotationXYZ(angles); - if(order == ORDER_TRANS_ROT) return r.Mul(p); + } + else + { + Matrix4f p = Matrix4f::Translation(-pos); + Matrix4f r = Matrix4f::RotationXYZ(angles); + Matrix4f d = Matrix4f::Translation(Vec3f(0.0f, 0.0f, dist)); - return p.Mul(r); + return d.Mul(r.Mul(p)); + } } const Vec3f Camera::GetPosition() const @@ -74,3 +83,8 @@ const Vec3f Camera::GetRight() const { return Matrix4f::RotationZYX(-angles).GetRight(); } + +const Vec3f Camera::GetUp() const +{ + return Matrix4f::RotationZYX(-angles).GetUp(); +} diff --git a/renderdoc/maths/camera.h b/renderdoc/maths/camera.h index c139eb1a9..031937526 100644 --- a/renderdoc/maths/camera.h +++ b/renderdoc/maths/camera.h @@ -33,10 +33,10 @@ class Camera { public: Camera() - : order(ORDER_TRANS_ROT), pos(), angles() + : type(eType_FPSLook), pos(), dist(0.0f), angles() { } - void Arcball(float dist, const Vec3f &rot); + void Arcball(const Vec3f &pos, float dist, const Vec3f &rot); void fpsLook(const Vec3f &pos, const Vec3f &rot); void SetPosition(const Vec3f &p) { pos = p; } @@ -49,12 +49,13 @@ class Camera const Matrix4f GetMatrix() const; private: - enum OperationOrder + enum CameraType { - ORDER_ROT_TRANS = 0, - ORDER_TRANS_ROT, - } order; + eType_Arcball = 0, + eType_FPSLook, + } type; Vec3f pos; + float dist; Vec3f angles; }; diff --git a/renderdoc/replay/entry_points.cpp b/renderdoc/replay/entry_points.cpp index 0a3f969bc..e32f8c0b9 100644 --- a/renderdoc/replay/entry_points.cpp +++ b/renderdoc/replay/entry_points.cpp @@ -41,14 +41,15 @@ extern "C" RENDERDOC_API uint16_t RENDERDOC_CC Maths_FloatToHalf(float f) return ConvertToHalf(f); } -extern "C" RENDERDOC_API void RENDERDOC_CC Maths_CameraArcball(float dist, const FloatVector &rot, FloatVector *pos, FloatVector *fwd, FloatVector *right) +extern "C" RENDERDOC_API void RENDERDOC_CC Maths_CameraArcball(const FloatVector &lookat, float dist, const FloatVector &rot, FloatVector *pos, FloatVector *fwd, FloatVector *right, FloatVector *up) { Camera c; - c.Arcball(dist, Vec3f(rot.x, rot.y, rot.z)); + c.Arcball(Vec3f(lookat.x, lookat.y, lookat.z), dist, Vec3f(rot.x, rot.y, rot.z)); Vec3f p = c.GetPosition(); Vec3f f = c.GetForward(); Vec3f r = c.GetRight(); + Vec3f u = c.GetUp(); pos->x = p.x; pos->y = p.y; @@ -61,9 +62,13 @@ extern "C" RENDERDOC_API void RENDERDOC_CC Maths_CameraArcball(float dist, const 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 void RENDERDOC_CC Maths_CameraFPSLook(const FloatVector &lookpos, const FloatVector &rot, FloatVector *pos, FloatVector *fwd, FloatVector *right) +extern "C" RENDERDOC_API void RENDERDOC_CC Maths_CameraFPSLook(const FloatVector &lookpos, const FloatVector &rot, FloatVector *pos, FloatVector *fwd, FloatVector *right, FloatVector *up) { Camera c; c.fpsLook(Vec3f(lookpos.x, lookpos.y, lookpos.z), Vec3f(rot.x, rot.y, rot.z)); @@ -71,6 +76,7 @@ extern "C" RENDERDOC_API void RENDERDOC_CC Maths_CameraFPSLook(const FloatVector Vec3f p = c.GetPosition(); Vec3f f = c.GetForward(); Vec3f r = c.GetRight(); + Vec3f u = c.GetUp(); pos->x = p.x; pos->y = p.y; @@ -83,6 +89,10 @@ extern "C" RENDERDOC_API void RENDERDOC_CC Maths_CameraFPSLook(const FloatVector 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 diff --git a/renderdocui/Code/Cameras.cs b/renderdocui/Code/Cameras.cs index 35e89a125..bd4c3bbc1 100644 --- a/renderdocui/Code/Cameras.cs +++ b/renderdocui/Code/Cameras.cs @@ -91,15 +91,16 @@ namespace renderdocui.Code virtual public void MouseClick(object sender, MouseEventArgs e) { - if (e.Button == MouseButtons.Left) - { - m_DragStartPos = e.Location; - } + m_DragStartPos = e.Location; } virtual public void MouseMove(object sender, MouseEventArgs e) { - if (e.Button == MouseButtons.Left) + if (e.Button == MouseButtons.None) + { + m_DragStartPos = new Point(-1, -1); + } + else { if (m_DragStartPos.X < 0) { @@ -108,10 +109,6 @@ namespace renderdocui.Code m_DragStartPos = e.Location; } - else - { - m_DragStartPos = new Point(-1, -1); - } } virtual public void KeyUp(object sender, KeyEventArgs e) @@ -177,20 +174,25 @@ namespace renderdocui.Code m_Rotation = new Vec3f(); } + public void SetDistance(float dist) + { + m_Distance = Math.Abs(dist); + } + public override void Update() { } public override void Apply() { - m_Camera.Arcball(m_Distance, Rotation); + m_Camera.Arcball(LookAtPos, m_Distance, Rotation); } public override void MouseWheel(object sender, MouseEventArgs e) { float mod = (1.0f - (float)e.Delta / 2500.0f); - m_Distance = Math.Max(1.0f, m_Distance * mod); + m_Distance = Math.Max(1e-6f, m_Distance * mod); ((HandledMouseEventArgs)e).Handled = true; @@ -199,12 +201,35 @@ namespace renderdocui.Code public override void MouseMove(object sender, MouseEventArgs e) { - if (DragStartPos.X > 0 && e.Button == MouseButtons.Left) + if (DragStartPos.X > 0) { - m_Rotation.y += (float)(e.X - DragStartPos.X) / 300.0f; - m_Rotation.x += (float)(e.Y - DragStartPos.Y) / 300.0f; + if (e.Button == MouseButtons.Middle || + (e.Button == MouseButtons.Left && (Control.ModifierKeys & Keys.Alt) == Keys.Alt) + ) + { + float xdelta = (float)(e.X - DragStartPos.X) / 300.0f; + float ydelta = (float)(e.Y - DragStartPos.Y) / 300.0f; - m_Dirty = true; + xdelta *= Math.Max(1.0f, m_Distance); + ydelta *= Math.Max(1.0f, m_Distance); + + LookAtPos.x -= m_Camera.Right.x * xdelta; + LookAtPos.y -= m_Camera.Right.y * xdelta; + LookAtPos.z -= m_Camera.Right.z * xdelta; + + LookAtPos.x += m_Camera.Up.x * ydelta; + LookAtPos.y += m_Camera.Up.y * ydelta; + LookAtPos.z += m_Camera.Up.z * ydelta; + + m_Dirty = true; + } + else if (e.Button == MouseButtons.Left) + { + m_Rotation.y += (float)(e.X - DragStartPos.X) / 300.0f; + m_Rotation.x += (float)(e.Y - DragStartPos.Y) / 300.0f; + + m_Dirty = true; + } } base.MouseMove(sender, e); @@ -223,6 +248,9 @@ namespace renderdocui.Code private float m_Distance = 10.0f; private Vec3f m_Rotation = new Vec3f(); + + public Vec3f LookAtPos = new Vec3f(); + public override Vec3f Position { get { return m_Camera.Position; } } public override Vec3f Rotation { get { return m_Rotation; } } } diff --git a/renderdocui/Interop/Camera.cs b/renderdocui/Interop/Camera.cs index 5c6071cbb..381455d0f 100644 --- a/renderdocui/Interop/Camera.cs +++ b/renderdocui/Interop/Camera.cs @@ -31,40 +31,44 @@ namespace renderdoc public class Camera { [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - private static extern void Maths_CameraArcball(float dist, ref FloatVector rot, IntPtr pos, IntPtr fwd, IntPtr right); + private static extern void Maths_CameraArcball(ref FloatVector lookat, float dist, ref FloatVector rot, IntPtr pos, IntPtr fwd, IntPtr right, IntPtr up); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - private static extern void Maths_CameraFPSLook(ref FloatVector lookpos, ref FloatVector rot, IntPtr pos, IntPtr fwd, IntPtr right); + private static extern void Maths_CameraFPSLook(ref FloatVector lookpos, ref FloatVector rot, IntPtr pos, IntPtr fwd, IntPtr right, IntPtr up); - public void Arcball(float dist, Vec3f rot) + public void Arcball(Vec3f pos, float dist, Vec3f rot) { IntPtr p = CustomMarshal.Alloc(typeof(FloatVector)); IntPtr f = CustomMarshal.Alloc(typeof(FloatVector)); IntPtr r = CustomMarshal.Alloc(typeof(FloatVector)); + IntPtr u = CustomMarshal.Alloc(typeof(FloatVector)); isarc = true; - parampos.x = dist; - parampos.y = 0.0f; - parampos.z = 0.0f; + paramdist = dist; + parampos = pos; paramrot = new Vec3f(rot); var rt = new FloatVector(rot); + var ps = new FloatVector(pos); - Maths_CameraArcball(dist, ref rt, p, f, r); + Maths_CameraArcball(ref ps, dist, ref rt, p, f, r, u); pos = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(p, typeof(FloatVector), false)); fwd = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(f, typeof(FloatVector), false)); right = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(r, typeof(FloatVector), false)); + up = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(u, typeof(FloatVector), false)); CustomMarshal.Free(p); CustomMarshal.Free(f); CustomMarshal.Free(r); + CustomMarshal.Free(u); } public void fpsLook(Vec3f lookpos, Vec3f lookrot) { IntPtr p = CustomMarshal.Alloc(typeof(FloatVector)); IntPtr f = CustomMarshal.Alloc(typeof(FloatVector)); IntPtr r = CustomMarshal.Alloc(typeof(FloatVector)); + IntPtr u = CustomMarshal.Alloc(typeof(FloatVector)); isarc = false; parampos = new Vec3f(lookpos); @@ -73,31 +77,37 @@ namespace renderdoc var ps = new FloatVector(lookpos); var rt = new FloatVector(lookrot); - Maths_CameraFPSLook(ref ps, ref rt, p, f, r); + Maths_CameraFPSLook(ref ps, ref rt, p, f, r, u); pos = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(p, typeof(FloatVector), false)); fwd = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(f, typeof(FloatVector), false)); right = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(r, typeof(FloatVector), false)); + up = new Vec3f((FloatVector)CustomMarshal.PtrToStructure(u, typeof(FloatVector), false)); CustomMarshal.Free(p); CustomMarshal.Free(f); CustomMarshal.Free(r); + CustomMarshal.Free(u); } private Vec3f pos = new Vec3f(0.0f, 0.0f, 0.0f); private Vec3f fwd = new Vec3f(0.0f, 0.0f, 1.0f); private Vec3f right = new Vec3f(1.0f, 0.0f, 0.0f); + private Vec3f up = new Vec3f(0.0f, 1.0f, 0.0f); public Vec3f Position { get { return pos; } } public Vec3f Forward { get { return fwd; } } public Vec3f Right { get { return right; } } + public Vec3f Up { get { return up; } } private bool isarc = false; private Vec3f parampos = new Vec3f(0.0f, 0.0f, 0.0f); + private float paramdist = 0.0f; private Vec3f paramrot = new Vec3f(0.0f, 0.0f, 0.0f); public bool IsArcball { get { return isarc; } } public Vec3f PositionParam { get { return parampos; } } + public float DistanceParam { get { return paramdist; } } public Vec3f RotationParam { get { return paramrot; } } } } diff --git a/renderdocui/Interop/FetchInfo.cs b/renderdocui/Interop/FetchInfo.cs index 1ce121afe..3fe9a896d 100644 --- a/renderdocui/Interop/FetchInfo.cs +++ b/renderdocui/Interop/FetchInfo.cs @@ -67,6 +67,7 @@ namespace renderdoc public FloatVector(float X, float Y, float Z, float W) { x = X; y = Y; z = Z; w = W; } public FloatVector(float X, float Y, float Z) { x = X; y = Y; z = Z; w = 1; } public FloatVector(Vec3f v) { x = v.x; y = v.y; z = v.z; w = 1; } + public FloatVector(Vec3f v, float W) { x = v.x; y = v.y; z = v.z; w = W; } public float x, y, z, w; }; @@ -405,6 +406,10 @@ namespace renderdoc public FloatVector prevMeshColour = new FloatVector(); public FloatVector currentMeshColour = new FloatVector(); + public FloatVector minBounds = new FloatVector(); + public FloatVector maxBounds = new FloatVector(); + public bool showBBox = false; + public SolidShadeMode solidShadeMode = SolidShadeMode.None; public bool wireframeDraw = true; }; diff --git a/renderdocui/Windows/BufferViewer.cs b/renderdocui/Windows/BufferViewer.cs index 8623a829a..1dc4e391f 100644 --- a/renderdocui/Windows/BufferViewer.cs +++ b/renderdocui/Windows/BufferViewer.cs @@ -123,8 +123,8 @@ namespace renderdocui.Windows public Thread m_DataParseThread = null; private Object m_ThreadLock = new Object(); - public Vec3f m_MinBounds = new Vec3f(float.MaxValue, float.MaxValue, float.MaxValue); - public Vec3f m_MaxBounds = new Vec3f(-float.MaxValue, -float.MaxValue, -float.MaxValue); + public Vec3f[] m_MinBounds = null; + public Vec3f[] m_MaxBounds = null; public void AbortThread() { @@ -1321,8 +1321,8 @@ namespace renderdocui.Windows state.m_Stream = new Stream[d.Length]; state.m_Reader = new BinaryReader[d.Length]; - state.m_MinBounds = new Vec3f(-1.0f, -1.0f, -1.0f); - state.m_MaxBounds = new Vec3f(1.0f, 1.0f, 1.0f); + state.m_MinBounds = null; + state.m_MaxBounds = null; var bufferFormats = input.BufferFormats; @@ -1387,8 +1387,14 @@ namespace renderdocui.Windows var bufferFormats = input.BufferFormats; var generics = input.GenericValues; - Vec3f minBounds = new Vec3f(float.MaxValue, float.MaxValue, float.MaxValue); - Vec3f maxBounds = new Vec3f(-float.MaxValue, -float.MaxValue, -float.MaxValue); + Vec3f[] minBounds = new Vec3f[bufferFormats.Length]; + Vec3f[] maxBounds = new Vec3f[bufferFormats.Length]; + + for (int el = 0; el < bufferFormats.Length; el++) + { + minBounds[el] = new Vec3f(float.MaxValue, float.MaxValue, float.MaxValue); + maxBounds[el] = new Vec3f(-float.MaxValue, -float.MaxValue, -float.MaxValue); + } while (!finished) { @@ -1483,7 +1489,7 @@ namespace renderdocui.Windows if (bytes.Length != bytesToRead) continue; - if (elname == "POSITION" || bufferFormats[el].systemValue == SystemAttribute.Position) + // update min/max for this element { for (int i = 0; i < fmt.compCount; i++) { @@ -1510,18 +1516,18 @@ namespace renderdocui.Windows if (i == 0) { - minBounds.x = Math.Min(minBounds.x, val); - maxBounds.x = Math.Max(maxBounds.x, val); + minBounds[el].x = Math.Min(minBounds[el].x, val); + maxBounds[el].x = Math.Max(maxBounds[el].x, val); } else if (i == 1) { - minBounds.y = Math.Min(minBounds.y, val); - maxBounds.y = Math.Max(maxBounds.y, val); + minBounds[el].y = Math.Min(minBounds[el].y, val); + maxBounds[el].y = Math.Max(maxBounds[el].y, val); } else if (i == 2) { - minBounds.z = Math.Min(minBounds.z, val); - maxBounds.z = Math.Max(maxBounds.z, val); + minBounds[el].z = Math.Min(minBounds[el].z, val); + maxBounds[el].z = Math.Max(maxBounds[el].z, val); } } } @@ -1544,6 +1550,8 @@ namespace renderdocui.Windows state.m_MinBounds = minBounds; state.m_MaxBounds = maxBounds; + UI_UpdateBoundingBox(); + UI_ShowRows(state, horizScroll); })); })); @@ -1940,6 +1948,8 @@ namespace renderdocui.Windows m_CurrentCamera = m_Flycam; } + UI_UpdateBoundingBox(); + m_CurrentCamera.Apply(); render.Invalidate(); } @@ -1953,14 +1963,20 @@ namespace renderdocui.Windows var state = GetUIState(m_MeshDisplay.type); - Vec3f diag = state.m_MaxBounds.Sub(state.m_MinBounds); - - if(diag.x < 0.0f || diag.y < 0.0f || diag.z < 0.0f || diag.Length() <= 0.00001f) + if (state.m_MinBounds == null || state.m_MaxBounds == null) return; - Vec3f middle = new Vec3f(state.m_MinBounds.x + diag.x / 2.0f, - state.m_MinBounds.y + diag.y / 2.0f, - state.m_MinBounds.z + diag.z / 2.0f); + if (CurPosElement < 0 || CurPosElement >= state.m_MinBounds.Length || CurPosElement >= state.m_MaxBounds.Length) + return; + + Vec3f diag = state.m_MaxBounds[CurPosElement].Sub(state.m_MinBounds[CurPosElement]); + + if (diag.x < 0.0f || diag.y < 0.0f || diag.z < 0.0f || diag.Length() <= 1e-6f) + return; + + Vec3f middle = new Vec3f(state.m_MinBounds[CurPosElement].x + diag.x / 2.0f, + state.m_MinBounds[CurPosElement].y + diag.y / 2.0f, + state.m_MinBounds[CurPosElement].z + diag.z / 2.0f); Vec3f pos = new Vec3f(middle); @@ -1970,6 +1986,8 @@ namespace renderdocui.Windows camSpeed.Value = Helpers.Clamp((decimal)(diag.Length() / 200.0f), camSpeed.Minimum, camSpeed.Maximum); + UI_UpdateBoundingBox(); + m_CurrentCamera.Apply(); render.Invalidate(); } @@ -2060,7 +2078,7 @@ namespace renderdocui.Windows if (m_Output == null) return; m_MeshDisplay.arcballCamera = m_Camera.IsArcball; - m_MeshDisplay.cameraPos = new FloatVector(m_Camera.PositionParam); + m_MeshDisplay.cameraPos = new FloatVector(m_Camera.PositionParam, m_Camera.DistanceParam); m_MeshDisplay.cameraRot = new FloatVector(m_Camera.RotationParam); m_Output.SetMeshDisplay(m_MeshDisplay); @@ -2331,6 +2349,36 @@ namespace renderdocui.Windows } } + private void UI_UpdateBoundingBox() + { + var ui = GetUIState(m_MeshDisplay.type); + + m_MeshDisplay.showBBox = false; + if (ui.m_Stage == MeshDataStage.VSIn && + CurPosElement >= 0 && + ui.m_MinBounds != null && CurPosElement < ui.m_MinBounds.Length && + ui.m_MaxBounds != null && CurPosElement < ui.m_MaxBounds.Length) + { + m_MeshDisplay.showBBox = true; + + m_MeshDisplay.minBounds = new FloatVector(ui.m_MinBounds[CurPosElement]); + m_MeshDisplay.maxBounds = new FloatVector(ui.m_MaxBounds[CurPosElement]); + + Vec3f diag = ui.m_MaxBounds[CurPosElement].Sub(ui.m_MinBounds[CurPosElement]); + + if (diag.x < 0.0f || diag.y < 0.0f || diag.z < 0.0f || diag.Length() <= 1e-6f) + return; + + m_Arcball.LookAtPos = new Vec3f(ui.m_MinBounds[CurPosElement].x + diag.x / 2.0f, + ui.m_MinBounds[CurPosElement].y + diag.y / 2.0f, + ui.m_MinBounds[CurPosElement].z + diag.z / 2.0f); + m_Arcball.SetDistance(diag.Length()*0.7f); + + m_CurrentCamera.Apply(); + render.Invalidate(); + } + } + private void UI_UpdateMeshRenderComponents() { var ui = GetUIState(m_MeshDisplay.type); @@ -2434,6 +2482,8 @@ namespace renderdocui.Windows } } + UI_UpdateBoundingBox(); + if (ui.m_Input == null || ui.m_Input.BufferFormats == null || CurSecondElement == -1 || CurSecondElement >= ui.m_Input.BufferFormats.Length) {