Blob Blame History Raw
diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm
index 7628a6c..d37199b 100644
--- a/lib/Slic3r/GUI/3DScene.pm
+++ b/lib/Slic3r/GUI/3DScene.pm
@@ -1,9 +1,9 @@
 package Slic3r::GUI::3DScene::Base;
 use strict;
 use warnings;
-
 use Wx::Event qw(EVT_PAINT EVT_SIZE EVT_ERASE_BACKGROUND EVT_IDLE EVT_MOUSEWHEEL EVT_MOUSE_EVENTS);
 # must load OpenGL *before* Wx::GLCanvas
+
 use OpenGL qw(:glconstants :glfunctions :glufunctions :gluconstants);
 use base qw(Wx::GLCanvas Class::Accessor);
 use Math::Trig qw(asin);
@@ -48,6 +48,12 @@ use constant DEFAULT_COLOR  => [1,1,0];
 use constant SELECTED_COLOR => [0,1,0,1];
 use constant HOVER_COLOR    => [0.4,0.9,0,1];
 
+# Constant to determine if Vertex Buffer objects are used to draw
+# bed grid and the cut plane for object separation.
+# Old Perl (5.10.x) should set to 0.
+use constant HAS_VBO        => 1;
+
+
 # make OpenGL::Array thread-safe
 {
     no warnings 'redefine';
@@ -114,6 +120,7 @@ sub new {
         $self->Refresh;
     });
     EVT_MOUSE_EVENTS($self, \&mouse_event);
+
     
     return $self;
 }
@@ -741,9 +748,19 @@ sub Render {
         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
         
         glEnableClientState(GL_VERTEX_ARRAY);
+        if (HAS_VBO) {
+            my ($triangle_vertex);
+            ($triangle_vertex) =
+                glGenBuffersARB_p(1);
+            $self->bed_triangles->bind($triangle_vertex);
+            glBufferDataARB_p(GL_ARRAY_BUFFER_ARB, $self->bed_triangles, GL_STATIC_DRAW_ARB);
+            glVertexPointer_c(3, GL_FLOAT, 0, 0);
+        } else {
+            # fall back on old behavior
+            glVertexPointer_p(3, $self->bed_triangles);
+        }
         glColor4f(0.8, 0.6, 0.5, 0.4);
         glNormal3d(0,0,1);
-        glVertexPointer_p(3, $self->bed_triangles);
         glDrawArrays(GL_TRIANGLES, 0, $self->bed_triangles->elements / 3);
         glDisableClientState(GL_VERTEX_ARRAY);
         
@@ -753,13 +770,29 @@ sub Render {
     
         # draw grid
         glLineWidth(3);
-        glColor4f(0.2, 0.2, 0.2, 0.4);
         glEnableClientState(GL_VERTEX_ARRAY);
-        glVertexPointer_p(3, $self->bed_grid_lines);
+        if (HAS_VBO) {
+            my ($grid_vertex);
+            ($grid_vertex) =
+                glGenBuffersARB_p(1);
+            $self->bed_grid_lines->bind($grid_vertex);
+            glBufferDataARB_p(GL_ARRAY_BUFFER_ARB, $self->bed_grid_lines, GL_STATIC_DRAW_ARB);
+            glVertexPointer_c(3, GL_FLOAT, 0, 0);
+        } else {
+            # fall back on old behavior
+            glVertexPointer_p(3, $self->bed_grid_lines);
+        }
+        glColor4f(0.2, 0.2, 0.2, 0.4);
+        glNormal3d(0,0,1);
         glDrawArrays(GL_LINES, 0, $self->bed_grid_lines->elements / 3);
         glDisableClientState(GL_VERTEX_ARRAY);
         
         glDisable(GL_BLEND);
+        if (HAS_VBO) { 
+            # Turn off buffer objects to let the rest of the draw code work.
+            glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+            glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+        }
     }
     
     my $volumes_bb = $self->volumes_bounding_box;
@@ -899,10 +932,26 @@ sub draw_volumes {
     glDisable(GL_BLEND);
     
     if (defined $self->cutting_plane_z) {
+        if (HAS_VBO) {
+            # Use Vertex Buffer Object for cutting plane (previous method crashes on modern POGL). 
+            my ($cut_vertex) = glGenBuffersARB_p(1);
+            $self->cut_lines_vertices->bind($cut_vertex);
+            glBufferDataARB_p(GL_ARRAY_BUFFER_ARB, $self->cut_lines_vertices, GL_STATIC_DRAW_ARB);
+            glVertexPointer_c(3, GL_FLOAT, 0, 0);
+        } else {
+            # Use legacy method.
+            glVertexPointer_p(3, $self->cut_lines_vertices);
+        }
         glLineWidth(2);
         glColor3f(0, 0, 0);
-        glVertexPointer_p(3, $self->cut_lines_vertices);
         glDrawArrays(GL_LINES, 0, $self->cut_lines_vertices->elements / 3);
+
+        if (HAS_VBO) { 
+            # Turn off buffer objects to let the rest of the draw code work.
+            glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+            glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+        }
+
     }
     glDisableClientState(GL_VERTEX_ARRAY);
 }