#!/usr/bin/perl use strict; use warnings; use SDL::App; use SDL::OpenGL; my ($done, $frame); my ($conf, $sdl_app); START: main(); sub main { init(); main_loop(); cleanup(); } sub init { $| = 1; init_conf(); init_window(); } sub init_conf { $conf = { title => 'Game', width => 1200, height => 900, fovy => 125, }; } sub init_window { my ($title, $w, $h) = @$conf{qw( title width height )}; $sdl_app = SDL::App->new(-title => $title, -width => $w, -height => $h, -gl => 1, ); SDL::ShowCursor(0); } sub main_loop { while (not $done) { $frame++; do_frame(); } } sub do_frame { prep_frame(); draw_frame(); end_frame(); } sub prep_frame { glClear(GL_COLOR_BUFFER_BIT); } sub draw_frame { set_projection_3d(); set_view_3d(); draw_view(); print '.'; sleep 1; $done = 1 if $frame == 4; } sub set_projection_3d { my ($fovy, $w, $h) = @$conf{qw( fovy width height )}; my $aspect = $w / $h; glMatrixMode(GL_PROJECTION); glLoadIdentity; gluPerspective($fovy, $aspect, 1, 1000); glMatrixMode(GL_MODELVIEW); glLoadIdentity; } sub set_view_3d { # Move the viewpoint so we can see the origin glTranslate(0, -2, -10); } sub draw_view { gen_fractal(); } sub iterate { my $inp=$_[0]; my $iterations=$_[1]; my(%rules) = @_; my $out=$inp; my $i; for (my $i2=0;$i2<$iterations;$i2++){ $inp=$out; foreach $i (split(//,$inp)){ $out.= $rules{$i};} } return $out; } sub gen_fractal() { my %rule = ( 'n' , 'nlnrrnln', 'l' , 'lnrnrnlln', "L", 'LnnRnnL', "r", 'rnllnrrn', "R",'RnnLnnR'); my %rule2 = ( 'n' , 0, 'l' , 60, "L", 120, "r", -60, "R",-120, "F",0); my ($count,$posi,$a2); my @pos=(0,0,0); my @oldpos=(0,0,0); my ($x,$y,$z,$rot,$flux,$cnt); foreach my $a(split(//,iterate('nLnLnL',4,%rule))){ $cnt+=1; $rot+=.01745*$rule2{$a}; if ($a eq'n'){ $x=cos($rot); $y=sin($rot); }else{$x=0;$y=0} @pos=($pos[0]+$x,$pos[1]+$y,0); for (my $step=0;$step<10;$step++){ draw_cube([$pos[0]-($x/10*$step),$pos[1]-($y/10*$step),$pos[2]],.03,(.2,.2,.2));} } @oldpos=($pos[0],$pos[1],0) } sub draw_axes { # Lines from origin along positive axes, for orientation # X axis = red, Y axis = green, Z axis = blue glBegin(GL_LINES); glColor(1, 0, 0); glVertex(0, 0, 0); glVertex(1, 0, 0); glColor(0, 1, 0); glVertex(0, 0, 0); glVertex(0, 1, 0); glColor(0, 0, 1); glVertex(0, 0, 0); glVertex(0, 0, 1); glEnd; } sub draw_cube { # A simple cube my $s =$_[1]; my (@col)=@_; my $x= $_[0][0];my $y= $_[0][1];my $z= $_[0][2]; my @indices = qw( 4 5 6 7 1 2 6 5 0 1 5 4 0 3 2 1 0 4 7 3 2 3 7 6 ); glColor($col[0], $col[1], $col[2]); my @vertices = ([-$s+$x, -$s+$y, -$s+$z], [ $s+$x, -$s+$y, -$s+$z], [ $s+$x, $s+$y, -$s+$z], [-$s+$x, $s+$y, -$s+$z], [-$s+$x, -$s+$y, $s+$z], [ $s+$x, -$s+$y, $s+$z], [ $s+$x, $s+$y, $s+$z], [-$s+$x, $s+$y, $s+$z]); glBegin(GL_QUADS); foreach my $face (0 .. 5) { foreach my $vertex (0 .. 3) { my $index = $indices[4 * $face + $vertex]; my $coords = $vertices[$index]; glVertex(@$coords); } } glEnd; } sub end_frame { $sdl_app->sync; } sub cleanup { print "\nDone.\n" }