diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 8b5de5ec4..e1dc3305c 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -730,8 +730,8 @@ void GLModel::render() const const Geometry& data = m_render_data.geometry; - GLenum mode = get_primitive_mode(data.format); - GLenum index_type = get_index_type(data.format); + const GLenum mode = get_primitive_mode(data.format); + const GLenum index_type = get_index_type(data.format); const size_t vertex_stride_bytes = Geometry::vertex_stride_bytes(data.format); const bool position = Geometry::has_position(data.format); diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index fd6265290..70220a75c 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -106,6 +106,8 @@ namespace GUI { unsigned int extract_uint_index(size_t id) const; unsigned short extract_ushort_index(size_t id) const; + bool is_empty() const { return vertices.empty() || indices.empty(); } + size_t vertices_count() const { return vertices.size() / vertex_stride_floats(format); } size_t indices_count() const { return indices.size() / index_stride_bytes(format); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index 1c1707151..cf316afd1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -18,7 +18,11 @@ namespace Slic3r::GUI { - std::shared_ptr GLGizmoPainterBase::s_sphere = nullptr; +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +std::shared_ptr GLGizmoPainterBase::s_sphere = nullptr; +#else +std::shared_ptr GLGizmoPainterBase::s_sphere = nullptr; +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) @@ -27,8 +31,13 @@ GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& ic GLGizmoPainterBase::~GLGizmoPainterBase() { +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + if (s_sphere != nullptr) + s_sphere.reset(); +#else if (s_sphere != nullptr && s_sphere->has_VBOs()) s_sphere->release_geometry(); +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL } void GLGizmoPainterBase::set_painter_gizmo_data(const Selection& selection) @@ -220,11 +229,20 @@ void GLGizmoPainterBase::render_cursor_circle() void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const { if (s_sphere == nullptr) { +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + s_sphere = std::make_shared(); + s_sphere->init_from(its_make_sphere(1.0, double(PI) / 12.0)); +#else s_sphere = std::make_shared(); s_sphere->load_its_flat_shading(its_make_sphere(1.0, double(PI) / 12.0)); s_sphere->finalize_geometry(true); +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL } + GLShaderProgram* shader = wxGetApp().get_shader("flat"); + if (shader == nullptr) + return; + const Transform3d complete_scaling_matrix_inverse = Geometry::Transformation(trafo).get_matrix(true, true, false, true).inverse(); const bool is_left_handed = Geometry::Transformation(trafo).is_left_handed(); @@ -243,11 +261,22 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const render_color = this->get_cursor_sphere_left_button_color(); else if (m_button_down == Button::Right) render_color = this->get_cursor_sphere_right_button_color(); +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + shader->start_using(); + + assert(s_sphere != nullptr); + s_sphere->set_color(render_color); +#else glsafe(::glColor4fv(render_color.data())); assert(s_sphere != nullptr); +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL s_sphere->render(); +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + shader->stop_using(); +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + if (is_left_handed) glFrontFace(GL_CCW); @@ -763,13 +792,28 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) shader->set_uniform("offset_depth_buffer", true); for (auto iva : {std::make_pair(&m_iva_enforcers, enforcers_color), std::make_pair(&m_iva_blockers, blockers_color)}) { +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + iva.first->set_color(iva.second); + iva.first->render(); +#else if (iva.first->has_VBOs()) { shader->set_uniform("uniform_color", iva.second); iva.first->render(); } +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL } - for (auto &iva : m_iva_seed_fills) +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + for (auto& iva : m_iva_seed_fills) { + size_t color_idx = &iva - &m_iva_seed_fills.front(); + const ColorRGBA& color = TriangleSelectorGUI::get_seed_fill_color(color_idx == 1 ? enforcers_color : + color_idx == 2 ? blockers_color : + GLVolume::NEUTRAL_COLOR); + iva.set_color(color); + iva.render(); + } +#else + for (auto& iva : m_iva_seed_fills) if (iva.has_VBOs()) { size_t color_idx = &iva - &m_iva_seed_fills.front(); const ColorRGBA& color = TriangleSelectorGUI::get_seed_fill_color(color_idx == 1 ? enforcers_color : @@ -778,6 +822,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) shader->set_uniform("uniform_color", color); iva.render(); } +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL if (m_paint_contour.has_VBO()) { ScopeGuard guard_gouraud([shader]() { shader->start_using(); }); @@ -798,7 +843,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) render_debug(imgui); else assert(false); // If you want debug output, pass ptr to ImGuiWrapper. -#endif +#endif // PRUSASLICER_TRIANGLE_SELECTOR_DEBUG } void TriangleSelectorGUI::update_render_data() @@ -807,20 +852,44 @@ void TriangleSelectorGUI::update_render_data() int blc_cnt = 0; std::vector seed_fill_cnt(m_iva_seed_fills.size(), 0); +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + for (auto* iva : { &m_iva_enforcers, &m_iva_blockers }) { + iva->reset(); + } + + for (auto& iva : m_iva_seed_fills) { + iva.reset(); + } + + GLModel::Geometry iva_enforcers_data; + iva_enforcers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT }; + GLModel::Geometry iva_blockers_data; + iva_blockers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT }; + std::array iva_seed_fills_data; + for (auto& data : iva_seed_fills_data) + data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT }; +#else for (auto *iva : {&m_iva_enforcers, &m_iva_blockers}) iva->release_geometry(); for (auto &iva : m_iva_seed_fills) iva.release_geometry(); +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL for (const Triangle &tr : m_triangles) { if (!tr.valid() || tr.is_split() || (tr.get_state() == EnforcerBlockerType::NONE && !tr.is_selected_by_seed_fill())) continue; int tr_state = int(tr.get_state()); +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + GLModel::Geometry &iva = tr.is_selected_by_seed_fill() ? iva_seed_fills_data[tr_state] : + tr.get_state() == EnforcerBlockerType::ENFORCER ? iva_enforcers_data : + iva_blockers_data; +#else GLIndexedVertexArray &iva = tr.is_selected_by_seed_fill() ? m_iva_seed_fills[tr_state] : tr.get_state() == EnforcerBlockerType::ENFORCER ? m_iva_enforcers : m_iva_blockers; +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL int &cnt = tr.is_selected_by_seed_fill() ? seed_fill_cnt[tr_state] : tr.get_state() == EnforcerBlockerType::ENFORCER ? enf_cnt : blc_cnt; @@ -830,18 +899,36 @@ void TriangleSelectorGUI::update_render_data() //FIXME the normal may likely be pulled from m_triangle_selectors, but it may not be worth the effort // or the current implementation may be more cache friendly. const Vec3f n = (v1 - v0).cross(v2 - v1).normalized(); +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + iva.add_vertex(v0, n); + iva.add_vertex(v1, n); + iva.add_vertex(v2, n); + iva.add_uint_triangle((unsigned int)cnt, (unsigned int)cnt + 1, (unsigned int)cnt + 2); +#else iva.push_geometry(v0, n); iva.push_geometry(v1, n); iva.push_geometry(v2, n); iva.push_triangle(cnt, cnt + 1, cnt + 2); +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL cnt += 3; } +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + if (!iva_enforcers_data.is_empty()) + m_iva_enforcers.init_from(std::move(iva_enforcers_data)); + if (!iva_blockers_data.is_empty()) + m_iva_blockers.init_from(std::move(iva_blockers_data)); + for (size_t i = 0; i < m_iva_seed_fills.size(); ++i) { + if (!iva_seed_fills_data[i].is_empty()) + m_iva_seed_fills[i].init_from(std::move(iva_seed_fills_data[i])); + } +#else for (auto *iva : {&m_iva_enforcers, &m_iva_blockers}) iva->finalize_geometry(true); for (auto &iva : m_iva_seed_fills) iva.finalize_geometry(true); +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL m_paint_contour.release_geometry(); std::vector contour_edges = this->get_seed_fill_contour(); @@ -956,45 +1043,111 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui) INVALID }; +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + for (auto& va : m_varrays) + va.reset(); +#else for (auto& va : m_varrays) va.release_geometry(); +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL std::array cnts; ::glScalef(1.01f, 1.01f, 1.01f); +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + std::array varrays_data; + for (auto& data : varrays_data) + data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT }; +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + for (int tr_id=0; tr_idadd_vertex(m_vertices[tr.verts_idxs[i]].v, Vec3f(0.0f, 0.0f, 1.0f)); + } + va->add_uint_triangle((unsigned int)*cnt, (unsigned int)*cnt + 1, (unsigned int)*cnt + 2); +#else + for (int i = 0; i < 3; ++i) va->push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), double(m_vertices[tr.verts_idxs[i]].v[1]), double(m_vertices[tr.verts_idxs[i]].v[2]), 0., 0., 1.); va->push_triangle(*cnt, - *cnt+1, - *cnt+2); + *cnt + 1, + *cnt + 2); +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL *cnt += 3; } +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + for (int i = 0; i < 3; ++i) { + if (!varrays_data[i].is_empty()) + m_varrays[i].init_from(std::move(varrays_data[i])); + } +#else + for (auto* iva : { &m_iva_enforcers, &m_iva_blockers }) + iva->finalize_geometry(true); + + for (auto& iva : m_iva_seed_fills) + iva.finalize_geometry(true); +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + GLShaderProgram* curr_shader = wxGetApp().get_current_shader(); + if (curr_shader != nullptr) + curr_shader->stop_using(); + + GLShaderProgram* shader = wxGetApp().get_shader("flat"); + if (shader != nullptr) { + shader->start_using(); +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + ::glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); for (vtype i : {ORIGINAL, SPLIT, INVALID}) { +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + GLModel& va = m_varrays[i]; + switch (i) { + case ORIGINAL: va.set_color({ 0.0f, 0.0f, 1.0f, 1.0f }); break; + case SPLIT: va.set_color({ 1.0f, 0.0f, 0.0f, 1.0f }); break; + case INVALID: va.set_color({ 1.0f, 1.0f, 0.0f, 1.0f }); break; + } + va.render(); +#else GLIndexedVertexArray& va = m_varrays[i]; va.finalize_geometry(true); if (va.has_VBOs()) { @@ -1005,11 +1158,18 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui) } va.render(); } +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL } ::glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + shader->stop_using(); + } + + if (curr_shader != nullptr) + curr_shader->start_using(); +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL } -#endif - - +#endif // PRUSASLICER_TRIANGLE_SELECTOR_DEBUG } // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index 079f3f08e..6d73c0505 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -3,7 +3,11 @@ #include "GLGizmoBase.hpp" +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL +#include "slic3r/GUI/GLModel.hpp" +#else #include "slic3r/GUI/3DScene.hpp" +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL #include "libslic3r/ObjectID.hpp" #include "libslic3r/TriangleSelector.hpp" @@ -81,7 +85,7 @@ public: void render_debug(ImGuiWrapper* imgui); bool m_show_triangles{false}; bool m_show_invalid{false}; -#endif +#endif // PRUSASLICER_TRIANGLE_SELECTOR_DEBUG protected: bool m_update_render_data = false; @@ -91,10 +95,19 @@ protected: private: void update_render_data(); +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + GLModel m_iva_enforcers; + GLModel m_iva_blockers; + std::array m_iva_seed_fills; +#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG + std::array m_varrays; +#endif // PRUSASLICER_TRIANGLE_SELECTOR_DEBUG +#else GLIndexedVertexArray m_iva_enforcers; GLIndexedVertexArray m_iva_blockers; std::array m_iva_seed_fills; std::array m_varrays; +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL protected: GLPaintContour m_paint_contour; @@ -209,7 +222,11 @@ private: const Camera& camera, const std::vector& trafo_matrices) const; +#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL + static std::shared_ptr s_sphere; +#else static std::shared_ptr s_sphere; +#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL bool m_internal_stack_active = false; bool m_schedule_update = false;