mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-18 11:45:55 +00:00
added original picking back in as a fallback.
This commit is contained in:
@@ -130,8 +130,9 @@ BINDING(0) uniform FontUBOData
|
||||
}
|
||||
INST_NAME(general);
|
||||
|
||||
#define MESH_TRIANGLE_LIST 0
|
||||
#define MESH_TRIANGLE_STRIP 1
|
||||
#define MESH_OTHER 0 // this covers points and lines, logic is the same
|
||||
#define MESH_TRIANGLE_LIST 1
|
||||
#define MESH_TRIANGLE_STRIP 2
|
||||
BINDING(0) uniform MeshPickUBOData
|
||||
{
|
||||
vec3 rayPos;
|
||||
@@ -140,8 +141,14 @@ BINDING(0) uniform MeshPickUBOData
|
||||
vec3 rayDir;
|
||||
uint numVerts;
|
||||
|
||||
int meshMode;//triangles, triangle strip, fan, etc...
|
||||
vec3 padding;
|
||||
vec2 coords;
|
||||
vec2 viewport;
|
||||
|
||||
uint meshMode; // triangles, triangle strip, fan, etc...
|
||||
uint unproject;
|
||||
vec2 padding;
|
||||
|
||||
mat4 mvp;
|
||||
}
|
||||
INST_NAME(meshpick);
|
||||
|
||||
|
||||
@@ -74,11 +74,9 @@ bool TriangleRayIntersect(vec3 A, vec3 B, vec3 C,
|
||||
return Result;
|
||||
}
|
||||
|
||||
void main()
|
||||
void trianglePath(uint threadID)
|
||||
{
|
||||
uvec3 tid = gl_GlobalInvocationID;
|
||||
|
||||
uint vertid = tid.x;
|
||||
uint vertid = threadID;
|
||||
|
||||
// NOTE(james): when I turn on following early out the shader doesn't do anything.
|
||||
// so I end up with a lot of duplicated work on smaller meshes
|
||||
@@ -92,14 +90,16 @@ void main()
|
||||
uint idx2 = 0;
|
||||
switch (meshpick.meshMode)
|
||||
{
|
||||
case MESH_TRIANGLE_LIST:{
|
||||
case MESH_TRIANGLE_LIST:
|
||||
{
|
||||
vertid *= 3;
|
||||
idx0 = meshpick.use_indices != 0u ? ib.data[vertid ] : vertid;
|
||||
idx1 = meshpick.use_indices != 0u ? ib.data[vertid+1] : vertid+1;
|
||||
idx2 = meshpick.use_indices != 0u ? ib.data[vertid+2] : vertid+2;
|
||||
break;
|
||||
}
|
||||
case MESH_TRIANGLE_STRIP:{
|
||||
case MESH_TRIANGLE_STRIP:
|
||||
{
|
||||
idx0 = meshpick.use_indices != 0u ? ib.data[vertid ] : vertid;
|
||||
idx1 = meshpick.use_indices != 0u ? ib.data[vertid+1] : vertid+1;
|
||||
idx2 = meshpick.use_indices != 0u ? ib.data[vertid+2] : vertid+2;
|
||||
@@ -137,4 +137,52 @@ void main()
|
||||
pickresult.results[result_idx] = uvec4(vertid,
|
||||
floatBitsToUint(hitPosition.x), floatBitsToUint(hitPosition.y), floatBitsToUint(hitPosition.z));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void defaultPath(uint threadID)
|
||||
{
|
||||
uint vertid = threadID;
|
||||
|
||||
if(vertid >= meshpick.numVerts)
|
||||
return;
|
||||
|
||||
uint idx = meshpick.use_indices != 0u ? ib.data[vertid] : vertid;
|
||||
|
||||
vec4 pos = vb.data[idx];
|
||||
|
||||
#ifdef VULKAN
|
||||
if(meshpick.unproject == 1u)
|
||||
pos = vec4(pos.x, -pos.y, pos.z, pos.w);
|
||||
#endif
|
||||
|
||||
vec4 wpos = meshpick.mvp * pos;
|
||||
|
||||
wpos.xyz /= wpos.www;
|
||||
|
||||
wpos.xy *= vec2(1.0f, -1.0f);
|
||||
|
||||
vec2 scr = (wpos.xy + 1.0f) * 0.5f * meshpick.viewport;
|
||||
|
||||
// close to target co-ords? add to list
|
||||
float len = length(scr - meshpick.coords);
|
||||
if(len < 35.0f)
|
||||
{
|
||||
uint result_idx = atomicAdd(pickresult.counter.x, 1u);
|
||||
pickresult.results[result_idx] = uvec4(vertid, idx, floatBitsToUint(len), floatBitsToUint(wpos.z));
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
if (meshpick.meshMode == MESH_TRIANGLE_LIST ||
|
||||
meshpick.meshMode == MESH_TRIANGLE_STRIP)
|
||||
{
|
||||
trianglePath(gl_GlobalInvocationID.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultPath(gl_GlobalInvocationID.x);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1076,25 +1076,35 @@ uint32_t GLReplay::PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t
|
||||
cdata->rayDir = rayDir;
|
||||
cdata->use_indices = cfg.position.idxByteWidth ? 1U : 0U;
|
||||
cdata->numVerts = cfg.position.numVerts;
|
||||
|
||||
bool isTriangleMesh = false;
|
||||
switch(cfg.position.topo)
|
||||
{
|
||||
case eTopology_TriangleList:
|
||||
{
|
||||
cdata->meshMode = MESH_TRIANGLE_LIST;
|
||||
isTriangleMesh = true;
|
||||
break;
|
||||
};
|
||||
case eTopology_TriangleStrip:
|
||||
{
|
||||
cdata->meshMode = MESH_TRIANGLE_STRIP;
|
||||
isTriangleMesh = true;
|
||||
break;
|
||||
};
|
||||
default:
|
||||
{
|
||||
cdata->meshMode = -1;
|
||||
RDCWARN("Mesh type unsupported by picking");
|
||||
cdata->meshMode = MESH_OTHER;
|
||||
RDCWARN("Mesh type defaulting to screenspace point picking");
|
||||
};
|
||||
}
|
||||
|
||||
// line/point data
|
||||
cdata->unproject = cfg.position.unproject;
|
||||
cdata->mvp = PickMVP;
|
||||
cdata->coords = Vec2f((float)x, (float)y);
|
||||
cdata->viewport = Vec2f(DebugData.outWidth, DebugData.outHeight);
|
||||
|
||||
gl.glUnmapBuffer(eGL_UNIFORM_BUFFER);
|
||||
|
||||
GLuint ib = 0;
|
||||
@@ -1213,44 +1223,88 @@ uint32_t GLReplay::PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t
|
||||
|
||||
if(numResults > 0)
|
||||
{
|
||||
struct PickResult
|
||||
if(isTriangleMesh)
|
||||
{
|
||||
uint32_t vertid;
|
||||
vec3 intersectionPoint;
|
||||
};
|
||||
|
||||
byte *mapped = (byte *)gl.glMapNamedBufferEXT(DebugData.pickResultBuf, eGL_READ_ONLY);
|
||||
|
||||
mapped += sizeof(uint32_t) * 4;
|
||||
|
||||
PickResult *pickResults = (PickResult *)mapped;
|
||||
|
||||
PickResult *closest = pickResults;
|
||||
// distance from raycast hit to nearest worldspace position of the mouse
|
||||
float closestPickDistance = (closest->intersectionPoint - rayPos).Length();
|
||||
|
||||
// min with size of results buffer to protect against overflows
|
||||
for(uint32_t i = 1; i < RDCMIN((uint32_t)DebugRenderData::maxMeshPicks, numResults); i++)
|
||||
{
|
||||
// We need to keep the picking order consistent in the face
|
||||
// of random buffer appends, when multiple vertices have the
|
||||
// identical position (e.g. if UVs or normals are different).
|
||||
//
|
||||
// We could do something to try and disambiguate, but it's
|
||||
// never going to be intuitive, it's just going to flicker
|
||||
// confusingly.
|
||||
float pickDistance = (pickResults[i].intersectionPoint - rayPos).Length();
|
||||
if(pickDistance < closestPickDistance)
|
||||
struct PickResult
|
||||
{
|
||||
closest = pickResults + i;
|
||||
uint32_t vertid;
|
||||
vec3 intersectionPoint;
|
||||
};
|
||||
|
||||
byte *mapped = (byte *)gl.glMapNamedBufferEXT(DebugData.pickResultBuf, eGL_READ_ONLY);
|
||||
|
||||
mapped += sizeof(uint32_t) * 4;
|
||||
|
||||
PickResult *pickResults = (PickResult *)mapped;
|
||||
|
||||
PickResult *closest = pickResults;
|
||||
// distance from raycast hit to nearest worldspace position of the mouse
|
||||
float closestPickDistance = (closest->intersectionPoint - rayPos).Length();
|
||||
|
||||
// min with size of results buffer to protect against overflows
|
||||
for(uint32_t i = 1; i < RDCMIN((uint32_t)DebugRenderData::maxMeshPicks, numResults); i++)
|
||||
{
|
||||
// We need to keep the picking order consistent in the face
|
||||
// of random buffer appends, when multiple vertices have the
|
||||
// identical position (e.g. if UVs or normals are different).
|
||||
//
|
||||
// We could do something to try and disambiguate, but it's
|
||||
// never going to be intuitive, it's just going to flicker
|
||||
// confusingly.
|
||||
float pickDistance = (pickResults[i].intersectionPoint - rayPos).Length();
|
||||
if(pickDistance < closestPickDistance)
|
||||
{
|
||||
closest = pickResults + i;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ret = closest->vertid;
|
||||
|
||||
gl.glUnmapNamedBufferEXT(DebugData.pickResultBuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct PickResult
|
||||
{
|
||||
uint32_t vertid;
|
||||
uint32_t idx;
|
||||
float len;
|
||||
float depth;
|
||||
};
|
||||
|
||||
uint32_t ret = closest->vertid;
|
||||
byte *mapped = (byte *)gl.glMapNamedBufferEXT(DebugData.pickResultBuf, eGL_READ_ONLY);
|
||||
|
||||
gl.glUnmapNamedBufferEXT(DebugData.pickResultBuf);
|
||||
mapped += sizeof(uint32_t) * 4;
|
||||
|
||||
return ret;
|
||||
PickResult *pickResults = (PickResult *)mapped;
|
||||
|
||||
PickResult *closest = pickResults;
|
||||
|
||||
// min with size of results buffer to protect against overflows
|
||||
for(uint32_t i = 1; i < RDCMIN((uint32_t)DebugRenderData::maxMeshPicks, numResults); i++)
|
||||
{
|
||||
// We need to keep the picking order consistent in the face
|
||||
// of random buffer appends, when multiple vertices have the
|
||||
// identical position (e.g. if UVs or normals are different).
|
||||
//
|
||||
// We could do something to try and disambiguate, but it's
|
||||
// never going to be intuitive, it's just going to flicker
|
||||
// confusingly.
|
||||
if(pickResults[i].len < closest->len ||
|
||||
(pickResults[i].len == closest->len && pickResults[i].depth < closest->depth) ||
|
||||
(pickResults[i].len == closest->len && pickResults[i].depth == closest->depth &&
|
||||
pickResults[i].vertid < closest->vertid))
|
||||
closest = pickResults + i;
|
||||
}
|
||||
|
||||
uint32_t ret = closest->vertid;
|
||||
|
||||
gl.glUnmapNamedBufferEXT(DebugData.pickResultBuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ~0U;
|
||||
|
||||
Reference in New Issue
Block a user