From b4beb7aae974491dbc29f345a1f9094d0cd0f005 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 23 May 2018 09:57:44 +0200 Subject: [PATCH] 3DScene plain shader moved to c++ --- lib/Slic3r/GUI/3DScene.pm | 48 +++++++------ lib/Slic3r/GUI/Plater.pm | 5 +- lib/Slic3r/GUI/Plater/3DPreview.pm | 5 +- xs/src/slic3r/GUI/3DScene.cpp | 30 ++++++++- xs/src/slic3r/GUI/3DScene.hpp | 9 ++- xs/src/slic3r/GUI/GLCanvas3D.cpp | 89 +++++++++++++++++++++++++ xs/src/slic3r/GUI/GLCanvas3D.hpp | 27 ++++++++ xs/src/slic3r/GUI/GLCanvas3DManager.cpp | 32 +++++++++ xs/src/slic3r/GUI/GLCanvas3DManager.hpp | 7 ++ xs/xsp/GUI_3DScene.xsp | 88 +++++++++++++++++------- 10 files changed, 289 insertions(+), 51 deletions(-) diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index 5f35fb8e3..3975c12ea 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -36,7 +36,6 @@ use Slic3r::Geometry qw(PI); #============================================================================================================================== __PACKAGE__->mk_accessors( qw(_quat init enable_moving - use_plain_shader on_viewport_changed on_hover on_select @@ -191,9 +190,7 @@ sub new { # $self->_zoom(1); # $self->_legend_enabled(0); # $self->_warning_enabled(0); -#============================================================================================================================== - $self->use_plain_shader(0); -#============================================================================================================================== +# $self->use_plain_shader(0); # $self->_apply_zoom_to_volumes_filter(0); #============================================================================================================================== $self->_mouse_dragging(0); @@ -1382,28 +1379,30 @@ sub InitGL { glEnable(GL_COLOR_MATERIAL); glEnable(GL_MULTISAMPLE) if ($self->{can_multisample}); - if ($self->UseVBOs) { - my $shader = new Slic3r::GUI::_3DScene::GLShader; #=================================================================================================================================== - if (! $shader->load_from_file("gouraud.fs", "gouraud.vs")) { + Slic3r::GUI::_3DScene::init($self, $self->UseVBOs); +# if ($self->UseVBOs) { +# my $shader = new Slic3r::GUI::_3DScene::GLShader; ## if (! $shader->load($self->_fragment_shader_Phong, $self->_vertex_shader_Phong)) { +# print "Compilaton of path shader failed: \n" . $shader->last_error . "\n"; +# $shader = undef; +# } else { +# $self->{plain_shader} = $shader; +# } +# } #=================================================================================================================================== - print "Compilaton of path shader failed: \n" . $shader->last_error . "\n"; - $shader = undef; - } else { - $self->{plain_shader} = $shader; - } - } } sub DestroyGL { my $self = shift; if ($self->GetContext) { $self->SetCurrent($self->GetContext); - if ($self->{plain_shader}) { - $self->{plain_shader}->release; - delete $self->{plain_shader}; - } +#=================================================================================================================================== +# if ($self->{plain_shader}) { +# $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}; @@ -1608,7 +1607,10 @@ sub Render { glEnable(GL_LIGHTING); # draw objects - if (! $self->use_plain_shader) { +#=================================================================================================================================== + if (!Slic3r::GUI::_3DScene::is_shader_enabled($self)) { +# if (! $self->use_plain_shader) { +#=================================================================================================================================== #============================================================================================================================== Slic3r::GUI::_3DScene::render_volumes($self, 0); # $self->draw_volumes; @@ -1624,9 +1626,15 @@ sub Render { # do not cull backfaces to show broken geometry, if any glDisable(GL_CULL_FACE); } - $self->{plain_shader}->enable if $self->{plain_shader}; +#============================================================================================================================== + Slic3r::GUI::_3DScene::start_using_shader($self); +# $self->{plain_shader}->enable if $self->{plain_shader}; +#============================================================================================================================== $self->volumes->render_VBOs; - $self->{plain_shader}->disable; +#============================================================================================================================== + Slic3r::GUI::_3DScene::stop_using_shader($self); +# $self->{plain_shader}->disable; +#============================================================================================================================== #============================================================================================================================== glEnable(GL_CULL_FACE) if (Slic3r::GUI::_3DScene::is_picking_enabled($self)); # glEnable(GL_CULL_FACE) if ($self->enable_picking); diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 481ffd013..41bcead29 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -122,7 +122,10 @@ sub new { $self->{canvas3D}->set_on_remove_object(sub { $self->remove() }); $self->{canvas3D}->set_on_instances_moved($on_instances_moved); $self->{canvas3D}->set_on_enable_action_buttons($enable_action_buttons); - $self->{canvas3D}->use_plain_shader(1); +#=================================================================================================================================== + Slic3r::GUI::_3DScene::enable_shader($self->{canvas3D}, 1); +# $self->{canvas3D}->use_plain_shader(1); +#=================================================================================================================================== $self->{canvas3D}->set_on_wipe_tower_moved(sub { my ($new_pos_3f) = @_; my $cfg = Slic3r::Config->new; diff --git a/lib/Slic3r/GUI/Plater/3DPreview.pm b/lib/Slic3r/GUI/Plater/3DPreview.pm index eb4077579..390e1b85e 100644 --- a/lib/Slic3r/GUI/Plater/3DPreview.pm +++ b/lib/Slic3r/GUI/Plater/3DPreview.pm @@ -24,7 +24,10 @@ sub new { # init GUI elements my $canvas = Slic3r::GUI::3DScene->new($self); - $canvas->use_plain_shader(1); +#=================================================================================================================================== + Slic3r::GUI::_3DScene::enable_shader($canvas, 1); +# $canvas->use_plain_shader(1); +#=================================================================================================================================== $self->canvas($canvas); my $slider_low = Wx::Slider->new( $self, -1, diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 76353c15d..38cfde713 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -1752,10 +1752,9 @@ void _3DScene::remove_all_canvases() std::cout << "# canvases not yet released: " << s_canvas_mgr.count() << std::endl; s_canvas_mgr.remove_all(); } - -void _3DScene::resize(wxGLCanvas* canvas, unsigned int w, unsigned int h) +bool _3DScene::init(wxGLCanvas* canvas, bool useVBOs) { - s_canvas_mgr.resize(canvas, w, h); + return s_canvas_mgr.init(canvas, useVBOs); } bool _3DScene::is_dirty(wxGLCanvas* canvas) @@ -1773,6 +1772,11 @@ bool _3DScene::is_shown_on_screen(wxGLCanvas* canvas) return s_canvas_mgr.is_shown_on_screen(canvas); } +void _3DScene::resize(wxGLCanvas* canvas, unsigned int w, unsigned int h) +{ + s_canvas_mgr.resize(canvas, w, h); +} + GLVolumeCollection* _3DScene::get_volumes(wxGLCanvas* canvas) { return s_canvas_mgr.get_volumes(canvas); @@ -1914,6 +1918,11 @@ 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); +} + void _3DScene::enable_warning_texture(wxGLCanvas* canvas, bool enable) { s_canvas_mgr.enable_warning_texture(canvas, enable); @@ -1929,6 +1938,11 @@ void _3DScene::enable_picking(wxGLCanvas* canvas, bool enable) s_canvas_mgr.enable_picking(canvas, enable); } +void _3DScene::enable_shader(wxGLCanvas* canvas, bool enable) +{ + s_canvas_mgr.enable_shader(canvas, enable); +} + void _3DScene::zoom_to_bed(wxGLCanvas* canvas) { s_canvas_mgr.zoom_to_bed(canvas); @@ -1944,6 +1958,16 @@ void _3DScene::select_view(wxGLCanvas* canvas, const std::string& direction) s_canvas_mgr.select_view(canvas, direction); } +bool _3DScene::start_using_shader(wxGLCanvas* canvas) +{ + return s_canvas_mgr.start_using_shader(canvas); +} + +void _3DScene::stop_using_shader(wxGLCanvas* canvas) +{ + s_canvas_mgr.stop_using_shader(canvas); +} + void _3DScene::render_background(wxGLCanvas* canvas) { s_canvas_mgr.render_background(canvas); diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 9c56fbb59..747bd3d42 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -544,13 +544,15 @@ public: static bool remove_canvas(wxGLCanvas* canvas); static void remove_all_canvases(); - static void resize(wxGLCanvas* canvas, unsigned int w, unsigned int h); + static bool init(wxGLCanvas* canvas, bool useVBOs); static bool is_dirty(wxGLCanvas* canvas); static void set_dirty(wxGLCanvas* canvas, bool dirty); static bool is_shown_on_screen(wxGLCanvas* canvas); + static void resize(wxGLCanvas* canvas, unsigned int w, unsigned int h); + static GLVolumeCollection* get_volumes(wxGLCanvas* canvas); static void set_volumes(wxGLCanvas* canvas, GLVolumeCollection* volumes); @@ -592,14 +594,19 @@ public: static bool is_layers_editing_enabled(wxGLCanvas* canvas); static bool is_picking_enabled(wxGLCanvas* canvas); + static bool is_shader_enabled(wxGLCanvas* canvas); 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); + static void enable_shader(wxGLCanvas* canvas, bool enable); static void zoom_to_bed(wxGLCanvas* canvas); static void zoom_to_volumes(wxGLCanvas* canvas); static void select_view(wxGLCanvas* canvas, const std::string& direction); + + static bool start_using_shader(wxGLCanvas* canvas); + static void stop_using_shader(wxGLCanvas* canvas); static void render_background(wxGLCanvas* canvas); static void render_bed(wxGLCanvas* canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index 4dadf8181..e243db011 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -1,6 +1,7 @@ #include "GLCanvas3D.hpp" #include "../../slic3r/GUI/3DScene.hpp" +#include "../../slic3r/GUI/GLShader.hpp" #include "../../libslic3r/ClipperUtils.hpp" #include @@ -413,6 +414,65 @@ bool GLCanvas3D::LayersEditing::is_enabled() const return m_enabled; } +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::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context) : m_canvas(canvas) , m_context(context) @@ -428,6 +488,15 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context) GLCanvas3D::~GLCanvas3D() { _deregister_callbacks(); + m_shader.reset(); +} + +bool GLCanvas3D::init(bool useVBOs) +{ + if (useVBOs && !m_shader.init("gouraud.vs", "gouraud.fs")) + return false; + + return true; } bool GLCanvas3D::set_current() @@ -698,6 +767,11 @@ bool GLCanvas3D::is_picking_enabled() const return m_picking_enabled; } +bool GLCanvas3D::is_shader_enabled() const +{ + return m_shader.is_enabled(); +} + void GLCanvas3D::enable_warning_texture(bool enable) { m_warning_texture_enabled = enable; @@ -713,6 +787,11 @@ void GLCanvas3D::enable_picking(bool enable) m_picking_enabled = enable; } +void GLCanvas3D::enable_shader(bool enable) +{ + m_shader.set_enabled(enable); +} + void GLCanvas3D::zoom_to_bed() { _zoom_to_bounding_box(bed_bounding_box()); @@ -756,6 +835,16 @@ void GLCanvas3D::select_view(const std::string& direction) } } +bool GLCanvas3D::start_using_shader() const +{ + return m_shader.start(); +} + +void GLCanvas3D::stop_using_shader() const +{ + m_shader.stop(); +} + void GLCanvas3D::render_background() const { static const float COLOR[3] = { 10.0f / 255.0f, 98.0f / 255.0f, 144.0f / 255.0f }; diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index dcf14e725..6a2af8324 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -14,6 +14,7 @@ class wxKeyEvent; namespace Slic3r { class GLVolumeCollection; +class GLShader; class ExPolygon; namespace GUI { @@ -141,6 +142,24 @@ public: bool is_enabled() 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; + }; + private: wxGLCanvas* m_canvas; wxGLContext* m_context; @@ -149,6 +168,7 @@ private: Axes m_axes; CuttingPlane m_cutting_plane; LayersEditing m_layers_editing; + Shader m_shader; GLVolumeCollection* m_volumes; @@ -164,6 +184,8 @@ public: GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context); ~GLCanvas3D(); + bool init(bool useVBOs); + bool set_current(); bool is_dirty() const; @@ -219,15 +241,20 @@ public: bool is_layers_editing_enabled() const; bool is_picking_enabled() const; + bool is_shader_enabled() const; void enable_warning_texture(bool enable); void enable_legend_texture(bool enable); void enable_picking(bool enable); + void enable_shader(bool enable); void zoom_to_bed(); void zoom_to_volumes(); void select_view(const std::string& direction); + bool start_using_shader() const; + void stop_using_shader() const; + void render_background() const; void render_bed() const; void render_axes() const; diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index 4349ae845..f612b5530 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -148,6 +148,12 @@ 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; +} + bool GLCanvas3DManager::is_dirty(wxGLCanvas* canvas) const { CanvasesMap::const_iterator it = _get_canvas(canvas); @@ -361,6 +367,12 @@ 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; +} + void GLCanvas3DManager::enable_warning_texture(wxGLCanvas* canvas, bool enable) { CanvasesMap::iterator it = _get_canvas(canvas); @@ -382,6 +394,13 @@ void GLCanvas3DManager::enable_picking(wxGLCanvas* canvas, bool enable) it->second->enable_picking(enable); } +void GLCanvas3DManager::enable_shader(wxGLCanvas* canvas, bool enable) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->enable_shader(enable); +} + void GLCanvas3DManager::zoom_to_bed(wxGLCanvas* canvas) { CanvasesMap::iterator it = _get_canvas(canvas); @@ -403,6 +422,19 @@ void GLCanvas3DManager::select_view(wxGLCanvas* canvas, const std::string& direc it->second->select_view(direction); } +bool GLCanvas3DManager::start_using_shader(wxGLCanvas* canvas) const +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); + return (it != m_canvases.end()) ? it->second->start_using_shader() : false; +} + +void GLCanvas3DManager::stop_using_shader(wxGLCanvas* canvas) const +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->stop_using_shader(); +} + void GLCanvas3DManager::render_background(wxGLCanvas* canvas) const { CanvasesMap::const_iterator it = _get_canvas(canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index 46eb872db..7c8b82075 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -52,6 +52,8 @@ public: bool use_VBOs() const; bool layer_editing_allowed() const; + bool init(wxGLCanvas* canvas, bool useVBOs); + bool is_dirty(wxGLCanvas* canvas) const; void set_dirty(wxGLCanvas* canvas, bool dirty); @@ -100,15 +102,20 @@ public: bool is_layers_editing_enabled(wxGLCanvas* canvas) const; bool is_picking_enabled(wxGLCanvas* canvas) const; + bool is_shader_enabled(wxGLCanvas* canvas) const; void enable_warning_texture(wxGLCanvas* canvas, bool enable); void enable_legend_texture(wxGLCanvas* canvas, bool enable); void enable_picking(wxGLCanvas* canvas, bool enable); + void enable_shader(wxGLCanvas* canvas, bool enable); void zoom_to_bed(wxGLCanvas* canvas); void zoom_to_volumes(wxGLCanvas* canvas); void select_view(wxGLCanvas* canvas, const std::string& direction); + bool start_using_shader(wxGLCanvas* canvas) const; + void stop_using_shader(wxGLCanvas* canvas) const; + void render_background(wxGLCanvas* canvas) const; void render_bed(wxGLCanvas* canvas) const; void render_axes(wxGLCanvas* canvas) const; diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index 51317ec5d..5f80741aa 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -190,6 +190,38 @@ remove_all_canvases() CODE: _3DScene::remove_all_canvases(); +bool +init(canvas, useVBOs) + SV *canvas; + bool useVBOs; + CODE: + RETVAL = _3DScene::init((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), useVBOs); + OUTPUT: + RETVAL + +bool +is_dirty(canvas) + SV *canvas; + CODE: + RETVAL = _3DScene::is_dirty((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + OUTPUT: + RETVAL + +void +set_dirty(canvas, dirty) + SV *canvas; + bool dirty; + CODE: + _3DScene::set_dirty((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), dirty); + +bool +is_shown_on_screen(canvas) + SV *canvas; + CODE: + RETVAL = _3DScene::is_shown_on_screen((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + OUTPUT: + RETVAL + void resize(canvas, w, h) SV *canvas; @@ -256,29 +288,6 @@ get_max_bounding_box(canvas) OUTPUT: RETVAL -bool -is_dirty(canvas) - SV *canvas; - CODE: - RETVAL = _3DScene::is_dirty((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); - OUTPUT: - RETVAL - -void -set_dirty(canvas, dirty) - SV *canvas; - bool dirty; - CODE: - _3DScene::set_dirty((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), dirty); - -bool -is_shown_on_screen(canvas) - SV *canvas; - CODE: - RETVAL = _3DScene::is_shown_on_screen((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); - OUTPUT: - RETVAL - Clone get_axes_origin(canvas) SV *canvas; @@ -422,7 +431,15 @@ is_picking_enabled(canvas) RETVAL = _3DScene::is_picking_enabled((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); 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 + void enable_warning_texture(canvas, enable) SV *canvas; @@ -443,7 +460,14 @@ enable_picking(canvas, enable) bool enable; CODE: _3DScene::enable_picking((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable); - + +void +enable_shader(canvas, enable) + SV *canvas; + bool enable; + CODE: + _3DScene::enable_shader((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable); + void zoom_to_bed(canvas) SV *canvas; @@ -463,6 +487,20 @@ select_view(canvas, direction) CODE: _3DScene::select_view((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), direction); +bool +start_using_shader(canvas) + SV *canvas; + CODE: + RETVAL = _3DScene::start_using_shader((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + OUTPUT: + RETVAL + +void +stop_using_shader(canvas) + SV *canvas; + CODE: + _3DScene::stop_using_shader((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + void render_background(canvas) SV *canvas;