Tech ENABLE_GLBEGIN_GLEND_REMOVAL - Removed Slic3r::GUI::GeometryBuffer from 3DBed.hpp and replaced with GLModel

This commit is contained in:
enricoturri1966 2022-02-07 10:24:24 +01:00
parent 1d7f4a081b
commit 6b041429f6
6 changed files with 239 additions and 13 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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<Vec2f> &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<Vec2f> 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<float>(l.a.x()), unscale<float>(l.a.y()), GROUND_Z));
init_data.add_vertex(Vec3f(unscale<float>(l.b.x()), unscale<float>(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

View file

@ -5,7 +5,10 @@
#include "3DScene.hpp"
#include "GLModel.hpp"
#include <libslic3r/BuildVolume.hpp>
#include "libslic3r/BuildVolume.hpp"
#if ENABLE_GLBEGIN_GLEND_REMOVAL
#include "libslic3r/ExPolygon.hpp"
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
#include <tuple>
#include <array>
@ -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<Type, std::string, std::string> 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

View file

@ -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; }

View file

@ -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);