/t_backcompat/OpenGL/tutorial/lesson18.pl
http://github.com/PerlGameDev/SDL · Perl · 411 lines · 301 code · 88 blank · 22 comment · 34 complexity · c181e6792f8bd1411d264a956cc8ce22 MD5 · raw file
- #!/usr/bin/perl
- # This code was created by Jeff Molofee '99
- # (ported to SDL by Sam Lantinga '2000)
- # (ported to Linux/SDL by Ti Leggett '01)
- # Lesson18 adapted by JusTiCe8 @2007 from others lesson and
- # ported to new Perl SDL, comments stripped (see Nehe lessons)
- # If you've found this code useful, please let me know.
- # Visit Jeff at http://nehe.gamedev.net/
- # or for port-specific comments, questions, bugreports etc.
- # email to leggett@eecs.tulane.edu (C/SDL)
- # or justice8@wanadoo.fr (SDL-Perl)
- use strict;
- use Getopt::Long;
- use SDL::Constants;
- use SDLx::App;
- use SDL::OpenGL::Constants;
- use SDL::OpenGL;
- use SDL::Event;
- use SDL::Cursor;
- use constant NUM_TEXTURES => 3;
- my $arg_screen_width = 640;
- my $arg_screen_height = 480;
- my $arg_fullscreen = 0;
- my $delay = 5;
- my $light = 0;
- my ( $part1, $part2 );
- my ( $p1, $p2 ) = ( 0, 1 );
- my ( $xrot, $yrot, $xspeed, $yspeed );
- my $z = -5.0;
- my $LightAmbient = [ 0.5, 0.5, 0.5, 1.0 ];
- my $LightDiffuse = [ 1.0, 1.0, 1.0, 1.0 ];
- my $LightPosition = [ 0.0, 0.0, 2.0, 1.0 ];
- my $quadratic;
- my $object = 5;
- my $filter = 1;
- # this flag is used to limit key strokes event
- my $pressed = 0;
- GetOptions(
- "width:i" => \$arg_screen_width,
- "height:i" => \$arg_screen_height,
- "fullscreen!" => \$arg_fullscreen,
- "delay:i" => \$delay,
- ) or die $!;
- main();
- exit;
- sub main {
- my $done = 0;
- my $fps = 0.0;
- my $frames_drawn = 0;
- my $app = SDLx::App->new(
- -title => "Jeff Molofee's lesson18: Quadratic",
- -icon => "icon.png",
- -width => $arg_screen_width,
- -height => $arg_screen_height,
- -opengl => 1,
- );
- $app->fullscreen if ($arg_fullscreen);
- SDL::ShowCursor(0);
- my $event = SDL::Event->new;
- $event->set( SDL_SYSWMEVENT(), SDL_IGNORE() );
- InitGL( $arg_screen_width, $arg_screen_height );
- my $prev_ticks = $app->ticks();
- my $fps_counter = 0.0;
- while ( !$done ) {
- DrawGLScene();
- $app->sync();
- $app->delay($delay) if ( $delay > 0 );
- $frames_drawn++;
- my $ticks_now = $app->ticks();
- $fps_counter += $ticks_now - $prev_ticks;
- $prev_ticks = $ticks_now;
- if ( $fps_counter >= 5000.0 ) {
- $fps = $frames_drawn / ( $fps_counter / 1000.0 );
- printf(
- "%d frames in %.2f seconds = %.3f FPS\n",
- $frames_drawn, $fps_counter / 1000.0, $fps
- );
- $frames_drawn = 0;
- $fps_counter = 0.0;
- }
- $event->pump;
- $event->poll;
- $done = 1 if ( $event->type == &SDL_QUIT );
- if ( $event->type == &SDL_KEYDOWN ) {
- $done = 1 if ( $event->key_sym == &SDLK_ESCAPE );
- if ( $event->key_sym == &SDLK_f and !$pressed ) {
- $filter = 1 + $filter % 3;
- #print "Filter = $filter\n";
- $pressed = 1;
- } elsif ( $event->key_sym == &SDLK_l and !$pressed ) {
- $light = !$light;
- if ( !$light ) {
- glDisable(&GL_LIGHTING);
- } else {
- glEnable(&GL_LIGHTING);
- }
- $pressed = 1;
- } elsif ( $event->key_sym == &SDLK_SPACE and !$pressed ) {
- $object = ++$object % 6;
- $pressed = 1;
- } elsif ( $event->key_sym == &SDLK_PAGEUP ) {
- $z -= 0.02;
- } elsif ( $event->key_sym == &SDLK_PAGEDOWN ) {
- $z += 0.02;
- } elsif ( $event->key_sym == &SDLK_UP ) {
- $xspeed -= 0.01;
- } elsif ( $event->key_sym == &SDLK_DOWN ) {
- $xspeed += 0.01;
- } elsif ( $event->key_sym == &SDLK_RIGHT ) {
- $yspeed += 0.01;
- } elsif ( $event->key_sym == &SDLK_LEFT ) {
- $yspeed -= 0.01;
- }
- } elsif ( $event->type == &SDL_KEYUP ) {
- $pressed = 0;
- }
- }
- }
- sub InitGL {
- my ( $Width, $Height ) = @_;
- ( $xrot, $yrot ) = ( 0.0, 0.0 );
- glViewport( 0, 0, $Width, $Height );
- LoadGLTexture();
- glEnable(&GL_TEXTURE_2D);
- glShadeModel(&GL_SMOOTH);
- glClearColor( 0.0, 0.0, 0.0, 0.0 );
- glClearDepth(1.0);
- glEnable(&GL_DEPTH_TEST);
- glDepthFunc(&GL_LESS); # GL_EQUAL as source tutorial don't work (?)
- glHint( &GL_PERSPECTIVE_CORRECTION_HINT, &GL_NICEST );
- glLight( &GL_LIGHT1, &GL_AMBIENT, @$LightAmbient );
- glLight( &GL_LIGHT1, &GL_DIFFUSE, @{$LightDiffuse} );
- glLight( &GL_LIGHT1, &GL_POSITION, @{$LightPosition} );
- glEnable(&GL_LIGHT1);
- $quadratic = gluNewQuadric();
- #gluQuadricNormals ( $quadratic, &GLU_SMOOTH );
- gluQuadricTexture( $quadratic, &GL_TRUE );
- glMatrixMode(&GL_PROJECTION);
- glLoadIdentity();
- gluPerspective( 45.0, $Width / $Height, 0.1, 100.0 );
- glMatrixMode(&GL_MODELVIEW);
- }
- sub drawGLCube {
- glBegin(&GL_QUADS);
- glNormal( 0.0, 0.0, 1.0 );
- glTexCoord( 1.0, 0.0 );
- glVertex( -1.0, -1.0, 1.0 );
- glTexCoord( 0.0, 0.0 );
- glVertex( 1.0, -1.0, 1.0 );
- glTexCoord( 0.0, 1.0 );
- glVertex( 1.0, 1.0, 1.0 );
- glTexCoord( 1.0, 1.0 );
- glVertex( -1.0, 1.0, 1.0 );
- glNormal( 0.0, 0.0, -1.0 );
- glTexCoord( 0.0, 0.0 );
- glVertex( -1.0, -1.0, -1.0 );
- glTexCoord( 0.0, 1.0 );
- glVertex( -1.0, 1.0, -1.0 );
- glTexCoord( 1.0, 1.0 );
- glVertex( 1.0, 1.0, -1.0 );
- glTexCoord( 1.0, 0.0 );
- glVertex( 1.0, -1.0, -1.0 );
- glNormal( 0.0, 1.0, 0.0 );
- glTexCoord( 1.0, 1.0 );
- glVertex( -1.0, 1.0, -1.0 );
- glTexCoord( 1.0, 0.0 );
- glVertex( -1.0, 1.0, 1.0 );
- glTexCoord( 0.0, 0.0 );
- glVertex( 1.0, 1.0, 1.0 );
- glTexCoord( 0.0, 1.0 );
- glVertex( 1.0, 1.0, -1.0 );
- glNormal( 0.0, -1.0, 0.0 );
- glTexCoord( 0.0, 1.0 );
- glVertex( -1.0, -1.0, -1.0 );
- glTexCoord( 1.0, 1.0 );
- glVertex( 1.0, -1.0, -1.0 );
- glTexCoord( 1.0, 0.0 );
- glVertex( 1.0, -1.0, 1.0 );
- glTexCoord( 0.0, 0.0 );
- glVertex( -1.0, -1.0, 1.0 );
- glNormal( 1.0, 0.0, 0.0 );
- glTexCoord( 0.0, 0.0 );
- glVertex( 1.0, -1.0, -1.0 );
- glTexCoord( 0.0, 1.0 );
- glVertex( 1.0, 1.0, -1.0 );
- glTexCoord( 1.0, 1.0 );
- glVertex( 1.0, 1.0, 1.0 );
- glTexCoord( 1.0, 0.0 );
- glVertex( 1.0, -1.0, 1.0 );
- glNormal( -1.0, 0.0, 0.0 );
- glTexCoord( 1.0, 0.0 );
- glVertex( -1.0, -1.0, -1.0 );
- glTexCoord( 0.0, 0.0 );
- glVertex( -1.0, -1.0, 1.0 );
- glTexCoord( 0.0, 1.0 );
- glVertex( -1.0, 1.0, 1.0 );
- glTexCoord( 1.0, 1.0 );
- glVertex( -1.0, 1.0, -1.0 );
- glEnd();
- }
- sub DrawGLScene {
- glClear( &GL_COLOR_BUFFER_BIT | &GL_DEPTH_BUFFER_BIT );
- glLoadIdentity();
- glTranslate( 0.0, 0.0, $z );
- glRotate( $xrot, 1.0, 0.0, 0.0 );
- glRotate( $yrot, 0.0, 1.0, 0.0 );
- glBindTexture( &GL_TEXTURE_2D, $filter );
- if ( $object == 0 ) {
- drawGLCube();
- } elsif ( $object == 1 ) {
- glTranslate( 0.0, 0.0, -1.5 );
- gluCylinder( $quadratic, 1.0, 1.0, 3.0, 32, 32 );
- } elsif ( $object == 2 ) {
- gluDisk( $quadratic, 0.5, 1.5, 32, 32 );
- } elsif ( $object == 3 ) {
- gluSphere( $quadratic, 1.3, 32, 32 );
- } elsif ( $object == 4 ) {
- glTranslate( 0.0, 0.0, -1.5 );
- gluCylinder( $quadratic, 1.0, 0.0, 3.0, 32, 32 );
- } elsif ( $object == 5 ) {
- $part1 += $p1;
- $part2 += $p2;
- if ( $part1 > 359 ) {
- $p1 = 0;
- $part1 = 0;
- $p2 = 1;
- $part2 = 0;
- }
- if ( $part2 > 359 ) {
- $p1 = 1;
- $p2 = 0;
- }
- gluPartialDisk( $quadratic, 0.5, 1.5, 32, 32, $part1, $part2 - $part1 );
- }
- $xrot += $xspeed;
- $yrot += $yspeed;
- }
- sub LoadGLTexture {
- my ( $pixels, $width, $height, $size ) = ImageLoad('data/wall.bmp');
- #print "LoadGLTexture: w:$width h:$height s:$size\n";
- my $textures = glGenTextures(NUM_TEXTURES);
- unless ( $$textures[0] ) {
- print "Could not generate textures\n";
- return 0;
- }
- glBindTexture( &GL_TEXTURE_2D, 1 ); #$$textures[0]);
- glTexImage2D(
- &GL_TEXTURE_2D, 0, 3, $width, $height, 0, &GL_BGR,
- &GL_UNSIGNED_BYTE, $pixels
- );
- glTexParameter( &GL_TEXTURE_2D, &GL_TEXTURE_MAG_FILTER, &GL_NEAREST );
- glTexParameter( &GL_TEXTURE_2D, &GL_TEXTURE_MIN_FILTER, &GL_NEAREST );
- glBindTexture( &GL_TEXTURE_2D, 2 );
- glTexImage2D(
- &GL_TEXTURE_2D, 0, 3, $width, $height, 0, &GL_BGR,
- &GL_UNSIGNED_BYTE, $pixels
- );
- glTexParameter( &GL_TEXTURE_2D, &GL_TEXTURE_MIN_FILTER, &GL_LINEAR );
- glTexParameter( &GL_TEXTURE_2D, &GL_TEXTURE_MAG_FILTER, &GL_LINEAR );
- glBindTexture( &GL_TEXTURE_2D, 3 );
- glTexParameter(
- &GL_TEXTURE_2D, &GL_TEXTURE_MIN_FILTER,
- &GL_LINEAR_MIPMAP_NEAREST
- );
- glTexParameter( &GL_TEXTURE_2D, &GL_TEXTURE_MAG_FILTER, &GL_LINEAR );
- gluBuild2DMipmaps(
- &GL_TEXTURE_2D, 3, $width, $height, &GL_BGR,
- &GL_UNSIGNED_BYTE, $pixels
- );
- my $glerr = glGetError();
- if ($glerr) {
- print "Problem setting up 2d Texture (dimensions not a power of 2?)): " . gluErrorString($glerr) . "\n";
- return 0;
- }
- }
- sub ImageLoad {
- my $filename = shift;
- return unless ( defined $filename and -e $filename );
- #somthing needs to keep the ref count alive for objects which represents data in C space (they have no ref count):
- my @ref = ();
- #makes use of SDL: BMP loader.
- my $surface = SDL::Surface->new( -name => $filename );
- my $width = $surface->width();
- my $height = $surface->height();
- my $bytespp = $surface->bytes_per_pixel();
- my $size = $width * $height * $bytespp;
- return ( $surface->pixels(), $width, $height, $size );
- my $surface_pixels = $surface->pixels();
- my $surface_size = $width * $height * $surface->bytes_per_pixel();
- my $raw_pixels = reverse $surface_pixels;
- #do a conversion (the pixel data is accessable as a simple string)
- my $pixels = $raw_pixels;
- my $pre_conv = $pixels;
- my $new_pixels = '';
- for ( my $y = 0; $y < $height; $y++ ) {
- # calculate offset into the image (a string)
- my $y_pos = $y * $width * $bytespp;
- # extract 1 pixel row
- my $row = substr( $pre_conv, $y_pos, $width * $bytespp );
- # turn the BMP BGR order into OpenGL RGB order;
- $row =~ s/\G(.)(.)(.)/$3$2$1/gms;
- $new_pixels .= reverse $row;
- }
- $raw_pixels = $new_pixels;
- push @ref, $raw_pixels, $surface;
- # we could have created another SDL surface frm the '$raw_pixel's... oh well.
- return ( $raw_pixels, $width, $height, $size );
- }
- END {
- gluDeleteQuadric($quadratic);
- $quadratic = undef;
- =item rem
- use Devel::Peek;
- print "Q=$quadratic\n";
- mstat;
- Dump ($quadratic, 5);
- gluDeleteQuadric ($quadratic);
- Dump ($quadratic, 5);
- $quadratic = undef;
- print "Q=$quadratic\n";
- Dump ($quadratic, 5);
- =cut
- }