#lang scheme ;;; Qv http://www.opengl.org/resources/code/samples/glut_examples/examples/molehill.c (require "glplus.ss" sgl sgl/gl-vectors) (require mred) (define my-canvas% (class* canvas% () (inherit with-gl-context swap-gl-buffers) (define/override on-paint (lambda () (with-gl-context (lambda () (display) (swap-gl-buffers))) )) (define/override on-size (lambda (w h) (with-gl-context (lambda () (create-view w h))))) (super-instantiate () (style '(gl no-autoclear))))) (define (create-view w h) (gl-viewport 0 0 w h) (gl-matrix-mode 'projection) (gl-load-identity) (gl-perspective 55 1 2 24) (gl-matrix-mode 'modelview) (gl-load-identity) ;; Move away from image and rotate in x-direction to give nice view. (gl-translate 0 0 -15) (gl-rotate 330 1 0 0) ) (define (display) (unless pts1 (create-surfaces) (render-surfaces)) (gl-clear-color 0.2 0 0.4 1) (gl-clear 'color-buffer-bit 'depth-buffer-bit) (gl-call-list 1)) (define (initialize) (gl-material-v 'front 'specular mat-specular) (gl-material-v 'front 'shininess mat-shininess) (gl-enable 'lighting) (gl-enable 'light0) (gl-enable 'depth-test) (gl-enable 'auto-normal) (gl-enable 'normalize) (set! nurb (gluNewNurbsRenderer)) (gluNurbsProperty nurb GLU_SAMPLING_TOLERANCE 25.0) (gluNurbsProperty nurb GLU_DISPLAY_MODE GLU_FILL) ) (define (render-surfaces) (define (render-surface mat surf) (gl-material-v 'front 'diffuse mat) (gluBeginSurface nurb) (gluNurbsSurface nurb 8 knots 8 knots (* 4 3) 3 surf 4 4 GL_MAP2_VERTEX_3) (gluEndSurface nurb)) (gl-new-list 1 'compile) ;; Render red hill. (render-surface mat-red-diffuse pts1) ;; Render green hill. (render-surface mat-green-diffuse pts2) ;; Render blue hill. (render-surface mat-blue-diffuse pts3) ;; Render yellow hill. (render-surface mat-yellow-diffuse pts4) (gl-end-list) ) (define (create-surfaces) (define (aset a r c coord v) (gl-vector-set! a (+ coord (* c 3) (* r 3 4)) v)) ;; Build control points for NURBS mole hills (set! pts1 (make-gl-float-vector (* 4 4 3))) (set! pts2 (make-gl-float-vector (* 4 4 3))) (set! pts3 (make-gl-float-vector (* 4 4 3))) (set! pts4 (make-gl-float-vector (* 4 4 3))) (do ((u 0 (+ u 1))) ((= u 4)) (do ((v 0 (+ v 1))) ((= v 4)) ;; Red. (aset pts1 u v 0 (* 2 u)) (aset pts1 u v 1 (* 2 v)) (aset pts1 u v 2 (if (and (or (= u 1) (= u 2)) (or (= v 1) (= v 2))) ;; Stretch up middle. 6 0)) ;; Green. (aset pts2 u v 0 (* 2 (- u 3))) (aset pts2 u v 1 (* 2 (- v 3))) (aset pts2 u v 2 (if (and (or (= u 1) (= u 2)) (or (= v 1) (= v 2))) (if (and (= u 1) (= v 1)) ;; Pull hard on single middle square. 15 ;; Push down on other middle squares. -2) 0)) ;; Blue. (aset pts3 u v 0 (* 2 (- u 3))) (aset pts3 u v 1 (* 2 v)) (aset pts3 u v 2 (if (and (or (= u 1) (= u 2)) (or (= v 1) (= v 2))) (if (and (= u 1) (= v 2)) ;; Pull up on single middle square. 11 ;; Push up slightly on other middle squares. 2) 0)) ;; Yellow (aset pts4 u v 0 (* 2 u)) (aset pts4 u v 1 (* 2 (- v 3))) (aset pts4 u v 2 (if (and (or (= u 1) (= u 2) (= u 3)) (or (= v 1) (= v 2))) (if (= v 1) ;; Push down front middle and right squares. -1 ;; Pull up back middle and right squares. 5) 0)) )) ;; Stretch up red's far right corner. (aset pts1 3 3 2 6) ;; Pull down green's near left corner a little. (aset pts2 0 0 2 -2) ;; Turn up meeting of four corners. (aset pts1 0 0 2 1) (aset pts2 3 3 2 1) (aset pts3 3 0 2 1) (aset pts4 0 3 2 1) ) (define nurb #f) (define pts1 #f) (define pts2 #f) (define pts3 #f) (define pts4 #f) (define mat-red-diffuse (gl-float-vector 0.7 0 0.1 1)) (define mat-green-diffuse (gl-float-vector 0 0.7 0.1 1)) (define mat-blue-diffuse (gl-float-vector 0 0.1 0.7 1)) (define mat-yellow-diffuse (gl-float-vector 0.7 0.8 0.1 1)) (define mat-specular (gl-float-vector 1 1 1 1)) (define mat-shininess (gl-float-vector 100)) (define knots (gl-float-vector 0 0 0 0 1 1 1 1)) (define f (instantiate frame% ("molehill") (width 300) (height 300))) (define a-canvas (instantiate my-canvas% (f) )) (send f show #t) (send a-canvas with-gl-context initialize)