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 786cd40133..68d2d89f85 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -35,6 +35,53 @@ static const Slic3r::ColorRGBA DEFAULT_TRANSPARENT_GRID_COLOR = { 0.9f, 0.9f, 0 namespace Slic3r { namespace GUI { +bool init_model_from_poly(GLModel &model, const ExPolygon &poly, float z) +{ + if (poly.empty()) + return false; + + const std::vector triangles = triangulate_expolygon_2f(poly, NORMALS_UP); + if (triangles.empty() || triangles.size() % 3 != 0) + return false; + + 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) { + 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 false; + + 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(), z}; + init_data.add_vertex(p, (Vec2f)(v - min).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); + } + } + + model.init_from(std::move(init_data)); + + return true; +} + +/* bool GeometryBuffer::set_from_triangles(const std::vector &triangles, float z) { if (triangles.empty()) { @@ -133,6 +180,7 @@ const float* GeometryBuffer::get_vertices_data() const { return (m_vertices.size() > 0) ? (const float*)m_vertices.data() : nullptr; } +*/ const float Bed3D::Axes::DefaultStemRadius = 0.5f; const float Bed3D::Axes::DefaultStemLength = 25.0f; @@ -261,25 +309,9 @@ bool Bed3D::set_shape(const Pointfs& printable_area, const double printable_heig //BBS: add part plate logic //BBS add default bed -#if 1 - ExPolygon poly{ Polygon::new_scale(printable_area) }; -#else - ExPolygon poly; - for (const Vec2d& p : printable_area) { - poly.contour.append(Point(scale_(p(0) + m_position.x()), scale_(p(1) + m_position.y()))); - } -#endif - - calc_triangles(poly); - - //no need gridline for 3dbed - //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_triangles.reset(); if (with_reset) { - this->release_VBOs(); //m_texture.reset(); m_model.reset(); } @@ -390,39 +422,6 @@ BoundingBoxf3 Bed3D::calc_extended_bounding_box(bool consider_model_offset) cons return out; } -void Bed3D::calc_triangles(const ExPolygon& poly) -{ - if (! m_triangles.set_from_triangles(triangulate_expolygon_2f(poly, NORMALS_UP), GROUND_Z)) - BOOST_LOG_TRIVIAL(error) << "Unable to create bed triangles"; -} - -void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox) -{ - /*Polylines axes_lines; - 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.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 += scale_(10.0)) { - 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(poly, (float)SCALED_EPSILON))); - - // append bed contours - Lines contour_lines = to_lines(poly); - std::copy(contour_lines.begin(), contour_lines.end(), std::back_inserter(gridlines)); - - if (!m_gridlines.set_from_lines(gridlines, GROUND_Z)) - BOOST_LOG_TRIVIAL(error) << "Unable to create bed grid lines\n";*/ -} - // Try to match the print bed shape with the shape of an active profile. If such a match exists, // return the print bed model. std::tuple Bed3D::detect_type(const Pointfs& shape) @@ -626,9 +625,10 @@ void Bed3D::update_model_offset() const const_cast(m_extended_bounding_box) = calc_extended_bounding_box(); } -GeometryBuffer Bed3D::update_bed_triangles() const +void Bed3D::update_bed_triangles() { - GeometryBuffer new_triangles; + m_triangles.reset(); + Vec3d shift = m_extended_bounding_box.center(); shift(2) = -0.03; Vec3d* model_offset_ptr = const_cast(&m_model_offset); @@ -636,7 +636,7 @@ GeometryBuffer Bed3D::update_bed_triangles() const //BBS: TODO: hack for default bed BoundingBoxf3 build_volume; - if (!m_build_volume.valid()) return new_triangles; + if (!m_build_volume.valid()) return; auto bed_ext = get_extents(m_bed_shape); (*model_offset_ptr)(0) = m_build_volume.bounding_volume2d().min.x() - bed_ext.min.x(); (*model_offset_ptr)(1) = m_build_volume.bounding_volume2d().min.y() - bed_ext.min.y(); @@ -648,12 +648,11 @@ GeometryBuffer Bed3D::update_bed_triangles() const new_bed_shape.push_back(new_point); } ExPolygon poly{ Polygon::new_scale(new_bed_shape) }; - if (!new_triangles.set_from_triangles(triangulate_expolygon_2f(poly, NORMALS_UP), GROUND_Z)) { - ; + if (!init_model_from_poly(m_triangles, poly, GROUND_Z)) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":Unable to update plate triangles\n"; } // update extended bounding box const_cast(m_extended_bounding_box) = calc_extended_bounding_box(); - return new_triangles; } void Bed3D::render_model() @@ -700,46 +699,34 @@ void Bed3D::render_default(bool bottom) bool picking = false; m_texture.reset(); - const unsigned int triangles_vcount = m_triangles.get_vertices_count(); - GeometryBuffer default_triangles = update_bed_triangles(); - if (triangles_vcount > 0) { - const bool has_model = !m_model.get_filename().empty(); + update_bed_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)); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - - if (!has_model && !bottom) { + if (m_model.get_filename().empty() && !bottom) { // draw background glsafe(::glDepthMask(GL_FALSE)); - glsafe(::glColor4fv(picking ? PICKING_MODEL_COLOR.data() : DEFAULT_MODEL_COLOR.data())); - glsafe(::glNormal3d(0.0f, 0.0f, 1.0f)); - glsafe(::glVertexPointer(3, GL_FLOAT, default_triangles.get_vertex_data_size(), (GLvoid*)default_triangles.get_vertices_data())); - glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount)); + 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)); - glsafe(::glColor4fv(has_model && !bottom ? DEFAULT_SOLID_GRID_COLOR.data() : DEFAULT_TRANSPARENT_GRID_COLOR.data())); - glsafe(::glVertexPointer(3, GL_FLOAT, default_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data())); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines.get_vertices_count())); + m_gridlines.set_color(picking ? DEFAULT_SOLID_GRID_COLOR : DEFAULT_TRANSPARENT_GRID_COLOR); + m_gridlines.render(); }*/ - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glDisable(GL_BLEND)); - } -} -void Bed3D::release_VBOs() -{ - if (m_vbo_id > 0) { - glsafe(::glDeleteBuffers(1, &m_vbo_id)); - m_vbo_id = 0; + shader->stop_using(); } } diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 7bb4ebfb74..661dee47b7 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -5,7 +5,8 @@ #include "3DScene.hpp" #include "GLModel.hpp" -#include +#include "libslic3r/BuildVolume.hpp" +#include "libslic3r/ExPolygon.hpp" #include #include @@ -15,6 +16,7 @@ namespace GUI { class GLCanvas3D; +/* class GeometryBuffer { struct Vertex @@ -38,6 +40,9 @@ 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(); } }; +*/ + +bool init_model_from_poly(GLModel &model, const ExPolygon &poly, float z); class Bed3D { @@ -91,14 +96,13 @@ private: BoundingBoxf3 m_extended_bounding_box; // Slightly expanded print bed polygon, for collision detection. //Polygon m_polygon; - GeometryBuffer m_triangles; - //GeometryBuffer m_gridlines; + GLModel m_triangles; + //GLModel m_gridlines; 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() }; - unsigned int m_vbo_id{ 0 }; Axes m_axes; float m_scale_factor{ 1.0f }; @@ -109,7 +113,7 @@ private: public: Bed3D() = default; - ~Bed3D() { release_VBOs(); } + ~Bed3D() = default; // Update print bed model from configuration. // Return true if the bed shape changed, so the calee will update the UI. @@ -151,11 +155,9 @@ private: //BBS: add partplate related logic // Calculate an extended bounding box from axes and current model for visualization purposes. BoundingBoxf3 calc_extended_bounding_box(bool consider_model_offset = true) const; - void calc_triangles(const ExPolygon& poly); - void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox); void update_model_offset() const; //BBS: with offset - GeometryBuffer update_bed_triangles() const; + void update_bed_triangles(); static std::tuple detect_type(const Pointfs& shape); void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes); @@ -165,7 +167,6 @@ private: void render_model(); void render_custom(GLCanvas3D& canvas, bool bottom); void render_default(bool bottom); - void release_VBOs(); }; } // GUI diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 57b14715ea..e1d18a70cb 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -41,6 +41,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); @@ -227,6 +237,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; } }; @@ -239,6 +250,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; } }; @@ -251,6 +263,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; } }; @@ -278,7 +291,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; } }; } @@ -288,6 +302,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; } }; } @@ -309,6 +324,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; } }; @@ -320,7 +336,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; } }; @@ -330,7 +347,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 54f96edaa5..fae1c63153 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -38,6 +38,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 }; @@ -62,6 +63,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); diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 546fd65546..67137e1621 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -151,7 +151,6 @@ PartPlate::~PartPlate() clear(); //if (m_quadric != nullptr) // ::gluDeleteQuadric(m_quadric); - release_opengl_resource(); //boost::nowide::remove(m_tmp_gcode_path.c_str()); } @@ -170,7 +169,6 @@ void PartPlate::init() m_print_index = -1; m_print = nullptr; - m_plate_name_vbo_id = 0; } BedType PartPlate::get_bed_type(bool load_from_project) const @@ -333,17 +331,71 @@ void PartPlate::calc_bounding_boxes() const { } } -void PartPlate::calc_triangles(const ExPolygon& poly) { - if (!m_triangles.set_from_triangles(triangulate_expolygon_2f(poly, NORMALS_UP), GROUND_Z)) +void PartPlate::calc_triangles(const ExPolygon &poly) +{ + m_triangles.reset(); + + if (!init_model_from_poly(m_triangles, poly, GROUND_Z)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":Unable to create plate triangles\n"; } -void PartPlate::calc_exclude_triangles(const ExPolygon& poly) { - if (!m_exclude_triangles.set_from_triangles(triangulate_expolygon_2f(poly, NORMALS_UP), GROUND_Z)) +void PartPlate::calc_exclude_triangles(const ExPolygon &poly) +{ + m_exclude_triangles.reset(); + + if (!init_model_from_poly(m_exclude_triangles, poly, GROUND_Z)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":Unable to create exclude triangles\n"; } +static bool init_model_from_lines(GLModel &model, const Lines &lines, float z) +{ + const GLModel::Geometry::EIndexType index_type = (lines.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 auto &l : lines) { + init_data.add_vertex(Vec3f(unscale(l.a.x()), unscale(l.a.y()), z)); + init_data.add_vertex(Vec3f(unscale(l.b.x()), unscale(l.b.y()), 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); + } + + model.init_from(std::move(init_data)); + + return true; +} + +static bool init_model_from_lines(GLModel &model, const Lines3 &lines) +{ + const GLModel::Geometry::EIndexType index_type = (lines.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 auto &l : lines) { + init_data.add_vertex(Vec3f(unscale(l.a.x()), unscale(l.a.y()), unscale(l.a.z()))); + init_data.add_vertex(Vec3f(unscale(l.b.x()), unscale(l.b.y()), unscale(l.b.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); + } + + model.init_from(std::move(init_data)); + + return true; +} + void PartPlate::calc_gridlines(const ExPolygon& poly, const BoundingBox& pp_bbox) { + m_gridlines.reset(); + m_gridlines_bolder.reset(); + Polylines axes_lines, axes_lines_bolder; int count = 0; for (coord_t x = pp_bbox.min(0); x <= pp_bbox.max(0); x += scale_(10.0)) { @@ -379,14 +431,18 @@ void PartPlate::calc_gridlines(const ExPolygon& poly, const BoundingBox& pp_bbox Lines contour_lines = to_lines(poly); std::copy(contour_lines.begin(), contour_lines.end(), std::back_inserter(gridlines)); - if (!m_gridlines.set_from_lines(gridlines, GROUND_Z_GRIDLINE)) + if (!init_model_from_lines(m_gridlines, gridlines, GROUND_Z_GRIDLINE)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to create bed grid lines\n"; - if (!m_gridlines_bolder.set_from_lines(gridlines_bolder, GROUND_Z_GRIDLINE)) + if (!init_model_from_lines(m_gridlines_bolder, gridlines_bolder, GROUND_Z_GRIDLINE)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to create bed grid lines\n"; } void PartPlate::calc_height_limit() { + m_height_limit_common.reset(); + m_height_limit_bottom.reset(); + m_height_limit_top.reset(); + Lines3 bottom_h_lines, top_lines, top_h_lines, common_lines; int shape_count = m_shape.size(); float first_z = 0.02f; @@ -418,18 +474,20 @@ void PartPlate::calc_height_limit() { //std::copy(bottom_lines.begin(), bottom_lines.end(), std::back_inserter(bottom_h_lines)); std::copy(top_lines.begin(), top_lines.end(), std::back_inserter(top_h_lines)); - if (!m_height_limit_common.set_from_3d_Lines(common_lines)) + if (!init_model_from_lines(m_height_limit_common, common_lines)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to create height limit bottom lines\n"; - if (!m_height_limit_bottom.set_from_3d_Lines(bottom_h_lines)) + if (!init_model_from_lines(m_height_limit_bottom, bottom_h_lines)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to create height limit bottom lines\n"; - if (!m_height_limit_top.set_from_3d_Lines(top_h_lines)) + if (!init_model_from_lines(m_height_limit_top, top_h_lines)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to create height limit top lines\n"; } -void PartPlate::calc_vertex_for_number(int index, bool one_number, GeometryBuffer &buffer) +void PartPlate::calc_vertex_for_number(int index, bool one_number, GLModel &buffer) { + buffer.reset(); + ExPolygon poly; #if 0 //in the up area Vec2d& p = m_shape[2]; @@ -449,13 +507,14 @@ void PartPlate::calc_vertex_for_number(int index, bool one_number, GeometryBuffe poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + PARTPLATE_ICON_SIZE - offset_x), scale_(p(1) + PARTPLATE_ICON_SIZE - PARTPLATE_TEXT_OFFSET_Y)}); poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x), scale_(p(1) + PARTPLATE_ICON_SIZE - PARTPLATE_TEXT_OFFSET_Y) }); #endif - auto triangles = triangulate_expolygon_2f(poly, NORMALS_UP); - if (!buffer.set_from_triangles(triangles, GROUND_Z)) + if (!init_model_from_poly(buffer, poly, GROUND_Z)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to generate geometry buffers for icons\n"; } -void PartPlate::calc_vertex_for_icons(int index, GeometryBuffer &buffer) +void PartPlate::calc_vertex_for_icons(int index, GLModel &buffer) { + buffer.reset(); + ExPolygon poly; auto bed_ext = get_extents(m_shape); Vec2d p = bed_ext[2]; @@ -468,13 +527,14 @@ void PartPlate::calc_vertex_for_icons(int index, GeometryBuffer &buffer) poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + PARTPLATE_ICON_SIZE), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y)- PARTPLATE_ICON_GAP_TOP)}); poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT), scale_(p(1) - index * (PARTPLATE_ICON_SIZE + PARTPLATE_ICON_GAP_Y)- PARTPLATE_ICON_GAP_TOP) }); - auto triangles = triangulate_expolygon_2f(poly, NORMALS_UP); - if (!buffer.set_from_triangles(triangles, GROUND_Z)) + if (!init_model_from_poly(buffer, poly, GROUND_Z)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to generate geometry buffers for icons\n"; } -void PartPlate::calc_vertex_for_icons_background(int icon_count, GeometryBuffer &buffer) +void PartPlate::calc_vertex_for_icons_background(int icon_count, GLModel &buffer) { + buffer.reset(); + ExPolygon poly; auto bed_ext = get_extents(m_shape); Vec2d p = bed_ext[2]; @@ -484,38 +544,36 @@ void PartPlate::calc_vertex_for_icons_background(int icon_count, GeometryBuffer poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + PARTPLATE_ICON_SIZE), scale_(p(1) - PARTPLATE_ICON_GAP_TOP)}); poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT), scale_(p(1) - PARTPLATE_ICON_GAP_TOP) }); - auto triangles = triangulate_expolygon_2f(poly, NORMALS_UP); - if (!buffer.set_from_triangles(triangles, GROUND_Z)) + if (!init_model_from_poly(buffer, poly, GROUND_Z)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to generate geometry buffers for icons\n"; } -void PartPlate::render_background(bool force_default_color) const { - unsigned int triangles_vcount = m_triangles.get_vertices_count(); - +void PartPlate::render_background(bool force_default_color) +{ //return directly for current plate if (m_selected && !force_default_color) return; // draw background glsafe(::glDepthMask(GL_FALSE)); + ColorRGBA color; if (!force_default_color) { if (m_selected) { - glsafe(::glColor4fv(PartPlate::SELECT_COLOR.data())); + color = PartPlate::SELECT_COLOR; } else { - glsafe(m_partplate_list->m_is_dark ? ::glColor4fv(PartPlate::UNSELECT_DARK_COLOR.data()) : ::glColor4fv(PartPlate::UNSELECT_COLOR.data())); + color = m_partplate_list->m_is_dark ? PartPlate::UNSELECT_DARK_COLOR : PartPlate::UNSELECT_COLOR; } } else { - glsafe(::glColor4fv(PartPlate::DEFAULT_COLOR.data())); + color = PartPlate::DEFAULT_COLOR; } - 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)); + m_triangles.set_color(color); + m_triangles.render(); glsafe(::glDepthMask(GL_TRUE)); } -void PartPlate::render_logo_texture(GLTexture &logo_texture, const GeometryBuffer& logo_buffer, bool bottom, unsigned int vbo_id) const +void PartPlate::render_logo_texture(GLTexture &logo_texture, GLModel& logo_buffer, bool bottom) { //check valid if (logo_texture.unsent_compressed_data_available()) { @@ -523,7 +581,7 @@ void PartPlate::render_logo_texture(GLTexture &logo_texture, const GeometryBuffe logo_texture.send_compressed_data_to_gpu(); } - if (logo_buffer.get_vertices_count() > 0) { + if (logo_buffer.is_initialized()) { GLShaderProgram* shader = wxGetApp().get_shader("printbed"); if (shader != nullptr) { shader->start_using(); @@ -532,44 +590,25 @@ void PartPlate::render_logo_texture(GLTexture &logo_texture, const GeometryBuffe //glsafe(::glEnable(GL_DEPTH_TEST)); glsafe(::glDepthMask(GL_FALSE)); + + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + if (bottom) glsafe(::glFrontFace(GL_CW)); - unsigned int stride = logo_buffer.get_vertex_data_size(); - - GLint position_id = shader->get_attrib_location("v_position"); - GLint tex_coords_id = shader->get_attrib_location("v_tex_coords"); - if (position_id != -1) { - glsafe(::glEnableVertexAttribArray(position_id)); - } - if (tex_coords_id != -1) { - glsafe(::glEnableVertexAttribArray(tex_coords_id)); - } - // show the temporary texture while no compressed data is available GLuint tex_id = (GLuint)logo_texture.get_id(); glsafe(::glBindTexture(GL_TEXTURE_2D, tex_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, vbo_id)); - - if (position_id != -1) - glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)(intptr_t)logo_buffer.get_position_offset())); - if (tex_coords_id != -1) - glsafe(::glVertexAttribPointer(tex_coords_id, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)(intptr_t)logo_buffer.get_tex_coords_offset())); - glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)logo_buffer.get_vertices_count())); - - if (tex_coords_id != -1) - glsafe(::glDisableVertexAttribArray(tex_coords_id)); - - if (position_id != -1) - glsafe(::glDisableVertexAttribArray(position_id)); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + logo_buffer.render(); glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); if (bottom) glsafe(::glFrontFace(GL_CCW)); + glsafe(::glDisable(GL_BLEND)); + glsafe(::glDepthMask(GL_TRUE)); shader->stop_using(); @@ -577,7 +616,7 @@ void PartPlate::render_logo_texture(GLTexture &logo_texture, const GeometryBuffe } } -void PartPlate::render_logo(bool bottom, bool render_cali) const +void PartPlate::render_logo(bool bottom, bool render_cali) { if (!m_partplate_list->render_bedtype_logo) { // render third-party printer texture logo @@ -643,15 +682,8 @@ void PartPlate::render_logo(bool bottom, bool render_cali) const //canvas.request_extra_frame(); } - if (m_vbo_id == 0) { - unsigned int* vbo_id_ptr = const_cast(&m_vbo_id); - glsafe(::glGenBuffers(1, vbo_id_ptr)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, *vbo_id_ptr)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_logo_triangles.get_vertices_data_size(), (const GLvoid*)m_logo_triangles.get_vertices_data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - } - if (m_vbo_id != 0 && m_logo_triangles.get_vertices_count() > 0) - render_logo_texture(m_partplate_list->m_logo_texture, m_logo_triangles, bottom, m_vbo_id); + if (m_logo_triangles.is_initialized()) + render_logo_texture(m_partplate_list->m_logo_texture, m_logo_triangles, bottom); return; } @@ -669,7 +701,7 @@ void PartPlate::render_logo(bool bottom, bool render_cali) const // render bed textures for (auto &part : m_partplate_list->bed_texture_info[bed_type_idx].parts) { if (part.texture) { - if (part.buffer && part.buffer->get_vertices_count() > 0 + if (part.buffer && part.buffer->is_initialized() //&& part.vbo_id != 0 ) { if (part.offset.x() != m_origin.x() || part.offset.y() != m_origin.y()) { @@ -678,8 +710,7 @@ void PartPlate::render_logo(bool bottom, bool render_cali) const } render_logo_texture(*(part.texture), *(part.buffer), - bottom, - part.vbo_id); + bottom); } } } @@ -688,29 +719,27 @@ void PartPlate::render_logo(bool bottom, bool render_cali) const if (render_cali) { for (auto& part : m_partplate_list->cali_texture_info.parts) { if (part.texture) { - if (part.buffer && part.buffer->get_vertices_count() > 0) { + if (part.buffer && part.buffer->is_initialized()) { if (part.offset.x() != m_origin.x() || part.offset.y() != m_origin.y()) { part.offset = Vec2d(m_origin.x(), m_origin.y()); part.update_buffer(); } render_logo_texture(*(part.texture), *(part.buffer), - bottom, - part.vbo_id); + bottom); } } } } } -void PartPlate::render_exclude_area(bool force_default_color) const { +void PartPlate::render_exclude_area(bool force_default_color) { if (force_default_color) //for thumbnail case return; - unsigned int triangles_vcount = m_exclude_triangles.get_vertices_count(); ColorRGBA select_color{ 0.765f, 0.7686f, 0.7686f, 1.0f }; ColorRGBA unselect_color{ 0.9f, 0.9f, 0.9f, 1.0f }; - ColorRGBA default_color{ 0.9f, 0.9f, 0.9f, 1.0f }; + //ColorRGBA default_color{ 0.9f, 0.9f, 0.9f, 1.0f }; // draw exclude area glsafe(::glDepthMask(GL_FALSE)); @@ -722,9 +751,8 @@ void PartPlate::render_exclude_area(bool force_default_color) const { glsafe(::glColor4fv(unselect_color.data())); } - glsafe(::glNormal3d(0.0f, 0.0f, 1.0f)); - glsafe(::glVertexPointer(3, GL_FLOAT, m_exclude_triangles.get_vertex_data_size(), (GLvoid*)m_exclude_triangles.get_vertices_data())); - glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount)); + m_exclude_triangles.set_color(m_selected ? select_color : unselect_color); + m_exclude_triangles.render(); glsafe(::glDepthMask(GL_TRUE)); } @@ -741,99 +769,68 @@ void PartPlate::render_exclude_area(bool force_default_color) const { glsafe(::glDepthMask(GL_TRUE)); }*/ -void PartPlate::render_grid(bool bottom) const { +void PartPlate::render_grid(bool bottom) { //glsafe(::glEnable(GL_MULTISAMPLE)); // draw grid glsafe(::glLineWidth(1.0f * m_scale_factor)); + + ColorRGBA color; if (bottom) - glsafe(::glColor4fv(LINE_BOTTOM_COLOR.data())); + color = LINE_BOTTOM_COLOR; else { if (m_selected) - glsafe(m_partplate_list->m_is_dark ? ::glColor4fv(LINE_TOP_SEL_DARK_COLOR.data()) : ::glColor4fv(LINE_TOP_SEL_COLOR.data())); + color = m_partplate_list->m_is_dark ? LINE_TOP_SEL_DARK_COLOR : LINE_TOP_SEL_COLOR; else - glsafe(m_partplate_list->m_is_dark ? ::glColor4fv(LINE_TOP_DARK_COLOR.data()) : ::glColor4fv(LINE_TOP_COLOR.data())); + color = m_partplate_list->m_is_dark ? LINE_TOP_DARK_COLOR : LINE_TOP_COLOR; } - glsafe(::glVertexPointer(3, GL_FLOAT, m_gridlines.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data())); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines.get_vertices_count())); + m_gridlines.set_color(color); + m_gridlines.render(); glsafe(::glLineWidth(2.0f * m_scale_factor)); - glsafe(::glVertexPointer(3, GL_FLOAT, m_gridlines_bolder.get_vertex_data_size(), (GLvoid*)m_gridlines_bolder.get_vertices_data())); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines_bolder.get_vertices_count())); + m_gridlines_bolder.set_color(color); + m_gridlines_bolder.render(); } -void PartPlate::render_height_limit(PartPlate::HeightLimitMode mode) const +void PartPlate::render_height_limit(PartPlate::HeightLimitMode mode) { if (m_print && m_print->config().print_sequence == PrintSequence::ByObject && mode != HEIGHT_LIMIT_NONE) { // draw lower limit glsafe(::glLineWidth(3.0f * m_scale_factor)); - glsafe(::glColor4fv(HEIGHT_LIMIT_BOTTOM_COLOR.data())); - glsafe(::glVertexPointer(3, GL_FLOAT, m_height_limit_common.get_vertex_data_size(), (GLvoid*)m_height_limit_common.get_vertices_data())); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_height_limit_common.get_vertices_count())); + m_height_limit_common.set_color(HEIGHT_LIMIT_BOTTOM_COLOR); + m_height_limit_common.render(); if ((mode == HEIGHT_LIMIT_BOTTOM) || (mode == HEIGHT_LIMIT_BOTH)) { glsafe(::glLineWidth(3.0f * m_scale_factor)); - glsafe(::glColor4fv(HEIGHT_LIMIT_BOTTOM_COLOR.data())); - glsafe(::glVertexPointer(3, GL_FLOAT, m_height_limit_bottom.get_vertex_data_size(), (GLvoid*)m_height_limit_bottom.get_vertices_data())); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_height_limit_bottom.get_vertices_count())); + m_height_limit_bottom.set_color(HEIGHT_LIMIT_BOTTOM_COLOR); + m_height_limit_bottom.render(); } // draw upper limit if ((mode == HEIGHT_LIMIT_TOP) || (mode == HEIGHT_LIMIT_BOTH)){ - glsafe(::glLineWidth(3.0f * m_scale_factor)); - glsafe(::glColor4fv(HEIGHT_LIMIT_TOP_COLOR.data())); - glsafe(::glVertexPointer(3, GL_FLOAT, m_height_limit_top.get_vertex_data_size(), (GLvoid*)m_height_limit_top.get_vertices_data())); - glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_height_limit_top.get_vertices_count())); + glsafe(::glLineWidth(3.0f * m_scale_factor)); + m_height_limit_top.set_color(HEIGHT_LIMIT_TOP_COLOR); + m_height_limit_top.render(); } } } - -void PartPlate::render_icon_texture(int position_id, int tex_coords_id, const GeometryBuffer &buffer, GLTexture &texture, unsigned int &vbo_id) const +void PartPlate::render_icon_texture(GLModel &buffer, GLTexture &texture) { - if (vbo_id == 0) { - glsafe(::glGenBuffers(1, &vbo_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, vbo_id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)buffer.get_vertices_data_size(), (const GLvoid*)buffer.get_vertices_data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - } - - unsigned int stride = buffer.get_vertex_data_size(); GLuint tex_id = (GLuint)texture.get_id(); glsafe(::glBindTexture(GL_TEXTURE_2D, tex_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, vbo_id)); - if (position_id != -1) - glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)(intptr_t)buffer.get_position_offset())); - if (tex_coords_id != -1) - glsafe(::glVertexAttribPointer(tex_coords_id, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)(intptr_t)buffer.get_tex_coords_offset())); - glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)buffer.get_vertices_count())); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + buffer.render(); glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); } -void PartPlate::render_plate_name_texture(int position_id, int tex_coords_id) + +void PartPlate::render_plate_name_texture() { if (m_name_texture.get_id() == 0) generate_plate_name_texture(); - if (m_plate_name_vbo_id == 0 && m_plate_name_icon.get_vertices_data_size() > 0) { - glsafe(::glGenBuffers(1, &m_plate_name_vbo_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_plate_name_vbo_id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_plate_name_icon.get_vertices_data_size(), (const GLvoid*)m_plate_name_icon.get_vertices_data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - } - - unsigned int stride = m_plate_name_icon.get_vertex_data_size(); GLuint tex_id = (GLuint)m_name_texture.get_id(); glsafe(::glBindTexture(GL_TEXTURE_2D, tex_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_plate_name_vbo_id)); - if (position_id != -1) - glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)(intptr_t)m_plate_name_icon.get_position_offset())); - if (tex_coords_id != -1) - glsafe(::glVertexAttribPointer(tex_coords_id, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)(intptr_t)m_plate_name_icon.get_tex_coords_offset())); - glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)m_plate_name_icon.get_vertices_count())); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + m_plate_name_icon.render(); glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); } @@ -865,92 +862,72 @@ void PartPlate::render_icons(bool bottom, bool only_name, int hover_id) // glsafe(::glFrontFace(GL_CW)); glsafe(::glDepthMask(GL_FALSE)); - GLint position_id = shader->get_attrib_location("v_position"); - GLint tex_coords_id = shader->get_attrib_location("v_tex_coords"); - if (position_id != -1) { - glsafe(::glEnableVertexAttribArray(position_id)); - } - if (tex_coords_id != -1) { - glsafe(::glEnableVertexAttribArray(tex_coords_id)); - } + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + if (!only_name) { if (hover_id == 1) { - render_icon_texture(position_id, tex_coords_id, m_del_icon, m_partplate_list->m_del_hovered_texture, - m_del_vbo_id); + render_icon_texture(m_del_icon, m_partplate_list->m_del_hovered_texture); show_tooltip(_u8L("Remove current plate (if not last one)")); } else - render_icon_texture(position_id, tex_coords_id, m_del_icon, m_partplate_list->m_del_texture, - m_del_vbo_id); + render_icon_texture(m_del_icon, m_partplate_list->m_del_texture); if (hover_id == 2) { - render_icon_texture(position_id, tex_coords_id, m_orient_icon, - m_partplate_list->m_orient_hovered_texture, m_orient_vbo_id); + render_icon_texture(m_orient_icon, m_partplate_list->m_orient_hovered_texture); show_tooltip(_u8L("Auto orient objects on current plate")); } else - render_icon_texture(position_id, tex_coords_id, m_orient_icon, m_partplate_list->m_orient_texture, - m_orient_vbo_id); + render_icon_texture(m_orient_icon, m_partplate_list->m_orient_texture); if (hover_id == 3) { - render_icon_texture(position_id, tex_coords_id, m_arrange_icon, - m_partplate_list->m_arrange_hovered_texture, m_arrange_vbo_id); + render_icon_texture(m_arrange_icon, m_partplate_list->m_arrange_hovered_texture); show_tooltip(_u8L("Arrange objects on current plate")); } else - render_icon_texture(position_id, tex_coords_id, m_arrange_icon, m_partplate_list->m_arrange_texture, - m_arrange_vbo_id); + render_icon_texture(m_arrange_icon, m_partplate_list->m_arrange_texture); if (hover_id == 4) { if (this->is_locked()) { - render_icon_texture(position_id, tex_coords_id, m_lock_icon, - m_partplate_list->m_locked_hovered_texture, m_lock_vbo_id); + render_icon_texture(m_lock_icon, + m_partplate_list->m_locked_hovered_texture); show_tooltip(_u8L("Unlock current plate")); } else { - render_icon_texture(position_id, tex_coords_id, m_lock_icon, - m_partplate_list->m_lockopen_hovered_texture, m_lock_vbo_id); + render_icon_texture(m_lock_icon, + m_partplate_list->m_lockopen_hovered_texture); show_tooltip(_u8L("Lock current plate")); } } else { if (this->is_locked()) - render_icon_texture(position_id, tex_coords_id, m_lock_icon, m_partplate_list->m_locked_texture, - m_lock_vbo_id); + render_icon_texture(m_lock_icon, m_partplate_list->m_locked_texture); else - render_icon_texture(position_id, tex_coords_id, m_lock_icon, m_partplate_list->m_lockopen_texture, - m_lock_vbo_id); + render_icon_texture(m_lock_icon, m_partplate_list->m_lockopen_texture); } if (m_partplate_list->render_plate_settings) { if (hover_id == 5) { if (get_bed_type() == BedType::btDefault && get_print_seq() == PrintSequence::ByDefault && get_first_layer_print_sequence().empty()) - render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_hovered_texture, m_plate_settings_vbo_id); + render_icon_texture(m_plate_settings_icon, m_partplate_list->m_plate_settings_hovered_texture); else - render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, - m_partplate_list->m_plate_settings_changed_hovered_texture, - m_plate_settings_vbo_id); + render_icon_texture(m_plate_settings_icon, m_partplate_list->m_plate_settings_changed_hovered_texture); show_tooltip(_u8L("Customize current plate")); } else { if (get_bed_type() == BedType::btDefault && get_print_seq() == PrintSequence::ByDefault && get_first_layer_print_sequence().empty()) - render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_texture, m_plate_settings_vbo_id); + render_icon_texture(m_plate_settings_icon, m_partplate_list->m_plate_settings_texture); else - render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, - m_partplate_list->m_plate_settings_changed_texture, m_plate_settings_vbo_id); + render_icon_texture(m_plate_settings_icon, m_partplate_list->m_plate_settings_changed_texture); } } if (m_plate_index >= 0 && m_plate_index < MAX_PLATE_COUNT) { - render_icon_texture(position_id, tex_coords_id, m_plate_idx_icon, - m_partplate_list->m_idx_textures[m_plate_index], m_plate_idx_vbo_id); + render_icon_texture(m_plate_idx_icon, m_partplate_list->m_idx_textures[m_plate_index]); } } - render_plate_name_texture(position_id, tex_coords_id); - if (tex_coords_id != -1) - glsafe(::glDisableVertexAttribArray(tex_coords_id)); + render_plate_name_texture(); - if (position_id != -1) - glsafe(::glDisableVertexAttribArray(position_id)); + glsafe(::glDisable(GL_BLEND)); //if (bottom) // glsafe(::glFrontFace(GL_CCW)); @@ -960,7 +937,7 @@ void PartPlate::render_icons(bool bottom, bool only_name, int hover_id) } } -void PartPlate::render_only_numbers(bool bottom) const +void PartPlate::render_only_numbers(bool bottom) { GLShaderProgram* shader = wxGetApp().get_shader("printbed"); if (shader != nullptr) { @@ -973,24 +950,14 @@ void PartPlate::render_only_numbers(bool bottom) const // glsafe(::glFrontFace(GL_CW)); glsafe(::glDepthMask(GL_FALSE)); - GLint position_id = shader->get_attrib_location("v_position"); - GLint tex_coords_id = shader->get_attrib_location("v_tex_coords"); - if (position_id != -1) { - glsafe(::glEnableVertexAttribArray(position_id)); - } - if (tex_coords_id != -1) { - glsafe(::glEnableVertexAttribArray(tex_coords_id)); - } + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); if (m_plate_index >=0 && m_plate_index < MAX_PLATE_COUNT) { - render_icon_texture(position_id, tex_coords_id, m_plate_idx_icon, m_partplate_list->m_idx_textures[m_plate_index], m_plate_idx_vbo_id); + render_icon_texture(m_plate_idx_icon, m_partplate_list->m_idx_textures[m_plate_index]); } - if (tex_coords_id != -1) - glsafe(::glDisableVertexAttribArray(tex_coords_id)); - - if (position_id != -1) - glsafe(::glDisableVertexAttribArray(position_id)); + glsafe(::glDisable(GL_BLEND)); //if (bottom) // glsafe(::glFrontFace(GL_CCW)); @@ -1000,20 +967,24 @@ void PartPlate::render_only_numbers(bool bottom) const } } -void PartPlate::render_rectangle_for_picking(const GeometryBuffer &buffer, const ColorRGBA render_color) const +void PartPlate::render_rectangle_for_picking(GLModel &buffer, const ColorRGBA render_color) { - unsigned int triangles_vcount = buffer.get_vertices_count(); + glsafe(::glDisable(GL_DEPTH_TEST)); - //glsafe(::glDepthMask(GL_FALSE)); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glColor4fv(render_color.data())); - glsafe(::glNormal3d(0.0f, 0.0f, 1.0f)); - glsafe(::glVertexPointer(3, GL_FLOAT, buffer.get_vertex_data_size(), (GLvoid*)buffer.get_vertices_data())); - glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount)); - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - //glsafe(::glDepthMask(GL_TRUE)); + GLShaderProgram *shader = wxGetApp().get_shader("flat"); + if (shader != nullptr) { + shader->start_using(); + + //glsafe(::glDepthMask(GL_FALSE)); + buffer.set_color(render_color); + buffer.render(); + //glsafe(::glDepthMask(GL_TRUE)); + + shader->stop_using(); + } } +/* void PartPlate::render_label(GLCanvas3D& canvas) const { std::string label = (boost::format("Plate %1%") % (m_plate_index + 1)).str(); const Camera& camera = wxGetApp().plater()->get_camera(); @@ -1229,8 +1200,9 @@ void PartPlate::render_right_arrow(const ColorRGBA render_color, bool use_lighti glsafe(::glDisable(GL_LIGHTING)); #endif } +*/ -void PartPlate::on_render_for_picking() const { +void PartPlate::on_render_for_picking() { //glsafe(::glDisable(GL_DEPTH_TEST)); int hover_id = 0; ColorRGBA color = picking_color_component(hover_id); @@ -1274,42 +1246,6 @@ ColorRGBA PartPlate::picking_color_component(int idx) const }; } -void PartPlate::release_opengl_resource() -{ - if (m_vbo_id > 0) { - glsafe(::glDeleteBuffers(1, &m_vbo_id)); - m_vbo_id = 0; - } - if (m_del_vbo_id > 0) { - glsafe(::glDeleteBuffers(1, &m_del_vbo_id)); - m_del_vbo_id = 0; - } - if (m_orient_vbo_id > 0) { - glsafe(::glDeleteBuffers(1, &m_orient_vbo_id)); - m_orient_vbo_id = 0; - } - if (m_arrange_vbo_id > 0) { - glsafe(::glDeleteBuffers(1, &m_arrange_vbo_id)); - m_arrange_vbo_id = 0; - } - if (m_lock_vbo_id > 0) { - glsafe(::glDeleteBuffers(1, &m_lock_vbo_id)); - m_lock_vbo_id = 0; - } - if (m_plate_settings_vbo_id > 0) { - glsafe(::glDeleteBuffers(1, &m_plate_settings_vbo_id)); - m_plate_settings_vbo_id = 0; - } - if (m_plate_idx_vbo_id > 0) { - glsafe(::glDeleteBuffers(1, &m_plate_idx_vbo_id)); - m_plate_idx_vbo_id = 0; - } - if (m_plate_name_vbo_id > 0) { - glsafe(::glDeleteBuffers(1, &m_plate_name_vbo_id)); - m_plate_name_vbo_id = 0; - } -} - std::vector PartPlate::get_extruders(bool conside_custom_gcode) const { std::vector plate_extruders; @@ -1746,6 +1682,8 @@ Vec3d PartPlate::get_center_origin() void PartPlate::generate_plate_name_texture() { + m_plate_name_icon.reset(); + // generate m_name_texture texture from m_name with generate_from_text_string m_name_texture.reset(); auto text = m_name.empty()? _L("Untitled") : from_u8(m_name); @@ -1768,14 +1706,8 @@ void PartPlate::generate_plate_name_texture() poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w - offset_x), scale_(p(1) - PARTPLATE_TEXT_OFFSET_Y)}); poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x), scale_(p(1) - PARTPLATE_TEXT_OFFSET_Y) }); - auto triangles = triangulate_expolygon_2f(poly, NORMALS_UP); - if (!m_plate_name_icon.set_from_triangles(triangles, GROUND_Z)) + if (!init_model_from_poly(m_plate_name_icon, poly, GROUND_Z)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to generate geometry buffers for icons\n"; - - if (m_plate_name_vbo_id > 0) { - glsafe(::glDeleteBuffers(1, &m_plate_name_vbo_id)); - m_plate_name_vbo_id = 0; - } } void PartPlate::set_plate_name(const std::string& name) { @@ -2481,11 +2413,9 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Ve ExPolygon logo_poly; generate_logo_polygon(logo_poly); - if (!m_logo_triangles.set_from_triangles(triangulate_expolygon_2f(logo_poly, NORMALS_UP), GROUND_Z+0.02f)) + m_logo_triangles.reset(); + if (!init_model_from_poly(m_logo_triangles, logo_poly, GROUND_Z + 0.02f)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":Unable to create logo triangles\n"; - else { - ; - } ExPolygon poly; /*for (const Vec2d& p : m_shape) { @@ -2519,8 +2449,6 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Ve calc_height_limit(); - release_opengl_resource(); - return true; } @@ -2567,40 +2495,45 @@ bool PartPlate::intersects(const BoundingBoxf3& bb) const void PartPlate::render(bool bottom, bool only_body, bool force_background_color, HeightLimitMode mode, int hover_id, bool render_cali) { - glsafe(::glEnable(GL_DEPTH_TEST)); - glsafe(::glEnable(GL_BLEND)); - glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + 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 (!bottom) { - // draw background - render_background(force_background_color); + if (!bottom) { + // draw background + render_background(force_background_color); - render_exclude_area(force_background_color); - } + render_exclude_area(force_background_color); + } - render_grid(bottom); + render_grid(bottom); - if (!bottom && m_selected && !force_background_color) { - if (m_partplate_list) - render_logo(bottom, m_partplate_list->render_cali_logo && render_cali); - else - render_logo(bottom); - } + render_height_limit(mode); - render_height_limit(mode); + glsafe(::glDisable(GL_BLEND)); - render_icons(bottom, only_body, hover_id); - if (!force_background_color){ - render_only_numbers(bottom); - } - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glDisable(GL_BLEND)); + // if (with_label) { + // render_label(canvas); + // } - //if (with_label) { - // render_label(canvas); - //} - glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_DEPTH_TEST)); + shader->stop_using(); + } + + if (!bottom && m_selected && !force_background_color) { + if (m_partplate_list) + render_logo(bottom, m_partplate_list->render_cali_logo && render_cali); + else + render_logo(bottom); + } + + render_icons(bottom, only_body, hover_id); + if (!force_background_color) { + render_only_numbers(bottom); + } } void PartPlate::set_selected() { @@ -3162,10 +3095,6 @@ void PartPlateList::release_icon_textures() part.texture->reset(); delete part.texture; } - if (part.vbo_id != 0) { - glsafe(::glDeleteBuffers(1, &part.vbo_id)); - part.vbo_id = 0; - } if (part.buffer) { delete part.buffer; } @@ -5078,19 +5007,11 @@ void PartPlateList::BedTextureInfo::TexturePart::update_buffer() } if (!buffer) - buffer = new GeometryBuffer(); + buffer = new GLModel(); - if (buffer->set_from_triangles(triangulate_expolygon_2f(poly, NORMALS_UP), GROUND_Z + 0.02f)) { - if (vbo_id != 0) { - glsafe(::glDeleteBuffers(1, &vbo_id)); - vbo_id = 0; - } - unsigned int* vbo_id_ptr = const_cast(&vbo_id); - glsafe(::glGenBuffers(1, vbo_id_ptr)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, *vbo_id_ptr)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)buffer->get_vertices_data_size(), (const GLvoid*)buffer->get_vertices_data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - } else { + buffer->reset(); + + if (!init_model_from_poly(*buffer, poly, GROUND_Z + 0.02f)) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":Unable to create buffer triangles\n"; } } diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index fc3da75315..9fcadf0598 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -115,28 +115,21 @@ private: Transform3d m_grabber_trans_matrix; Slic3r::Geometry::Transformation position; std::vector positions; - unsigned int m_vbo_id{ 0 }; - GeometryBuffer m_triangles; - GeometryBuffer m_exclude_triangles; - GeometryBuffer m_logo_triangles; - GeometryBuffer m_gridlines; - GeometryBuffer m_gridlines_bolder; - GeometryBuffer m_height_limit_common; - GeometryBuffer m_height_limit_bottom; - GeometryBuffer m_height_limit_top; - GeometryBuffer m_del_icon; - //GeometryBuffer m_del_and_background_icon; - mutable unsigned int m_del_vbo_id{ 0 }; - GeometryBuffer m_arrange_icon; - mutable unsigned int m_arrange_vbo_id{ 0 }; - GeometryBuffer m_orient_icon; - mutable unsigned int m_orient_vbo_id{ 0 }; - GeometryBuffer m_lock_icon; - mutable unsigned int m_lock_vbo_id{ 0 }; - GeometryBuffer m_plate_settings_icon; - mutable unsigned int m_plate_settings_vbo_id{ 0 }; - GeometryBuffer m_plate_idx_icon; - mutable unsigned int m_plate_idx_vbo_id{ 0 }; + GLModel m_triangles; + GLModel m_exclude_triangles; + GLModel m_logo_triangles; + GLModel m_gridlines; + GLModel m_gridlines_bolder; + GLModel m_height_limit_common; + GLModel m_height_limit_bottom; + GLModel m_height_limit_top; + GLModel m_del_icon; + //GLModel m_del_and_background_icon; + GLModel m_arrange_icon; + GLModel m_orient_icon; + GLModel m_lock_icon; + GLModel m_plate_settings_icon; + GLModel m_plate_idx_icon; GLTexture m_texture; mutable ColorRGBA m_grabber_color; @@ -152,8 +145,7 @@ private: // SoftFever // part plate name std::string m_name; - GeometryBuffer m_plate_name_icon; - mutable unsigned int m_plate_name_vbo_id{ 0 }; + GLModel m_plate_name_icon; GLTexture m_name_texture; wxCoord m_name_texture_width; wxCoord m_name_texture_height; @@ -168,31 +160,30 @@ private: void calc_exclude_triangles(const ExPolygon& poly); void calc_gridlines(const ExPolygon& poly, const BoundingBox& pp_bbox); void calc_height_limit(); - void calc_vertex_for_number(int index, bool one_number, GeometryBuffer &buffer); - void calc_vertex_for_icons(int index, GeometryBuffer &buffer); - void calc_vertex_for_icons_background(int icon_count, GeometryBuffer &buffer); - void render_background(bool force_default_color = false) const; - void render_logo(bool bottom, bool render_cali = true) const; - void render_logo_texture(GLTexture& logo_texture, const GeometryBuffer& logo_buffer, bool bottom, unsigned int vbo_id) const; - void render_exclude_area(bool force_default_color) const; + void calc_vertex_for_number(int index, bool one_number, GLModel &buffer); + void calc_vertex_for_icons(int index, GLModel &buffer); + void calc_vertex_for_icons_background(int icon_count, GLModel &buffer); + void render_background(bool force_default_color = false); + void render_logo(bool bottom, bool render_cali = true); + void render_logo_texture(GLTexture &logo_texture, GLModel &logo_buffer, bool bottom); + void render_exclude_area(bool force_default_color); //void render_background_for_picking(const ColorRGBA render_color) const; - void render_grid(bool bottom) const; - void render_height_limit(PartPlate::HeightLimitMode mode = HEIGHT_LIMIT_BOTH) const; - void render_label(GLCanvas3D& canvas) const; - void render_grabber(const ColorRGBA render_color, bool use_lighting) const; - void render_face(float x_size, float y_size) const; - void render_arrows(const ColorRGBA render_color, bool use_lighting) const; - void render_left_arrow(const ColorRGBA render_color, bool use_lighting) const; - void render_right_arrow(const ColorRGBA render_color, bool use_lighting) const; - void render_icon_texture(int position_id, int tex_coords_id, const GeometryBuffer &buffer, GLTexture &texture, unsigned int &vbo_id) const; + void render_grid(bool bottom); + void render_height_limit(PartPlate::HeightLimitMode mode = HEIGHT_LIMIT_BOTH); + // void render_label(GLCanvas3D& canvas) const; + // void render_grabber(const ColorRGBA render_color, bool use_lighting) const; + // void render_face(float x_size, float y_size) const; + // void render_arrows(const ColorRGBA render_color, bool use_lighting) const; + // void render_left_arrow(const ColorRGBA render_color, bool use_lighting) const; + // void render_right_arrow(const ColorRGBA render_color, bool use_lighting) const; + void render_icon_texture(GLModel &buffer, GLTexture &texture); void show_tooltip(const std::string tooltip); void render_icons(bool bottom, bool only_name = false, int hover_id = -1); - void render_only_numbers(bool bottom) const; - void render_plate_name_texture(int position_id, int tex_coords_id); - void render_rectangle_for_picking(const GeometryBuffer &buffer, const ColorRGBA render_color) const; - void on_render_for_picking() const; + void render_only_numbers(bool bottom); + void render_plate_name_texture(); + void render_rectangle_for_picking(GLModel &buffer, const ColorRGBA render_color); + void on_render_for_picking(); ColorRGBA picking_color_component(int idx) const; - void release_opengl_resource(); public: static const unsigned int PLATE_BASE_ID = 255 * 255 * 253; @@ -351,7 +342,7 @@ public: bool intersects(const BoundingBoxf3& bb) const; void render(bool bottom, bool only_body = false, bool force_background_color = false, HeightLimitMode mode = HEIGHT_LIMIT_NONE, int hover_id = -1, bool render_cali = false); - void render_for_picking() const { on_render_for_picking(); } + void render_for_picking() { on_render_for_picking(); } void set_selected(); void set_unselected(); void set_hover_id(int id) { m_hover_id = id; } @@ -569,18 +560,16 @@ public: float y; float w; float h; - unsigned int vbo_id; std::string filename; GLTexture* texture { nullptr }; Vec2d offset; - GeometryBuffer* buffer { nullptr }; + GLModel* buffer { nullptr }; TexturePart(float xx, float yy, float ww, float hh, std::string file){ x = xx; y = yy; w = ww; h = hh; filename = file; texture = nullptr; buffer = nullptr; - vbo_id = 0; offset = Vec2d(0, 0); } @@ -593,7 +582,6 @@ public: this->buffer = part.buffer; this->filename = part.filename; this->texture = part.texture; - this->vbo_id = part.vbo_id; } void update_buffer();