orange has asked for the wisdom of the Perl Monks concerning the following question:
#! /usr/bin/perl -w # Requires OpenGL module in addition to OpenGL use OpenGL qw(:all); # Use the OpenGL module use strict; # ASCII constant for the escape key use constant ESCAPE => 27; # Global variable for our window my $window; my $a;my $b; my $c; my $angle; my $speed; my $i; my $angle_horizontal=0; #rotation of the Fan body left and right my $angle_step = 0.3; my @position = (0.0, 0.0, 2.0, 1.0); my @light0_position = (5.0, 5.0, 5.0, 0.0); my @mat_specular = (1.0, 1.0, 1.0, 1.0); my @mat_shininess = (50.0); my @mat_amb_diff_color = (1.0, 0.5, 0.0, 0.5); my @light_diffuse = (1.0, 1.0, 1.0, 1.0); my @light_ambient = (0.15, 0.15, 0.15, 0.15); my @light_specular = (1.0, 1.0, 1.0, 1.0); # A general GL initialization function # Called right after our OpenGL window is created # Sets all of the initial parameters sub InitGL { # Shift the width and height off of @_, in that order my ($width, $height) = @_; glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); # Reset the projection matrix glMatrixMode(GL_PROJECTION); glLoadIdentity; # Calculate the aspect ratio of the Window gluPerspective(45.0, $width/$height, 0.1, 100.0); # Reset the modelview matrix glMatrixMode(GL_MODELVIEW); } # The function called when our window is resized # This shouldn't happen, because we're fullscreen sub ReSizeGLScene { # Shift width and height off of @_, in that order my ($width, $height) = @_; # Prevent divide by zero error if window is too small if ($height == 0) { $height = 1; } # Reset the current viewport and perspective transformation glViewport(0, 0, $width, $height); # Re-initialize the window (same lines from InitGL) glMatrixMode(GL_PROJECTION); glLoadIdentity; gluPerspective(45.0, $width/$height, 0.1, 100.0); glMatrixMode(GL_MODELVIEW); } # The main drawing function. sub DrawGLScene { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLightfv_p(GL_LIGHT0, GL_POSITION, @light0_position); glLightfv_p(GL_LIGHT0, GL_DIFFUSE, @light_diffuse); glLightfv_p(GL_LIGHT0, GL_AMBIENT, @light_ambient); glLightfv_p(GL_LIGHT0, GL_SPECULAR, @light_specular); glMaterialfv_p(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,@mat_amb_diff_color); # Reset the screen glLoadIdentity; # Move to the into (inside) the screen 6.0 units glTranslatef(0.0, 0.0, -6.0); gluLookAt(5,5,5,0,1.5,0,0,1,0); &Fan_Physics(); &Fan_Render(); # Since this is double buffered, swap the buffers. # This will display what just got drawn. glutSwapBuffers; } # The function called whenever a key is pressed. sub keyPressed { # Shift the unsigned char key, and the x,y placement off @_, in # that order. my ($key, $x, $y) = @_; # Avoid thrashing this procedure # Note standard Perl does not support usleep # For finer resolution sleep than seconds, try: # 'select undef, undef, undef, 0.1;' # to sleep for (at least) 0.1 seconds sleep(1); # If f key pressed, undo fullscreen and resize to 640x480 if ($key == ord('f')) { # Use reshape window, which undoes fullscreen glutReshapeWindow(640, 480); } # If escape is pressed, kill everything. if ($key == ESCAPE) { # Shut down our window glutDestroyWindow($window); # Exit the program...normal termination. exit(0); } } sub Fan_Physics() { $angle_horizontal = $angle_horizontal + $angle_step; if ($angle_horizontal > 110) {$angle_step = -0.3;} else{if ($angle_horizontal < 0) { $angle_step = 0.3; } } $speed += 90/100; if ($speed > 600){ $speed = 600}; $angle += $speed/100; } sub Fan_Render{ glPushMatrix; #-- Base glPushMatrix; my $quad = OpenGL::gluNewQuadric(); gluQuadricDrawStyle($quad, GLU_FILL); glScalef( 4 , 0.5 , 4 ); #Sphere with radius 0.25 then scaled gluSphere( $quad , 0.25 , 20 , 20 ); glPopMatrix; glPushMatrix; glRotatef(-90, 1.0, 0.0, 0.0); gluCylinder($quad, 0.125, 0.125, 3, 16, 10); glPopMatrix; glPushMatrix; glTranslatef(0.0, 3.0, 0.0); glRotatef($angle_horizontal, 0, 1, 0); glScalef( 0.5, 0.5, 1); gluSphere( $quad , 1 , 20 , 20 ); glPopMatrix; # Fan $quad = OpenGL::gluNewQuadric(); gluQuadricDrawStyle($quad, GLU_FILL); glRotatef($angle_horizontal, 0, 1, 0); glPushMatrix; glTranslatef(0.0, 3.0, 0.5); glRotatef( $angle, 0.0, 0.0, 1.0 ); for ($i = 1; $i<=360; $i=$i+60) { glPushMatrix; glRotatef( $i, 0.0, 0.0, 1.0 ); glTranslatef(1.5, 0.0, 0.0); glRotatef( -45, 1.0, 0.0, 0.0 ); my @mat_amb_diff_color = (0.5, 1, 0.5, 0.5); glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glMaterialfv_p(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,@mat_amb_diff_color); glPushMatrix; #calling Box ie: drawing the Blade of the fan &Box(1, 0.3, 0.01); glEnable(GL_LIGHTING); glPopMatrix; glPopMatrix; } glPopMatrix; glPopMatrix; glPopMatrix; } sub Box { $a = $_[0]; $b = $_[1]; $c = $_[2]; glBegin(GL_QUADS); # Top face of box glVertex3f($a, $b, -$c); # Top right vertex (Top of cube) glVertex3f(-$a, $b, -$c); # Top left vertex (Top of cube) glVertex3f(-$a, $b, $c); # Bottom left vertex (Top of cube) glVertex3f($a, $b, $c); # Bottom right vertex (Top of cube) # Bottom face of box glVertex3f($a, -$b, -$c); # Top right vertex (Bottom of cube) glVertex3f(-$a, -$b, -$c); # Top left vertex (Bottom of cube) glVertex3f(-$a, -$b, $c); # Bottom left vertex (Bottom of cube) glVertex3f( $a, -$b, $c); # Bottom right vertex (Bottom of cube) # Front of box glVertex3f($a, $b, $c); # Top right vertex (Front) glVertex3f(-$a, $b, $c); # Top left vertex (Front) glVertex3f(-$a, -$b, $c); # Bottom left vertex (Front) glVertex3f($a, -$b, $c); # Bottom right vertex (Front) # Back of box glVertex3f($a, -$b, -$c); # Bottom right vertex (Back) glVertex3f(-$a, -$b, -$c); # Bottom left vertex (Back) glVertex3f(-$a, $b, -$c); # top left vertex (Back) glVertex3f($a, $b, -$c); # Top right vertex (Back) # Left of box glVertex3f(-$a, $b, $c); # Top right vertex (Left) glVertex3f(-$a, $b, -$c); # Top left vertex (Left) glVertex3f(-$a, -$b, -$c); # Bottom left vertex (Left) glVertex3f(-$a, -$b, $c); # Bottom vertex (Left) # Right of box glVertex3f($a, $b, -$c); # Top right vertex (Right) glVertex3f($a, $b, $c); # Top left vertex (Right) glVertex3f($a, -$b, $c); # Bottom left vertex (Right) glVertex3f($a, -$b, -$c); # Bottom right vertex (Right) # End drawing the box glEnd; } # --- Main program --- # Initialize GLUT state glutInit; # Select type of Display mode: # Double buffer # RGB color (Also try GLUT_RGBA) # Alpha components removed (try GLUT_ALPHA) # Depth buffer */ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); # Get a 640 x 480 window glutInitWindowSize(640, 480); # The window starts at the upper left corner of the screen glutInitWindowPosition(0, 0); # Open the window $window = glutCreateWindow("Fan for Hot Summer -perl opengl example"); # Register the function to do all our OpenGL drawing. glutDisplayFunc(\&DrawGLScene); # Go fullscreen. This is as soon as possible. #glutFullScreen; glutReshapeWindow(640,480); # Even if there are no events, redraw our gl scene. glutIdleFunc(\&DrawGLScene); # Register the function called when our window is resized. glutReshapeFunc(\&ReSizeGLScene); # Register the function called when the keyboard is pressed. glutKeyboardFunc(\&keyPressed); # Initialize our window. InitGL(640, 480); # Start Event Processing Engine glutMainLoop; return 1;
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Fan For Summer, perl opengl example
by grizzley (Chaplain) on Jul 03, 2009 at 13:31 UTC | |
by orange (Beadle) on Jul 03, 2009 at 16:08 UTC |