From 363a964ebb0cc4247382e8cec53a309449c42510 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 29 May 2018 13:54:34 +0200 Subject: [PATCH] 3DScene render method partially moved to c++ --- lib/Slic3r/GUI/3DScene.pm | 35 +- xs/src/libslic3r/Utils.hpp | 14 +- xs/src/libslic3r/utils.cpp | 20 +- xs/src/slic3r/GUI/3DScene.cpp | 45 +-- xs/src/slic3r/GUI/3DScene.hpp | 10 +- xs/src/slic3r/GUI/GLCanvas3D.cpp | 506 +++++++++++++----------- xs/src/slic3r/GUI/GLCanvas3D.hpp | 22 +- xs/src/slic3r/GUI/GLCanvas3DManager.cpp | 60 +-- xs/src/slic3r/GUI/GLCanvas3DManager.hpp | 10 +- xs/xsp/GUI_3DScene.xsp | 54 +-- 10 files changed, 326 insertions(+), 450 deletions(-) diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index 435a4892b..327d2976c 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -1482,31 +1482,20 @@ sub Render { my @rotmat = quat_to_rotmatrix($self->quat); glMultMatrixd_p(@rotmat[0..15]); } + #============================================================================================================================== - glTranslatef(@{ Slic3r::GUI::_3DScene::get_camera_target($self)->negative }); + Slic3r::GUI::_3DScene::render($self); + # glTranslatef(@{ $self->_camera_target->negative }); -#============================================================================================================================== - - # light from above - glLightfv_p(GL_LIGHT0, GL_POSITION, -0.5, -0.5, 1, 0); - glLightfv_p(GL_LIGHT0, GL_SPECULAR, 0.2, 0.2, 0.2, 1); - glLightfv_p(GL_LIGHT0, GL_DIFFUSE, 0.5, 0.5, 0.5, 1); - - # Head light - glLightfv_p(GL_LIGHT1, GL_POSITION, 1, 0, 1, 0); - -#============================================================================================================================== - Slic3r::GUI::_3DScene::picking_pass($self); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - Slic3r::GUI::_3DScene::render_background($self); - Slic3r::GUI::_3DScene::render_bed($self); - Slic3r::GUI::_3DScene::render_axes($self); - Slic3r::GUI::_3DScene::render_objects($self, $self->UseVBOs); - Slic3r::GUI::_3DScene::render_cutting_plane($self); - Slic3r::GUI::_3DScene::render_warning_texture($self); - Slic3r::GUI::_3DScene::render_legend_texture($self); - Slic3r::GUI::_3DScene::render_layer_editing_overlay($self, $self->{print}); - +# +# # light from above +# glLightfv_p(GL_LIGHT0, GL_POSITION, -0.5, -0.5, 1, 0); +# glLightfv_p(GL_LIGHT0, GL_SPECULAR, 0.2, 0.2, 0.2, 1); +# glLightfv_p(GL_LIGHT0, GL_DIFFUSE, 0.5, 0.5, 0.5, 1); +# +# # Head light +# glLightfv_p(GL_LIGHT1, GL_POSITION, 1, 0, 1, 0); +# # if ($self->enable_picking && !$self->_mouse_dragging) { # if (my $pos = $self->_mouse_pos) { # # Render the object for picking. diff --git a/xs/src/libslic3r/Utils.hpp b/xs/src/libslic3r/Utils.hpp index e5157741e..8e4d654de 100644 --- a/xs/src/libslic3r/Utils.hpp +++ b/xs/src/libslic3r/Utils.hpp @@ -91,10 +91,16 @@ public: ~PerlCallback() { this->deregister_callback(); } void register_callback(void *sv); void deregister_callback(); - void call(); - void call(int i); - void call(int i, int j); -// void call(const std::vector &ints); +//############################################################################################################## + void call() const; + void call(int i) const; + void call(int i, int j) const; + // void call(const std::vector &ints); +// void call(); +// void call(int i); +// void call(int i, int j); +//// void call(const std::vector &ints); +//############################################################################################################## private: void *m_callback; }; diff --git a/xs/src/libslic3r/utils.cpp b/xs/src/libslic3r/utils.cpp index 582488c5a..c691073a4 100644 --- a/xs/src/libslic3r/utils.cpp +++ b/xs/src/libslic3r/utils.cpp @@ -184,7 +184,10 @@ void PerlCallback::deregister_callback() } } -void PerlCallback::call() +//############################################################################################################## +void PerlCallback::call() const +//void PerlCallback::call() +//############################################################################################################## { if (! m_callback) return; @@ -198,7 +201,10 @@ void PerlCallback::call() LEAVE; } -void PerlCallback::call(int i) +//############################################################################################################## +void PerlCallback::call(int i) const +//void PerlCallback::call(int i) +//############################################################################################################## { if (! m_callback) return; @@ -213,7 +219,10 @@ void PerlCallback::call(int i) LEAVE; } -void PerlCallback::call(int i, int j) +//############################################################################################################## +void PerlCallback::call(int i, int j) const +//void PerlCallback::call(int i, int j) +//############################################################################################################## { if (! m_callback) return; @@ -230,7 +239,10 @@ void PerlCallback::call(int i, int j) } /* -void PerlCallback::call(const std::vector &ints) +//############################################################################################################## +void PerlCallback::call(const std::vector &ints) const +//void PerlCallback::call(const std::vector &ints) +//############################################################################################################## { if (! m_callback) return; diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 23f0f0194..469c03cbc 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -2115,24 +2115,9 @@ void _3DScene::stop_using_shader(wxGLCanvas* canvas) s_canvas_mgr.stop_using_shader(canvas); } -void _3DScene::picking_pass(wxGLCanvas* canvas) +void _3DScene::render(wxGLCanvas* canvas) { - s_canvas_mgr.picking_pass(canvas); -} - -void _3DScene::render_background(wxGLCanvas* canvas) -{ - s_canvas_mgr.render_background(canvas); -} - -void _3DScene::render_bed(wxGLCanvas* canvas) -{ - s_canvas_mgr.render_bed(canvas); -} - -void _3DScene::render_axes(wxGLCanvas* canvas) -{ - s_canvas_mgr.render_axes(canvas); + s_canvas_mgr.render(canvas); } void _3DScene::render_volumes(wxGLCanvas* canvas, bool fake_colors) @@ -2140,32 +2125,6 @@ void _3DScene::render_volumes(wxGLCanvas* canvas, bool fake_colors) s_canvas_mgr.render_volumes(canvas, fake_colors); } -void _3DScene::render_objects(wxGLCanvas* canvas, bool useVBOs) -{ - s_canvas_mgr.render_objects(canvas, useVBOs); -} - -void _3DScene::render_cutting_plane(wxGLCanvas* canvas) -{ - s_canvas_mgr.render_cutting_plane(canvas); -} - -void _3DScene::render_warning_texture(wxGLCanvas* canvas) -{ - s_canvas_mgr.render_warning_texture(canvas); -} - -void _3DScene::render_legend_texture(wxGLCanvas* canvas) -{ - s_canvas_mgr.render_legend_texture(canvas); -} - -void _3DScene::render_layer_editing_overlay(wxGLCanvas* canvas, const Print* print) -{ - if (print != nullptr) - s_canvas_mgr.render_layer_editing_overlay(canvas, *print); -} - void _3DScene::render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) { s_canvas_mgr.render_texture(canvas, tex_id, left, right, bottom, top); diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 973b5eeb2..434f7a5b0 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -648,17 +648,9 @@ public: static bool start_using_shader(wxGLCanvas* canvas); static void stop_using_shader(wxGLCanvas* canvas); - static void picking_pass(wxGLCanvas* canvas); + static void render(wxGLCanvas* canvas); - static void render_background(wxGLCanvas* canvas); - static void render_bed(wxGLCanvas* canvas); - static void render_axes(wxGLCanvas* canvas); static void render_volumes(wxGLCanvas* canvas, bool fake_colors); - static void render_objects(wxGLCanvas* canvas, bool useVBOs); - static void render_cutting_plane(wxGLCanvas* canvas); - static void render_warning_texture(wxGLCanvas* canvas); - static void render_legend_texture(wxGLCanvas* canvas); - static void render_layer_editing_overlay(wxGLCanvas* canvas, const Print* print); static void render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index cc968755b..406e8939c 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -1530,91 +1530,32 @@ void GLCanvas3D::stop_using_shader() const m_shader.stop_using(); } -void GLCanvas3D::picking_pass() +void GLCanvas3D::render(bool useVBOs) const { - if (is_picking_enabled() && !is_mouse_dragging() && (m_volumes != nullptr)) - { - // Render the object for picking. - // FIXME This cannot possibly work in a multi - sampled context as the color gets mangled by the anti - aliasing. - // Better to use software ray - casting on a bounding - box hierarchy. + Pointf3 neg_target = get_camera_target().negative(); + ::glTranslatef((GLfloat)neg_target.x, (GLfloat)neg_target.y, (GLfloat)neg_target.z); - if (is_multisample_allowed()) - ::glDisable(GL_MULTISAMPLE); + // light from above + GLfloat position0[4] = { -0.5f, -0.5f, 1.0f, 0.0f }; + ::glLightfv(GL_LIGHT0, GL_POSITION, position0); + GLfloat specular[4] = { 0.2f, 0.2f, 0.2f, 1.0f }; + ::glLightfv(GL_LIGHT0, GL_SPECULAR, specular); + GLfloat diffuse[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; + ::glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); - ::glDisable(GL_LIGHTING); - ::glDisable(GL_BLEND); + // Head light + GLfloat position1[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; + ::glLightfv(GL_LIGHT1, GL_POSITION, position1); - ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - ::glPushAttrib(GL_ENABLE_BIT); - - render_volumes(true); - - ::glPopAttrib(); - - if (is_multisample_allowed()) - ::glEnable(GL_MULTISAMPLE); - - const Size& cnv_size = get_canvas_size(); - - const Pointf& pos = get_mouse_position(); - GLubyte color[4]; - ::glReadPixels(pos.x, cnv_size.get_height() - pos.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color); - int volume_id = color[0] + color[1] * 256 + color[2] * 256 * 256; - - set_hover_volume_id(-1); - - for (GLVolume* vol : m_volumes->volumes) - { - vol->hover = false; - } - - if (volume_id < m_volumes->volumes.size()) - { - set_hover_volume_id(volume_id); - m_volumes->volumes[volume_id]->hover = true; - int group_id = m_volumes->volumes[volume_id]->select_group_id; - if (group_id != -1) - { - for (GLVolume* vol : m_volumes->volumes) - { - if (vol->select_group_id == group_id) - vol->hover = true; - } - } - } - } -} - -void GLCanvas3D::render_background() const -{ - static const float COLOR[3] = { 10.0f / 255.0f, 98.0f / 255.0f, 144.0f / 255.0f }; - - ::glDisable(GL_LIGHTING); - - ::glPushMatrix(); - ::glLoadIdentity(); - ::glMatrixMode(GL_PROJECTION); - ::glPushMatrix(); - ::glLoadIdentity(); - - // Draws a bluish bottom to top gradient over the complete screen. - ::glDisable(GL_DEPTH_TEST); - - ::glBegin(GL_QUADS); - ::glColor3f(0.0f, 0.0f, 0.0f); - ::glVertex3f(-1.0f, -1.0f, 1.0f); - ::glVertex3f(1.0f, -1.0f, 1.0f); - ::glColor3f(COLOR[0], COLOR[1], COLOR[2]); - ::glVertex3f(1.0f, 1.0f, 1.0f); - ::glVertex3f(-1.0f, 1.0f, 1.0f); - ::glEnd(); - - ::glEnable(GL_DEPTH_TEST); - - ::glPopMatrix(); - ::glMatrixMode(GL_MODELVIEW); - ::glPopMatrix(); + _picking_pass(); + _render_background(); + _render_bed(); + _render_axes(); + _render_objects(useVBOs); + _render_cutting_plane(); + _render_warning_texture(); + _render_legend_texture(); + _render_layer_editing_overlay(); } unsigned int GLCanvas3D::get_layers_editing_z_texture_id() const @@ -1697,16 +1638,6 @@ bool GLCanvas3D::reset_rect_contains(float x, float y) const return m_layers_editing.reset_rect_contains(*this, x, y); } -void GLCanvas3D::render_bed() const -{ - m_bed.render(); -} - -void GLCanvas3D::render_axes() const -{ - m_axes.render(); -} - void GLCanvas3D::render_volumes(bool fake_colors) const { static const float INV_255 = 1.0f / 255.0f; @@ -1756,153 +1687,6 @@ void GLCanvas3D::render_volumes(bool fake_colors) const ::glEnable(GL_CULL_FACE); } -void GLCanvas3D::render_objects(bool useVBOs) -{ - if ((m_volumes == nullptr) || m_volumes->empty()) - return; - - ::glEnable(GL_LIGHTING); - - if (!m_shader_enabled) - render_volumes(false); - else if (useVBOs) - { - if (is_picking_enabled()) - { - m_on_mark_volumes_for_layer_height_callback.call(); - - if (m_config != nullptr) - { - const BoundingBoxf3& bed_bb = bed_bounding_box(); - m_volumes->set_print_box((float)bed_bb.min.x, (float)bed_bb.min.y, 0.0f, (float)bed_bb.max.x, (float)bed_bb.max.y, (float)m_config->opt_float("max_print_height")); - m_volumes->check_outside_state(m_config); - } - // do not cull backfaces to show broken geometry, if any - ::glDisable(GL_CULL_FACE); - } - - start_using_shader(); - m_volumes->render_VBOs(); - stop_using_shader(); - - if (is_picking_enabled()) - ::glEnable(GL_CULL_FACE); - } - else - { - // do not cull backfaces to show broken geometry, if any - if (is_picking_enabled()) - ::glDisable(GL_CULL_FACE); - - m_volumes->render_legacy(); - - if (is_picking_enabled()) - ::glEnable(GL_CULL_FACE); - } -} - -void GLCanvas3D::render_cutting_plane() const -{ - m_cutting_plane.render(volumes_bounding_box()); -} - -void GLCanvas3D::render_warning_texture() const -{ - if (!m_warning_texture_enabled) - return; - - // If the warning texture has not been loaded into the GPU, do it now. - unsigned int tex_id = _3DScene::finalize_warning_texture(); - if (tex_id > 0) - { - unsigned int w = _3DScene::get_warning_texture_width(); - unsigned int h = _3DScene::get_warning_texture_height(); - if ((w > 0) && (h > 0)) - { - ::glDisable(GL_DEPTH_TEST); - ::glPushMatrix(); - ::glLoadIdentity(); - - const Size& cnv_size = get_canvas_size(); - float zoom = get_camera_zoom(); - float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; - float l = (-0.5f * (float)w) * inv_zoom; - float t = (-0.5f * (float)cnv_size.get_height() + (float)h) * inv_zoom; - float r = l + (float)w * inv_zoom; - float b = t - (float)h * inv_zoom; - - render_texture(tex_id, l, r, b, t); - - ::glPopMatrix(); - ::glEnable(GL_DEPTH_TEST); - } - } -} - -void GLCanvas3D::render_legend_texture() const -{ - if (!m_legend_texture_enabled) - return; - - // If the legend texture has not been loaded into the GPU, do it now. - unsigned int tex_id = _3DScene::finalize_legend_texture(); - if (tex_id > 0) - { - unsigned int w = _3DScene::get_legend_texture_width(); - unsigned int h = _3DScene::get_legend_texture_height(); - if ((w > 0) && (h > 0)) - { - ::glDisable(GL_DEPTH_TEST); - ::glPushMatrix(); - ::glLoadIdentity(); - - const Size& cnv_size = get_canvas_size(); - float zoom = get_camera_zoom(); - float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; - float l = (-0.5f * (float)cnv_size.get_width()) * inv_zoom; - float t = (0.5f * (float)cnv_size.get_height()) * inv_zoom; - float r = l + (float)w * inv_zoom; - float b = t - (float)h * inv_zoom; - render_texture(tex_id, l, r, b, t); - - ::glPopMatrix(); - ::glEnable(GL_DEPTH_TEST); - } - } -} - -void GLCanvas3D::render_layer_editing_overlay(const Print& print) const -{ - if (m_volumes == nullptr) - return; - - GLVolume* volume = nullptr; - - for (GLVolume* vol : m_volumes->volumes) - { - if ((vol != nullptr) && vol->selected && vol->has_layer_height_texture()) - { - volume = vol; - break; - } - } - - if (volume == nullptr) - return; - - // If the active object was not allocated at the Print, go away.This should only be a momentary case between an object addition / deletion - // and an update by Platter::async_apply_config. - int object_idx = int(volume->select_group_id / 1000000); - if ((int)print.objects.size() < object_idx) - return; - - const PrintObject* print_object = print.get_object(object_idx); - if (print_object == nullptr) - return; - - m_layers_editing.render(*this, *print_object, *volume); -} - void GLCanvas3D::render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const { ::glColor4f(1.0f, 1.0f, 1.0f, 1.0f); @@ -2172,5 +1956,251 @@ void GLCanvas3D::_refresh_if_shown_on_screen() } } +void GLCanvas3D::_picking_pass() const +{ + if (is_picking_enabled() && !is_mouse_dragging() && (m_volumes != nullptr)) + { + // Render the object for picking. + // FIXME This cannot possibly work in a multi - sampled context as the color gets mangled by the anti - aliasing. + // Better to use software ray - casting on a bounding - box hierarchy. + + if (is_multisample_allowed()) + ::glDisable(GL_MULTISAMPLE); + + ::glDisable(GL_LIGHTING); + ::glDisable(GL_BLEND); + + ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + ::glPushAttrib(GL_ENABLE_BIT); + + render_volumes(true); + + ::glPopAttrib(); + + if (is_multisample_allowed()) + ::glEnable(GL_MULTISAMPLE); + + const Size& cnv_size = get_canvas_size(); + + const Pointf& pos = get_mouse_position(); + GLubyte color[4]; + ::glReadPixels(pos.x, cnv_size.get_height() - pos.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color); + int volume_id = color[0] + color[1] * 256 + color[2] * 256 * 256; + + m_hover_volume_id = -1; + + for (GLVolume* vol : m_volumes->volumes) + { + vol->hover = false; + } + + if (volume_id < m_volumes->volumes.size()) + { + m_hover_volume_id = volume_id; + m_volumes->volumes[volume_id]->hover = true; + int group_id = m_volumes->volumes[volume_id]->select_group_id; + if (group_id != -1) + { + for (GLVolume* vol : m_volumes->volumes) + { + if (vol->select_group_id == group_id) + vol->hover = true; + } + } + } + } +} + +void GLCanvas3D::_render_background() const +{ + ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + static const float COLOR[3] = { 10.0f / 255.0f, 98.0f / 255.0f, 144.0f / 255.0f }; + + ::glDisable(GL_LIGHTING); + + ::glPushMatrix(); + ::glLoadIdentity(); + ::glMatrixMode(GL_PROJECTION); + ::glPushMatrix(); + ::glLoadIdentity(); + + // Draws a bluish bottom to top gradient over the complete screen. + ::glDisable(GL_DEPTH_TEST); + + ::glBegin(GL_QUADS); + ::glColor3f(0.0f, 0.0f, 0.0f); + ::glVertex3f(-1.0f, -1.0f, 1.0f); + ::glVertex3f(1.0f, -1.0f, 1.0f); + ::glColor3f(COLOR[0], COLOR[1], COLOR[2]); + ::glVertex3f(1.0f, 1.0f, 1.0f); + ::glVertex3f(-1.0f, 1.0f, 1.0f); + ::glEnd(); + + ::glEnable(GL_DEPTH_TEST); + + ::glPopMatrix(); + ::glMatrixMode(GL_MODELVIEW); + ::glPopMatrix(); +} + +void GLCanvas3D::_render_bed() const +{ + m_bed.render(); +} + +void GLCanvas3D::_render_axes() const +{ + m_axes.render(); +} + +void GLCanvas3D::_render_objects(bool useVBOs) const +{ + if ((m_volumes == nullptr) || m_volumes->empty()) + return; + + ::glEnable(GL_LIGHTING); + + if (!m_shader_enabled) + render_volumes(false); + else if (useVBOs) + { + if (is_picking_enabled()) + { + m_on_mark_volumes_for_layer_height_callback.call(); + + if (m_config != nullptr) + { + const BoundingBoxf3& bed_bb = bed_bounding_box(); + m_volumes->set_print_box((float)bed_bb.min.x, (float)bed_bb.min.y, 0.0f, (float)bed_bb.max.x, (float)bed_bb.max.y, (float)m_config->opt_float("max_print_height")); + m_volumes->check_outside_state(m_config); + } + // do not cull backfaces to show broken geometry, if any + ::glDisable(GL_CULL_FACE); + } + + start_using_shader(); + m_volumes->render_VBOs(); + stop_using_shader(); + + if (is_picking_enabled()) + ::glEnable(GL_CULL_FACE); + } + else + { + // do not cull backfaces to show broken geometry, if any + if (is_picking_enabled()) + ::glDisable(GL_CULL_FACE); + + m_volumes->render_legacy(); + + if (is_picking_enabled()) + ::glEnable(GL_CULL_FACE); + } +} + +void GLCanvas3D::_render_cutting_plane() const +{ + m_cutting_plane.render(volumes_bounding_box()); +} + +void GLCanvas3D::_render_warning_texture() const +{ + if (!m_warning_texture_enabled) + return; + + // If the warning texture has not been loaded into the GPU, do it now. + unsigned int tex_id = _3DScene::finalize_warning_texture(); + if (tex_id > 0) + { + unsigned int w = _3DScene::get_warning_texture_width(); + unsigned int h = _3DScene::get_warning_texture_height(); + if ((w > 0) && (h > 0)) + { + ::glDisable(GL_DEPTH_TEST); + ::glPushMatrix(); + ::glLoadIdentity(); + + const Size& cnv_size = get_canvas_size(); + float zoom = get_camera_zoom(); + float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; + float l = (-0.5f * (float)w) * inv_zoom; + float t = (-0.5f * (float)cnv_size.get_height() + (float)h) * inv_zoom; + float r = l + (float)w * inv_zoom; + float b = t - (float)h * inv_zoom; + + render_texture(tex_id, l, r, b, t); + + ::glPopMatrix(); + ::glEnable(GL_DEPTH_TEST); + } + } +} + +void GLCanvas3D::_render_legend_texture() const +{ + if (!m_legend_texture_enabled) + return; + + // If the legend texture has not been loaded into the GPU, do it now. + unsigned int tex_id = _3DScene::finalize_legend_texture(); + if (tex_id > 0) + { + unsigned int w = _3DScene::get_legend_texture_width(); + unsigned int h = _3DScene::get_legend_texture_height(); + if ((w > 0) && (h > 0)) + { + ::glDisable(GL_DEPTH_TEST); + ::glPushMatrix(); + ::glLoadIdentity(); + + const Size& cnv_size = get_canvas_size(); + float zoom = get_camera_zoom(); + float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; + float l = (-0.5f * (float)cnv_size.get_width()) * inv_zoom; + float t = (0.5f * (float)cnv_size.get_height()) * inv_zoom; + float r = l + (float)w * inv_zoom; + float b = t - (float)h * inv_zoom; + render_texture(tex_id, l, r, b, t); + + ::glPopMatrix(); + ::glEnable(GL_DEPTH_TEST); + } + } +} + +void GLCanvas3D::_render_layer_editing_overlay() const +{ + if ((m_volumes == nullptr) && (m_print == nullptr)) + return; + + GLVolume* volume = nullptr; + + for (GLVolume* vol : m_volumes->volumes) + { + if ((vol != nullptr) && vol->selected && vol->has_layer_height_texture()) + { + volume = vol; + break; + } + } + + if (volume == nullptr) + return; + + // If the active object was not allocated at the Print, go away.This should only be a momentary case between an object addition / deletion + // and an update by Platter::async_apply_config. + int object_idx = int(volume->select_group_id / 1000000); + if ((int)m_print->objects.size() < object_idx) + return; + + const PrintObject* print_object = m_print->get_object(object_idx); + if (print_object == nullptr) + return; + + m_layers_editing.render(*this, *print_object, *volume); +} + } // namespace GUI } // namespace Slic3r diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index c5aa5a1cd..d5065986c 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -307,7 +307,7 @@ private: bool m_dirty; bool m_apply_zoom_to_volumes_filter; - int m_hover_volume_id; + mutable int m_hover_volume_id; bool m_warning_texture_enabled; bool m_legend_texture_enabled; bool m_picking_enabled; @@ -432,17 +432,9 @@ public: bool start_using_shader() const; void stop_using_shader() const; - void picking_pass(); + void render(bool useVBOs) const; - void render_background() const; - void render_bed() const; - void render_axes() const; void render_volumes(bool fake_colors) const; - void render_objects(bool useVBOs); - void render_cutting_plane() const; - void render_warning_texture() const; - void render_legend_texture() const; - void render_layer_editing_overlay(const Print& print) const; void render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const; @@ -464,6 +456,16 @@ private: void _deregister_callbacks(); void _refresh_if_shown_on_screen(); + + void _picking_pass() const; + void _render_background() const; + void _render_bed() const; + void _render_axes() const; + void _render_objects(bool useVBOs) const; + void _render_cutting_plane() const; + void _render_warning_texture() const; + void _render_legend_texture() const; + void _render_layer_editing_overlay() const; }; } // namespace GUI diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index fea8dab8a..9d2e3733e 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -610,32 +610,11 @@ void GLCanvas3DManager::stop_using_shader(wxGLCanvas* canvas) const it->second->stop_using_shader(); } -void GLCanvas3DManager::picking_pass(wxGLCanvas* canvas) +void GLCanvas3DManager::render(wxGLCanvas* canvas) const { CanvasesMap::const_iterator it = _get_canvas(canvas); if (it != m_canvases.end()) - it->second->picking_pass(); -} - -void GLCanvas3DManager::render_background(wxGLCanvas* canvas) const -{ - CanvasesMap::const_iterator it = _get_canvas(canvas); - if (it != m_canvases.end()) - it->second->render_background(); -} - -void GLCanvas3DManager::render_bed(wxGLCanvas* canvas) const -{ - CanvasesMap::const_iterator it = _get_canvas(canvas); - if (it != m_canvases.end()) - it->second->render_bed(); -} - -void GLCanvas3DManager::render_axes(wxGLCanvas* canvas) const -{ - CanvasesMap::const_iterator it = _get_canvas(canvas); - if (it != m_canvases.end()) - it->second->render_axes(); + it->second->render(m_use_VBOs); } void GLCanvas3DManager::render_volumes(wxGLCanvas* canvas, bool fake_colors) const @@ -645,41 +624,6 @@ void GLCanvas3DManager::render_volumes(wxGLCanvas* canvas, bool fake_colors) con it->second->render_volumes(fake_colors); } -void GLCanvas3DManager::render_objects(wxGLCanvas* canvas, bool useVBOs) -{ - CanvasesMap::const_iterator it = _get_canvas(canvas); - if (it != m_canvases.end()) - it->second->render_objects(useVBOs); -} - -void GLCanvas3DManager::render_cutting_plane(wxGLCanvas* canvas) const -{ - CanvasesMap::const_iterator it = _get_canvas(canvas); - if (it != m_canvases.end()) - it->second->render_cutting_plane(); -} - -void GLCanvas3DManager::render_warning_texture(wxGLCanvas* canvas) const -{ - CanvasesMap::const_iterator it = _get_canvas(canvas); - if (it != m_canvases.end()) - it->second->render_warning_texture(); -} - -void GLCanvas3DManager::render_legend_texture(wxGLCanvas* canvas) const -{ - CanvasesMap::const_iterator it = _get_canvas(canvas); - if (it != m_canvases.end()) - it->second->render_legend_texture(); -} - -void GLCanvas3DManager::render_layer_editing_overlay(wxGLCanvas* canvas, const Print& print) const -{ - CanvasesMap::const_iterator it = _get_canvas(canvas); - if (it != m_canvases.end()) - it->second->render_layer_editing_overlay(print); -} - void GLCanvas3DManager::render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) const { CanvasesMap::const_iterator it = _get_canvas(canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index 786c095e8..dcb10e63b 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -148,17 +148,9 @@ public: bool start_using_shader(wxGLCanvas* canvas) const; void stop_using_shader(wxGLCanvas* canvas) const; - void picking_pass(wxGLCanvas* canvas); + void render(wxGLCanvas* canvas) const; - void render_background(wxGLCanvas* canvas) const; - void render_bed(wxGLCanvas* canvas) const; - void render_axes(wxGLCanvas* canvas) const; void render_volumes(wxGLCanvas* canvas, bool fake_colors) const; - void render_objects(wxGLCanvas* canvas, bool useVBOs); - void render_cutting_plane(wxGLCanvas* canvas) const; - void render_warning_texture(wxGLCanvas* canvas) const; - void render_legend_texture(wxGLCanvas* canvas) const; - void render_layer_editing_overlay(wxGLCanvas* canvas, const Print& print) const; void render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) const; diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index 8aff20ae3..fc57ce89b 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -732,28 +732,10 @@ stop_using_shader(canvas) _3DScene::stop_using_shader((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); void -picking_pass(canvas) +render(canvas) SV *canvas; CODE: - _3DScene::picking_pass((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); - -void -render_background(canvas) - SV *canvas; - CODE: - _3DScene::render_background((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); - -void -render_bed(canvas) - SV *canvas; - CODE: - _3DScene::render_bed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); - -void -render_axes(canvas) - SV *canvas; - CODE: - _3DScene::render_axes((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + _3DScene::render((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); void render_volumes(canvas, fake_colors) @@ -762,38 +744,6 @@ render_volumes(canvas, fake_colors) CODE: _3DScene::render_volumes((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), fake_colors); -void -render_objects(canvas, useVBOs) - SV *canvas; - bool useVBOs; - CODE: - _3DScene::render_objects((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), useVBOs); - -void -render_cutting_plane(canvas) - SV *canvas; - CODE: - _3DScene::render_cutting_plane((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); - -void -render_warning_texture(canvas) - SV *canvas; - CODE: - _3DScene::render_warning_texture((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); - -void -render_legend_texture(canvas) - SV *canvas; - CODE: - _3DScene::render_legend_texture((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); - -void -render_layer_editing_overlay(canvas, print) - SV *canvas; - Print *print; - CODE: - _3DScene::render_layer_editing_overlay((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), print); - void render_texture(canvas, tex_id, left, right, bottom, top) SV *canvas;