Hi, the only reliable OpenGL implmentation for perl ( so far), is that which comes with SDL-Perl. This snippet just shows you can control an OpenGL SDL app from Gtk2 or Tk. It is only a "proof-of-concept", but it opens the possibilities for using OpenGL for Gtk2 or Tk.
#!/usr/bin/perl
use warnings;
use strict;
use Gtk2;
use SDL;
use SDL::App;
use SDL::Surface;
use SDL::Event;
use SDL::OpenGL;
# proof of concept to use SDL OpenGL from Gtk2 or Tk
# SDL opengl code taken from the tutorial included with SDL-Perl
# 1 known problem is there is no command to close an sdl window
# it can be iconified, but ->close or ->destroy dosn't work
my $app; #sdl window
my $appcontrol = 0;
my $sdl_timer;
my $event;
my $angle;
my $other;
my $cube;
my $white;
my $toggle;
package SDL::OpenGL::Cube;
use SDL;
use SDL::OpenGL;
my $vertex_array = pack "d24",
-0.5,-0.5,-0.5, 0.5,-0.5,-0.5, 0.5,0.5,-0.5, -0.5,0.5,-0.5, # back
-0.5,-0.5,0.5, 0.5,-0.5,0.5, 0.5,0.5,0.5, -0.5,0.5,0.5 ; # fro
+nt
my $indicies = pack "C24",
4,5,6,7, # front
1,2,6,5, # right
0,1,5,4, # bottom
0,3,2,1, # back
0,4,7,3, # left
2,3,7,6; # top
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
bless $self,$class;
$self;
}
sub draw {
my ($self) = @_;
$self->color();
glEnableClientState(GL_VERTEX_ARRAY());
glVertexPointer(3,GL_DOUBLE(),0,$vertex_array);
glDrawElements(GL_QUADS(), 24, GL_UNSIGNED_BYTE(), $indicies);
}
sub color {
my ($self,@colors) = @_;
if (@colors) {
$$self{colored} = 1;
die "SDL::OpenGL::Cube::color requires 24 floating point color
+ values\n"
unless (scalar(@colors) == 24);
$$self{-colors} = pack "f24",@colors;
}
if ($$self{colored}) {
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3,GL_FLOAT,0,$$self{-colors});
} else {
glDisableClientState(GL_COLOR_ARRAY);
}
}
1;
## end of package #######################################
package main;
Gtk2->init;
my $gtkwindow = Gtk2::Window->new('toplevel');
$gtkwindow->set_title('Gtk2 Window');
$gtkwindow->signal_connect( delete_event => sub {
Gtk2->main_quit;
return 1;
});
my $count_gtk = 0;
my $gtk_timer_control = 1;
####setup gtk2 window###################
my $vbox = Gtk2::VBox->new( 0, 6 );
$gtkwindow->add($vbox);
my $frame = Gtk2::Frame->new('Count');
$vbox->pack_start( $frame, 1, 1, 0 );
$frame->set_border_width(3);
my $label = Gtk2::Label->new("Count $count_gtk");
$frame->add( $label);
my $button = Gtk2::Button->new('Stop Count');
$vbox->pack_start( $button, 1, 1, 0 );
$button->signal_connect( clicked =>
sub { $gtk_timer_control = 0 } );
my $button1 = Gtk2::Button->new('Launch OpenGL');
$vbox->pack_start( $button1, 1, 1, 0 );
$button1->signal_connect( clicked => \&init_SDL );
my $button2 = Gtk2::Button->new('Stop OpenGL');
$vbox->pack_start( $button2, 1, 1, 0 );
$button2->signal_connect( clicked => sub{ $appcontrol = 0;
return 0;
} );
my $button3 = Gtk2::Button->new('Close OpenGL Window');
$vbox->pack_start( $button3, 1, 1, 0 );
$button3->signal_connect( clicked => sub{ $appcontrol = 0;
SDL::FreeSurface($app);
} );
my $quit_button = Gtk2::Button->new('_Quit');
$vbox->pack_start( $quit_button, 0, 0, 0 );
$quit_button->signal_connect(
clicked => sub {
$gtkwindow->destroy;
exit;
}
);
my $timer1 = Glib::Timeout->add (1000,\&show_loop);
$gtkwindow->show_all;
###################################################
Gtk2->main;
########################################
sub show_loop{
$count_gtk++;
$label->set_text("Count $count_gtk");
return $gtk_timer_control; #return FALSE to end gtk2 timer
}
###################################################
sub init_SDL{
$appcontrol = 1;
$app = new SDL::App -w => 800, -h => 600, -d => 16, -gl =>1;
print "Initializing OpenGL settings\n";
printf "%-24s%s\n", "GL_RED_SIZE ", $app->attribute( SDL_GL_RED_SIZE()
+ );
printf "%-24s%s\n", "GL_GREEN_SIZE ", $app->attribute( SDL_GL_GREEN_SI
+ZE());
printf "%-24s%s\n", "GL_BLUE_SIZE ", $app->attribute( SDL_GL_BLUE_SIZE
+() );
printf "%-24s%s\n", "GL_DEPTH_SIZE ", $app->attribute( SDL_GL_DEPTH_SI
+ZE() );
printf "%-24s%s\n", "GL_DOUBLEBUFFER ", $app->attribute( SDL_GL_DOUBLE
+BUFFER() );
$angle = 0;
$other = 0;
my @colors = (
1.0,1.0,0.0, 1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0, #back
0.4,0.4,0.4, 0.3,0.3,0.3, 0.2,0.2,0.2, 0.1,0.1,0.1 ); #fr
+ont
$cube = new SDL::OpenGL::Cube;
$cube->color(@colors);
$white = new SDL::OpenGL::Cube;
$toggle = 1;
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
InitView();
DrawScene();
$app->sync();
$event = new SDL::Event;
$sdl_timer = Glib::Timeout->add (100,\&pump_sdl);
}
#######################################################
sub pump_sdl{
if ($appcontrol == 0){return 0}
for (0 .. 5) {
if ($appcontrol == 0){return 0}
$event->pump();
$event->poll();
# dosn't work to close sdl window (but should :-) )
#if ($event->type() == SDL_QUIT()){$app ->destroy }
if ($appcontrol == 0){return 0};
if (SDL::GetKeyState(SDLK_SPACE()) == SDL_PRESSED()) {
$toggle = 0;
} else {
$toggle = 1;
}
DrawScene();
}
return 1;
}
#######################################################
sub DrawScene {
glClear( GL_DEPTH_BUFFER_BIT()
| GL_COLOR_BUFFER_BIT());
glLoadIdentity();
glTranslate(0,0,-6.0);
glRotate($angle % 360,1,1,0);
glRotate($other % 360,0,1,1);
$angle += 6;
$other += $angle % 5;
glColor(1,1,1);
$toggle ? $cube->draw() : $white->draw();
$app->sync();
}
sub InitView {
glViewport(0,0,800,600);
glMatrixMode(GL_PROJECTION());
glLoadIdentity();
if ( @_ ) {
gluPerspective(45.0,4/3,0.1,100.0);
} else {
glFrustum(-0.1,0.1,-0.075,0.075,0.3,100.0);
}
glMatrixMode(GL_MODELVIEW());
glLoadIdentity();
}