#!/usr/bin/newlisp # # rings.c # # To compile: cc -o rings rings.c -lGL -lGLU -lX11 -lglut -lXmu -lm # # Usage: rings # # Homework 4, Part 1: perspective, hierarchical coords, moving eye pos. # # Do a slow zoom on a bunch of rings (ala Superman III?) # # Philip Winston - 2/21/95 # pwinston@hmc.edu # http://www.cs.hmc.edu/people/pwinston # #------------------------------------------------------------------- # Ported to newLisp by Peter van Eerten. # # This is a 1-to-1 port of the original program. # October 18, 2005 - november 18, 2005. #------------------------------------------------------------------- (load "GL.lsp" "GLU.lsp" "freeglut.lsp") (constant 'M_PI 3.14159265) (map set '(MENU_STARTOVER MENU_ZOOM_OUT MENU_STOP_RINGS MENU_STOP_FADE MENU_START_RINGS MENU_START_FADE MENU_QUIT) '(0 1 2 3 4 5 6)) (map set '(NOTALLOWED CONE TORUS INNERMAT OUTTERMAT) '(0 1 2 3 4)) (constant 'STEPS 30) (set 'Fade 1) # Start moving out (set 'Axis 0.0) (set 'AxisInc (div (mul 2.0 M_PI) STEPS)) # mainly computes the translation amount as a function of the # tilt angle and torus radii (define (myInit) (set 'InnerRad 0.70) (set 'OutterRad 5.0) (set 'Tilt 15.0) (set 'Dist 10.0) (set 'sinoftilt (sin (div (mul Tilt M_PI 2.0) 360.0))) (set 'Trans (sub (add (add (mul (add (mul 2.0 OutterRad) InnerRad) sinoftilt) InnerRad) (mul (sub 1.0 sinoftilt) InnerRad)) (mul InnerRad (div 1.0 10.0)))) (set 'TransCone (add Trans (add (mul OutterRad sinoftilt) InnerRad))) ) # I used code from the book's accnot.c as a starting point for lighting. # I have one positional light in center, then one directional (define (myglInit) (constant 'light0_position (pack "ffff" 1.0 0.2 1.0 0.0)) (constant 'light1_position (pack "ffff" 0.0 0.0 0.0 1.0)) (constant 'light1_diffuse (pack "ffff" 1.0 1.0 1.0 1.0)) (constant 'light1_specular (pack "ffff" 1.0 1.0 1.0 1.0)) (constant 'lm_ambient (pack "ffff" 0.2 0.2 0.2 1.0)) (GL:glEnable GL:GL_NORMALIZE) (GL:glMatrixMode GL:GL_PROJECTION) (GL:glLoadIdentity) (GL:glMatrixMode GL:GL_MODELVIEW) (GL:glLoadIdentity) (GL:glLightfv GL:GL_LIGHT0 GL:GL_POSITION light0_position) (GL:glLightfv GL:GL_LIGHT1 GL:GL_POSITION light1_position) (GL:glLightfv GL:GL_LIGHT1 GL:GL_DIFFUSE light1_diffuse) (GL:glLightfv GL:GL_LIGHT1 GL:GL_SPECULAR light1_specular) (GL:glLightf GL:GL_LIGHT1 GL:GL_LINEAR_ATTENUATION (flt 0.2)) (GL:glLightModelfv GL:GL_LIGHT_MODEL_AMBIENT lm_ambient) (GL:glEnable GL:GL_LIGHTING) (GL:glEnable GL:GL_LIGHT0) (GL:glEnable GL:GL_LIGHT1) (GL:glDepthFunc GL:GL_LESS) (GL:glEnable GL:GL_DEPTH_TEST) (GL:glFlush) ) (define (myreshape w h) (GL:glViewport 0 0 w h) (GL:glFlush) ) #* setup display lists to change material for inner/outter rings and # to draw a single torus or cone (define (MakeDisplayLists) (constant 'cone_diffuse (pack "ffff" 0.0 0.7 0.7 1.0)) (constant 'mat1_ambient (pack "ffff" 1.0 1.0 1.0 1.0)) (constant 'mat2_ambient (pack "ffff" 0.0 0.0 0.0 0.0)) (constant 'torus1_diffuse (pack "ffff" 0.7 0.7 0.0 1.0)) (constant 'torus2_diffuse (pack "ffff" 0.3 0.0 0.0 1.0)) (constant 'mat1_specular (pack "ffff" 1.0 1.0 1.0 1.0)) (constant 'mat2_specular (pack "ffff" 0.5 0.5 0.5 1.0)) (GL:glNewList INNERMAT GL:GL_COMPILE) (GL:glMaterialfv GL:GL_FRONT GL:GL_SPECULAR mat1_specular) (GL:glMaterialf GL:GL_FRONT GL:GL_SHININESS (flt 50.0)) (GL:glMaterialfv GL:GL_FRONT GL:GL_DIFFUSE torus1_diffuse) (GL:glMaterialfv GL:GL_FRONT GL:GL_AMBIENT mat1_ambient) (GL:glEndList) (GL:glNewList OUTTERMAT GL:GL_COMPILE) (GL:glMaterialfv GL:GL_FRONT GL:GL_SPECULAR mat2_specular) (GL:glMaterialf GL:GL_FRONT GL:GL_SHININESS (flt 25.0)) (GL:glMaterialfv GL:GL_FRONT GL:GL_DIFFUSE torus2_diffuse) (GL:glMaterialfv GL:GL_FRONT GL:GL_AMBIENT mat2_ambient) (GL:glEndList) (GL:glNewList CONE GL:GL_COMPILE) (GL:glMaterialfv GL:GL_FRONT GL:GL_DIFFUSE cone_diffuse) (GL:glPushMatrix) (GL:glTranslatef (flt 0) (flt (mul -1 TransCone)) (flt 0)) (GL:glRotatef (flt 90) (flt 1) (flt 0) (flt 0)) (GLUT:glutSolidCone OutterRad 10.0 8 8) (GL:glPopMatrix) (GL:glEndList) (GL:glNewList TORUS GL:GL_COMPILE) (GL:glPushMatrix) (GL:glRotatef (flt 90.0) (flt 1) (flt 0) (flt 0)) (GLUT:glutSolidTorus InnerRad OutterRad 15 25) (GL:glPopMatrix) (GL:glEndList) ) # Draw three rings, rotated and translate so they look cool (define (DrawRings axis) (set 'x (sin axis)) (set 'y (cos axis)) (GL:glPushMatrix) (GL:glTranslatef (flt 0) (flt Trans) (flt 0)) (GL:glRotatef (flt Tilt) (flt x) (flt 0) (flt y)) (GL:glCallList TORUS) (GL:glPopMatrix) (GL:glPushMatrix) (GL:glRotatef (flt (sub 0 Tilt)) (flt x) (flt 0) (flt y)) (GL:glCallList TORUS) (GL:glPopMatrix) (GL:glPushMatrix) (GL:glTranslatef (flt 0) (flt (sub 0 Trans)) (flt 0)) (GL:glRotatef (flt Tilt) (flt x) (flt 0) (flt y)) (GL:glCallList TORUS) (GL:glPopMatrix) ) # Draw the inner thing, then glScale and draw 3 huge rings (define (mydisplay) (GL:glClear (| GL:GL_COLOR_BUFFER_BIT GL:GL_DEPTH_BUFFER_BIT)) (GL:glMatrixMode GL:GL_PROJECTION) (GL:glLoadIdentity) (GL:glFrustum -1.0 1.0 -1.0 1.0 10.0 1000.0) (GLU:gluLookAt 0.0 0.0 Dist 0.0 0.0 0.0 0.0 1.0 0.0) (GL:glMatrixMode GL:GL_MODELVIEW) (GL:glCallList INNERMAT) (DrawRings Axis) (GL:glCallList CONE) (GL:glCallList OUTTERMAT) (GL:glPushMatrix) (GL:glScalef (flt 10) (flt 10) (flt 10)) (DrawRings (div Axis 3)) (GL:glPopMatrix) (GLUT:glutSwapBuffers) (GL:glFlush) ) # rotate the axis and adjust position if nec. */ (define (myidle) (set 'Axis (add Axis AxisInc)) (if (and (< Dist 15.0) (= Fade 1)) # start slow (set 'Dist (add Dist 0.1)) (if (and (< Dist 800.0) (= Fade 1)) # don't go back too far (set 'Dist (mul Dist 1.005)) ) ) (mydisplay) (sleep 1) ) # nothing fancy (define (handlemenu value) (case value (0: # MENU_STARTOVER: (set 'Dist 10.0) # Axis = 0; Fade = 1; (set 'AxisInc (div (mul 2.0 M_PI) STEPS)) (GLUT:glutChangeToMenuEntry 3 "Stop rings" MENU_STOP_RINGS) (GLUT:glutChangeToMenuEntry 4 "Stop fade" MENU_STOP_FADE) ) (1: # MENU_ZOOM_OUT: (set 'Dist 800.0) ) (2: # MENU_STOP_RINGS: (set 'AxisInc 0.0) (GLUT:glutChangeToMenuEntry 3 "Start rings" MENU_START_RINGS) ) (4: # MENU_START_RINGS: (set 'AxisInc (div (mul 2.0 M_PI) STEPS)) (GLUT:glutChangeToMenuEntry 3 "Stop rings" MENU_STOP_RINGS) ) (3: # MENU_STOP_FADE: (set 'Fade 0) (GLUT:glutChangeToMenuEntry 4 "Start fade" MENU_START_FADE) ) (5: # MENU_START_FADE: (set 'Fade 1) (GLUT:glutChangeToMenuEntry 4 "Stop fade" MENU_STOP_FADE) ) (6: # MENU_QUIT: (exit) ) ) ) (define (MenuInit) (GLUT:glutCreateMenu 'handlemenu) (GLUT:glutAddMenuEntry "Start Over" MENU_STARTOVER) (GLUT:glutAddMenuEntry "Zoom Out" MENU_ZOOM_OUT) (GLUT:glutAddMenuEntry "Stop rings" MENU_STOP_RINGS) (GLUT:glutAddMenuEntry "Stop fade" MENU_STOP_FADE) (GLUT:glutAddMenuEntry "Quit" MENU_QUIT) (GLUT:glutAttachMenu GLUT:GLUT_RIGHT_BUTTON) ) (define (vis visible) (if (= visible GLUT:GLUT_VISIBLE) (GLUT:glutIdleFunc 'myidle) (GLUT:glutIdleFunc 'NULL) ) ) (define (main argc argv) (GLUT:glutInit (address argc) (address argv)) (GLUT:glutInitWindowSize 512 512) (GLUT:glutInitDisplayMode (| GLUT:GLUT_DOUBLE GLUT:GLUT_RGB GLUT:GLUT_DEPTH)) (GLUT:glutCreateWindow "rings") (myInit) (myglInit) (MakeDisplayLists) (MenuInit) (GLUT:glutReshapeFunc 'myreshape) (GLUT:glutDisplayFunc 'mydisplay) (GLUT:glutVisibilityFunc 'vis) (GLUT:glutMainLoop) ) (main 0 0) (exit)