#!/usr/bin/newlisp # # SimpleDraw.c # # Example program illustrating a simple use # of OpenGL to draw straight lines in 2D, and # to draw overlapping triangles in 3D. # # 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 # # Version 1.1. Updated September 28, 2003. # 1.1. 9/28/30: Added glEnable(GL_DEPTH_TEST). Thanks to Rob Wilkens. # 1.0. Original version released Spring 2003. # #------------------------------------------------------------------- # Ported to newLisp by Peter van Eerten. # # This is a 1-to-1 port of the original program. # October 17, 2005. #------------------------------------------------------------------- (load "GL.lsp" "freeglut.lsp") # These variables control the current mode (set 'CurrentMode 0) (constant 'NumModes 5) # These variables set the dimensions of the rectanglar region we wish to view. (constant 'Xmin (float 0.0)) (constant 'Xmax (float 3.0)) (constant 'Ymin (float 0.0)) (constant 'Ymax (float 3.0)) # glutKeyboardFunc is called below to set this function to handle # all "normal" ascii key presses. # Only space bar and escape key have an effect. (define (myKeyboardFunc key x y) (case key (32: # ' ' // Space bar # Increment the current mode, and tell operating system screen needs redrawing (set 'CurrentMode (% (+ CurrentMode 1) NumModes)) (GLUT:glutPostRedisplay) ) (27: # "27" is theEscape key (exit) ) ) ) # drawScene() handles the animation and the redrawing of the # graphics window contents. (define (drawScene) # Clear the rendering window (GL:glClear (| GL:GL_COLOR_BUFFER_BIT GL:GL_DEPTH_BUFFER_BIT)) # Set drawing color to white (GL:glColor3f (flt 1.0) (flt 1.0) (flt 1.0)) (case CurrentMode (0: # Draw three points (GL:glBegin GL:GL_POINTS) (GL:glVertex2f (flt 1.0) (flt 1.0)) (GL:glVertex2f (flt 2.0) (flt 1.0)) (GL:glVertex2f (flt 2.0) (flt 2.0)) (GL:glEnd) ) (4: # Overlapping triangles (GL:glBegin GL:GL_TRIANGLES) (GL:glColor3f (flt 1.0) (flt 0.0) (flt 0.0)) (GL:glVertex3f (flt 0.3) (flt 1.0) (flt 0.5)) (GL:glVertex3f (flt 2.7) (flt 0.85) (flt 0.0)) (GL:glVertex3f (flt 2.7) (flt 1.15) (flt 0.0)) (GL:glColor3f (flt 0.0) (flt 1.0) (flt 0.0)) (GL:glVertex3f (flt 2.53) (flt 0.71) (flt 0.5)) (GL:glVertex3f (flt 1.46) (flt 2.86) (flt 0.0)) (GL:glVertex3f (flt 1.2) (flt 2.71) (flt 0.0)) (GL:glColor3f (flt 0.0) (flt 0.0) (flt 1.0)) (GL:glVertex3f (flt 1.667) (flt 2.79) (flt 0.5)) (GL:glVertex3f (flt 0.337) (flt 0.786) (flt 0.0)) (GL:glVertex3f (flt 0.597) (flt 0.636) (flt 0.0)) (GL:glEnd) ) #case 1: #case 2: #case 3: (true (if (= CurrentMode 1 ) # Draw lines in GL_LINES mode (GL:glBegin GL:GL_LINES) (begin (if (= CurrentMode 2) (GL:glBegin GL:GL_LINE_STRIP) # Draw lines in GL_LINE_STRIP mode (GL:glBegin GL:GL_LINE_LOOP) # Draw lines in GL_LINE_LOOP mode ) ) ) (GL:glVertex2f (flt 0.5) (flt 1.0)) (GL:glVertex2f (flt 2.0) (flt 2.0)) (GL:glVertex2f (flt 1.8) (flt 2.6)) (GL:glVertex2f (flt 0.7) (flt 2.2)) (GL:glVertex2f (flt 1.6) (flt 1.2)) (GL:glVertex2f (flt 1.0) (flt 0.5)) (GL:glEnd) ) ) # Flush the pipeline. (Not usually necessary.) (GL:glFlush) ) # Initialize OpenGL's rendering modes (define (initRendering) (GL:glEnable GL:GL_DEPTH_TEST) # Uncomment out the first block of code below, and then the second block, # to see how they affect line and point drawing. # The following commands should cause points and line to be drawn larger # than a single pixel width. # (GL:glPointSize (flt 8)) # (GL:glLineWidth (flt 5)) # The following commands should induce OpenGL to create round points and # antialias points and lines. (This is implementation dependent unfortunately). # (GL:glEnable GL:GL_POINT_SMOOTH) # (GL:glEnable GL:GL_LINE_SMOOTH) # (GL:glHint GL:GL_POINT_SMOOTH_HINT GL:GL_NICEST) # Make round points, not square points # (GL:glHint GL:GL_LINE_SMOOTH_HINT GL:GL_NICEST) # Antialias the lines # (GL:glEnable GL:GL_BLEND) # (GL:glBlendFunc GL:GL_SRC_ALPHA GL:GL_ONE_MINUS_SRC_ALPHA) ) # Called when the window is resized # w, h - width and height of the window in pixels. (define (resizeWindow w h) # Define the portion of the window used for OpenGL rendering. (GL:glViewport 0 0 w h) # View port uses whole window # Set up the projection view matrix: orthographic projection # Determine the min and max values for x and y that should appear in the window. # The complication is that the aspect ratio of the window may not match the # aspect ratio of the scene we want to view. (if (= w 0) (set 'w 1)) (if (= h 0) (set 'h 1)) (if (< (div (sub Xmax Xmin) w) (div (sub Ymax Ymin) h) ) (begin (set 'scale (div (div (sub Ymax Ymin) h) (div (sub Xmax Xmin) w))) (set 'center (div (add Xmax Xmin) 2)) (set 'windowXmin (sub center (mul (sub center Xmin) scale))) (set 'windowXmax (add center (mul (sub Xmax center) scale))) (set 'windowYmin Ymin) (set 'windowYmax Ymax) ) (begin (set 'scale (div (div (sub Xmax Xmin) w) (div (sub Ymax Ymin) h))) (set 'center (div (add Ymax Ymin) 2)) (set 'windowYmin (sub center (mul (sub center Ymin) scale))) (set 'windowYmax (add center (mul (sub Ymax center) scale))) (set 'windowXmin Xmin) (set 'windowXmax Xmax) ) ) # Now that we know the max & min values for x & y that should be visible in the window, # we set up the orthographic projection. (GL:glMatrixMode GL:GL_PROJECTION) (GL:glLoadIdentity) (GL:glOrtho (float windowXmin) (float windowXmax) (float windowYmin) (float windowYmax) (float -1) (float 1)) ) # Main routine # Set up OpenGL, define the callbacks and start the main loop (define (main argc argv) (GLUT:glutInit (address argc) (address argv)) # The image is not animated so single buffering is OK. (GLUT:glutInitDisplayMode (| GLUT:GLUT_SINGLE GLUT:GLUT_RGB GLUT:GLUT_DEPTH)) # Window position (from top corner), and size (width and hieght) (GLUT:glutInitWindowPosition 20 60) (GLUT:glutInitWindowSize 360 360) (GLUT:glutCreateWindow "SimpleDraw - Press space bar to toggle images") # Initialize OpenGL as we like it.. (initRendering) # Set up callback functions for key presses (GLUT:glutKeyboardFunc 'myKeyboardFunc) # Handles "normal" ascii symbols # (GLUT:glutSpecialFunc 'mySpecialKeyFunc) # Handles "special" keyboard keys # Set up the callback function for resizing windows (GLUT:glutReshapeFunc 'resizeWindow) # Call this for background processing # (GLUT:glutIdleFunc 'myIdleFunction) # call this whenever window needs redrawing (GLUT:glutDisplayFunc 'drawScene) (println "Press space bar to toggle images; escape button to quit.") # Start the main loop. glutMainLoop never returns. (GLUT:glutMainLoop) ) (main 0 0) (exit)