diff --git a/resources/shaders/picking.fs b/resources/shaders/picking.fs new file mode 100644 index 000000000..0c9683e0d --- /dev/null +++ b/resources/shaders/picking.fs @@ -0,0 +1,14 @@ +#version 110 + +uniform vec4 uniform_color; +uniform bool viewed_from_top; + +varying float world_pos_z; + +void main() +{ + if (viewed_from_top && world_pos_z < 0.0) + discard; + + gl_FragColor = uniform_color; +} diff --git a/resources/shaders/picking.vs b/resources/shaders/picking.vs new file mode 100644 index 000000000..0dc084dc1 --- /dev/null +++ b/resources/shaders/picking.vs @@ -0,0 +1,11 @@ +#version 110 + +uniform mat4 world_matrix; + +varying float world_pos_z; + +void main() +{ + world_pos_z = (world_matrix * gl_Vertex).z; + gl_Position = ftransform(); +} diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c064a48f7..cc36a0f8f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5288,28 +5288,50 @@ void GLCanvas3D::_render_volumes_for_picking() const { static const GLfloat INV_255 = 1.0f / 255.0f; +#if ENABLE_ALLOW_NEGATIVE_Z + auto* shader = wxGetApp().get_shader("picking"); + if (!shader) + return; +#endif // ENABLE_ALLOW_NEGATIVE_Z + // do not cull backfaces to show broken geometry, if any glsafe(::glDisable(GL_CULL_FACE)); glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); +#if ENABLE_ALLOW_NEGATIVE_Z + shader->start_using(); + shader->set_uniform("viewed_from_top", wxGetApp().plater()->get_camera().is_looking_downward()); +#endif // ENABLE_ALLOW_NEGATIVE_Z + const Transform3d& view_matrix = wxGetApp().plater()->get_camera().get_view_matrix(); for (size_t type = 0; type < 2; ++ type) { GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::ERenderType::Opaque : GLVolumeCollection::ERenderType::Transparent, view_matrix); for (const GLVolumeWithIdAndZ& volume : to_render) - if (!volume.first->disabled && ((volume.first->composite_id.volume_id >= 0) || m_render_sla_auxiliaries)) { + if (!volume.first->disabled && (volume.first->composite_id.volume_id >= 0 || m_render_sla_auxiliaries)) { // Object picking mode. Render the object with a color encoding the object index. unsigned int id = volume.second.first; unsigned int r = (id & (0x000000FF << 0)) << 0; unsigned int g = (id & (0x000000FF << 8)) >> 8; unsigned int b = (id & (0x000000FF << 16)) >> 16; unsigned int a = picking_checksum_alpha_channel(r, g, b); - glsafe(::glColor4f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255)); +#if ENABLE_ALLOW_NEGATIVE_Z + std::array color = { (float)r * INV_255, (float)g * INV_255, (float)b * INV_255, (float)a * INV_255 }; + shader->set_uniform("uniform_color", color); + shader->set_uniform("world_matrix", volume.first->world_matrix()); +#else + glsafe(::glColor4f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255)); +#endif // ENABLE_ALLOW_NEGATIVE_Z + volume.first->render(); } } +#if ENABLE_ALLOW_NEGATIVE_Z + shader->stop_using(); +#endif // ENABLE_ALLOW_NEGATIVE_Z + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 5ee14c526..d853ef198 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -50,6 +50,10 @@ std::pair GLShadersManager::init() ); // used to render variable layers heights in 3d editor valid &= append_shader("variable_layer_height", { "variable_layer_height.vs", "variable_layer_height.fs" }); +#if ENABLE_ALLOW_NEGATIVE_Z + // used to render volumes during picking pass + valid &= append_shader("picking", { "picking.vs", "picking.fs" }); +#endif // ENABLE_ALLOW_NEGATIVE_Z return { valid, error }; }