My anonymous offerings.
#!/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" }

Replies are listed 'Best First'.
Re: OpenGL L-System Fractal Generator
by jwkrahn (Abbot) on Apr 11, 2012 at 00:25 UTC

    If you remove unused code and variables and use more idiomatic perl you get something like:

    #!/usr/bin/perl use strict; use warnings; use SDL::App; use SDL::OpenGL; $| = 1; my %conf = ( title => 'Game', width => 1200, height => 900, fovy => 125, ); my $sdl_app = SDL::App->new( -title => $conf{ title }, -width => $conf{ width }, -height => $conf{ height }, -gl => 1, ); SDL::ShowCursor( 0 ); 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, ); for ( 1 .. 4 ) { glClear( GL_COLOR_BUFFER_BIT ); glMatrixMode( GL_PROJECTION ); glLoadIdentity; my $aspect = $conf{ width } / $conf{ height }; gluPerspective( $conf{ fovy }, $aspect, 1, 1000 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity; # Move the viewpoint so we can see the origin glTranslate( 0, -2, -10 ); my @pos = ( 0, 0, 0 ); my $rot; for my $char ( split //, iterate( 'nLnLnL', 4, %rule ) ) { $rot += .01745 * $rule2{ $char }; my ( $x, $y ) = $char eq 'n' ? ( cos( $rot ), sin( $rot ) ) : +( 0, 0 ); @pos = ( $pos[ 0 ] + $x, $pos[ 1 ] + $y, 0 ); for my $step ( 0 .. 9 ) { draw_cube( [ $pos[ 0 ] - ( $x / 10 * $step ), $pos[ 1 ] - +( $y / 10 * $step ), $pos[ 2 ] ], .03, ( .2, .2, .2 ) ); } } print '.'; sleep 1; $sdl_app->sync; } print "\nDone.\n" sub iterate { my ( $inp, $iterations ) = @_; my %rules = @_; for ( 1 .. $iterations ) { $inp .= join '', @rules{ split //, $inp }; } return $inp; } 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 ); sub draw_cube { # A simple cube my ( $x, $y, $z ) = @{ $_[ 0 ] }; my $s = $_[ 1 ]; glColor( @_[ 0, 1, 2 ] ); glBegin( GL_QUADS ); 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 ], ); for my $face ( 0 .. 5 ) { for my $vertex ( 0 .. 3 ) { glVertex( @{ $vertices[ $indices[ 4 * $face + $vertex ] ] +} ); } } glEnd(); }