From 455076231b6b45395d628cd7966c1d25768cfef1 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 May 2018 14:05:08 +0200 Subject: [PATCH] Layers editing shader moved to c++ --- lib/Slic3r/GUI/3DScene.pm | 167 ++++++++++-------- lib/Slic3r/GUI/Plater.pm | 26 ++- xs/lib/Slic3r/XS.pm | 1 + xs/src/slic3r/GUI/3DScene.cpp | 20 ++- xs/src/slic3r/GUI/3DScene.hpp | 5 +- xs/src/slic3r/GUI/GLCanvas3D.cpp | 223 ++++++++++++++++-------- xs/src/slic3r/GUI/GLCanvas3D.hpp | 61 ++++--- xs/src/slic3r/GUI/GLCanvas3DManager.cpp | 40 +++-- xs/src/slic3r/GUI/GLCanvas3DManager.hpp | 13 +- xs/xsp/GUI_3DScene.xsp | 42 +++-- 10 files changed, 387 insertions(+), 211 deletions(-) diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index e48d2cf5c..7debb898a 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -197,13 +197,10 @@ sub new { #============================================================================================================================== # $self->_camera_type('ortho'); ## $self->_camera_type('perspective'); -#============================================================================================================================== -#============================================================================================================================== # $self->_camera_target(Slic3r::Pointf3->new(0,0,0)); # $self->_camera_distance(0.); +# $self->layer_editing_enabled(0); #============================================================================================================================== - - $self->layer_editing_enabled(0); $self->{layer_height_edit_band_width} = 2.; $self->{layer_height_edit_strength} = 0.005; $self->{layer_height_edit_last_object_id} = -1; @@ -307,54 +304,53 @@ sub Destroy { return $self->SUPER::Destroy; } -sub layer_editing_enabled { - my ($self, $value) = @_; - if (@_ == 2) { - $self->{layer_editing_enabled} = $value; - if ($value) { - if (! $self->{layer_editing_initialized}) { - # Enabling the layer editing for the first time. This triggers compilation of the necessary OpenGL shaders. - # If compilation fails, a message box is shown with the error codes. - $self->SetCurrent($self->GetContext); - my $shader = new Slic3r::GUI::_3DScene::GLShader; - my $error_message; #============================================================================================================================== - if (! $shader->load_from_file("variable_layer_height.fs", "variable_layer_height.vs")) { +#sub layer_editing_enabled { +# my ($self, $value) = @_; +# if (@_ == 2) { +# $self->{layer_editing_enabled} = $value; +# if ($value) { +# if (! $self->{layer_editing_initialized}) { +# # Enabling the layer editing for the first time. This triggers compilation of the necessary OpenGL shaders. +# # If compilation fails, a message box is shown with the error codes. +# $self->SetCurrent($self->GetContext); +# my $shader = new Slic3r::GUI::_3DScene::GLShader; +# my $error_message; # if (! $shader->load_from_text($self->_fragment_shader_variable_layer_height, $self->_vertex_shader_variable_layer_height)) { +# # Compilation or linking of the shaders failed. +# $error_message = "Cannot compile an OpenGL Shader, therefore the Variable Layer Editing will be disabled.\n\n" +# . $shader->last_error; +# $shader = undef; +# } else { +# $self->{layer_height_edit_shader} = $shader; +# ($self->{layer_preview_z_texture_id}) = glGenTextures_p(1); +# glBindTexture(GL_TEXTURE_2D, $self->{layer_preview_z_texture_id}); +# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); +# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); +# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); +# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); +# glBindTexture(GL_TEXTURE_2D, 0); +# } +# if (defined($error_message)) { +# # Don't enable the layer editing tool. +# $self->{layer_editing_enabled} = 0; +# # 2 means failed +# $self->{layer_editing_initialized} = 2; +# # Show the error message. +# Wx::MessageBox($error_message, "Slic3r Error", wxOK | wxICON_EXCLAMATION, $self); +# } else { +# $self->{layer_editing_initialized} = 1; +# } +# } elsif ($self->{layer_editing_initialized} == 2) { +# # Initilization failed before. Don't try to initialize and disable layer editing. +# $self->{layer_editing_enabled} = 0; +# } +# } +# } +# return $self->{layer_editing_enabled}; +#} #============================================================================================================================== - # Compilation or linking of the shaders failed. - $error_message = "Cannot compile an OpenGL Shader, therefore the Variable Layer Editing will be disabled.\n\n" - . $shader->last_error; - $shader = undef; - } else { - $self->{layer_height_edit_shader} = $shader; - ($self->{layer_preview_z_texture_id}) = glGenTextures_p(1); - glBindTexture(GL_TEXTURE_2D, $self->{layer_preview_z_texture_id}); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); - glBindTexture(GL_TEXTURE_2D, 0); - } - if (defined($error_message)) { - # Don't enable the layer editing tool. - $self->{layer_editing_enabled} = 0; - # 2 means failed - $self->{layer_editing_initialized} = 2; - # Show the error message. - Wx::MessageBox($error_message, "Slic3r Error", wxOK | wxICON_EXCLAMATION, $self); - } else { - $self->{layer_editing_initialized} = 1; - } - } elsif ($self->{layer_editing_initialized} == 2) { - # Initilization failed before. Don't try to initialize and disable layer editing. - $self->{layer_editing_enabled} = 0; - } - } - } - return $self->{layer_editing_enabled}; -} sub layer_editing_allowed { my ($self) = @_; @@ -463,7 +459,10 @@ sub mouse_event { my ($self, $e) = @_; my $pos = Slic3r::Pointf->new($e->GetPositionXY); - my $object_idx_selected = $self->{layer_height_edit_last_object_id} = ($self->layer_editing_enabled && $self->{print}) ? $self->_first_selected_object_id_for_variable_layer_height_editing : -1; +#============================================================================================================================== + my $object_idx_selected = $self->{layer_height_edit_last_object_id} = (Slic3r::GUI::_3DScene::is_layers_editing_enabled($self) && $self->{print}) ? $self->_first_selected_object_id_for_variable_layer_height_editing : -1; +# my $object_idx_selected = $self->{layer_height_edit_last_object_id} = ($self->layer_editing_enabled && $self->{print}) ? $self->_first_selected_object_id_for_variable_layer_height_editing : -1; +#============================================================================================================================== #============================================================================================================================== Slic3r::GUI::_3DScene::set_mouse_dragging($self, $e->Dragging); @@ -507,7 +506,9 @@ sub mouse_event { # Don't deselect a volume if layer editing is enabled. We want the object to stay selected # during the scene manipulation. #============================================================================================================================== - if (Slic3r::GUI::_3DScene::is_picking_enabled($self) && ($volume_idx != -1 || ! $self->layer_editing_enabled)) { + +#============================================================================================================================== + if (Slic3r::GUI::_3DScene::is_picking_enabled($self) && ($volume_idx != -1 || ! Slic3r::GUI::_3DScene::is_layers_editing_enabled($self))) { Slic3r::GUI::_3DScene::deselect_volumes($self); Slic3r::GUI::_3DScene::select_volume($self, $volume_idx); # if ($self->enable_picking && ($volume_idx != -1 || ! $self->layer_editing_enabled)) { @@ -690,8 +691,10 @@ sub mouse_wheel_event { # Ignore the wheel events if the middle button is pressed. return; } - - if ($self->layer_editing_enabled && $self->{print}) { +#============================================================================================================================== + if (Slic3r::GUI::_3DScene::is_layers_editing_enabled($self) && $self->{print}) { +# if ($self->layer_editing_enabled && $self->{print}) { +#============================================================================================================================== my $object_idx_selected = $self->_first_selected_object_id_for_variable_layer_height_editing; if ($object_idx_selected != -1) { # A volume is selected. Test, whether hovering over a layer thickness bar. @@ -1393,11 +1396,11 @@ sub DestroyGL { # $self->{plain_shader}->release; # delete $self->{plain_shader}; # } +# if ($self->{layer_height_edit_shader}) { +# $self->{layer_height_edit_shader}->release; +# delete $self->{layer_height_edit_shader}; +# } #=================================================================================================================================== - if ($self->{layer_height_edit_shader}) { - $self->{layer_height_edit_shader}->release; - delete $self->{layer_height_edit_shader}; - } $self->volumes->release_geometry; } } @@ -1702,10 +1705,19 @@ sub mark_volumes_for_layer_height { foreach my $volume_idx (0..$#{$self->volumes}) { my $volume = $self->volumes->[$volume_idx]; my $object_id = int($volume->select_group_id / 1000000); - if ($self->layer_editing_enabled && $volume->selected && $self->{layer_height_edit_shader} && +#============================================================================================================================== + my $shader = Slic3r::GUI::_3DScene::get_layers_editing_shader($self); + + if (Slic3r::GUI::_3DScene::is_layers_editing_enabled($self) && $shader && $volume->selected && $volume->has_layer_height_texture && $object_id < $self->{print}->object_count) { - $volume->set_layer_height_texture_data($self->{layer_preview_z_texture_id}, $self->{layer_height_edit_shader}->shader_program_id, - $self->{print}->get_object($object_id), $self->_variable_layer_thickness_bar_mouse_cursor_z_relative, $self->{layer_height_edit_band_width}); + $volume->set_layer_height_texture_data(Slic3r::GUI::_3DScene::get_layers_editing_z_texture_id($self), $shader->shader_program_id, + $self->{print}->get_object($object_id), $self->_variable_layer_thickness_bar_mouse_cursor_z_relative, $self->{layer_height_edit_band_width}); + +# if ($self->layer_editing_enabled && $volume->selected && $self->{layer_height_edit_shader} && +# $volume->has_layer_height_texture && $object_id < $self->{print}->object_count) { +# $volume->set_layer_height_texture_data($self->{layer_preview_z_texture_id}, $self->{layer_height_edit_shader}->shader_program_id, +# $self->{print}->get_object($object_id), $self->_variable_layer_thickness_bar_mouse_cursor_z_relative, $self->{layer_height_edit_band_width}); +#============================================================================================================================== } else { $volume->reset_layer_height_texture_data(); } @@ -1794,7 +1806,10 @@ sub draw_active_object_annotations { # $fakecolor is a boolean indicating, that the objects shall be rendered in a color coding the object index for picking. my ($self) = @_; - return if (! $self->{layer_height_edit_shader} || ! $self->layer_editing_enabled); +#============================================================================================================================== + return if (!Slic3r::GUI::_3DScene::is_layers_editing_enabled($self)); +# return if (! $self->{layer_height_edit_shader} || ! $self->layer_editing_enabled); +#============================================================================================================================== # Find the selected volume, over which the layer editing is active. my $volume; @@ -1821,12 +1836,25 @@ sub draw_active_object_annotations { my $print_object = $self->{print}->get_object($object_idx); my $z_max = $print_object->model_object->bounding_box->z_max; - $self->{layer_height_edit_shader}->enable; - $self->{layer_height_edit_shader}->set_uniform('z_to_texture_row', $volume->layer_height_texture_z_to_row_id); - $self->{layer_height_edit_shader}->set_uniform('z_texture_row_to_normalized', 1. / $volume->layer_height_texture_height); - $self->{layer_height_edit_shader}->set_uniform('z_cursor', $z_max * $z_cursor_relative); - $self->{layer_height_edit_shader}->set_uniform('z_cursor_band_width', $self->{layer_height_edit_band_width}); - glBindTexture(GL_TEXTURE_2D, $self->{layer_preview_z_texture_id}); +#============================================================================================================================== + my $shader = Slic3r::GUI::_3DScene::get_layers_editing_shader($self); + $shader->enable; + $shader->set_uniform('z_to_texture_row', $volume->layer_height_texture_z_to_row_id); + $shader->set_uniform('z_texture_row_to_normalized', 1. / $volume->layer_height_texture_height); + $shader->set_uniform('z_cursor', $z_max * $z_cursor_relative); + $shader->set_uniform('z_cursor_band_width', $self->{layer_height_edit_band_width}); + + +# $self->{layer_height_edit_shader}->enable; +# $self->{layer_height_edit_shader}->set_uniform('z_to_texture_row', $volume->layer_height_texture_z_to_row_id); +# $self->{layer_height_edit_shader}->set_uniform('z_texture_row_to_normalized', 1. / $volume->layer_height_texture_height); +# $self->{layer_height_edit_shader}->set_uniform('z_cursor', $z_max * $z_cursor_relative); +# $self->{layer_height_edit_shader}->set_uniform('z_cursor_band_width', $self->{layer_height_edit_band_width}); +#============================================================================================================================== +#============================================================================================================================== + glBindTexture(GL_TEXTURE_2D, Slic3r::GUI::_3DScene::get_layers_editing_z_texture_id($self)); +# glBindTexture(GL_TEXTURE_2D, $self->{layer_preview_z_texture_id}); +#============================================================================================================================== glTexImage2D_c(GL_TEXTURE_2D, 0, GL_RGBA8, $volume->layer_height_texture_width, $volume->layer_height_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexImage2D_c(GL_TEXTURE_2D, 1, GL_RGBA8, $volume->layer_height_texture_width / 2, $volume->layer_height_texture_height / 2, @@ -1850,7 +1878,10 @@ sub draw_active_object_annotations { glVertex3f($bar_left, $bar_top, $z_max); glEnd(); glBindTexture(GL_TEXTURE_2D, 0); - $self->{layer_height_edit_shader}->disable; +#============================================================================================================================== + $shader->disable; +# $self->{layer_height_edit_shader}->disable; +#============================================================================================================================== #============================================================================================================================== Slic3r::GUI::_3DScene::render_layer_editing_textures($self, $print_object); diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index e5e6a73d4..3e78b5c95 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -329,7 +329,10 @@ sub new { EVT_TOOL($self, TB_CUT, sub { $_[0]->object_cut_dialog }); EVT_TOOL($self, TB_SETTINGS, sub { $_[0]->object_settings_dialog }); EVT_TOOL($self, TB_LAYER_EDITING, sub { - my $state = $self->{canvas3D}->layer_editing_enabled; +#============================================================================================================================== + my $state = Slic3r::GUI::_3DScene::is_layers_editing_enabled($self->{canvas3D}); +# my $state = $self->{canvas3D}->layer_editing_enabled; +#============================================================================================================================== $self->{htoolbar}->ToggleTool(TB_LAYER_EDITING, ! $state); $self->on_layer_editing_toggled(! $state); }); @@ -608,8 +611,12 @@ sub _on_select_preset { sub on_layer_editing_toggled { my ($self, $new_state) = @_; - $self->{canvas3D}->layer_editing_enabled($new_state); - if ($new_state && ! $self->{canvas3D}->layer_editing_enabled) { +#============================================================================================================================== + Slic3r::GUI::_3DScene::enable_layers_editing($self->{canvas3D}, $new_state); + if ($new_state && ! Slic3r::GUI::_3DScene::is_layers_editing_enabled($self->{canvas3D})) { +# $self->{canvas3D}->layer_editing_enabled($new_state); +# if ($new_state && ! $self->{canvas3D}->layer_editing_enabled) { +#============================================================================================================================== # Initialization of the OpenGL shaders failed. Disable the tool. if ($self->{htoolbar}) { $self->{htoolbar}->EnableTool(TB_LAYER_EDITING, 0); @@ -1237,8 +1244,12 @@ sub async_apply_config { my $invalidated = $self->{print}->apply_config(wxTheApp->{preset_bundle}->full_config); # Just redraw the 3D canvas without reloading the scene. -# $self->{canvas3D}->Refresh if ($invalidated && $self->{canvas3D}->layer_editing_enabled); - $self->{canvas3D}->Refresh if ($self->{canvas3D}->layer_editing_enabled); +#============================================================================================================================== +# $self->{canvas3D}->Refresh if ($invalidated && Slic3r::GUI::_3DScene::is_layers_editing_enabled($self->{canvas3D})); + $self->{canvas3D}->Refresh if Slic3r::GUI::_3DScene::is_layers_editing_enabled($self->{canvas3D}); +## $self->{canvas3D}->Refresh if ($invalidated && $self->{canvas3D}->layer_editing_enabled); +# $self->{canvas3D}->Refresh if ($self->{canvas3D}->layer_editing_enabled); +#============================================================================================================================== # Hide the slicing results if the current slicing status is no more valid. $self->{"print_info_box_show"}->(0) if $invalidated; @@ -1819,7 +1830,10 @@ sub on_config_change { $self->{"btn_layer_editing"}->Disable; $self->{"btn_layer_editing"}->SetValue(0); } - $self->{canvas3D}->layer_editing_enabled(0); +#============================================================================================================================== + Slic3r::GUI::_3DScene::enable_layers_editing($self->{canvas3D}, 0); +# $self->{canvas3D}->layer_editing_enabled(0); +#============================================================================================================================== $self->{canvas3D}->Refresh; $self->{canvas3D}->Update; } elsif ($self->{canvas3D}->layer_editing_allowed) { diff --git a/xs/lib/Slic3r/XS.pm b/xs/lib/Slic3r/XS.pm index bd0b698ee..a4847fb45 100644 --- a/xs/lib/Slic3r/XS.pm +++ b/xs/lib/Slic3r/XS.pm @@ -282,6 +282,7 @@ for my $class (qw( Slic3r::Geometry::BoundingBox Slic3r::Geometry::BoundingBoxf Slic3r::Geometry::BoundingBoxf3 + Slic3r::GUI::_3DScene::GLShader Slic3r::GUI::_3DScene::GLVolume Slic3r::GUI::Preset Slic3r::GUI::PresetCollection diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index affca1083..2969f3e8a 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -1939,16 +1939,16 @@ bool _3DScene::is_picking_enabled(wxGLCanvas* canvas) return s_canvas_mgr.is_picking_enabled(canvas); } -bool _3DScene::is_shader_enabled(wxGLCanvas* canvas) -{ - return s_canvas_mgr.is_shader_enabled(canvas); -} - bool _3DScene::is_multisample_allowed(wxGLCanvas* canvas) { return s_canvas_mgr.is_multisample_allowed(canvas); } +void _3DScene::enable_layers_editing(wxGLCanvas* canvas, bool enable) +{ + s_canvas_mgr.enable_layers_editing(canvas, enable); +} + void _3DScene::enable_warning_texture(wxGLCanvas* canvas, bool enable) { s_canvas_mgr.enable_warning_texture(canvas, enable); @@ -2005,6 +2005,16 @@ void _3DScene::set_hover_volume_id(wxGLCanvas* canvas, int id) s_canvas_mgr.set_hover_volume_id(canvas, id); } +unsigned int _3DScene::get_layers_editing_z_texture_id(wxGLCanvas* canvas) +{ + return s_canvas_mgr.get_layers_editing_z_texture_id(canvas); +} + +GLShader* _3DScene::get_layers_editing_shader(wxGLCanvas* canvas) +{ + return s_canvas_mgr.get_layers_editing_shader(canvas); +} + void _3DScene::zoom_to_bed(wxGLCanvas* canvas) { s_canvas_mgr.zoom_to_bed(canvas); diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index e09c226c7..ab7f1ba7d 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -598,9 +598,9 @@ public: static bool is_layers_editing_enabled(wxGLCanvas* canvas); static bool is_picking_enabled(wxGLCanvas* canvas); - static bool is_shader_enabled(wxGLCanvas* canvas); static bool is_multisample_allowed(wxGLCanvas* canvas); + static void enable_layers_editing(wxGLCanvas* canvas, bool enable); static void enable_warning_texture(wxGLCanvas* canvas, bool enable); static void enable_legend_texture(wxGLCanvas* canvas, bool enable); static void enable_picking(wxGLCanvas* canvas, bool enable); @@ -616,6 +616,9 @@ public: static int get_hover_volume_id(wxGLCanvas* canvas); static void set_hover_volume_id(wxGLCanvas* canvas, int id); + static unsigned int get_layers_editing_z_texture_id(wxGLCanvas* canvas); + static GLShader* get_layers_editing_shader(wxGLCanvas* canvas); + static void zoom_to_bed(wxGLCanvas* canvas); static void zoom_to_volumes(wxGLCanvas* canvas); static void select_view(wxGLCanvas* canvas, const std::string& direction); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index 3e93b8a1b..31680148e 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -501,6 +501,73 @@ void GLCanvas3D::CuttingPlane::_render_contour() const ::glDisableClientState(GL_VERTEX_ARRAY); } +GLCanvas3D::Shader::Shader() + : m_shader(nullptr) +{ +} + +GLCanvas3D::Shader::~Shader() +{ + _reset(); +} + +bool GLCanvas3D::Shader::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename) +{ + if (is_initialized()) + return true; + + m_shader = new GLShader(); + if (m_shader != nullptr) + { + if (!m_shader->load_from_file(fragment_shader_filename.c_str(), vertex_shader_filename.c_str())) + { + std::cout << "Compilaton of shader failed:" << std::endl; + std::cout << m_shader->last_error << std::endl; + _reset(); + return false; + } + } + + return true; +} + +bool GLCanvas3D::Shader::is_initialized() const +{ + return (m_shader != nullptr); +} + +bool GLCanvas3D::Shader::start_using() const +{ + if (is_initialized()) + { + m_shader->enable(); + return true; + } + else + return false; +} + +void GLCanvas3D::Shader::stop_using() const +{ + if (m_shader != nullptr) + m_shader->disable(); +} + +GLShader* GLCanvas3D::Shader::get_shader() +{ + return m_shader; +} + +void GLCanvas3D::Shader::_reset() +{ + if (m_shader != nullptr) + { + m_shader->release(); + delete m_shader; + m_shader = nullptr; + } +} + GLCanvas3D::LayersEditing::GLTextureData::GLTextureData() : id(0) , width(0) @@ -516,7 +583,9 @@ GLCanvas3D::LayersEditing::GLTextureData::GLTextureData(unsigned int id, int wid } GLCanvas3D::LayersEditing::LayersEditing() - : m_enabled(false) + : m_allowed(false) + , m_enabled(false) + , m_z_texture_id(0) { } @@ -533,6 +602,39 @@ GLCanvas3D::LayersEditing::~LayersEditing() ::glDeleteTextures(1, &m_reset_texture.id); m_reset_texture = GLTextureData(); } + + if (m_z_texture_id != 0) + { + ::glDeleteTextures(1, &m_z_texture_id); + m_z_texture_id = 0; + } +} + +bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename) +{ + if (!m_shader.init(vertex_shader_filename, fragment_shader_filename)) + return false; + + ::glGenTextures(1, (GLuint*)&m_z_texture_id); + ::glBindTexture(GL_TEXTURE_2D, m_z_texture_id); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + ::glBindTexture(GL_TEXTURE_2D, 0); + + return true; +} + +bool GLCanvas3D::LayersEditing::is_allowed() const +{ + return m_allowed; +} + +void GLCanvas3D::LayersEditing::set_allowed(bool allowed) +{ + m_allowed = allowed; } bool GLCanvas3D::LayersEditing::is_enabled() const @@ -540,6 +642,16 @@ bool GLCanvas3D::LayersEditing::is_enabled() const return m_enabled; } +void GLCanvas3D::LayersEditing::set_enabled(bool enabled) +{ + m_enabled = m_allowed && m_shader.is_initialized() && enabled; +} + +unsigned int GLCanvas3D::LayersEditing::get_z_texture_id() const +{ + return m_z_texture_id; +} + void GLCanvas3D::LayersEditing::render(const GLCanvas3D& canvas, const PrintObject& print_object) const { const Rect& bar_rect = _get_bar_rect_viewport(canvas); @@ -549,6 +661,16 @@ void GLCanvas3D::LayersEditing::render(const GLCanvas3D& canvas, const PrintObje _render_profile(print_object, bar_rect); } +GLShader* GLCanvas3D::LayersEditing::get_shader() +{ + return m_shader.get_shader(); +} + +bool GLCanvas3D::LayersEditing::_is_initialized() const +{ + return m_shader.is_initialized(); +} + GLCanvas3D::LayersEditing::GLTextureData GLCanvas3D::LayersEditing::_load_texture_from_file(const std::string& filename) const { const std::string& path = resources_dir() + "/icons/"; @@ -729,65 +851,6 @@ Rect GLCanvas3D::LayersEditing::_get_reset_rect_viewport(const GLCanvas3D& canva return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom); } -GLCanvas3D::Shader::Shader() - : m_enabled(false) - , m_shader(nullptr) -{ -} - -bool GLCanvas3D::Shader::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename) -{ - m_shader = new GLShader(); - if (m_shader != nullptr) - { - if (!m_shader->load_from_file(fragment_shader_filename.c_str(), vertex_shader_filename.c_str())) - { - std::cout << "Compilaton of path shader failed:" << std::endl; - std::cout << m_shader->last_error << std::endl; - reset(); - return false; - } - } - - return true; -} - -void GLCanvas3D::Shader::reset() -{ - if (m_shader != nullptr) - { - delete m_shader; - m_shader = nullptr; - } -} - -bool GLCanvas3D::Shader::is_enabled() const -{ - return m_enabled; -} - -void GLCanvas3D::Shader::set_enabled(bool enabled) -{ - m_enabled = enabled; -} - -bool GLCanvas3D::Shader::start() const -{ - if (m_enabled && (m_shader != nullptr)) - { - m_shader->enable(); - return true; - } - else - return false; -} - -void GLCanvas3D::Shader::stop() const -{ - if (m_shader != nullptr) - m_shader->disable(); -} - GLCanvas3D::Mouse::Mouse() : m_dragging(false) { @@ -824,6 +887,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context) , m_warning_texture_enabled(false) , m_legend_texture_enabled(false) , m_picking_enabled(false) + , m_shader_enabled(false) , m_multisample_allowed(false) { } @@ -831,10 +895,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context) GLCanvas3D::~GLCanvas3D() { _deregister_callbacks(); - m_shader.reset(); } -bool GLCanvas3D::init(bool useVBOs) +bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl) { ::glClearColor(0.0f, 0.0f, 0.0f, 1.0f); ::glEnable(GL_DEPTH_TEST); @@ -876,6 +939,11 @@ bool GLCanvas3D::init(bool useVBOs) if (useVBOs && !m_shader.init("gouraud.vs", "gouraud.fs")) return false; + if (useVBOs && !m_layers_editing.init("variable_layer_height.vs", "variable_layer_height.fs")) + return false; + + m_layers_editing.set_allowed(!use_legacy_opengl); + return true; } @@ -1179,16 +1247,16 @@ bool GLCanvas3D::is_picking_enabled() const return m_picking_enabled; } -bool GLCanvas3D::is_shader_enabled() const -{ - return m_shader.is_enabled(); -} - bool GLCanvas3D::is_multisample_allowed() const { return m_multisample_allowed; } +void GLCanvas3D::enable_layers_editing(bool enable) +{ + m_layers_editing.set_enabled(enable); +} + void GLCanvas3D::enable_warning_texture(bool enable) { m_warning_texture_enabled = enable; @@ -1206,9 +1274,8 @@ void GLCanvas3D::enable_picking(bool enable) void GLCanvas3D::enable_shader(bool enable) { - m_shader.set_enabled(enable); + m_shader_enabled = enable; } - void GLCanvas3D::allow_multisample(bool allow) { m_multisample_allowed = allow; @@ -1289,12 +1356,12 @@ void GLCanvas3D::select_view(const std::string& direction) bool GLCanvas3D::start_using_shader() const { - return m_shader.start(); + return m_shader.start_using(); } void GLCanvas3D::stop_using_shader() const { - m_shader.stop(); + m_shader.stop_using(); } void GLCanvas3D::picking_pass() @@ -1384,6 +1451,16 @@ void GLCanvas3D::render_background() const ::glPopMatrix(); } +unsigned int GLCanvas3D::get_layers_editing_z_texture_id() const +{ + return m_layers_editing.get_z_texture_id(); +} + +GLShader* GLCanvas3D::get_layers_editing_shader() +{ + return m_layers_editing.get_shader(); +} + void GLCanvas3D::render_bed() const { m_bed.render(); @@ -1445,12 +1522,12 @@ void GLCanvas3D::render_volumes(bool fake_colors) const void GLCanvas3D::render_objects(bool useVBOs) { - if (m_volumes == nullptr) + if ((m_volumes == nullptr) || m_volumes->empty()) return; ::glEnable(GL_LIGHTING); - if (!is_shader_enabled()) + if (!m_shader_enabled) render_volumes(false); else if (useVBOs) { diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index 2a0a19772..a11780349 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -174,6 +174,27 @@ public: void _render_contour() const; }; + class Shader + { + GLShader* m_shader; + + public: + Shader(); + ~Shader(); + + bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename); + + bool is_initialized() const; + + bool start_using() const; + void stop_using() const; + + GLShader* get_shader(); + + private: + void _reset(); + }; + class LayersEditing { struct GLTextureData @@ -186,7 +207,10 @@ public: GLTextureData(unsigned int id, int width, int height); }; + bool m_allowed; bool m_enabled; + Shader m_shader; + unsigned int m_z_texture_id; mutable GLTextureData m_tooltip_texture; mutable GLTextureData m_reset_texture; @@ -194,11 +218,22 @@ public: LayersEditing(); ~LayersEditing(); + bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename); + + bool is_allowed() const; + void set_allowed(bool allowed); + bool is_enabled() const; + void set_enabled(bool enabled); + + unsigned int get_z_texture_id() const; void render(const GLCanvas3D& canvas, const PrintObject& print_object) const; + GLShader* get_shader(); + private: + bool _is_initialized() const; GLTextureData _load_texture_from_file(const std::string& filename) const; void _render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const; void _render_reset_texture(const GLCanvas3D& canvas, const Rect& reset_rect) const; @@ -209,24 +244,6 @@ public: Rect _get_reset_rect_viewport(const GLCanvas3D& canvas) const; }; - class Shader - { - bool m_enabled; - GLShader* m_shader; - - public: - Shader(); - - bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename); - void reset(); - - bool is_enabled() const; - void set_enabled(bool enabled); - - bool start() const; - void stop() const; - }; - class Mouse { bool m_dragging; @@ -262,6 +279,7 @@ private: bool m_warning_texture_enabled; bool m_legend_texture_enabled; bool m_picking_enabled; + bool m_shader_enabled; bool m_multisample_allowed; PerlCallback m_on_viewport_changed_callback; @@ -271,7 +289,7 @@ public: GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context); ~GLCanvas3D(); - bool init(bool useVBOs); + bool init(bool useVBOs, bool use_legacy_opengl); bool set_current(); @@ -332,9 +350,9 @@ public: bool is_layers_editing_enabled() const; bool is_picking_enabled() const; - bool is_shader_enabled() const; bool is_multisample_allowed() const; + void enable_layers_editing(bool enable); void enable_warning_texture(bool enable); void enable_legend_texture(bool enable); void enable_picking(bool enable); @@ -350,6 +368,9 @@ public: int get_hover_volume_id() const; void set_hover_volume_id(int id); + unsigned int get_layers_editing_z_texture_id() const; + GLShader* get_layers_editing_shader(); + void zoom_to_bed(); void zoom_to_volumes(); void select_view(const std::string& direction); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index 6dd7744c5..66a66307e 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -56,11 +56,6 @@ bool GLCanvas3DManager::GLVersion::is_greater_or_equal_to(unsigned int major, un return vn_minor >= minor; } -GLCanvas3DManager::LayerEditing::LayerEditing() - : allowed(false) -{ -} - GLCanvas3DManager::GLCanvas3DManager() : m_gl_initialized(false) , m_use_legacy_opengl(false) @@ -129,12 +124,11 @@ void GLCanvas3DManager::init_gl() const AppConfig* config = GUI::get_app_config(); m_use_legacy_opengl = (config == nullptr) || (config->get("use_legacy_opengl") == "1"); m_use_VBOs = !m_use_legacy_opengl && m_gl_version.is_greater_or_equal_to(2, 0); - m_layer_editing.allowed = !m_use_legacy_opengl; m_gl_initialized = true; std::cout << "DETECTED OPENGL: " << m_gl_version.vn_major << "." << m_gl_version.vn_minor << std::endl; std::cout << "USE VBOS = " << (m_use_VBOs ? "YES" : "NO") << std::endl; - std::cout << "LAYER EDITING ALLOWED = " << (m_layer_editing.allowed ? "YES" : "NO") << std::endl; + std::cout << "LAYER EDITING ALLOWED = " << (!m_use_legacy_opengl ? "YES" : "NO") << std::endl; } } @@ -143,15 +137,10 @@ bool GLCanvas3DManager::use_VBOs() const return m_use_VBOs; } -bool GLCanvas3DManager::layer_editing_allowed() const -{ - return m_layer_editing.allowed; -} - bool GLCanvas3DManager::init(wxGLCanvas* canvas, bool useVBOs) { CanvasesMap::const_iterator it = _get_canvas(canvas); - return (it != m_canvases.end()) ? it->second->init(useVBOs) : false; + return (it != m_canvases.end()) ? it->second->init(useVBOs, m_use_legacy_opengl) : false; } bool GLCanvas3DManager::is_dirty(wxGLCanvas* canvas) const @@ -391,18 +380,19 @@ bool GLCanvas3DManager::is_picking_enabled(wxGLCanvas* canvas) const return (it != m_canvases.end()) ? it->second->is_picking_enabled() : false; } -bool GLCanvas3DManager::is_shader_enabled(wxGLCanvas* canvas) const -{ - CanvasesMap::const_iterator it = _get_canvas(canvas); - return (it != m_canvases.end()) ? it->second->is_shader_enabled() : false; -} - bool GLCanvas3DManager::is_multisample_allowed(wxGLCanvas* canvas) const { CanvasesMap::const_iterator it = _get_canvas(canvas); return (it != m_canvases.end()) ? it->second->is_multisample_allowed() : false; } +void GLCanvas3DManager::enable_layers_editing(wxGLCanvas* canvas, bool enable) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->enable_layers_editing(enable); +} + void GLCanvas3DManager::enable_warning_texture(wxGLCanvas* canvas, bool enable) { CanvasesMap::iterator it = _get_canvas(canvas); @@ -477,6 +467,18 @@ void GLCanvas3DManager::set_hover_volume_id(wxGLCanvas* canvas, int id) it->second->set_hover_volume_id(id); } +unsigned int GLCanvas3DManager::get_layers_editing_z_texture_id(wxGLCanvas* canvas) const +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); + return (it != m_canvases.end()) ? it->second->get_layers_editing_z_texture_id() : 0; +} + +GLShader* GLCanvas3DManager::get_layers_editing_shader(wxGLCanvas* canvas) +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); + return (it != m_canvases.end()) ? it->second->get_layers_editing_shader() : nullptr; +} + void GLCanvas3DManager::zoom_to_bed(wxGLCanvas* canvas) { CanvasesMap::iterator it = _get_canvas(canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index 98baa3070..3b3e35c36 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -21,18 +21,10 @@ class GLCanvas3DManager bool is_greater_or_equal_to(unsigned int major, unsigned int minor) const; }; - struct LayerEditing - { - bool allowed; - - LayerEditing(); - }; - typedef std::map CanvasesMap; CanvasesMap m_canvases; GLVersion m_gl_version; - LayerEditing m_layer_editing; bool m_gl_initialized; bool m_use_legacy_opengl; bool m_use_VBOs; @@ -106,9 +98,9 @@ public: bool is_layers_editing_enabled(wxGLCanvas* canvas) const; bool is_picking_enabled(wxGLCanvas* canvas) const; - bool is_shader_enabled(wxGLCanvas* canvas) const; bool is_multisample_allowed(wxGLCanvas* canvas) const; + void enable_layers_editing(wxGLCanvas* canvas, bool enable); void enable_warning_texture(wxGLCanvas* canvas, bool enable); void enable_legend_texture(wxGLCanvas* canvas, bool enable); void enable_picking(wxGLCanvas* canvas, bool enable); @@ -124,6 +116,9 @@ public: int get_hover_volume_id(wxGLCanvas* canvas) const; void set_hover_volume_id(wxGLCanvas* canvas, int id); + unsigned int get_layers_editing_z_texture_id(wxGLCanvas* canvas) const; + GLShader* get_layers_editing_shader(wxGLCanvas* canvas); + void zoom_to_bed(wxGLCanvas* canvas); void zoom_to_volumes(wxGLCanvas* canvas); void select_view(wxGLCanvas* canvas, const std::string& direction); diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index c2314e3f0..0f47454da 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -451,7 +451,15 @@ set_camera_target(canvas, target) Pointf3 *target; CODE: _3DScene::set_camera_target((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), target); - + +bool +is_layers_editing_enabled(canvas) + SV *canvas; + CODE: + RETVAL = _3DScene::is_layers_editing_enabled((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + OUTPUT: + RETVAL + bool is_picking_enabled(canvas) SV *canvas; @@ -460,14 +468,6 @@ is_picking_enabled(canvas) OUTPUT: RETVAL -bool -is_shader_enabled(canvas) - SV *canvas; - CODE: - RETVAL = _3DScene::is_shader_enabled((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); - OUTPUT: - RETVAL - bool is_multisample_allowed(canvas) SV *canvas; @@ -476,6 +476,13 @@ is_multisample_allowed(canvas) OUTPUT: RETVAL +void +enable_layers_editing(canvas, enable) + SV *canvas; + bool enable; + CODE: + _3DScene::enable_layers_editing((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable); + void enable_warning_texture(canvas, enable) SV *canvas; @@ -556,6 +563,22 @@ set_hover_volume_id(canvas, id) CODE: _3DScene::set_hover_volume_id((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), id); +unsigned int +get_layers_editing_z_texture_id(canvas) + SV *canvas; + CODE: + RETVAL = _3DScene::get_layers_editing_z_texture_id((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + OUTPUT: + RETVAL + +Ref +get_layers_editing_shader(canvas) + SV *canvas; + CODE: + RETVAL = _3DScene::get_layers_editing_shader((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + OUTPUT: + RETVAL + void zoom_to_bed(canvas) SV *canvas; @@ -679,7 +702,6 @@ register_on_mark_volumes_for_layer_height_callback(canvas, callback) - unsigned int finalize_legend_texture() CODE: