From 6b041429f6f137add530c900c3160d431286366f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 7 Feb 2022 10:24:24 +0100 Subject: [PATCH] Tech ENABLE_GLBEGIN_GLEND_REMOVAL - Removed Slic3r::GUI::GeometryBuffer from 3DBed.hpp and replaced with GLModel --- resources/shaders/printbed.fs | 2 +- resources/shaders/printbed.vs | 9 +- src/slic3r/GUI/3DBed.cpp | 186 +++++++++++++++++++++++++++++++++- src/slic3r/GUI/3DBed.hpp | 29 +++++- src/slic3r/GUI/GLModel.cpp | 24 ++++- src/slic3r/GUI/GLModel.hpp | 2 + 6 files changed, 239 insertions(+), 13 deletions(-) diff --git a/resources/shaders/printbed.fs b/resources/shaders/printbed.fs index d1316ca2fe..bef0751580 100644 --- a/resources/shaders/printbed.fs +++ b/resources/shaders/printbed.fs @@ -1,6 +1,6 @@ #version 110 -const vec3 back_color_dark = vec3(0.235, 0.235, 0.235); +const vec3 back_color_dark = vec3(0.235, 0.235, 0.235); const vec3 back_color_light = vec3(0.365, 0.365, 0.365); uniform sampler2D texture; diff --git a/resources/shaders/printbed.vs b/resources/shaders/printbed.vs index 7633017f12..3b3f8875d2 100644 --- a/resources/shaders/printbed.vs +++ b/resources/shaders/printbed.vs @@ -1,14 +1,9 @@ #version 110 -attribute vec3 v_position; -attribute vec2 v_tex_coords; - varying vec2 tex_coords; void main() { - gl_Position = gl_ModelViewProjectionMatrix * vec4(v_position.x, v_position.y, v_position.z, 1.0); - // the following line leads to crash on some Intel graphics card - //gl_Position = gl_ModelViewProjectionMatrix * vec4(v_position, 1.0); - tex_coords = v_tex_coords; + gl_Position = ftransform(); + tex_coords = gl_MultiTexCoord0.xy; } diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index c4f1a4407c..01484708ba 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -27,6 +27,7 @@ static const Slic3r::ColorRGBA DEFAULT_TRANSPARENT_GRID_COLOR = { 0.9f, 0.9f, 0 namespace Slic3r { namespace GUI { +#if !ENABLE_GLBEGIN_GLEND_REMOVAL bool GeometryBuffer::set_from_triangles(const std::vector &triangles, float z) { if (triangles.empty()) { @@ -95,6 +96,7 @@ const float* GeometryBuffer::get_vertices_data() const { return (m_vertices.size() > 0) ? (const float*)m_vertices.data() : nullptr; } +#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL const float Bed3D::Axes::DefaultStemRadius = 0.5f; const float Bed3D::Axes::DefaultStemLength = 25.0f; @@ -198,6 +200,13 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c m_model_filename = model_filename; m_extended_bounding_box = this->calc_extended_bounding_box(); +#if ENABLE_GLBEGIN_GLEND_REMOVAL + m_contour = ExPolygon(Polygon::new_scale(bed_shape)); + m_polygon = offset(m_contour.contour, (float)m_contour.contour.bounding_box().radius() * 1.7f, jtRound, scale_(0.5)).front(); + + m_triangles.reset(); + m_gridlines.reset(); +#else ExPolygon poly{ Polygon::new_scale(bed_shape) }; calc_triangles(poly); @@ -205,9 +214,10 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c const BoundingBox& bed_bbox = poly.contour.bounding_box(); calc_gridlines(poly, bed_bbox); - m_polygon = offset(poly.contour, (float)bed_bbox.radius() * 1.7f, jtRound, scale_(0.5))[0]; + m_polygon = offset(poly.contour, (float)bed_bbox.radius() * 1.7f, jtRound, scale_(0.5)).front(); this->release_VBOs(); +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL m_texture.reset(); m_model.reset(); @@ -288,6 +298,105 @@ BoundingBoxf3 Bed3D::calc_extended_bounding_box() const return out; } +#if ENABLE_GLBEGIN_GLEND_REMOVAL +void Bed3D::init_triangles() +{ + if (m_triangles.is_initialized()) + return; + + if (m_contour.empty()) + return; + + const std::vector triangles = triangulate_expolygon_2f(m_contour, NORMALS_UP); + if (triangles.empty() || triangles.size() % 3 != 0) + return; + + const GLModel::Geometry::EIndexType index_type = (triangles.size() < 65536) ? GLModel::Geometry::EIndexType::USHORT : GLModel::Geometry::EIndexType::UINT; + + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3T2, index_type }; + + Vec2f min = triangles.front(); + Vec2f max = min; + for (const Vec2f v : triangles) { + const Vec3f p = { v.x(), v.y(), GROUND_Z }; + min = min.cwiseMin(v).eval(); + max = max.cwiseMax(v).eval(); + } + + const Vec2f size = max - min; + if (size.x() <= 0.0f || size.y() <= 0.0f) + return; + + Vec2f inv_size = size.cwiseInverse(); + inv_size.y() *= -1.0f; + + unsigned int vertices_counter = 0; + for (const Vec2f v : triangles) { + const Vec3f p = { v.x(), v.y(), GROUND_Z }; + init_data.add_vertex(p, (Vec2f)v.cwiseProduct(inv_size).eval()); + ++vertices_counter; + if (vertices_counter % 3 == 0) { + if (index_type == GLModel::Geometry::EIndexType::USHORT) + init_data.add_ushort_triangle((unsigned short)vertices_counter - 3, (unsigned short)vertices_counter - 2, (unsigned short)vertices_counter - 1); + else + init_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1); + } + } + + m_triangles.init_from(std::move(init_data)); +} + +void Bed3D::init_gridlines() +{ + if (m_gridlines.is_initialized()) + return; + + if (m_contour.empty()) + return; + + const BoundingBox& bed_bbox = m_contour.contour.bounding_box(); + const coord_t step = scale_(10.0); + + Polylines axes_lines; + for (coord_t x = bed_bbox.min.x(); x <= bed_bbox.max.x(); x += step) { + Polyline line; + 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.y(); y <= bed_bbox.max.y(); y += step) { + Polyline line; + line.append(Point(bed_bbox.min.x(), y)); + line.append(Point(bed_bbox.max.x(), y)); + axes_lines.push_back(line); + } + + // clip with a slightly grown expolygon because our lines lay on the contours and may get erroneously clipped + Lines gridlines = to_lines(intersection_pl(axes_lines, offset(m_contour, float(SCALED_EPSILON)))); + + // append bed contours + Lines contour_lines = to_lines(m_contour); + std::copy(contour_lines.begin(), contour_lines.end(), std::back_inserter(gridlines)); + + const GLModel::Geometry::EIndexType index_type = (gridlines.size() < 65536 / 2) ? GLModel::Geometry::EIndexType::USHORT : GLModel::Geometry::EIndexType::UINT; + + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, index_type }; + + for (const Line& l : gridlines) { + init_data.add_vertex(Vec3f(unscale(l.a.x()), unscale(l.a.y()), GROUND_Z)); + init_data.add_vertex(Vec3f(unscale(l.b.x()), unscale(l.b.y()), GROUND_Z)); + const unsigned int vertices_counter = (unsigned int)init_data.vertices_count(); + if (index_type == GLModel::Geometry::EIndexType::USHORT) + init_data.add_ushort_line((unsigned short)vertices_counter - 2, (unsigned short)vertices_counter - 1); + else + init_data.add_uint_line(vertices_counter - 2, vertices_counter - 1); + } + + m_gridlines.init_from(std::move(init_data)); +} +#else void Bed3D::calc_triangles(const ExPolygon& poly) { if (! m_triangles.set_from_triangles(triangulate_expolygon_2f(poly, NORMALS_UP), GROUND_Z)) @@ -320,6 +429,7 @@ void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox) if (!m_gridlines.set_from_lines(gridlines, GROUND_Z)) BOOST_LOG_TRIVIAL(error) << "Unable to create bed grid lines\n"; } +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL // Try to match the print bed shape with the shape of an active profile. If such a match exists, // return the print bed model. @@ -421,6 +531,44 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) canvas.request_extra_frame(); } +#if ENABLE_GLBEGIN_GLEND_REMOVAL + init_triangles(); + + GLShaderProgram* shader = wxGetApp().get_shader("printbed"); + if (shader != nullptr) { + shader->start_using(); + shader->set_uniform("transparent_background", bottom); + shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg")); + + glsafe(::glEnable(GL_DEPTH_TEST)); + if (bottom) + glsafe(::glDepthMask(GL_FALSE)); + + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + + if (bottom) + glsafe(::glFrontFace(GL_CW)); + + // show the temporary texture while no compressed data is available + GLuint tex_id = (GLuint)m_temp_texture.get_id(); + if (tex_id == 0) + tex_id = (GLuint)m_texture.get_id(); + + glsafe(::glBindTexture(GL_TEXTURE_2D, tex_id)); + m_triangles.render(); + glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); + + if (bottom) + glsafe(::glFrontFace(GL_CCW)); + + glsafe(::glDisable(GL_BLEND)); + if (bottom) + glsafe(::glDepthMask(GL_TRUE)); + + shader->stop_using(); + } +#else if (m_triangles.get_vertices_count() > 0) { GLShaderProgram* shader = wxGetApp().get_shader("printbed"); if (shader != nullptr) { @@ -488,6 +636,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) shader->stop_using(); } } +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL } void Bed3D::render_model() @@ -541,6 +690,38 @@ void Bed3D::render_default(bool bottom, bool picking) { m_texture.reset(); +#if ENABLE_GLBEGIN_GLEND_REMOVAL + init_gridlines(); + init_triangles(); + + GLShaderProgram* shader = wxGetApp().get_shader("flat"); + if (shader != nullptr) { + shader->start_using(); + + glsafe(::glEnable(GL_DEPTH_TEST)); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + + if (m_model.get_filename().empty() && !bottom) { + // draw background + glsafe(::glDepthMask(GL_FALSE)); + m_triangles.set_color(picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR); + m_triangles.render(); + glsafe(::glDepthMask(GL_TRUE)); + } + + if (!picking) { + // draw grid + glsafe(::glLineWidth(1.5f * m_scale_factor)); + m_gridlines.set_color(picking ? DEFAULT_SOLID_GRID_COLOR : DEFAULT_TRANSPARENT_GRID_COLOR); + m_gridlines.render(); + } + + glsafe(::glDisable(GL_BLEND)); + + shader->stop_using(); + } +#else const unsigned int triangles_vcount = m_triangles.get_vertices_count(); if (triangles_vcount > 0) { const bool has_model = !m_model.get_filename().empty(); @@ -573,8 +754,10 @@ void Bed3D::render_default(bool bottom, bool picking) glsafe(::glDisable(GL_BLEND)); } +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL } +#if !ENABLE_GLBEGIN_GLEND_REMOVAL void Bed3D::release_VBOs() { if (m_vbo_id > 0) { @@ -582,6 +765,7 @@ void Bed3D::release_VBOs() m_vbo_id = 0; } } +#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL } // GUI } // Slic3r diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 82c6b817be..350ae48f6a 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -5,7 +5,10 @@ #include "3DScene.hpp" #include "GLModel.hpp" -#include +#include "libslic3r/BuildVolume.hpp" +#if ENABLE_GLBEGIN_GLEND_REMOVAL +#include "libslic3r/ExPolygon.hpp" +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL #include #include @@ -15,6 +18,7 @@ namespace GUI { class GLCanvas3D; +#if !ENABLE_GLBEGIN_GLEND_REMOVAL class GeometryBuffer { struct Vertex @@ -36,6 +40,7 @@ public: size_t get_tex_coords_offset() const { return (size_t)(3 * sizeof(float)); } unsigned int get_vertices_count() const { return (unsigned int)m_vertices.size(); } }; +#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL class Bed3D { @@ -79,23 +84,38 @@ private: std::string m_model_filename; // Print volume bounding box exteded with axes and model. BoundingBoxf3 m_extended_bounding_box; +#if ENABLE_GLBEGIN_GLEND_REMOVAL + // Print bed polygon + ExPolygon m_contour; +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL // Slightly expanded print bed polygon, for collision detection. Polygon m_polygon; +#if ENABLE_GLBEGIN_GLEND_REMOVAL + GLModel m_triangles; + GLModel m_gridlines; +#else GeometryBuffer m_triangles; GeometryBuffer m_gridlines; +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL GLTexture m_texture; // temporary texture shown until the main texture has still no levels compressed GLTexture m_temp_texture; GLModel m_model; Vec3d m_model_offset{ Vec3d::Zero() }; +#if !ENABLE_GLBEGIN_GLEND_REMOVAL unsigned int m_vbo_id{ 0 }; +#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL Axes m_axes; float m_scale_factor{ 1.0f }; public: Bed3D() = default; +#if ENABLE_GLBEGIN_GLEND_REMOVAL + ~Bed3D() = default; +#else ~Bed3D() { release_VBOs(); } +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL // Update print bed model from configuration. // Return true if the bed shape changed, so the calee will update the UI. @@ -125,8 +145,13 @@ public: private: // Calculate an extended bounding box from axes and current model for visualization purposes. BoundingBoxf3 calc_extended_bounding_box() const; +#if ENABLE_GLBEGIN_GLEND_REMOVAL + void init_triangles(); + void init_gridlines(); +#else void calc_triangles(const ExPolygon& poly); void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox); +#endif // ENABLE_GLBEGIN_GLEND_REMOVAL static std::tuple detect_type(const Pointfs& shape); void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture, bool picking); @@ -136,7 +161,9 @@ private: void render_model(); void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking); void render_default(bool bottom, bool picking); +#if !ENABLE_GLBEGIN_GLEND_REMOVAL void release_VBOs(); +#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL }; } // GUI diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 4d3be069ca..8ac1e5534d 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -42,6 +42,16 @@ void GLModel::Geometry::add_vertex(const Vec3f& position) vertices.emplace_back(position.z()); } +void GLModel::Geometry::add_vertex(const Vec3f& position, const Vec2f& tex_coord) +{ + assert(format.vertex_layout == EVertexLayout::P3T2); + vertices.emplace_back(position.x()); + vertices.emplace_back(position.y()); + vertices.emplace_back(position.z()); + vertices.emplace_back(tex_coord.x()); + vertices.emplace_back(tex_coord.y()); +} + void GLModel::Geometry::add_vertex(const Vec3f& position, const Vec3f& normal) { assert(format.vertex_layout == EVertexLayout::P3N3); @@ -228,6 +238,7 @@ size_t GLModel::Geometry::vertex_stride_floats(const Format& format) case EVertexLayout::P2: { return 2; } case EVertexLayout::P2T2: { return 4; } case EVertexLayout::P3: { return 3; } + case EVertexLayout::P3T2: { return 5; } case EVertexLayout::P3N3: { return 6; } default: { assert(false); return 0; } }; @@ -240,6 +251,7 @@ size_t GLModel::Geometry::position_stride_floats(const Format& format) case EVertexLayout::P2: case EVertexLayout::P2T2: { return 2; } case EVertexLayout::P3: + case EVertexLayout::P3T2: case EVertexLayout::P3N3: { return 3; } default: { assert(false); return 0; } }; @@ -252,6 +264,7 @@ size_t GLModel::Geometry::position_offset_floats(const Format& format) case EVertexLayout::P2: case EVertexLayout::P2T2: case EVertexLayout::P3: + case EVertexLayout::P3T2: case EVertexLayout::P3N3: { return 0; } default: { assert(false); return 0; } }; @@ -279,7 +292,8 @@ size_t GLModel::Geometry::tex_coord_stride_floats(const Format& format) { switch (format.vertex_layout) { - case EVertexLayout::P2T2: { return 2; } + case EVertexLayout::P2T2: + case EVertexLayout::P3T2: { return 2; } default: { assert(false); return 0; } }; } @@ -289,6 +303,7 @@ size_t GLModel::Geometry::tex_coord_offset_floats(const Format& format) switch (format.vertex_layout) { case EVertexLayout::P2T2: { return 2; } + case EVertexLayout::P3T2: { return 3; } default: { assert(false); return 0; } }; } @@ -310,6 +325,7 @@ bool GLModel::Geometry::has_position(const Format& format) case EVertexLayout::P2: case EVertexLayout::P2T2: case EVertexLayout::P3: + case EVertexLayout::P3T2: case EVertexLayout::P3N3: { return true; } default: { assert(false); return false; } }; @@ -321,7 +337,8 @@ bool GLModel::Geometry::has_normal(const Format& format) { case EVertexLayout::P2: case EVertexLayout::P2T2: - case EVertexLayout::P3: { return false; } + case EVertexLayout::P3: + case EVertexLayout::P3T2: { return false; } case EVertexLayout::P3N3: { return true; } default: { assert(false); return false; } }; @@ -331,7 +348,8 @@ bool GLModel::Geometry::has_tex_coord(const Format& format) { switch (format.vertex_layout) { - case EVertexLayout::P2T2: { return true; } + case EVertexLayout::P2T2: + case EVertexLayout::P3T2: { return true; } case EVertexLayout::P2: case EVertexLayout::P3: case EVertexLayout::P3N3: { return false; } diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 61456f3773..c02f5186ca 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -58,6 +58,7 @@ namespace GUI { P2, // position 2 floats P2T2, // position 2 floats + texture coords 2 floats P3, // position 3 floats + P3T2, // position 3 floats + texture coords 2 floats P3N3, // position 3 floats + normal 3 floats }; @@ -82,6 +83,7 @@ namespace GUI { void add_vertex(const Vec2f& position); void add_vertex(const Vec2f& position, const Vec2f& tex_coord); void add_vertex(const Vec3f& position); + void add_vertex(const Vec3f& position, const Vec2f& tex_coord); void add_vertex(const Vec3f& position, const Vec3f& normal); void add_ushort_index(unsigned short id);