mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-20 21:27:52 -06:00
Tech ENABLE_GLBEGIN_GLEND_REMOVAL - Layers editing profile's background texture rendering
Tech ENABLE_GLBEGIN_GLEND_REMOVAL - A few fixes in layers editing profile rendering (cherry picked from commit prusa3d/PrusaSlicer@a939d8e4c0) (cherry picked from commit prusa3d/PrusaSlicer@8c807dbcc4)
This commit is contained in:
parent
354f8e20fb
commit
35899b96ba
6 changed files with 89 additions and 97 deletions
|
@ -334,8 +334,11 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas)
|
||||||
{
|
{
|
||||||
render_variable_layer_height_dialog(canvas);
|
render_variable_layer_height_dialog(canvas);
|
||||||
const Rect& bar_rect = get_bar_rect_viewport(canvas);
|
const Rect& bar_rect = get_bar_rect_viewport(canvas);
|
||||||
render_background_texture(canvas, bar_rect);
|
m_profile.dirty = m_profile.old_bar_rect != bar_rect;
|
||||||
render_curve(bar_rect);
|
render_active_object_annotations(canvas, bar_rect);
|
||||||
|
render_profile(bar_rect);
|
||||||
|
m_profile.old_bar_rect = bar_rect;
|
||||||
|
m_profile.dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
|
float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
|
||||||
|
@ -409,7 +412,7 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::LayersEditing::render_background_texture(const GLCanvas3D& canvas, const Rect& bar_rect)
|
void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect)
|
||||||
{
|
{
|
||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
return;
|
return;
|
||||||
|
@ -430,25 +433,39 @@ void GLCanvas3D::LayersEditing::render_background_texture(const GLCanvas3D& canv
|
||||||
glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id));
|
glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id));
|
||||||
|
|
||||||
// Render the color bar
|
// Render the color bar
|
||||||
|
if (!m_profile.background.is_initialized() || m_profile.dirty) {
|
||||||
|
m_profile.background.reset();
|
||||||
|
|
||||||
|
GLModel::Geometry init_data;
|
||||||
|
init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT };
|
||||||
|
init_data.vertices.reserve(4 * GLModel::Geometry::vertex_stride_floats(init_data.format));
|
||||||
|
init_data.indices.reserve(6 * GLModel::Geometry::index_stride_bytes(init_data.format));
|
||||||
|
|
||||||
|
// vertices
|
||||||
const float l = bar_rect.get_left();
|
const float l = bar_rect.get_left();
|
||||||
const float r = bar_rect.get_right();
|
const float r = bar_rect.get_right();
|
||||||
const float t = bar_rect.get_top();
|
const float t = bar_rect.get_top();
|
||||||
const float b = bar_rect.get_bottom();
|
const float b = bar_rect.get_bottom();
|
||||||
|
init_data.add_vertex(Vec2f(l, b), Vec2f(0.0f, 0.0f));
|
||||||
|
init_data.add_vertex(Vec2f(r, b), Vec2f(1.0f, 0.0f));
|
||||||
|
init_data.add_vertex(Vec2f(r, t), Vec2f(1.0f, 1.0f));
|
||||||
|
init_data.add_vertex(Vec2f(l, t), Vec2f(0.0f, 1.0f));
|
||||||
|
|
||||||
::glBegin(GL_QUADS);
|
// indices
|
||||||
::glNormal3f(0.0f, 0.0f, 1.0f);
|
init_data.add_ushort_triangle(0, 1, 2);
|
||||||
::glTexCoord2f(0.0f, 0.0f); ::glVertex2f(l, b);
|
init_data.add_ushort_triangle(2, 3, 0);
|
||||||
::glTexCoord2f(1.0f, 0.0f); ::glVertex2f(r, b);
|
|
||||||
::glTexCoord2f(1.0f, 1.0f); ::glVertex2f(r, t);
|
m_profile.background.init_from(std::move(init_data));
|
||||||
::glTexCoord2f(0.0f, 1.0f); ::glVertex2f(l, t);
|
}
|
||||||
glsafe(::glEnd());
|
|
||||||
|
m_profile.background.render();
|
||||||
|
|
||||||
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
||||||
|
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::LayersEditing::render_curve(const Rect & bar_rect)
|
void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect)
|
||||||
{
|
{
|
||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
return;
|
return;
|
||||||
|
@ -460,24 +477,21 @@ void GLCanvas3D::LayersEditing::render_curve(const Rect & bar_rect)
|
||||||
// Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region.
|
// Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region.
|
||||||
const float scale_x = bar_rect.get_width() / float(1.12 * m_slicing_parameters->max_layer_height);
|
const float scale_x = bar_rect.get_width() / float(1.12 * m_slicing_parameters->max_layer_height);
|
||||||
const float scale_y = bar_rect.get_height() / m_object_max_z;
|
const float scale_y = bar_rect.get_height() / m_object_max_z;
|
||||||
const float x = bar_rect.get_left() + float(m_slicing_parameters->layer_height) * scale_x;
|
|
||||||
|
|
||||||
const bool bar_rect_changed = m_profile.old_bar_rect != bar_rect;
|
|
||||||
m_profile.old_bar_rect = bar_rect;
|
|
||||||
|
|
||||||
// Baseline
|
// Baseline
|
||||||
if (!m_profile.baseline.is_initialized() || bar_rect_changed) {
|
if (!m_profile.baseline.is_initialized() || m_profile.dirty) {
|
||||||
m_profile.old_bar_rect = bar_rect;
|
m_profile.baseline.reset();
|
||||||
|
|
||||||
GLModel::Geometry init_data;
|
GLModel::Geometry init_data;
|
||||||
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
|
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::EIndexType::USHORT };
|
||||||
init_data.color = ColorRGBA::BLACK();
|
init_data.color = ColorRGBA::BLACK();
|
||||||
init_data.vertices.reserve(2 * GLModel::Geometry::vertex_stride_floats(init_data.format));
|
init_data.vertices.reserve(2 * GLModel::Geometry::vertex_stride_floats(init_data.format));
|
||||||
init_data.indices.reserve(2 * GLModel::Geometry::index_stride_bytes(init_data.format));
|
init_data.indices.reserve(2 * GLModel::Geometry::index_stride_bytes(init_data.format));
|
||||||
|
|
||||||
// vertices
|
// vertices
|
||||||
init_data.add_vertex(Vec3f(x, bar_rect.get_bottom(), 0.0f));
|
const float x = bar_rect.get_left() + float(m_slicing_parameters->layer_height) * scale_x;
|
||||||
init_data.add_vertex(Vec3f(x, bar_rect.get_top(), 0.0f));
|
init_data.add_vertex(Vec2f(x, bar_rect.get_bottom()));
|
||||||
|
init_data.add_vertex(Vec2f(x, bar_rect.get_top()));
|
||||||
|
|
||||||
// indices
|
// indices
|
||||||
init_data.add_ushort_line(0, 1);
|
init_data.add_ushort_line(0, 1);
|
||||||
|
@ -485,21 +499,20 @@ void GLCanvas3D::LayersEditing::render_curve(const Rect & bar_rect)
|
||||||
m_profile.baseline.init_from(std::move(init_data));
|
m_profile.baseline.init_from(std::move(init_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_profile.profile.is_initialized() || bar_rect_changed || m_profile.old_layer_height_profile != m_layer_height_profile) {
|
if (!m_profile.profile.is_initialized() || m_profile.dirty || m_profile.old_layer_height_profile != m_layer_height_profile) {
|
||||||
m_profile.old_layer_height_profile = m_layer_height_profile;
|
m_profile.old_layer_height_profile = m_layer_height_profile;
|
||||||
m_profile.profile.reset();
|
m_profile.profile.reset();
|
||||||
|
|
||||||
GLModel::Geometry init_data;
|
GLModel::Geometry init_data;
|
||||||
init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::UINT };
|
init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::EIndexType::UINT };
|
||||||
init_data.color = ColorRGBA::BLUE();
|
init_data.color = ColorRGBA::BLUE();
|
||||||
init_data.vertices.reserve(m_layer_height_profile.size() * GLModel::Geometry::vertex_stride_floats(init_data.format));
|
init_data.vertices.reserve(m_layer_height_profile.size() * GLModel::Geometry::vertex_stride_floats(init_data.format));
|
||||||
init_data.indices.reserve(m_layer_height_profile.size() * GLModel::Geometry::index_stride_bytes(init_data.format));
|
init_data.indices.reserve(m_layer_height_profile.size() * GLModel::Geometry::index_stride_bytes(init_data.format));
|
||||||
|
|
||||||
// vertices + indices
|
// vertices + indices
|
||||||
for (unsigned int i = 0; i < (unsigned int)m_layer_height_profile.size(); i += 2) {
|
for (unsigned int i = 0; i < (unsigned int)m_layer_height_profile.size(); i += 2) {
|
||||||
init_data.add_vertex(Vec3f(bar_rect.get_left() + float(m_layer_height_profile[i + 1]) * scale_x,
|
init_data.add_vertex(Vec2f(bar_rect.get_left() + float(m_layer_height_profile[i + 1]) * scale_x,
|
||||||
bar_rect.get_bottom() + float(m_layer_height_profile[i]) * scale_y,
|
bar_rect.get_bottom() + float(m_layer_height_profile[i]) * scale_y));
|
||||||
0.0f));
|
|
||||||
init_data.add_uint_index(i / 2);
|
init_data.add_uint_index(i / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,49 +672,6 @@ float GLCanvas3D::LayersEditing::thickness_bar_width(const GLCanvas3D & canvas)
|
||||||
* THICKNESS_BAR_WIDTH;
|
* THICKNESS_BAR_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
Size::Size()
|
|
||||||
: m_width(0)
|
|
||||||
, m_height(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Size::Size(int width, int height, float scale_factor)
|
|
||||||
: m_width(width)
|
|
||||||
, m_height(height)
|
|
||||||
, m_scale_factor(scale_factor)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int Size::get_width() const
|
|
||||||
{
|
|
||||||
return m_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Size::set_width(int width)
|
|
||||||
{
|
|
||||||
m_width = width;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Size::get_height() const
|
|
||||||
{
|
|
||||||
return m_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Size::set_height(int height)
|
|
||||||
{
|
|
||||||
m_height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Size::get_scale_factor() const
|
|
||||||
{
|
|
||||||
return m_scale_factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Size::set_scale_factor(int scale_factor)
|
|
||||||
{
|
|
||||||
m_scale_factor = scale_factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Point GLCanvas3D::Mouse::Drag::Invalid_2D_Point(INT_MAX, INT_MAX);
|
const Point GLCanvas3D::Mouse::Drag::Invalid_2D_Point(INT_MAX, INT_MAX);
|
||||||
const Vec3d GLCanvas3D::Mouse::Drag::Invalid_3D_Point(DBL_MAX, DBL_MAX, DBL_MAX);
|
const Vec3d GLCanvas3D::Mouse::Drag::Invalid_3D_Point(DBL_MAX, DBL_MAX, DBL_MAX);
|
||||||
const int GLCanvas3D::Mouse::Drag::MoveThresholdPx = 5;
|
const int GLCanvas3D::Mouse::Drag::MoveThresholdPx = 5;
|
||||||
|
|
|
@ -62,25 +62,24 @@ class RetinaHelper;
|
||||||
|
|
||||||
class Size
|
class Size
|
||||||
{
|
{
|
||||||
int m_width;
|
int m_width{ 0 };
|
||||||
int m_height;
|
int m_height{ 0 };
|
||||||
float m_scale_factor;
|
float m_scale_factor{ 1.0f };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Size();
|
Size() = default;
|
||||||
Size(int width, int height, float scale_factor = 1.0);
|
Size(int width, int height, float scale_factor = 1.0f) : m_width(width), m_height(height), m_scale_factor(scale_factor) {}
|
||||||
|
|
||||||
int get_width() const;
|
int get_width() const { return m_width; }
|
||||||
void set_width(int width);
|
void set_width(int width) { m_width = width; }
|
||||||
|
|
||||||
int get_height() const;
|
int get_height() const { return m_height; }
|
||||||
void set_height(int height);
|
void set_height(int height) { m_height = height; }
|
||||||
|
|
||||||
int get_scale_factor() const;
|
float get_scale_factor() const { return m_scale_factor; }
|
||||||
void set_scale_factor(int height);
|
void set_scale_factor(float factor) { m_scale_factor = factor; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class RenderTimerEvent : public wxEvent
|
class RenderTimerEvent : public wxEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -261,8 +260,10 @@ class GLCanvas3D
|
||||||
{
|
{
|
||||||
GLModel baseline;
|
GLModel baseline;
|
||||||
GLModel profile;
|
GLModel profile;
|
||||||
|
GLModel background;
|
||||||
Rect old_bar_rect;
|
Rect old_bar_rect;
|
||||||
std::vector<double> old_layer_height_profile;
|
std::vector<double> old_layer_height_profile;
|
||||||
|
bool dirty{ false };
|
||||||
};
|
};
|
||||||
Profile m_profile;
|
Profile m_profile;
|
||||||
|
|
||||||
|
@ -303,10 +304,8 @@ class GLCanvas3D
|
||||||
private:
|
private:
|
||||||
bool is_initialized() const;
|
bool is_initialized() const;
|
||||||
void generate_layer_height_texture();
|
void generate_layer_height_texture();
|
||||||
|
void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect);
|
||||||
void render_background_texture(const GLCanvas3D& canvas, const Rect& bar_rect);
|
void render_profile(const Rect& bar_rect);
|
||||||
void render_curve(const Rect& bar_rect);
|
|
||||||
|
|
||||||
void update_slicing_parameters();
|
void update_slicing_parameters();
|
||||||
|
|
||||||
static float thickness_bar_width(const GLCanvas3D& canvas);
|
static float thickness_bar_width(const GLCanvas3D& canvas);
|
||||||
|
|
|
@ -24,6 +24,15 @@ void GLModel::Geometry::add_vertex(const Vec2f& position)
|
||||||
vertices.emplace_back(position.y());
|
vertices.emplace_back(position.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLModel::Geometry::add_vertex(const Vec2f& position, const Vec2f& tex_coord)
|
||||||
|
{
|
||||||
|
assert(format.vertex_layout == EVertexLayout::P2T2);
|
||||||
|
vertices.emplace_back(position.x());
|
||||||
|
vertices.emplace_back(position.y());
|
||||||
|
vertices.emplace_back(tex_coord.x());
|
||||||
|
vertices.emplace_back(tex_coord.y());
|
||||||
|
}
|
||||||
|
|
||||||
void GLModel::Geometry::add_vertex(const Vec3f& position)
|
void GLModel::Geometry::add_vertex(const Vec3f& position)
|
||||||
{
|
{
|
||||||
assert(format.vertex_layout == EVertexLayout::P3);
|
assert(format.vertex_layout == EVertexLayout::P3);
|
||||||
|
@ -331,8 +340,11 @@ bool GLModel::Geometry::has_tex_coord(const Format& format)
|
||||||
|
|
||||||
void GLModel::init_from(Geometry&& data)
|
void GLModel::init_from(Geometry&& data)
|
||||||
{
|
{
|
||||||
if (is_initialized()) // call reset() if you want to reuse this model
|
if (is_initialized()) {
|
||||||
|
// call reset() if you want to reuse this model
|
||||||
|
assert(false);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (data.vertices.empty() || data.indices.empty()) {
|
if (data.vertices.empty() || data.indices.empty()) {
|
||||||
assert(false);
|
assert(false);
|
||||||
|
@ -353,10 +365,18 @@ void GLModel::init_from(Geometry&& data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLModel::init_from(const TriangleMesh& mesh)
|
||||||
|
{
|
||||||
|
init_from(mesh.its);
|
||||||
|
}
|
||||||
|
|
||||||
void GLModel::init_from(const indexed_triangle_set& its)
|
void GLModel::init_from(const indexed_triangle_set& its)
|
||||||
{
|
{
|
||||||
if (is_initialized()) // call reset() if you want to reuse this model
|
if (is_initialized()) {
|
||||||
|
// call reset() if you want to reuse this model
|
||||||
|
assert(false);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (its.vertices.empty() || its.indices.empty()){
|
if (its.vertices.empty() || its.indices.empty()){
|
||||||
assert(false);
|
assert(false);
|
||||||
|
@ -389,8 +409,11 @@ void GLModel::init_from(const indexed_triangle_set& its)
|
||||||
|
|
||||||
void GLModel::init_from(const Polygons& polygons, float z)
|
void GLModel::init_from(const Polygons& polygons, float z)
|
||||||
{
|
{
|
||||||
if (is_initialized()) // call reset() if you want to reuse this model
|
if (is_initialized()) {
|
||||||
|
// call reset() if you want to reuse this model
|
||||||
|
assert(false);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (polygons.empty()) {
|
if (polygons.empty()) {
|
||||||
assert(false);
|
assert(false);
|
||||||
|
@ -443,8 +466,7 @@ bool GLModel::init_from_file(const std::string& filename)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TriangleMesh mesh = model.mesh();
|
init_from(model.mesh());
|
||||||
init_from(mesh.its);
|
|
||||||
|
|
||||||
m_filename = filename;
|
m_filename = filename;
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ namespace GUI {
|
||||||
ColorRGBA color{ ColorRGBA::BLACK() };
|
ColorRGBA color{ ColorRGBA::BLACK() };
|
||||||
|
|
||||||
void add_vertex(const Vec2f& position);
|
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);
|
||||||
void add_vertex(const Vec3f& position, const Vec3f& normal);
|
void add_vertex(const Vec3f& position, const Vec3f& normal);
|
||||||
|
|
||||||
|
@ -141,6 +142,7 @@ namespace GUI {
|
||||||
size_t indices_size_bytes() const { return indices_count() * Geometry::index_stride_bytes(m_render_data.geometry.format); }
|
size_t indices_size_bytes() const { return indices_count() * Geometry::index_stride_bytes(m_render_data.geometry.format); }
|
||||||
|
|
||||||
void init_from(Geometry&& data);
|
void init_from(Geometry&& data);
|
||||||
|
void init_from(const TriangleMesh& mesh);
|
||||||
void init_from(const indexed_triangle_set& its);
|
void init_from(const indexed_triangle_set& its);
|
||||||
void init_from(const Polygons& polygons, float z);
|
void init_from(const Polygons& polygons, float z);
|
||||||
bool init_from_file(const std::string& filename);
|
bool init_from_file(const std::string& filename);
|
||||||
|
|
|
@ -33,8 +33,7 @@ std::pair<bool, std::string> GLShadersManager::init()
|
||||||
|
|
||||||
bool valid = true;
|
bool valid = true;
|
||||||
|
|
||||||
// basic shader, used to render selection bbox, gizmo cut plane and grabbers connections,
|
// basic shader, used to render all what was previously rendered using the immediate mode
|
||||||
// gizmo move grabbers connections, gizmo scale grabbers connections
|
|
||||||
valid &= append_shader("flat", { "flat.vs", "flat.fs" });
|
valid &= append_shader("flat", { "flat.vs", "flat.fs" });
|
||||||
// used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview
|
// used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview
|
||||||
valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" });
|
valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" });
|
||||||
|
|
|
@ -40,14 +40,14 @@ public:
|
||||||
Rect() = default;
|
Rect() = default;
|
||||||
Rect(float left, float top, float right, float bottom) : m_left(left) , m_top(top) , m_right(right) , m_bottom(bottom) {}
|
Rect(float left, float top, float right, float bottom) : m_left(left) , m_top(top) , m_right(right) , m_bottom(bottom) {}
|
||||||
|
|
||||||
bool operator == (const Rect& other) {
|
bool operator == (const Rect& other) const {
|
||||||
if (std::abs(m_left - other.m_left) > EPSILON) return false;
|
if (std::abs(m_left - other.m_left) > EPSILON) return false;
|
||||||
if (std::abs(m_top - other.m_top) > EPSILON) return false;
|
if (std::abs(m_top - other.m_top) > EPSILON) return false;
|
||||||
if (std::abs(m_right - other.m_right) > EPSILON) return false;
|
if (std::abs(m_right - other.m_right) > EPSILON) return false;
|
||||||
if (std::abs(m_bottom - other.m_bottom) > EPSILON) return false;
|
if (std::abs(m_bottom - other.m_bottom) > EPSILON) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool operator != (const Rect& other) { return !operator==(other); }
|
bool operator != (const Rect& other) const { return !operator==(other); }
|
||||||
|
|
||||||
float get_left() const { return m_left; }
|
float get_left() const { return m_left; }
|
||||||
void set_left(float left) { m_left = left; }
|
void set_left(float left) { m_left = left; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue