#!/usr/bin/perl # modules use OpenGL ":old",":glutfunctions",":gluconstants",":functions"; use Time::HiRes qw (gettimeofday tv_interval usleep); use strict; no strict "subs"; use Math::Trig; # global variables our ($PI,@tri2d,@tri3d,@options,$zsize,$fps,$time,$z,$t,$xmin,$xmax,$ymin,$ymax,$zmin,$zmax,$tmin,$tmax,$xres,$zres,$tres,$width,$height); # window $xmin = -5; $xmax = 5; $ymin = -5; $ymax = 5; $zmin = -5; $zmax = 5; $tmin = -5; $tmax = 5; # points/axis and fps $xres = 100; $zres = 200; $tres = 50; $fps = 25; # variables init $PI = 3.415926535898; $z = $zmin; $t = $tmin; $time = [gettimeofday]; $zsize = 0; # 0(0): 2d # 0(1): 3d wire # 0(2): 3d solid # 1(0): stable # 1(1): time-function # 2(0): orthographic viewing # 2(1): perspective viewing # 2(2): stereo viewing # 2(3): 2nd way of stereo viewing @options = (0,0,0); # main program ;-) init(); glutMainLoop; sub init{ # glut init glutInit(@ARGV); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(600, 600); glutInitWindowPosition(50, 50); glutCreateWindow("graph window"); # functions glutKeyboardFunc(\&keyboard); glutDisplayFunc(\&display); glutReshapeFunc(\&resize); glutIdleFunc(\&idle); glClearColor(0,0,0,0); glMatrixMode(GL_PROJECTION); glOrtho($xmin,$xmax,$ymin,$ymax,$zmin,$zmax); glRotatef(-30, 5, -0.5, 0.0); glScalef(0.85,0.85,0.85); reset(); } sub idle { my (@tripar,$dim,$x,$y,$j); if ($options[0] == 0) {$dim=2;} else {$dim=3;} if ($zsize < $zres) { $x=$xmin; for ($j=0; $j<=($dim*$xres-$dim); $j=$j+$dim) { eval { $y=cos(4*sqrt($z*$z+$x*$x)-2*atan($x/$z)); }; $tripar[$j]=$x; $tripar[$j+1]=$y; if ($dim == 3) {$tripar[$j+2]=$z;} $x += ($xmax-$xmin)/($xres-1); } $j = 0; if ($dim == 3) { $z += ($zmax-$zmin)/($zres-1); $zsize++; } # if (tv_interval($time)<(1/$fps)) { # usleep (1/120); # return; } # $time = [gettimeofday]; if ($dim == 3) { unshift(@tri3d,@tripar); splice(@tri3d,(9*$xres*$zres)); if ($zsize == $zres) {display();} } else { unshift(@tri2d,@tripar); splice(@tri2d,(2*$xres)); display();} } } sub display { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1,1,1); my ($h,$i); # display2d() if ($options[0] == 0) { glColor3f(0.8,0.8,0.8); glBegin(GL_LINE_STRIP); { glVertex2f($tri2d[0],$tri2d[1]); for ($i=2; $i<=(2*$xres-2); $i=$i+2) { glVertex2f($tri2d[$i],$tri2d[$i+1]); } } glEnd(); } # display3d_wire() elsif ($options[0] == 1) { glColor3f(0.8,0.8,0.8); for $h (0..($zsize-2)) { glBegin(GL_LINE_STRIP); { # jeweils um einen Punkt springen for ($i=0; $i<=(3*$xres-4); $i=$i+3) { # left bottom glVertex3f($tri3d[$i+3*$h*$xres],$tri3d[$i+1+3*$h*$xres],$tri3d[$i+2+3*$h*$xres]); # left top glVertex3f($tri3d[$i+3*$xres+3*$h*$xres],$tri3d[$i+3*$xres+1+3*$h*$xres],$tri3d[$i+3*$xres+2+3*$h*$xres]); # rigth top glVertex3f($tri3d[$i+3*$xres+3+3*$h*$xres],$tri3d[$i+3*$xres+4+3*$h*$xres],$tri3d[$i+3*$xres+5+3*$h*$xres]); # left bottom glVertex3f($tri3d[$i+3*$h*$xres],$tri3d[$i+1+3*$h*$xres],$tri3d[$i+2+3*$h*$xres]); } } glEnd(); } } # display3d_solid() # FALSCH elsif ($options[0] == 2) { for $h (0..($zsize-2)) { glBegin(GL_TRIANGLE_STRIP); { my $basec = 3*$xres+1+3*$h*$xres; glColor3f(abs($tri3d[$basec]/($ymax-$ymin))*2,0,0); # left top glVertex3f($tri3d[$basec-1],$tri3d[$basec],$tri3d[$basec+1]); for ($i=3; $i<=(3*$xres-4); $i=$i+3) { my $basec = $i+1+3*$h*$xres; glColor3f(abs($tri3d[$basec]/($ymax-$ymin))*2,0,0); # left bottom glVertex3f($tri3d[$basec-1],$tri3d[$basec],$tri3d[$basec+1]); # right top glVertex3f($tri3d[$basec+3*$xres-1],$tri3d[$basec+3*$xres],$tri3d[$basec+3*$xres+1]); } } glEnd(); } } glFlush(); glutSwapBuffers(); } sub keyboard { my ($key) = @_; $key = chr($key); if($key=~/w/i){ # rotate up glRotatef(3.0, 0.5, 0, 0.0); } elsif($key=~/s/i){ # rotate down glRotatef(-3.0, 0.5, 0, 0.0); } elsif($key=~/a/i){ # rotate left glRotatef(3.0, 0.0, 0.5, 0); } elsif($key=~/d/i){ # rotate right glRotatef(-3.0, 0.0, 0.5, 0); } elsif($key=~/q/i){ exit(); } elsif($key=~/m/i){ screenshot(); } elsif($key=~/r/i){ glScalef(1.1,1.1,1.1); } elsif($key=~/f/i){ glScalef(0.9,0.9,0.9); } # repaint the window display(); } sub resize{ ($width,$height)=@_; } sub getheader{ my ($width,$height) = @_; my ($header); $header = pack("s",hex("4d42")); #signature $header .= pack("i",$width*$height*3+hex(36));#size (inc header) $header .= pack("s",0); #reserved $header .= pack("s",0); #reserved $header .= pack("i",hex(36)); #offset $header .= pack("i",40); #size of BITMAPINFOHEADER structure, must be 40 $header .= pack("i",$width); #width $header .= pack("i",$height); #hight $header .= pack("s",1); #number of planes in the image, must be 1 $header .= pack("s",24); #bites per pixel $header .= pack("i",0); #compression type (0=none, 1=RLE-8, 2=RLE-4) $header .= pack("i",$width*$height*3); #size of image data $header .= pack("i",0); #horizontal resolution in pixels per meter (unreliable) $header .= pack("i",0); #vertical resolution in pixels per meter (unreliable) $header .= pack("i",0); #number of colors in image, or zero $header .= pack("i",0); #number of important colors, or zero return $header; } sub screenshot { my $num = 1; my $i; $num++ while(-f "image$num.bmp"); if(open(IMAGE,">image$num.bmp")){ print IMAGE getheader($width,$height); my @pixels=glReadPixels_p(0, 0,$width,$height, GL_RGB,GL_UNSIGNED_INT); #{print (IMAGE pack("B*", $i )); }for $i (@pixels); for $i (0..(($#pixels-1)/3)){ my ($red, $green, $blue) = ($pixels[$i*3],$pixels[$i*3+1],$pixels[$i*3+2]); print IMAGE pack("B B B",$blue,$green,$red); } #for $pixel (@pixels){ print IMAGE pack ("B*",$pixel);} close(IMAGE); } } sub reset { # gl init glLoadIdentity(); # light # my @mat_diffuse = (1.0, 1.0, 1.0, 1.0); # my $mat_shininess = 50.0; # my @light_position = ($xmax,$ymax,$zmax,1); # my @light_ambient = (1.0, 1.0, 1.0, 1.0); # glShadeModel (GL_SMOOTH); # OpenGL::glMaterialfv_p(GL_FRONT, GL_DIFFUSE, @mat_diffuse); # OpenGL::glMaterialfv_p(GL_FRONT, GL_SHININESS, $mat_shininess); # OpenGL::glLightfv_p(GL_LIGHT0, GL_POSITION, @light_position); # OpenGL::glLightfv_p(GL_LIGHT0, GL_AMBIENT, @light_ambient); # glEnable(GL_LIGHTING); # glEnable(GL_LIGHT0); # glEnable(GL_DEPTH_TEST); # window properties glFlush(); # calculation idle(); } #- eval error #- perldoc -f eval # color(rot,grün,blau)