diff --git a/resources/shaders/picking.fs b/resources/shaders/picking.fs deleted file mode 100644 index 0c9683e0d..000000000 --- a/resources/shaders/picking.fs +++ /dev/null @@ -1,14 +0,0 @@ -#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 deleted file mode 100644 index 0dc084dc1..000000000 --- a/resources/shaders/picking.vs +++ /dev/null @@ -1,11 +0,0 @@ -#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/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 4bbffbcac..1e85a10b6 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -20,6 +20,8 @@ #include static const float GROUND_Z = -0.02f; +static const std::array DEFAULT_MODEL_COLOR = { 0.235f, 0.235f, 0.235f, 1.0f }; +static const std::array PICKING_MODEL_COLOR = { 0.0f, 0.0f, 0.0f, 1.0f }; namespace Slic3r { namespace GUI { @@ -211,8 +213,18 @@ Point Bed3D::point_projection(const Point& point) const return m_polygon.point_projection(point); } -void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, - bool show_axes, bool show_texture) const +void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture) +{ + render_internal(canvas, bottom, scale_factor, show_axes, show_texture, false); +} + +void Bed3D::render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor) +{ + render_internal(canvas, bottom, scale_factor, false, false, true); +} + +void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor, + bool show_axes, bool show_texture, bool picking) { float* factor = const_cast(&m_scale_factor); *factor = scale_factor; @@ -222,11 +234,13 @@ void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, glsafe(::glEnable(GL_DEPTH_TEST)); + m_model.set_color(-1, picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR); + switch (m_type) { case System: { render_system(canvas, bottom, show_texture); break; } default: - case Custom: { render_custom(canvas, bottom, show_texture); break; } + case Custom: { render_custom(canvas, bottom, show_texture, picking); break; } } glsafe(::glDisable(GL_DEPTH_TEST)); @@ -237,7 +251,7 @@ void Bed3D::calc_bounding_boxes() const BoundingBoxf3* bounding_box = const_cast(&m_bounding_box); *bounding_box = BoundingBoxf3(); for (const Vec2d& p : m_shape) { - bounding_box->merge({ p(0), p(1), 0.0 }); + bounding_box->merge({ p.x(), p.y(), 0.0 }); } BoundingBoxf3* extended_bounding_box = const_cast(&m_extended_bounding_box); @@ -264,16 +278,16 @@ void Bed3D::calc_triangles(const ExPolygon& poly) void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox) { Polylines axes_lines; - for (coord_t x = bed_bbox.min(0); x <= bed_bbox.max(0); x += scale_(10.0)) { + for (coord_t x = bed_bbox.min.x(); x <= bed_bbox.max.x(); x += scale_(10.0)) { Polyline line; - line.append(Point(x, bed_bbox.min(1))); - line.append(Point(x, bed_bbox.max(1))); + line.append(Point(x, bed_bbox.min.y())); + line.append(Point(x, bed_bbox.max.y())); axes_lines.push_back(line); } - for (coord_t y = bed_bbox.min(1); y <= bed_bbox.max(1); y += scale_(10.0)) { + for (coord_t y = bed_bbox.min.y(); y <= bed_bbox.max.y(); y += scale_(10.0)) { Polyline line; - line.append(Point(bed_bbox.min(0), y)); - line.append(Point(bed_bbox.max(0), y)); + line.append(Point(bed_bbox.min.x(), y)); + line.append(Point(bed_bbox.max.x(), y)); axes_lines.push_back(line); } @@ -333,7 +347,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const if (m_texture_filename.empty()) { texture->reset(); - render_default(bottom); + render_default(bottom, false); return; } @@ -346,7 +360,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const if (temp_texture->get_id() == 0 || temp_texture->get_source() != m_texture_filename) { // generate a temporary lower resolution texture to show while no main texture levels have been compressed if (!temp_texture->load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) { - render_default(bottom); + render_default(bottom, false); return; } canvas.request_extra_frame(); @@ -354,7 +368,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const // starts generating the main texture, compression will run asynchronously if (!texture->load_from_svg_file(m_texture_filename, true, true, true, max_tex_size)) { - render_default(bottom); + render_default(bottom, false); return; } } @@ -362,7 +376,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const // generate a temporary lower resolution texture to show while no main texture levels have been compressed if (temp_texture->get_id() == 0 || temp_texture->get_source() != m_texture_filename) { if (!temp_texture->load_from_file(m_texture_filename, false, GLTexture::None, false)) { - render_default(bottom); + render_default(bottom, false); return; } canvas.request_extra_frame(); @@ -370,12 +384,12 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const // starts generating the main texture, compression will run asynchronously if (!texture->load_from_file(m_texture_filename, true, GLTexture::MultiThreaded, true)) { - render_default(bottom); + render_default(bottom, false); return; } } else { - render_default(bottom); + render_default(bottom, false); return; } } @@ -388,7 +402,6 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const temp_texture->reset(); canvas.request_extra_frame(); - } if (m_triangles.get_vertices_count() > 0) { @@ -470,7 +483,7 @@ void Bed3D::render_model() const GLModel* model = const_cast(&m_model); if (model->get_filename() != m_model_filename && model->init_from_file(m_model_filename)) { - model->set_color(-1, m_model_color); + model->set_color(-1, DEFAULT_MODEL_COLOR); // move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad Vec3d shift = m_bounding_box.center(); @@ -495,10 +508,10 @@ void Bed3D::render_model() const } } -void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture) const +void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking) const { if (m_texture_filename.empty() && m_model_filename.empty()) { - render_default(bottom); + render_default(bottom, picking); return; } @@ -509,7 +522,7 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture) co render_texture(bottom, canvas); } -void Bed3D::render_default(bool bottom) const +void Bed3D::render_default(bool bottom, bool picking) const { const_cast(&m_texture)->reset(); @@ -526,21 +539,23 @@ void Bed3D::render_default(bool bottom) const if (!has_model && !bottom) { // draw background glsafe(::glDepthMask(GL_FALSE)); - glsafe(::glColor4fv(m_model_color.data())); + glsafe(::glColor4fv(picking ? PICKING_MODEL_COLOR.data() : DEFAULT_MODEL_COLOR.data())); glsafe(::glNormal3d(0.0f, 0.0f, 1.0f)); glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_triangles.get_vertices_data())); glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount)); glsafe(::glDepthMask(GL_TRUE)); } - // draw grid - glsafe(::glLineWidth(1.5f * m_scale_factor)); - if (has_model && !bottom) - glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 1.0f)); - else - glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.6f)); - glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data())); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines.get_vertices_count())); + if (!picking) { + // draw grid + glsafe(::glLineWidth(1.5f * m_scale_factor)); + if (has_model && !bottom) + glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 1.0f)); + else + glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.6f)); + glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data())); + glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines.get_vertices_count())); + } glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 71382315d..a2a643519 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -84,7 +84,6 @@ private: GLTexture m_temp_texture; GLModel m_model; Vec3d m_model_offset{ Vec3d::Zero() }; - std::array m_model_color{ 0.235f, 0.235f, 0.235f, 1.0f }; unsigned int m_vbo_id{ 0 }; Axes m_axes; @@ -110,19 +109,23 @@ public: Point point_projection(const Point& point) const; void render(GLCanvas3D& canvas, bool bottom, float scale_factor, - bool show_axes, bool show_texture) const; + bool show_axes, bool show_texture); + + void render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor); private: void calc_bounding_boxes() const; void calc_triangles(const ExPolygon& poly); void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox); std::tuple detect_type(const Pointfs& shape) const; + void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor, + bool show_axes, bool show_texture, bool picking); void render_axes() const; void render_system(GLCanvas3D& canvas, bool bottom, bool show_texture) const; void render_texture(bool bottom, GLCanvas3D& canvas) const; void render_model() const; - void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture) const; - void render_default(bool bottom) const; + void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking) const; + void render_default(bool bottom, bool picking) const; void reset(); }; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 303d228c7..5be2fc7ad 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2449,8 +2449,8 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case 'O': case 'o': { _update_camera_zoom(-1.0); break; } #if ENABLE_RENDER_PICKING_PASS - case 'P': - case 'p': { + case 'T': + case 't': { m_show_picking_texture = !m_show_picking_texture; m_dirty = true; break; @@ -4842,21 +4842,30 @@ void GLCanvas3D::_picking_pass() if (m_camera_clipping_plane.is_active()) ::glDisable(GL_CLIP_PLANE0); + _render_bed_for_picking(!wxGetApp().plater()->get_camera().is_looking_downward()); + m_gizmos.render_current_gizmo_for_picking_pass(); if (m_multisample_allowed) glsafe(::glEnable(GL_MULTISAMPLE)); int volume_id = -1; + int gizmo_id = -1; GLubyte color[4] = { 0, 0, 0, 0 }; const Size& cnv_size = get_canvas_size(); bool inside = 0 <= m_mouse.position(0) && m_mouse.position(0) < cnv_size.get_width() && 0 <= m_mouse.position(1) && m_mouse.position(1) < cnv_size.get_height(); 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)); - if (picking_checksum_alpha_channel(color[0], color[1], color[2]) == color[3]) - // Only non-interpolated colors are valid, those have their lowest three bits zeroed. - volume_id = color[0] + (color[1] << 8) + (color[2] << 16); + if (picking_checksum_alpha_channel(color[0], color[1], color[2]) == color[3]) { + // Only non-interpolated colors are valid, those have their lowest three bits zeroed. + // we reserve color = (0,0,0) for occluders (as the printbed) + // volumes' id are shifted by 1 + // see: _render_volumes_for_picking() + volume_id = color[0] + (color[1] << 8) + (color[2] << 16) - 1; + // gizmos' id are instead properly encoded by the color + gizmo_id = color[0] + (color[1] << 8) + (color[2] << 16); + } } if (0 <= volume_id && volume_id < (int)m_volumes.volumes.size()) { // do not add the volume id if any gizmo is active and CTRL is pressed @@ -4865,7 +4874,7 @@ void GLCanvas3D::_picking_pass() m_gizmos.set_hover_id(-1); } else - m_gizmos.set_hover_id(inside && (unsigned int)volume_id <= GLGizmoBase::BASE_ID ? ((int)GLGizmoBase::BASE_ID - volume_id) : -1); + m_gizmos.set_hover_id(inside && (unsigned int)gizmo_id <= GLGizmoBase::BASE_ID ? ((int)GLGizmoBase::BASE_ID - gizmo_id) : -1); _update_volumes_hover_state(); } @@ -5028,6 +5037,17 @@ void GLCanvas3D::_render_bed(bool bottom, bool show_axes) wxGetApp().plater()->get_bed().render(*this, bottom, scale_factor, show_axes, show_texture); } +void GLCanvas3D::_render_bed_for_picking(bool bottom) +{ + float scale_factor = 1.0; +#if ENABLE_RETINA_GL + scale_factor = m_retina_helper->get_scale_factor(); +#endif // ENABLE_RETINA_GL + + wxGetApp().plater()->get_bed().render_for_picking(*this, bottom, scale_factor); +} + + #if ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type) #else @@ -5270,50 +5290,30 @@ 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)) { // 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; + // we reserve color = (0,0,0) for occluders (as the printbed) + // so we shift volumes' id by 1 to get the proper color + unsigned int id = 1 + 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); -#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/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index e934f9926..3ea32a9b7 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -816,6 +816,7 @@ private: void _rectangular_selection_picking_pass(); void _render_background() const; void _render_bed(bool bottom, bool show_axes); + void _render_bed_for_picking(bool bottom); #if ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING void _render_objects(GLVolumeCollection::ERenderType type); #else diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index d853ef198..5ee14c526 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -50,10 +50,6 @@ 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 }; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 2fa16bc03..4337290dc 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -91,9 +91,9 @@ void GLGizmoHollow::on_render() const void GLGizmoHollow::on_render_for_picking() const { const Selection& selection = m_parent.get_selection(); -#if ENABLE_RENDER_PICKING_PASS - m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z(); -#endif +//#if ENABLE_RENDER_PICKING_PASS +// m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z(); +//#endif glsafe(::glEnable(GL_DEPTH_TEST)); render_points(selection, true);