Browse Source

Layers editing shader moved to c++

Enrico Turri 6 years ago
parent
commit
455076231b

+ 100 - 69
lib/Slic3r/GUI/3DScene.pm

@@ -197,13 +197,10 @@ sub new {
 #==============================================================================================================================
 #==============================================================================================================================
 #    $self->_camera_type('ortho');
 #    $self->_camera_type('ortho');
 ##    $self->_camera_type('perspective');
 ##    $self->_camera_type('perspective');
-#==============================================================================================================================
-#==============================================================================================================================
 #    $self->_camera_target(Slic3r::Pointf3->new(0,0,0));
 #    $self->_camera_target(Slic3r::Pointf3->new(0,0,0));
 #    $self->_camera_distance(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_band_width} = 2.;
     $self->{layer_height_edit_strength} = 0.005;
     $self->{layer_height_edit_strength} = 0.005;
     $self->{layer_height_edit_last_object_id} = -1;
     $self->{layer_height_edit_last_object_id} = -1;
@@ -307,54 +304,53 @@ sub Destroy {
     return $self->SUPER::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)) {
 #                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 {
 sub layer_editing_allowed {
     my ($self) = @_;
     my ($self) = @_;
@@ -463,7 +459,10 @@ sub mouse_event {
     my ($self, $e) = @_;
     my ($self, $e) = @_;
     
     
     my $pos = Slic3r::Pointf->new($e->GetPositionXY);
     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);
     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
             # Don't deselect a volume if layer editing is enabled. We want the object to stay selected
             # during the scene manipulation.
             # 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::deselect_volumes($self);
                 Slic3r::GUI::_3DScene::select_volume($self, $volume_idx);
                 Slic3r::GUI::_3DScene::select_volume($self, $volume_idx);
 #            if ($self->enable_picking && ($volume_idx != -1 || ! $self->layer_editing_enabled)) {
 #            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.
         # Ignore the wheel events if the middle button is pressed.
         return;
         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;
         my $object_idx_selected = $self->_first_selected_object_id_for_variable_layer_height_editing;
         if ($object_idx_selected != -1) {
         if ($object_idx_selected != -1) {
             # A volume is selected. Test, whether hovering over a layer thickness bar.
             # A volume is selected. Test, whether hovering over a layer thickness bar.
@@ -1393,11 +1396,11 @@ sub DestroyGL {
 #            $self->{plain_shader}->release;
 #            $self->{plain_shader}->release;
 #            delete $self->{plain_shader};
 #            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;
         $self->volumes->release_geometry;
     }
     }
 }
 }
@@ -1702,10 +1705,19 @@ sub mark_volumes_for_layer_height {
     foreach my $volume_idx (0..$#{$self->volumes}) {
     foreach my $volume_idx (0..$#{$self->volumes}) {
         my $volume = $self->volumes->[$volume_idx];
         my $volume = $self->volumes->[$volume_idx];
         my $object_id = int($volume->select_group_id / 1000000);
         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->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 {
         } else {
             $volume->reset_layer_height_texture_data();
             $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.
     # $fakecolor is a boolean indicating, that the objects shall be rendered in a color coding the object index for picking.
     my ($self) = @_;
     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.
     # Find the selected volume, over which the layer editing is active.
     my $volume;
     my $volume;
@@ -1821,12 +1836,25 @@ sub draw_active_object_annotations {
     my $print_object = $self->{print}->get_object($object_idx);
     my $print_object = $self->{print}->get_object($object_idx);
     my $z_max = $print_object->model_object->bounding_box->z_max;
     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, 
     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);
         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,
     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);
     glVertex3f($bar_left,  $bar_top, $z_max);
     glEnd();
     glEnd();
     glBindTexture(GL_TEXTURE_2D, 0);
     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);
     Slic3r::GUI::_3DScene::render_layer_editing_textures($self, $print_object);

+ 20 - 6
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_CUT, sub { $_[0]->object_cut_dialog });
         EVT_TOOL($self, TB_SETTINGS, sub { $_[0]->object_settings_dialog });
         EVT_TOOL($self, TB_SETTINGS, sub { $_[0]->object_settings_dialog });
         EVT_TOOL($self, TB_LAYER_EDITING, sub {
         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->{htoolbar}->ToggleTool(TB_LAYER_EDITING, ! $state);
             $self->on_layer_editing_toggled(! $state);
             $self->on_layer_editing_toggled(! $state);
         });
         });
