diff --git a/resources/shaders/flat.fs b/resources/shaders/flat.fs new file mode 100644 index 000000000..ab656998d --- /dev/null +++ b/resources/shaders/flat.fs @@ -0,0 +1,8 @@ +#version 110 + +uniform vec4 uniform_color; + +void main() +{ + gl_FragColor = uniform_color; +} diff --git a/resources/shaders/flat.vs b/resources/shaders/flat.vs new file mode 100644 index 000000000..d0d3ee42a --- /dev/null +++ b/resources/shaders/flat.vs @@ -0,0 +1,6 @@ +#version 110 + +void main() +{ + gl_Position = ftransform(); +} diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 82ed7bc13..03f3071ee 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -62,6 +62,8 @@ #define ENABLE_OBJECT_MANIPULATOR_FOCUS (1 && ENABLE_2_5_0_ALPHA1) // Enable removal of wipe tower magic object_id equal to 1000 #define ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL (1 && ENABLE_2_5_0_ALPHA1) +// Enable removal of old OpenGL render calls +#define ENABLE_GLBEGIN_GLEND_REMOVAL (1 && ENABLE_2_5_0_ALPHA1) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f2fbf50a9..12698e212 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5240,7 +5240,11 @@ void GLCanvas3D::_render_gcode() m_gcode_viewer.render(); } +#if ENABLE_GLBEGIN_GLEND_REMOVAL +void GLCanvas3D::_render_selection() +#else void GLCanvas3D::_render_selection() const +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL { float scale_factor = 1.0; #if ENABLE_RETINA_GL @@ -5271,7 +5275,7 @@ void GLCanvas3D::_render_sequential_clearance() } #if ENABLE_RENDER_SELECTION_CENTER -void GLCanvas3D::_render_selection_center() const +void GLCanvas3D::_render_selection_center() { m_selection.render_center(m_gizmos.is_dragging()); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index ebffe4695..84fc405f5 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -915,10 +915,14 @@ private: void _render_bed_for_picking(bool bottom); void _render_objects(GLVolumeCollection::ERenderType type); void _render_gcode(); +#if ENABLE_GLBEGIN_GLEND_REMOVAL + void _render_selection(); +#else void _render_selection() const; +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL void _render_sequential_clearance(); #if ENABLE_RENDER_SELECTION_CENTER - void _render_selection_center() const; + void _render_selection_center(); #endif // ENABLE_RENDER_SELECTION_CENTER void _check_and_update_toolbar_icon_scale(); void _render_overlays(); diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 7fc03d421..38ea91df6 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -33,6 +33,10 @@ std::pair GLShadersManager::init() bool valid = true; +#if ENABLE_GLBEGIN_GLEND_REMOVAL + // basic shader, used to render selection bbox + valid &= append_shader("flat", { "flat.vs", "flat.fs" }); +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL // used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" }); // used to render printbed diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index f84f3cb9a..8a00c5337 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -132,9 +132,8 @@ bool Selection::init() { m_arrow.init_from(straight_arrow(10.0f, 5.0f, 5.0f, 10.0f, 1.0f)); m_curved_arrow.init_from(circular_arrow(16, 10.0f, 5.0f, 10.0f, 5.0f, 1.0f)); - #if ENABLE_RENDER_SELECTION_CENTER - m_vbo_sphere.init_from(make_sphere(0.75, 2*PI/24)); + m_vbo_sphere.init_from(its_make_sphere(0.75, PI / 12.0)); #endif // ENABLE_RENDER_SELECTION_CENTER return true; @@ -1256,20 +1255,29 @@ void Selection::erase() } } +#if ENABLE_GLBEGIN_GLEND_REMOVAL +void Selection::render(float scale_factor) +#else void Selection::render(float scale_factor) const +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL { if (!m_valid || is_empty()) return; +#if ENABLE_GLBEGIN_GLEND_REMOVAL + m_scale_factor = scale_factor; + render_bounding_box(get_bounding_box(), ColorRGB::WHITE()); +#else *const_cast(&m_scale_factor) = scale_factor; // render cumulative bounding box of selected volumes render_selected_volumes(); +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL render_synchronized_volumes(); } #if ENABLE_RENDER_SELECTION_CENTER -void Selection::render_center(bool gizmo_is_dragging) const +void Selection::render_center(bool gizmo_is_dragging) { if (!m_valid || is_empty()) return; @@ -1278,10 +1286,22 @@ void Selection::render_center(bool gizmo_is_dragging) const glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glColor3f(1.0f, 1.0f, 1.0f)); glsafe(::glPushMatrix()); - glsafe(::glTranslated(center(0), center(1), center(2))); + glsafe(::glTranslated(center.x(), center.y(), center.z())); + +#if ENABLE_GLBEGIN_GLEND_REMOVAL + GLShaderProgram* shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + + shader->start_using(); +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL + m_vbo_sphere.set_color(-1, ColorRGBA::WHITE()); m_vbo_sphere.render(); +#if ENABLE_GLBEGIN_GLEND_REMOVAL + shader->stop_using(); +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL + glsafe(::glPopMatrix()); } #endif // ENABLE_RENDER_SELECTION_CENTER @@ -1798,50 +1818,171 @@ void Selection::do_remove_object(unsigned int object_idx) } } +#if !ENABLE_GLBEGIN_GLEND_REMOVAL void Selection::render_selected_volumes() const { float color[3] = { 1.0f, 1.0f, 1.0f }; render_bounding_box(get_bounding_box(), color); } +#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL +#if ENABLE_GLBEGIN_GLEND_REMOVAL +void Selection::render_synchronized_volumes() +#else void Selection::render_synchronized_volumes() const +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL { if (m_mode == Instance) return; +#if !ENABLE_GLBEGIN_GLEND_REMOVAL float color[3] = { 1.0f, 1.0f, 0.0f }; +#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL for (unsigned int i : m_list) { - const GLVolume* volume = (*m_volumes)[i]; - int object_idx = volume->object_idx(); - int volume_idx = volume->volume_idx(); + const GLVolume& volume = *(*m_volumes)[i]; + int object_idx = volume.object_idx(); + int volume_idx = volume.volume_idx(); for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) { if (i == j) continue; - const GLVolume* v = (*m_volumes)[j]; - if (v->object_idx() != object_idx || v->volume_idx() != volume_idx) + const GLVolume& v = *(*m_volumes)[j]; + if (v.object_idx() != object_idx || v.volume_idx() != volume_idx) continue; - render_bounding_box(v->transformed_convex_hull_bounding_box(), color); +#if ENABLE_GLBEGIN_GLEND_REMOVAL + render_bounding_box(v.transformed_convex_hull_bounding_box(), ColorRGB::YELLOW()); +#else + render_bounding_box(v.transformed_convex_hull_bounding_box(), color); +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL } } } -void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) const +#if ENABLE_GLBEGIN_GLEND_REMOVAL +void Selection::render_bounding_box(const BoundingBoxf3& box, const ColorRGB& color) +{ +#else +void Selection::render_bounding_box(const BoundingBoxf3 & box, float* color) const { if (color == nullptr) return; - Vec3f b_min = box.min.cast(); - Vec3f b_max = box.max.cast(); - Vec3f size = 0.2f * box.size().cast(); + const Vec3f b_min = box.min.cast(); + const Vec3f b_max = box.max.cast(); + const Vec3f size = 0.2f * box.size().cast(); + + glsafe(::glEnable(GL_DEPTH_TEST)); + glsafe(::glColor3fv(color)); + glsafe(::glLineWidth(2.0f * m_scale_factor)); +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL + +#if ENABLE_GLBEGIN_GLEND_REMOVAL + auto is_approx = [](const Vec3d& v1, const Vec3d& v2) { + for (int i = 0; i < 3; ++i) { + if (std::abs(v1[i] - v2[i]) > EPSILON) + return false; + } + return true; + }; + + const BoundingBoxf3& curr_box = m_box.get_bounding_box(); + if (!m_box.is_initialized() || !is_approx(box.min, curr_box.min) || !is_approx(box.max, curr_box.max)) { + m_box.reset(); + + const Vec3f b_min = box.min.cast(); + const Vec3f b_max = box.max.cast(); + const Vec3f size = 0.2f * box.size().cast(); + + GLModel::InitializationData init_data; + GUI::GLModel::InitializationData::Entity entity; + entity.type = GUI::GLModel::PrimitiveType::Lines; + entity.positions.reserve(48); + + entity.positions.emplace_back(Vec3f(b_min.x(), b_min.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_min.x() + size.x(), b_min.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_min.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_min.y() + size.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_min.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_min.y(), b_min.z() + size.z())); + + entity.positions.emplace_back(Vec3f(b_max.x(), b_min.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_max.x() - size.x(), b_min.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_min.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_min.y() + size.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_min.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_min.y(), b_min.z() + size.z())); + + entity.positions.emplace_back(Vec3f(b_max.x(), b_max.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_max.x() - size.x(), b_max.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_max.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_max.y() - size.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_max.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_max.y(), b_min.z() + size.z())); + + entity.positions.emplace_back(Vec3f(b_min.x(), b_max.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_min.x() + size.x(), b_max.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_max.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_max.y() - size.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_max.y(), b_min.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_max.y(), b_min.z() + size.z())); + + entity.positions.emplace_back(Vec3f(b_min.x(), b_min.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_min.x() + size.x(), b_min.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_min.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_min.y() + size.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_min.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_min.y(), b_max.z() - size.z())); + + entity.positions.emplace_back(Vec3f(b_max.x(), b_min.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_max.x() - size.x(), b_min.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_min.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_min.y() + size.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_min.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_min.y(), b_max.z() - size.z())); + + entity.positions.emplace_back(Vec3f(b_max.x(), b_max.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_max.x() - size.x(), b_max.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_max.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_max.y() - size.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_max.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_max.x(), b_max.y(), b_max.z() - size.z())); + + entity.positions.emplace_back(Vec3f(b_min.x(), b_max.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_min.x() + size.x(), b_max.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_max.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_max.y() - size.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_max.y(), b_max.z())); + entity.positions.emplace_back(Vec3f(b_min.x(), b_max.y(), b_max.z() - size.z())); + + entity.normals.reserve(48); + for (size_t i = 0; i < 48; ++i) { + entity.normals.emplace_back(Vec3f::UnitZ()); + } + + entity.indices.reserve(48); + for (size_t i = 0; i < 48; ++i) { + entity.indices.emplace_back(i); + } + + init_data.entities.emplace_back(entity); + m_box.init_from(init_data); + } glsafe(::glEnable(GL_DEPTH_TEST)); - glsafe(::glColor3fv(color)); glsafe(::glLineWidth(2.0f * m_scale_factor)); + GLShaderProgram* shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + + shader->start_using(); + m_box.set_color(-1, to_rgba(color)); + m_box.render(); + shader->stop_using(); +#else ::glBegin(GL_LINES); ::glVertex3f(b_min(0), b_min(1), b_min(2)); ::glVertex3f(b_min(0) + size(0), b_min(1), b_min(2)); @@ -1877,6 +2018,7 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) cons ::glVertex3f(b_min(0), b_max(1), b_max(2)); ::glVertex3f(b_min(0), b_max(1), b_max(2) - size(2)); glsafe(::glEnd()); +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL } static ColorRGBA get_color(Axis axis) diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 537c07207..1fccad18f 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -218,6 +218,9 @@ private: GLModel m_arrow; GLModel m_curved_arrow; +#if ENABLE_GLBEGIN_GLEND_REMOVAL + GLModel m_box; +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL float m_scale_factor; bool m_dragging; @@ -329,9 +332,13 @@ public: void erase(); +#if ENABLE_GLBEGIN_GLEND_REMOVAL + void render(float scale_factor = 1.0); +#else void render(float scale_factor = 1.0) const; +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL #if ENABLE_RENDER_SELECTION_CENTER - void render_center(bool gizmo_is_dragging) const; + void render_center(bool gizmo_is_dragging); #endif // ENABLE_RENDER_SELECTION_CENTER void render_sidebar_hints(const std::string& sidebar_field) const; @@ -363,9 +370,14 @@ private: void do_remove_instance(unsigned int object_idx, unsigned int instance_idx); void do_remove_object(unsigned int object_idx); void set_bounding_boxes_dirty() { m_bounding_box.reset(); m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset(); } +#if ENABLE_GLBEGIN_GLEND_REMOVAL + void render_synchronized_volumes(); + void render_bounding_box(const BoundingBoxf3& box, const ColorRGB& color); +#else void render_selected_volumes() const; void render_synchronized_volumes() const; void render_bounding_box(const BoundingBoxf3& box, float* color) const; +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL void render_sidebar_position_hints(const std::string& sidebar_field) const; void render_sidebar_rotation_hints(const std::string& sidebar_field) const; void render_sidebar_scale_hints(const std::string& sidebar_field) const;