#!/usr/bin/newlisp # # Solar.c # # Program to demonstrate how to use a local # coordinate method to position parts of a # model in relation to other model parts. # # Draws a simple solar system, with a sun, planet and moon. # Based on sample code from the OpenGL programming guide # by Woo, Neider, Davis. Addison-Wesley. # # Author: Samuel R. Buss # # Software accompanying the book # 3D Computer Graphics: A Mathematical Introduction with OpenGL, # by S. Buss, Cambridge University Press, 2003. # # Software is "as-is" and carries no warranty. It may be used without # restriction, but if you modify it, please change the filenames to # prevent confusion between different versions. # Bug reports: Sam Buss, sbuss@ucsd.edu. # Web page: http://math.ucsd.edu/~sbuss/MathCG # # USAGE: # Press "r" key to toggle (off and on) running the animation # Press "s" key to single-step animation # The up arrow key and down array key control the # time step used in the animation rate. Each key # press multiplies or divides the times by a factor # of two (2). # Press ESCAPE to exit. # #------------------------------------------------------------------- # Ported to newLisp by Peter van Eerten. # # This is a 1-to-1 port of the original program. # October 18, 2005. # Adapted for newLisp 10, january 6 2009 - PvE. #------------------------------------------------------------------- (load "GL.lsp" "GLU.lsp" "freeglut.lsp") (set 'spinMode GL:GL_TRUE) (set 'singleStep GL:GL_FALSE) # These three variables control the animation's state and speed. (set 'HourOfDay (flt 0.0)) (set 'DayOfYear (flt 0.0)) (set 'AnimateIncrement (float 24.0)) # Time step for animation (hours) # glutKeyboardFunc is called below to set this function to handle # all normal key presses. (define (KeyPressFunc Key x y) (case Key #'R': (114: # 'r' (Key_r) ) #'S': (115: # 's' (Key_s) ) (27: # Escape key (exit) ) ) ) # glutSpecialFunc is called below to set this function to handle # all special key presses. See glut.h for the names of # special keys. (define (SpecialKeyFunc Key x y) (case Key (0x0065: #GLUT_KEY_UP (Key_up) ) (0x0067: #GLUT_KEY_DOWN: (Key_down) ) ) ) (define (Key_r) (if (= singleStep GL:GL_TRUE) # If ending single step mode (begin (set 'singleStep GL:GL_FALSE) (set 'spinMode GL:GL_TRUE) # Restart animation ) (set 'spinMode (- 1 spinMode)) # Toggle animation on and off. ) ) (define (Key_s) (set 'singleStep GL:GL_TRUE) (set 'spinMode GL:GL_TRUE) ) (define (Key_up) (set 'AnimateIncrement (mul AnimateIncrement 2.0)) # Double the animation time step ) (define (Key_down) (set 'AnimateIncrement (div AnimateIncrement 2.0)) # Halve the animation time step ) # Animate() handles the animation and the redrawing of the # graphics window contents. (define (Animate) # Clear the redering window (GL:glClear (| GL:GL_COLOR_BUFFER_BIT GL:GL_DEPTH_BUFFER_BIT)) (if (= spinMode GL:GL_TRUE) (begin # Update the animation state (set 'HourOfDay (add HourOfDay AnimateIncrement)) (set 'DayOfYear (add DayOfYear (div AnimateIncrement 24.0))) (set 'HourOfDay (sub HourOfDay (mul (int (div HourOfDay 24)) 24))) (set 'DayOfYear (sub DayOfYear (mul (int (div DayOfYear 365)) 365))) ) ) # Clear the current matrix (Modelview) (GL:glLoadIdentity) # Back off eight units to be able to view from the origin. (GL:glTranslatef (flt 0.0) (flt 0.0) (flt -8.0)) # Rotate the plane of the elliptic # (rotate the model's plane about the x axis by fifteen degrees) (GL:glRotatef (flt 15.0) (flt 1.0) (flt 0.0) (flt 0.0)) # Draw the sun -- as a yellow, wireframe sphere (GL:glColor3f (flt 1.0) (flt 1.0) (flt 0.0)) (GLUT:glutWireSphere (float 1.0) 15 15) # Draw the Earth # First position it around the sun # Use DayOfYear to determine its position (GL:glRotatef (flt (div (mul 360.0 DayOfYear) 365.0)) (flt 0.0) (flt 1.0) (flt 0.0)) (GL:glTranslatef (flt 4.0) (flt 0.0) (flt 0.0)) (GL:glPushMatrix) # Save matrix state # Second, rotate the earth on its axis. # Use HourOfDay to determine its rotation. (GL:glRotatef (flt (div (mul 360.0 HourOfDay) 24.0)) (flt 0.0) (flt 1.0) (flt 0.0)) # Third, draw the earth as a wireframe sphere. (GL:glColor3f (flt 0.2) (flt 0.2) (flt 1.0)) (GLUT:glutWireSphere (float 0.4) 10 10) (GL:glPopMatrix) # Restore matrix state # Draw the moon. # Use DayOfYear to control its rotation around the earth (GL:glRotatef (flt (div (mul (mul 360.0 12.0) DayOfYear) 365.0)) (flt 0.0) (flt 1.0) (flt 0.0)) (GL:glTranslatef (flt 0.7) (flt 0.0) (flt 0.0)) (GL:glColor3f (flt 0.3) (flt 0.7) (flt 0.3)) (GLUT:glutWireSphere (float 0.1) 5 5) # Flush the pipeline, and swap the buffers (GL:glFlush) (GLUT:glutSwapBuffers) (if (= singleStep GL:GL_TRUE) (set 'spinMode GL:GL_FALSE) ) (GLUT:glutPostRedisplay) # Request a re-draw for animation purposes ) # Initialize OpenGL's rendering modes (define (OpenGLInit) (GL:glShadeModel GL:GL_FLAT) (GL:glClearColor (flt 0.0) (flt 0.0) (flt 0.0) (flt 0.0)) (GL:glClearDepth (float 1.0)) (GL:glEnable GL:GL_DEPTH_TEST) ) # ResizeWindow is called when the window is resized (define (ResizeWindow w h) (if (= w 0) (set 'w 1)) (if (= h 0) (set 'h 1)) (GL:glViewport 0 0 w h) # View port uses whole window (set 'aspectRatio (div w h)) # Set up the projection view matrix (not very well!) (GL:glMatrixMode GL:GL_PROJECTION) (GL:glLoadIdentity) (GLU:gluPerspective 60.0 aspectRatio 1.0 30.0) # Select the Modelview matrix (GL:glMatrixMode GL:GL_MODELVIEW) ) # Main routine # Set up OpenGL, hook up callbacks, and start the main loop (define (main argc argv) # Need to double buffer for animation (GLUT:glutInit (address argc) (address argv)) (GLUT:glutInitDisplayMode (| GLUT:GLUT_DOUBLE GLUT:GLUT_RGB GLUT:GLUT_DEPTH)) # Create and position the graphics window (GLUT:glutInitWindowPosition 0 0) (GLUT:glutInitWindowSize 600 360) (GLUT:glutCreateWindow "Solar System Demo") # Initialize OpenGL. (OpenGLInit) # Set up callback functions for key presses (GLUT:glutKeyboardFunc 'KeyPressFunc) (GLUT:glutSpecialFunc 'SpecialKeyFunc) # Set up the callback function for resizing windows (GLUT:glutReshapeFunc 'ResizeWindow) # Callback for graphics image redrawing (GLUT:glutDisplayFunc 'Animate) # Start the main loop. glutMainLoop never returns. (GLUT:glutMainLoop) ) (main 0 0) (exit)