@@ -608,8 +611,12 @@ sub _on_select_preset {
 
 
 sub on_layer_editing_toggled {
 sub on_layer_editing_toggled {
     my ($self, $new_state) = @_;
     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.
         # Initialization of the OpenGL shaders failed. Disable the tool.
         if ($self->{htoolbar}) {
         if ($self->{htoolbar}) {
             $self->{htoolbar}->EnableTool(TB_LAYER_EDITING, 0);
             $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);
     my $invalidated = $self->{print}->apply_config(wxTheApp->{preset_bundle}->full_config);
 
 
     # Just redraw the 3D canvas without reloading the scene.
     # 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.    
     # Hide the slicing results if the current slicing status is no more valid.    
     $self->{"print_info_box_show"}->(0) if $invalidated;
     $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"}->Disable;
                     $self->{"btn_layer_editing"}->SetValue(0);
                     $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}->Refresh;
                 $self->{canvas3D}->Update;
                 $self->{canvas3D}->Update;
             } elsif ($self->{canvas3D}->layer_editing_allowed) {
             } elsif ($self->{canvas3D}->layer_editing_allowed) {

+ 1 - 0
xs/lib/Slic3r/XS.pm

@@ -282,6 +282,7 @@ for my $class (qw(
         Slic3r::Geometry::BoundingBox
         Slic3r::Geometry::BoundingBox
         Slic3r::Geometry::BoundingBoxf
         Slic3r::Geometry::BoundingBoxf
         Slic3r::Geometry::BoundingBoxf3
         Slic3r::Geometry::BoundingBoxf3
+        Slic3r::GUI::_3DScene::GLShader        
         Slic3r::GUI::_3DScene::GLVolume
         Slic3r::GUI::_3DScene::GLVolume
         Slic3r::GUI::Preset
         Slic3r::GUI::Preset
         Slic3r::GUI::PresetCollection
         Slic3r::GUI::PresetCollection

+ 14 - 4
xs/src/slic3r/GUI/3DScene.cpp

@@ -1939,14 +1939,14 @@ bool _3DScene::is_picking_enabled(wxGLCanvas* canvas)
     return s_canvas_mgr.is_picking_enabled(canvas);
     return s_canvas_mgr.is_picking_enabled(canvas);
 }
 }
 
 
-bool _3DScene::is_shader_enabled(wxGLCanvas* canvas)
+bool _3DScene::is_multisample_allowed(wxGLCanvas* canvas)
 {
 {
-    return s_canvas_mgr.is_shader_enabled(canvas);
+    return s_canvas_mgr.is_multisample_allowed(canvas);
 }
 }
 
 
-bool _3DScene::is_multisample_allowed(wxGLCanvas* canvas)
+void _3DScene::enable_layers_editing(wxGLCanvas* canvas, bool enable)
 {
 {
-    return s_canvas_mgr.is_multisample_allowed(canvas);
+    s_canvas_mgr.enable_layers_editing(canvas, enable);
 }
 }
 
 
 void _3DScene::enable_warning_texture(wxGLCanvas* canvas, bool enable)
 void _3DScene::enable_warning_texture(wxGLCanvas* canvas, bool enable)
@@ -2005,6 +2005,16 @@ void _3DScene::set_hover_volume_id(wxGLCanvas* canvas, int id)
     s_canvas_mgr.set_hover_volume_id(canvas, 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)
 void _3DScene::zoom_to_bed(wxGLCanvas* canvas)
 {
 {
     s_canvas_mgr.zoom_to_bed(canvas);
     s_canvas_mgr.zoom_to_bed(canvas);

+ 4 - 1
xs/src/slic3r/GUI/3DScene.hpp

@@ -598,9 +598,9 @@ public:
 
 
     static bool is_layers_editing_enabled(wxGLCanvas* canvas);
     static bool is_layers_editing_enabled(wxGLCanvas* canvas);
     static bool is_picking_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 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_warning_texture(wxGLCanvas* canvas, bool enable);
     static void enable_legend_texture(wxGLCanvas* canvas, bool enable);
     static void enable_legend_texture(wxGLCanvas* canvas, bool enable);
     static void enable_picking(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 int get_hover_volume_id(wxGLCanvas* canvas);
     static void set_hover_volume_id(wxGLCanvas* canvas, int id);
     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_bed(wxGLCanvas* canvas);
     static void zoom_to_volumes(wxGLCanvas* canvas);
     static void zoom_to_volumes(wxGLCanvas* canvas);
     static void select_view(wxGLCanvas* canvas, const std::string& direction);
     static void select_view(wxGLCanvas* canvas, const std::string& direction);

+ 149 - 72
xs/src/slic3r/GUI/GLCanvas3D.cpp

@@ -501,6 +501,73 @@ void GLCanvas3D::CuttingPlane::_render_contour() const
     ::glDisableClientState(GL_VERTEX_ARRAY);
     ::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()
 GLCanvas3D::LayersEditing::GLTextureData::GLTextureData()
     : id(0)
     : id(0)
     , width(0)
     , width(0)
@@ -516,7 +583,9 @@ GLCanvas3D::LayersEditing::GLTextureData::GLTextureData(unsigned int id, int wid
 }
 }
 
 
 GLCanvas3D::LayersEditing::LayersEditing()
 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);
         ::glDeleteTextures(1, &m_reset_texture.id);
         m_reset_texture = GLTextureData();
         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
 bool GLCanvas3D::LayersEditing::is_enabled() const
@@ -540,6 +642,16 @@ bool GLCanvas3D::LayersEditing::is_enabled() const
     return m_enabled;
     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
 void GLCanvas3D::LayersEditing::render(const GLCanvas3D& canvas, const PrintObject& print_object) const
 {
 {
     const Rect& bar_rect = _get_bar_rect_viewport(canvas);
     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);
     _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
 GLCanvas3D::LayersEditing::GLTextureData GLCanvas3D::LayersEditing::_load_texture_from_file(const std::string& filename) const
 {
 {
     const std::string& path = resources_dir() + "/icons/";
     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);
     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()
 GLCanvas3D::Mouse::Mouse()
     : m_dragging(false)
     : m_dragging(false)
 {
 {
@@ -824,6 +887,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context)
     , m_warning_texture_enabled(false)
     , m_warning_texture_enabled(false)
     , m_legend_texture_enabled(false)
     , m_legend_texture_enabled(false)
     , m_picking_enabled(false)
     , m_picking_enabled(false)
+    , m_shader_enabled(false)
     , m_multisample_allowed(false)
     , m_multisample_allowed(false)
 {
 {
 }
 }
@@ -831,10 +895,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context)
 GLCanvas3D::~GLCanvas3D()
 GLCanvas3D::~GLCanvas3D()
 {
 {
     _deregister_callbacks();
     _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);
     ::glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
     ::glEnable(GL_DEPTH_TEST);
     ::glEnable(GL_DEPTH_TEST);
@@ -876,6 +939,11 @@ bool GLCanvas3D::init(bool useVBOs)
     if (useVBOs && !m_shader.init("gouraud.vs", "gouraud.fs"))
     if (useVBOs && !m_shader.init("gouraud.vs", "gouraud.fs"))
         return false;
         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;
     return true;
 }
 }
 
 
@@ -1179,14 +1247,14 @@ bool GLCanvas3D::is_picking_enabled() const
     return m_picking_enabled;
     return m_picking_enabled;
 }
 }
 
 
-bool GLCanvas3D::is_shader_enabled() const
+bool GLCanvas3D::is_multisample_allowed() const
 {
 {
-    return m_shader.is_enabled();
+    return m_multisample_allowed;
 }
 }
 
 
-bool GLCanvas3D::is_multisample_allowed() const
+void GLCanvas3D::enable_layers_editing(bool enable)
 {
 {
-    return m_multisample_allowed;
+    m_layers_editing.set_enabled(enable);
 }
 }
 
 
 void GLCanvas3D::enable_warning_texture(bool enable)
 void GLCanvas3D::enable_warning_texture(bool enable)
@@ -1206,9 +1274,8 @@ void GLCanvas3D::enable_picking(bool enable)
 
 
 void GLCanvas3D::enable_shader(bool enable)
 void GLCanvas3D::enable_shader(bool enable)
 {
 {
-    m_shader.set_enabled(enable);
+    m_shader_enabled = enable;
 }
 }
-
 void GLCanvas3D::allow_multisample(bool allow)
 void GLCanvas3D::allow_multisample(bool allow)
 {
 {
     m_multisample_allowed = allow;
     m_multisample_allowed = allow;
@@ -1289,12 +1356,12 @@ void GLCanvas3D::select_view(const std::string& direction)
 
 
 bool GLCanvas3D::start_using_shader() const
 bool GLCanvas3D::start_using_shader() const
 {
 {
-    return m_shader.start();
+    return m_shader.start_using();
 }
 }
 
 
 void GLCanvas3D::stop_using_shader() const
 void GLCanvas3D::stop_using_shader() const
 {
 {
-    m_shader.stop();
+    m_shader.stop_using();
 }
 }
 
 
 void GLCanvas3D::picking_pass()
 void GLCanvas3D::picking_pass()
@@ -1384,6 +1451,16 @@ void GLCanvas3D::render_background() const
     ::glPopMatrix();
     ::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
 void GLCanvas3D::render_bed() const
 {
 {
     m_bed.render();
     m_bed.render();
@@ -1445,12 +1522,12 @@ void GLCanvas3D::render_volumes(bool fake_colors) const
 
 
 void GLCanvas3D::render_objects(bool useVBOs)
 void GLCanvas3D::render_objects(bool useVBOs)
 {
 {
-    if (m_volumes == nullptr)
+    if ((m_volumes == nullptr) || m_volumes->empty())
         return;
         return;
 
 
     ::glEnable(GL_LIGHTING);
     ::glEnable(GL_LIGHTING);
 
 
-    if (!is_shader_enabled())
+    if (!m_shader_enabled)
         render_volumes(false);
         render_volumes(false);
     else if (useVBOs)
     else if (useVBOs)
     {
     {

+ 41 - 20
xs/src/slic3r/GUI/GLCanvas3D.hpp

@@ -174,6 +174,27 @@ public:
         void _render_contour() const;
         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
     class LayersEditing
     {
     {
         struct GLTextureData
         struct GLTextureData
@@ -186,7 +207,10 @@ public:
             GLTextureData(unsigned int id, int width, int height);
             GLTextureData(unsigned int id, int width, int height);
         };
         };
 
 
+        bool m_allowed;
         bool m_enabled;
         bool m_enabled;
+        Shader m_shader;
+        unsigned int m_z_texture_id;
         mutable GLTextureData m_tooltip_texture;
         mutable GLTextureData m_tooltip_texture;
         mutable GLTextureData m_reset_texture;
         mutable GLTextureData m_reset_texture;
 
 
@@ -194,11 +218,22 @@ public:
         LayersEditing();
         LayersEditing();
         ~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;
         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;
         void render(const GLCanvas3D& canvas, const PrintObject& print_object) const;
 
 
+        GLShader* get_shader();
+
     private:
     private:
+        bool _is_initialized() const;
         GLTextureData _load_texture_from_file(const std::string& filename) 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_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;
         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;
         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
     class Mouse
     {
     {
         bool m_dragging;
         bool m_dragging;
@@ -262,6 +279,7 @@ private:
     bool m_warning_texture_enabled;
     bool m_warning_texture_enabled;
     bool m_legend_texture_enabled;
     bool m_legend_texture_enabled;
     bool m_picking_enabled;
     bool m_picking_enabled;
+    bool m_shader_enabled;
     bool m_multisample_allowed;
     bool m_multisample_allowed;
 
 
     PerlCallback m_on_viewport_changed_callback;
     PerlCallback m_on_viewport_changed_callback;
@@ -271,7 +289,7 @@ public:
     GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context);
     GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context);
     ~GLCanvas3D();
     ~GLCanvas3D();
 
 
-    bool init(bool useVBOs);
+    bool init(bool useVBOs, bool use_legacy_opengl);
 
 
     bool set_current();
     bool set_current();
 
 
@@ -332,9 +350,9 @@ public:
 
 
     bool is_layers_editing_enabled() const;
     bool is_layers_editing_enabled() const;
     bool is_picking_enabled() const;
     bool is_picking_enabled() const;
-    bool is_shader_enabled() const;
     bool is_multisample_allowed() const;
     bool is_multisample_allowed() const;
 
 
+    void enable_layers_editing(bool enable);
     void enable_warning_texture(bool enable);
     void enable_warning_texture(bool enable);
     void enable_legend_texture(bool enable);
     void enable_legend_texture(bool enable);
     void enable_picking(bool enable);
     void enable_picking(bool enable);
@@ -350,6 +368,9 @@ public:
     int get_hover_volume_id() const;
     int get_hover_volume_id() const;
     void set_hover_volume_id(int id);
     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_bed();
     void zoom_to_volumes();
     void zoom_to_volumes();
     void select_view(const std::string& direction);
     void select_view(const std::string& direction);

+ 20 - 18
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;
         return vn_minor >= minor;
 }
 }
 
 
-GLCanvas3DManager::LayerEditing::LayerEditing()
-    : allowed(false)
-{
-}
-
 GLCanvas3DManager::GLCanvas3DManager()
 GLCanvas3DManager::GLCanvas3DManager()
     : m_gl_initialized(false)
     : m_gl_initialized(false)
     , m_use_legacy_opengl(false)
     , m_use_legacy_opengl(false)
@@ -129,12 +124,11 @@ void GLCanvas3DManager::init_gl()
         const AppConfig* config = GUI::get_app_config();
         const AppConfig* config = GUI::get_app_config();
         m_use_legacy_opengl = (config == nullptr) || (config->get("use_legacy_opengl") == "1");
         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_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;
         m_gl_initialized = true;
 
 
         std::cout << "DETECTED OPENGL: " << m_gl_version.vn_major << "." << m_gl_version.vn_minor << std::endl;
         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 << "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;
     return m_use_VBOs;
 }
 }
 
 
-bool GLCanvas3DManager::layer_editing_allowed() const
-{
-    return m_layer_editing.allowed;
-}
-
 bool GLCanvas3DManager::init(wxGLCanvas* canvas, bool useVBOs)
 bool GLCanvas3DManager::init(wxGLCanvas* canvas, bool useVBOs)
 {
 {
     CanvasesMap::const_iterator it = _get_canvas(canvas);
     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
 bool GLCanvas3DManager::is_dirty(wxGLCanvas* canvas) const
@@ -391,16 +380,17 @@ bool GLCanvas3DManager::is_picking_enabled(wxGLCanvas* canvas) const
     return (it != m_canvases.end()) ? it->second->is_picking_enabled() : false;
     return (it != m_canvases.end()) ? it->second->is_picking_enabled() : false;
 }
 }
 
 
-bool GLCanvas3DManager::is_shader_enabled(wxGLCanvas* canvas) const
+bool GLCanvas3DManager::is_multisample_allowed(wxGLCanvas* canvas) const
 {
 {
     CanvasesMap::const_iterator it = _get_canvas(canvas);
     CanvasesMap::const_iterator it = _get_canvas(canvas);
-    return (it != m_canvases.end()) ? it->second->is_shader_enabled() : false;
+    return (it != m_canvases.end()) ? it->second->is_multisample_allowed() : false;
 }
 }
 
 
-bool GLCanvas3DManager::is_multisample_allowed(wxGLCanvas* canvas) const
+void GLCanvas3DManager::enable_layers_editing(wxGLCanvas* canvas, bool enable)
 {
 {
-    CanvasesMap::const_iterator it = _get_canvas(canvas);
-    return (it != m_canvases.end()) ? it->second->is_multisample_allowed() : false;
+    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)
 void GLCanvas3DManager::enable_warning_texture(wxGLCanvas* canvas, bool enable)
@@ -477,6 +467,18 @@ void GLCanvas3DManager::set_hover_volume_id(wxGLCanvas* canvas, int id)
         it->second->set_hover_volume_id(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)
 void GLCanvas3DManager::zoom_to_bed(wxGLCanvas* canvas)
 {
 {
     CanvasesMap::iterator it = _get_canvas(canvas);
     CanvasesMap::iterator it = _get_canvas(canvas);

+ 4 - 9
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;
         bool is_greater_or_equal_to(unsigned int major, unsigned int minor) const;
     };
     };
 
 
-    struct LayerEditing
-    {
-        bool allowed;
-
-        LayerEditing();
-    };
-
     typedef std::map<wxGLCanvas*, GLCanvas3D*> CanvasesMap;
     typedef std::map<wxGLCanvas*, GLCanvas3D*> CanvasesMap;
 
 
     CanvasesMap m_canvases;
     CanvasesMap m_canvases;
     GLVersion m_gl_version;
     GLVersion m_gl_version;
-    LayerEditing m_layer_editing;
     bool m_gl_initialized;
     bool m_gl_initialized;
     bool m_use_legacy_opengl;
     bool m_use_legacy_opengl;
     bool m_use_VBOs;
     bool m_use_VBOs;
@@ -106,9 +98,9 @@ public:
 
 
     bool is_layers_editing_enabled(wxGLCanvas* canvas) const;
     bool is_layers_editing_enabled(wxGLCanvas* canvas) const;
     bool is_picking_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;
     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_warning_texture(wxGLCanvas* canvas, bool enable);
     void enable_legend_texture(wxGLCanvas* canvas, bool enable);
     void enable_legend_texture(wxGLCanvas* canvas, bool enable);
     void enable_picking(wxGLCanvas* canvas, bool enable);
     void enable_picking(wxGLCanvas* canvas, bool enable);
@@ -124,6 +116,9 @@ public:
     int get_hover_volume_id(wxGLCanvas* canvas) const;
     int get_hover_volume_id(wxGLCanvas* canvas) const;
     void set_hover_volume_id(wxGLCanvas* canvas, int id);
     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_bed(wxGLCanvas* canvas);
     void zoom_to_volumes(wxGLCanvas* canvas);
     void zoom_to_volumes(wxGLCanvas* canvas);
     void select_view(wxGLCanvas* canvas, const std::string& direction);
     void select_view(wxGLCanvas* canvas, const std::string& direction);

+ 28 - 6
xs/xsp/GUI_3DScene.xsp

@@ -451,20 +451,20 @@ set_camera_target(canvas, target)
         Pointf3 *target;
         Pointf3 *target;
     CODE:
     CODE:
         _3DScene::set_camera_target((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), target);
         _3DScene::set_camera_target((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), target);
-    
+
 bool
 bool
-is_picking_enabled(canvas)
+is_layers_editing_enabled(canvas)
         SV *canvas;
         SV *canvas;
     CODE:
     CODE:
-        RETVAL = _3DScene::is_picking_enabled((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+        RETVAL = _3DScene::is_layers_editing_enabled((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
     OUTPUT:
     OUTPUT:
         RETVAL
         RETVAL
 
 
 bool
 bool
-is_shader_enabled(canvas)
+is_picking_enabled(canvas)
         SV *canvas;
         SV *canvas;
     CODE:
     CODE:
-        RETVAL = _3DScene::is_shader_enabled((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+        RETVAL = _3DScene::is_picking_enabled((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
     OUTPUT:
     OUTPUT:
         RETVAL
         RETVAL
 
 
@@ -476,6 +476,13 @@ is_multisample_allowed(canvas)
     OUTPUT:
     OUTPUT:
         RETVAL
         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
 void
 enable_warning_texture(canvas, enable)
 enable_warning_texture(canvas, enable)
         SV   *canvas;
         SV   *canvas;
@@ -556,6 +563,22 @@ set_hover_volume_id(canvas, id)
     CODE:
     CODE:
         _3DScene::set_hover_volume_id((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), id);
         _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<GLShader>
+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
 void
 zoom_to_bed(canvas)
 zoom_to_bed(canvas)
         SV *canvas;
         SV *canvas;
@@ -679,7 +702,6 @@ register_on_mark_volumes_for_layer_height_callback(canvas, callback)
     
     
     
     
     
     
-    
 unsigned int
 unsigned int
 finalize_legend_texture()
 finalize_legend_texture()
     CODE:
     CODE: