WIP: Picking fix - disable alpha blending and render with false colors
including the alpha channels, which have their 3 lowest bits set to zero. In case some blending occurs, the lowest 3 bits will likely be used to interpolate between the false colors, therefore the 3 lowest bits may be used to detect alpha blending or multi-sampling.
This commit is contained in:
parent
2f642ffffb
commit
a58b1844e0
1 changed files with 31 additions and 42 deletions
|
@ -3764,6 +3764,7 @@ void GLCanvas3D::_picking_pass() const
|
||||||
// Better to use software ray - casting on a bounding - box hierarchy.
|
// Better to use software ray - casting on a bounding - box hierarchy.
|
||||||
|
|
||||||
if (m_multisample_allowed)
|
if (m_multisample_allowed)
|
||||||
|
// This flag is often ignored by NVIDIA drivers if rendering into a screen buffer.
|
||||||
glsafe(::glDisable(GL_MULTISAMPLE));
|
glsafe(::glDisable(GL_MULTISAMPLE));
|
||||||
|
|
||||||
glsafe(::glDisable(GL_BLEND));
|
glsafe(::glDisable(GL_BLEND));
|
||||||
|
@ -3793,7 +3794,9 @@ void GLCanvas3D::_picking_pass() const
|
||||||
if (inside)
|
if (inside)
|
||||||
{
|
{
|
||||||
glsafe(::glReadPixels(m_mouse.position(0), cnv_size.get_height() - m_mouse.position(1) - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color));
|
glsafe(::glReadPixels(m_mouse.position(0), cnv_size.get_height() - m_mouse.position(1) - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color));
|
||||||
volume_id = color[0] + (color[1] << 8) + (color[2] << 16);
|
if (((color[0] | color[1] | color[2] | color[3]) & 0x7) == 0)
|
||||||
|
// Only non-interpolated colors are valid, those have their lowest three bits zeroed.
|
||||||
|
volume_id = (color[0] >> 3) + (color[1] << (5 - 3)) + (color[2] << (10 - 3)) + (color[3] << (15 - 3));
|
||||||
}
|
}
|
||||||
if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size()))
|
if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size()))
|
||||||
{
|
{
|
||||||
|
@ -3816,6 +3819,7 @@ void GLCanvas3D::_rectangular_selection_picking_pass() const
|
||||||
if (m_picking_enabled)
|
if (m_picking_enabled)
|
||||||
{
|
{
|
||||||
if (m_multisample_allowed)
|
if (m_multisample_allowed)
|
||||||
|
// This flag is often ignored by NVIDIA drivers if rendering into a screen buffer.
|
||||||
glsafe(::glDisable(GL_MULTISAMPLE));
|
glsafe(::glDisable(GL_MULTISAMPLE));
|
||||||
|
|
||||||
glsafe(::glDisable(GL_BLEND));
|
glsafe(::glDisable(GL_BLEND));
|
||||||
|
@ -3841,7 +3845,9 @@ void GLCanvas3D::_rectangular_selection_picking_pass() const
|
||||||
struct Pixel
|
struct Pixel
|
||||||
{
|
{
|
||||||
std::array<GLubyte, 4> data;
|
std::array<GLubyte, 4> data;
|
||||||
int id() const { return data[0] + (data[1] << 8) + (data[2] << 16); }
|
// Only non-interpolated colors are valid, those have their lowest three bits zeroed.
|
||||||
|
bool valid() const { return ((data[0] | data[1] | data[2] | data[3]) & 0x7) == 0; }
|
||||||
|
int id() const { return (data[0] >> 3) + (data[1] << (5 - 3)) + (data[2] << (10 - 3)) + (data[3] << (15 - 3)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Pixel> frame(px_count);
|
std::vector<Pixel> frame(px_count);
|
||||||
|
@ -3851,17 +3857,15 @@ void GLCanvas3D::_rectangular_selection_picking_pass() const
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, frame.size(), (size_t)width),
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, frame.size(), (size_t)width),
|
||||||
[this, &frame, &idxs, &mutex](const tbb::blocked_range<size_t>& range) {
|
[this, &frame, &idxs, &mutex](const tbb::blocked_range<size_t>& range) {
|
||||||
for (size_t i = range.begin(); i < range.end(); ++i)
|
for (size_t i = range.begin(); i < range.end(); ++i)
|
||||||
{
|
if (frame[i].valid()) {
|
||||||
int volume_id = frame[i].id();
|
int volume_id = frame[i].id();
|
||||||
if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size()))
|
if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size())) {
|
||||||
{
|
mutex.lock();
|
||||||
mutex.lock();
|
idxs.insert(volume_id);
|
||||||
idxs.insert(volume_id);
|
mutex.unlock();
|
||||||
mutex.unlock();
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
#else
|
#else
|
||||||
std::vector<GLubyte> frame(4 * px_count);
|
std::vector<GLubyte> frame(4 * px_count);
|
||||||
glsafe(::glReadPixels(left, top, width, height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)frame.data()));
|
glsafe(::glReadPixels(left, top, width, height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)frame.data()));
|
||||||
|
@ -4040,42 +4044,27 @@ void GLCanvas3D::_render_volumes_for_picking() const
|
||||||
// do not cull backfaces to show broken geometry, if any
|
// do not cull backfaces to show broken geometry, if any
|
||||||
glsafe(::glDisable(GL_CULL_FACE));
|
glsafe(::glDisable(GL_CULL_FACE));
|
||||||
|
|
||||||
glsafe(::glEnable(GL_BLEND));
|
|
||||||
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
|
||||||
|
|
||||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||||
|
|
||||||
const Transform3d& view_matrix = m_camera.get_view_matrix();
|
const Transform3d& view_matrix = m_camera.get_view_matrix();
|
||||||
GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, GLVolumeCollection::Opaque, view_matrix);
|
for (size_t type = 0; type < 2; ++ type) {
|
||||||
for (const GLVolumeWithIdAndZ& volume : to_render)
|
GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::Opaque : GLVolumeCollection::Transparent, view_matrix);
|
||||||
{
|
for (const GLVolumeWithIdAndZ& volume : to_render)
|
||||||
// Object picking mode. Render the object with a color encoding the object index.
|
if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries)) {
|
||||||
unsigned int r = (volume.second.first & 0x000000FF) >> 0;
|
// Object picking mode. Render the object with a color encoding the object index.
|
||||||
unsigned int g = (volume.second.first & 0x0000FF00) >> 8;
|
unsigned int id = volume.second.first;
|
||||||
unsigned int b = (volume.second.first & 0x00FF0000) >> 16;
|
unsigned int r = (id & (0x0000001F << 0)) << 3;
|
||||||
glsafe(::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255));
|
unsigned int g = (id & (0x0000001F << 5)) >> (5 - 3);
|
||||||
|
unsigned int b = (id & (0x0000001F << 10)) >> (10 - 3);
|
||||||
if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries))
|
unsigned int a = (id & (0x0000001F << 15)) >> (15 - 3);
|
||||||
volume.first->render();
|
glsafe(::glColor4f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255));
|
||||||
}
|
volume.first->render();
|
||||||
|
}
|
||||||
to_render = volumes_to_render(m_volumes.volumes, GLVolumeCollection::Transparent, view_matrix);
|
}
|
||||||
for (const GLVolumeWithIdAndZ& volume : to_render)
|
|
||||||
{
|
|
||||||
// Object picking mode. Render the object with a color encoding the object index.
|
|
||||||
unsigned int r = (volume.second.first & 0x000000FF) >> 0;
|
|
||||||
unsigned int g = (volume.second.first & 0x0000FF00) >> 8;
|
|
||||||
unsigned int b = (volume.second.first & 0x00FF0000) >> 16;
|
|
||||||
glsafe(::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255));
|
|
||||||
|
|
||||||
if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries))
|
|
||||||
volume.first->render();
|
|
||||||
}
|
|
||||||
|
|
||||||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||||
glsafe(::glDisable(GL_BLEND));
|
|
||||||
|
|
||||||
glsafe(::glEnable(GL_CULL_FACE));
|
glsafe(::glEnable(GL_CULL_FACE));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue