Implement multi-instance mesh picking

This commit is contained in:
Steve Legg
2017-01-20 16:12:48 +00:00
committed by Baldur Karlsson
parent a41c35b764
commit 87adee1bf1
6 changed files with 65 additions and 13 deletions
+3 -2
View File
@@ -739,8 +739,9 @@ void BufferViewer::render_clicked(QMouseEvent *e)
if((e->buttons() & Qt::RightButton) && m_Output)
{
m_Ctx->Renderer()->AsyncInvoke([this, curpos](IReplayRenderer *r) {
uint32_t vertSelected =
m_Output->PickVertex(m_Ctx->CurEvent(), (uint32_t)curpos.x(), (uint32_t)curpos.y());
uint32_t instanceSelected = 0;
uint32_t vertSelected = m_Output->PickVertex(m_Ctx->CurEvent(), (uint32_t)curpos.x(),
(uint32_t)curpos.y(), &instanceSelected);
if(vertSelected != ~0U)
{
+3 -2
View File
@@ -170,7 +170,7 @@ struct IReplayOutput
virtual ResourceId GetCustomShaderTexID() = 0;
virtual bool PickPixel(ResourceId texID, bool customShader, uint32_t x, uint32_t y,
uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val) = 0;
virtual uint32_t PickVertex(uint32_t eventID, uint32_t x, uint32_t y) = 0;
virtual uint32_t PickVertex(uint32_t eventID, uint32_t x, uint32_t y, uint32_t *pickedInstance) = 0;
};
#endif
@@ -224,7 +224,8 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_PickPixel(
uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val);
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC ReplayOutput_PickVertex(ReplayOutput *output,
uint32_t eventID, uint32_t x,
uint32_t y);
uint32_t y,
uint32_t *pickedInstance);
// for C++ expose the interface as a virtual interface
#ifdef __cplusplus
+37 -4
View File
@@ -421,7 +421,7 @@ bool ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint
return true;
}
uint32_t ReplayOutput::PickVertex(uint32_t eventID, uint32_t x, uint32_t y)
uint32_t ReplayOutput::PickVertex(uint32_t eventID, uint32_t x, uint32_t y, uint32_t *pickedInstance)
{
FetchDrawcall *draw = m_pRenderer->GetDrawcallByEID(eventID);
@@ -442,7 +442,39 @@ uint32_t ReplayOutput::PickVertex(uint32_t eventID, uint32_t x, uint32_t y)
cfg.second.buf = m_pDevice->GetLiveID(cfg.second.buf);
cfg.second.idxbuf = m_pDevice->GetLiveID(cfg.second.idxbuf);
return m_pDevice->PickVertex(m_EventID, cfg, x, y);
*pickedInstance = 0;
if(draw->flags & eDraw_Instanced)
{
uint32_t maxInst = 0;
if(m_RenderData.meshDisplay.showPrevInstances)
maxInst = RDCMAX(1U, m_RenderData.meshDisplay.curInstance);
if(m_RenderData.meshDisplay.showAllInstances)
maxInst = RDCMAX(1U, draw->numInstances);
for(uint32_t inst = 0; inst < maxInst; inst++)
{
// get the 'most final' stage
MeshFormat fmt = m_pDevice->GetPostVSBuffers(draw->eventID, inst, eMeshDataStage_GSOut);
if(fmt.buf == ResourceId())
fmt = m_pDevice->GetPostVSBuffers(draw->eventID, inst, eMeshDataStage_VSOut);
cfg.position = fmt;
uint32_t ret = m_pDevice->PickVertex(m_EventID, cfg, x, y);
if(ret != ~0U)
{
*pickedInstance = inst;
return ret;
}
}
return ~0U;
}
else
{
return m_pDevice->PickVertex(m_EventID, cfg, x, y);
}
}
bool ReplayOutput::SetPixelContextLocation(uint32_t x, uint32_t y)
@@ -898,7 +930,8 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_PickPixel(
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC ReplayOutput_PickVertex(ReplayOutput *output,
uint32_t eventID, uint32_t x,
uint32_t y)
uint32_t y,
uint32_t *pickedInstance)
{
return output->PickVertex(eventID, x, y);
return output->PickVertex(eventID, x, y, pickedInstance);
}
+1 -1
View File
@@ -60,7 +60,7 @@ public:
ResourceId GetCustomShaderTexID() { return m_CustomShaderResourceId; }
bool PickPixel(ResourceId texID, bool customShader, uint32_t x, uint32_t y, uint32_t sliceFace,
uint32_t mip, uint32_t sample, PixelValue *val);
uint32_t PickVertex(uint32_t eventID, uint32_t x, uint32_t y);
uint32_t PickVertex(uint32_t eventID, uint32_t x, uint32_t y, uint32_t *pickedInstance);
private:
ReplayOutput(ReplayRenderer *parent, WindowingSystem system, void *data, OutputType type);
+10 -3
View File
@@ -152,7 +152,7 @@ namespace renderdoc
private static extern bool ReplayOutput_PickPixel(IntPtr real, ResourceId texID, bool customShader,
UInt32 x, UInt32 y, UInt32 sliceFace, UInt32 mip, UInt32 sample, IntPtr outval);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern UInt32 ReplayOutput_PickVertex(IntPtr real, UInt32 eventID, UInt32 x, UInt32 y);
private static extern UInt32 ReplayOutput_PickVertex(IntPtr real, UInt32 eventID, UInt32 x, UInt32 y, IntPtr outPickedInstance);
private IntPtr m_Real = IntPtr.Zero;
@@ -269,9 +269,16 @@ namespace renderdoc
return ret;
}
public UInt32 PickVertex(UInt32 eventID, UInt32 x, UInt32 y)
public UInt32 PickVertex(UInt32 eventID, UInt32 x, UInt32 y, out UInt32 pickedInstance)
{
return ReplayOutput_PickVertex(m_Real, eventID, x, y);
IntPtr mem = CustomMarshal.Alloc(typeof(UInt32));
UInt32 pickedVertex = ReplayOutput_PickVertex(m_Real, eventID, x, y, mem);
pickedInstance = (UInt32)CustomMarshal.PtrToStructure(mem, typeof(UInt32), true);
CustomMarshal.Free(mem);
return pickedVertex;
}
};
+11 -1
View File
@@ -2379,12 +2379,21 @@ namespace renderdocui.Windows
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
{
UInt32 vertSelected = m_Output.PickVertex(m_Core.CurEvent, (UInt32)p.X, (UInt32)p.Y);
UInt32 instanceSelected = 0;
UInt32 vertSelected = m_Output.PickVertex(m_Core.CurEvent, (UInt32)p.X, (UInt32)p.Y, out instanceSelected);
if (vertSelected != UInt32.MaxValue)
{
this.BeginInvoke(new Action(() =>
{
if (instanceSelected != m_MeshDisplay.curInstance)
{
m_MeshDisplay.curInstance = instanceSelected;
instanceIdx.Text = instanceSelected.ToString();
instanceIdxToolitem.Text = instanceIdx.Text;
OnEventSelected(m_Core.CurEvent);
}
var ui = GetUIState(m_MeshDisplay.type);
int row = (int)vertSelected;
@@ -2401,6 +2410,7 @@ namespace renderdocui.Windows
SyncViews(ui.m_GridView, true, true);
}
}));
}
});