Hi
here is my way to plot 2D graphics using perl opengl for windows, it uses win32gui, and the OpenGLFrame-0.02 from cpan, the only short of the OpenGLFrame-0.02 is that after exiting the program it gives a warning :"Can't call method "FETCH" on an undefined value at
c:/perl/site/lib/Win32/GUI/OpenGLFrame.pm line 108 during global destruction", the author said ==It can
nearly always be mitigated by undef'ing the variable holding the main window object before program exit. It's a Win32::GUI problem, not a Win32::GUI::OpenGLFrame problem ==,
else everything is okay
the first one mathArt-1 is a fractal program from the book "Python programming in OpenGL" by Stan Blank page 102, a freeware and educational book can be downloaded from here :(by the approval of the author for that forum)
[
http://community.thinbasic.com/index.php?topic=3239.0]
i have translated it to perl; it is almost the same with small adaptations.
it's picture like
this
i will list the programs below, also available from :
here
the program show the evolution of draw in time, and while doing so it stores the graphics continuasly to a special list (glist), and after the plotting finished i assign a $flag = 1; so in any case to updating the screen the main plotting routine will not executed; rather it will call the glist which will displayed instantly. you can minimize, maximize, cover the screen without executing the heavy math to redraw the scene again as in the original python example..
one important feature is using the gluOrtho2D(left, right, bottom, top) function ; this function allows you to define your virtual window; in wich it will projected to real opengl frame dimensions; this is very usefull.
the -doubleBuffer => 0, so a small unnoticeable flicker may be observed in the keen artist eyes only.
in the second examples mathArt-2 it is the same as the above but with choosing -doubleBuffer => 1, you need to wait several seconds for the display to appear ; not like the first example which shows the evolution of drawing.
its picture like
this
can be downloaded from :
here
the third example is a translation to perl the biomorph fractal written in quick basic here:
[
http://www.madteddy.com/biomorph.htm]
the program have the CLS button; look how to erase the gl window.
its picture like
this
can be downloaded from :
here
below i have listed the mathArt-1.pl and mathArt-2.pl
of course you can improve the code, correct it, plug another functions to plot... . this is a beginner for ever way of coding (i am too old to change my neurons), i will post in another messages a 3D examples.
regards
#mathArt-1
use strict;
use warnings;
use Win32::GUI qw(WS_CLIPCHILDREN);
use Win32::GUI::OpenGLFrame qw(w32gSwapBuffers);
use OpenGL qw(:all);
my $flag = 0;
my $axrng = 10.0;
my $x; my $y; my $r; my $w; my $h;
our $glist=[]; #to store all vertexes in a list to easy on the cpu
my $mw = Win32::GUI::Window->new(
-title => "OpenGL Demonstration MathArt",
-pos => [0,0],
-size => [640,480],
-pushstyle => WS_CLIPCHILDREN, # stop flickering on resize
-onResize => \&mainWinResize,
);
my $glw = $mw->AddOpenGLFrame(
-name => 'oglwin',
-width => $mw->ScaleWidth()-240,
-height => $mw->ScaleHeight() - 80,
-pos => [100,0],
-display => \&display,
-init => \&Init,
-reshape => \&reshape,
-doubleBuffer => 0,
-visible => 1,
);
$mw->AddButton(
-name => 'button1',
-text => 'Draw',
-left => $mw->ScaleWidth()-100,
-top => $mw->ScaleHeight()-30,
);
$mw->AddButton(
-name => 'button3',
-text => 'Exit',
-left => $mw->ScaleWidth()-220,
-top => $mw->ScaleHeight()-30,
-onClick => sub{undef($mw);exit(0)},
);
$mw->Show();
while(Win32::GUI::DoEvents() != -1) {
$mw->oglwin->InvalidateRect(0);
}
sub mainWinResize {
my $win = shift;
$win->oglwin->Resize($win->ScaleWidth()-240, $win->ScaleHeight()-80);
$win->button1->Move($win->ScaleWidth()-100, $win->ScaleHeight()-30);
$win->button3->Move($win->ScaleWidth()-220, $win->ScaleHeight()-30);
$flag = 1;
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
plotmathart();
return 0;
}
sub reshape {
#my ($w, $h) = @_;
my $width=$mw->ScaleWidth()-240;
my $height=$mw->ScaleHeight()-80;
glViewport(0, 0, $width, $height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity (); # define the projection
#gluOrtho2D(left, right, bottom, top)
gluOrtho2D(-$axrng, $axrng, -$axrng*$height/$width, $axrng*$height/
+$width);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return 0;
}
sub Init {
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
w32gSwapBuffers();
}
sub display {
if ($flag == 1) #ie you have clicked the Draw button
# and the scene stored in the glist, so it just calling that glist
{
plotmathart();
glFlush();
w32gSwapBuffers();return 1;
}
return 1;
}
sub plotmathart {
glPushMatrix();
glCallList($glist);
glPopMatrix();
}
sub plot {
glPushMatrix(); #save current matrix
glClearColor(1.0, 1.0, 1.0, 1.0);
# make the glist
$glist = glGenLists(1);
glNewList($glist, GL_COMPILE_AND_EXECUTE);
glLoadIdentity();
for($x=-$axrng; $x <= $axrng; $x += 0.03) {
for($y=-$axrng; $y <= $axrng; $y += 0.03) {
$r = cos($x) + sin($y);
glColor3f(cos($y*$r), cos($x*$y*$r), sin($r*$x));
glBegin(GL_POINTS);
glVertex2f($x, $y);
glEnd;
}
}
glEndList();
glPopMatrix(); #restore matrix
#glFlush();
#w32gSwapBuffers();
return 1;
}
sub button1_Click {
$flag = 1;plot();
}
#mathArt-2
use strict;
use warnings;
use Win32::GUI qw(WS_CLIPCHILDREN);
use Win32::GUI::OpenGLFrame qw(w32gSwapBuffers);
use OpenGL qw(:all);
my $flag = 0;
my $width = 500 ; my $height = 500; my $axrng = 10.0;
my $x; my $y; my $r; my $w; my $h;
my $glist; #to store all vertexes in a list to easy on the cpu
my $mw = Win32::GUI::Window->new(
-title => "OpenGL Demonstration MathArt",
-pos => [0,0],
-size => [640,480],
-pushstyle => WS_CLIPCHILDREN, # stop flickering on resize
-onResize => \&mainWinResize,
);
my $glw = $mw->AddOpenGLFrame(
-name => 'oglwin',
-width => $mw->ScaleWidth(),
-height => $mw->ScaleHeight() - 50,
-display => \&display,
-init => \&Init,
-reshape => \&reshape,
-doubleBuffer => 1,
);
$mw->AddButton(
-name => 'button1',
-text => 'Draw',
-left => $mw->ScaleWidth()-100,
-top => $mw->ScaleHeight()-30,
);
$mw->AddButton(
-name => 'button3',
-text => 'Exit',
-left => $mw->ScaleWidth()-220,
-top => $mw->ScaleHeight()-30,
-onClick => sub{undef($mw);exit(0)},
);
$mw->Show();
while(Win32::GUI::DoEvents() != -1) {
$mw->oglwin->InvalidateRect(0);
}
sub mainWinResize {
my $win = shift;
$win->oglwin->Resize($win->ScaleWidth(), $win->ScaleHeight()-50);
$win->button1->Move($win->ScaleWidth()-100, $win->ScaleHeight()-30);
$win->button3->Move($win->ScaleWidth()-220, $win->ScaleHeight()-30);
return 0;
}
sub reshape {
my ($w, $h) = @_;
glViewport(0, 0, $w, $h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity (); # define the projection
gluPerspective(45.0, $h ? $w/$h : 0, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return 0;
}
sub Init {
glClearColor(1.0, 1.0, 1.0, 1.0);
}
sub display {
if ($flag == 1) #ie you have click Draw button
{
plotmathart();
}
glFlush();
w32gSwapBuffers();
return 1;
}
sub plotmathart {
glPushMatrix();
glCallList($glist);
glPopMatrix();
}
sub plot {
glPushMatrix(); #save current matrix
glClearColor(1.0, 1.0, 1.0, 1.0);
# make the glist
$glist = glGenLists(1);
glNewList($glist, GL_COMPILE);
glLoadIdentity();
glTranslatef(0.0, 0.0, -20.0);
for($x=-$axrng; $x <= $axrng; $x += 0.03) {
for($y=-$axrng; $y <= $axrng; $y += 0.03) {
$r = cos($x) + sin($y);
glColor3f(cos($y*$r), cos($x*$y*$r), sin($r*$x));
glBegin(GL_POINTS);
glVertex2f($x, $y);
glEnd;
}
}
glEndList();
glPopMatrix(); #restore matrix
return 1;
}
sub button1_Click {
$flag = 1;plot();
}