/examples/perlin-noise/ui/source.scm

http://github.com/dharmatech/abstracting · Scheme · 356 lines · 230 code · 72 blank · 54 comment · 0 complexity · b2b3cb3d2c09c7ef00919523648c080b MD5 · raw file

  1. ;; Perlin noise calculations GUI
  2. ;;
  3. ;; by David St-Hilaire
  4. ;; comp-521: assignement 2, winter 2008
  5. ;;
  6. ;;
  7. ;; This is a opengl/glut gui implementation and demonstration of the
  8. ;; implemented perlin noise library. It has several features, notably,
  9. ;; animation (double buffering) and 3 display modes (grayscale, cloud and
  10. ;; terrain).
  11. ;; Ported to Abstracting by Ed Cavazos
  12. ;;;;;;;;;;;;;;;;;;;;;;; Global state variables ;;;;;;;;;;;;;;;;;;;;;;;
  13. (define image-height #f)
  14. (define image-width #f)
  15. (define octaves 1)
  16. (define x-offset 0)
  17. (define y-offset 0)
  18. (define image-modified #f)
  19. (define animation-activated #f)
  20. (define animation-velocity 1)
  21. (define status-message #f)
  22. (define interpolation-fun #f)
  23. (define display-mode #f)
  24. ;;;;;;;;;;;;;;;;;;;;;;; State modification functions ;;;;;;;;;;;;;;;;;;;;;;;
  25. (define (move-image! delta-x delta-y)
  26. (let ((new-x (+ x-offset delta-x))
  27. (new-y (+ y-offset delta-y)))
  28. (if (and (>= new-x 0) (>= new-y 0))
  29. (begin
  30. (set! x-offset new-x)
  31. (set! y-offset new-y)
  32. (set! image-modified #t)))))
  33. (define (set-octave! number)
  34. (set! octaves number)
  35. (set! status-message (string-append "Now using "
  36. (number->string number)
  37. " octaves."))
  38. (set! image-modified #t))
  39. (define (switch-octave!)
  40. (set-octave! (modulo (+ octaves 1) 10)))
  41. (define (set-display-mode! mode-fun)
  42. (set! display-mode mode-fun)
  43. (set! image-modified #t))
  44. (define (switch-animation-mode!)
  45. (set! animation-activated (not animation-activated))
  46. (set! status-message (if animation-activated
  47. "Animation turned on."
  48. "Animation turned off.")))
  49. (define switch-interpolation-fun!
  50. (let* ((index 2)
  51. (functions (vector (cons "s-curve" s-curve-interpolation)
  52. (cons "linear" linear-interpolation)
  53. (cons "cosine" cos-interpolation)))
  54. (length (vector-length functions)))
  55. (lambda ()
  56. (set! index (modulo (+ index 1) length))
  57. (set! interpolation-fun (cdr (vector-ref functions index)))
  58. (set! status-message (string-append "Now using "
  59. (car (vector-ref functions index))
  60. " interpolation."))
  61. (set! image-modified #t))))
  62. ;;;;;;;;;;;;;;;;;;;;;;; Menu functionnalities ;;;;;;;;;;;;;;;;;;;;;;;
  63. (define gray-scale-mode 3)
  64. (define cloud-mode 0)
  65. (define terrain-mode 1)
  66. (define animation-mode 2)
  67. (define interpolation-mode 4)
  68. (define octaves-mode 5)
  69. (define (menu value)
  70. (cond
  71. ((eqv? value gray-scale-mode) (set-display-mode! grayscalify))
  72. ((eqv? value cloud-mode) (set-display-mode! cloudify))
  73. ((eqv? value terrain-mode) (set-display-mode! terrainify))
  74. ((eqv? value interpolation-mode)(switch-interpolation-fun!))
  75. ((eqv? value animation-mode) (switch-animation-mode!))
  76. ((eqv? value octaves-mode) (switch-octave!))))
  77. (define (create-menu)
  78. (glutCreateMenu menu)
  79. (glutAddMenuEntry "Gray Scale Mode" gray-scale-mode)
  80. (glutAddMenuEntry "Cloud Mode" cloud-mode)
  81. (glutAddMenuEntry "Terrain Mode" terrain-mode)
  82. (glutAddMenuEntry "Toggle Animation" animation-mode)
  83. (glutAddMenuEntry "Toggle Interpolation" interpolation-mode)
  84. (glutAddMenuEntry "Toggle Octaves Number" octaves-mode)
  85. (glutAttachMenu GLUT_RIGHT_BUTTON))
  86. ;;;;;;;;;;;;;;;;;;;;;;; Display Modes ;;;;;;;;;;;;;;;;;;;;;;;
  87. (define (grayscalify noise)
  88. (glColor3f noise noise noise))
  89. (define (cloudify noise)
  90. (let ((noise (+ .3 (* .7 noise))))
  91. (glColor3f noise noise 1.)))
  92. (define (terrainify noise)
  93. (define water-threshold 0.5)
  94. (define beach-threshold 0.54)
  95. (define plain-threshold 0.70)
  96. (define forest-threshold 0.77)
  97. (define mountain-threshold 0.92)
  98. (cond
  99. ;; Water
  100. ((< noise water-threshold)
  101. (let ((noise (+ noise 0.4)))
  102. (glColor3f .2 .2 noise)))
  103. ;; Beaches
  104. ((< noise beach-threshold)
  105. (glColor3f 1. 1. noise))
  106. ;; Plains / Green Terrain
  107. ((< noise plain-threshold)
  108. (let ((noise (- 1 (/ (- noise beach-threshold)
  109. (- forest-threshold beach-threshold)))))
  110. (glColor3f .3 noise .3)))
  111. ;; Forests
  112. ((< noise forest-threshold)
  113. (let ((noise (- 1 noise)))
  114. (glColor3f .2 noise .2)))
  115. ;; Light Mountains
  116. ((< noise mountain-threshold)
  117. (let ((noise (/ (- noise 0.4) 0.7)))
  118. (glColor3f noise (/ noise 3.) (/ noise 4.))))
  119. ;; Snow
  120. (else
  121. (let ((noise (/ (- noise 0.1) 0.9)))
  122. (glColor3f noise noise noise)))))
  123. ;;;;;;;;;;;;;;;;;;;;;;; Render-Sceneing function ;;;;;;;;;;;;;;;;;;;;;;;
  124. ;; (define (display-message x y msg)
  125. ;; (let ((chars (map char->integer (string->list msg)))
  126. ;; (font GLUT_BITMAP_HELVETICA_12))
  127. ;; (glColor3f 1. 1. 1.)
  128. ;; (glRasterPos2i x y)
  129. ;; (for-each (lambda (char) (glutBitmapCharacter font char))
  130. ;; chars)))
  131. (define (display-message x y msg)
  132. (print msg "\n"))
  133. (define (render-scene)
  134. (glClearColor 0. 0. 0. 0.)
  135. (glClear GL_COLOR_BUFFER_BIT)
  136. (glColor3f 0.0 1.0 0.0)
  137. (print "Rendering...")
  138. (for i 0 (< i image-height)
  139. (for j 0 (< j image-width)
  140. (begin
  141. (let ((noise (cached-perlin-noise (+ j x-offset)
  142. (+ i y-offset)
  143. octaves
  144. image-height image-width
  145. interpolation-fun)))
  146. (display-mode noise)
  147. (glBegin GL_POINTS)
  148. (glVertex2i j i)
  149. (glEnd)))
  150. (lambda () 'ok))
  151. (lambda () 'ok))
  152. (print "done\n")
  153. (if status-message
  154. (display-message 0 0 status-message))
  155. (glutSwapBuffers))
  156. ;;;;;;;;;;;;;;;;;;;;;;; Viewport and projection ;;;;;;;;;;;;;;;;;;;;;;;
  157. (define (reshape w h)
  158. (let ((zoom-x (/ w image-width))
  159. (zoom-y (/ h image-height)))
  160. (glPointSize (exact->inexact (+ (max zoom-x zoom-y) 1)))
  161. (glViewport 0 0 w h)
  162. (glMatrixMode GL_PROJECTION)
  163. (glLoadIdentity)
  164. (glOrtho 0. ;;left clip
  165. (exact->inexact (/ w zoom-x)) ;;right clip
  166. 0. ;;bottom clip
  167. (exact->inexact (/ h zoom-y)) ;;top
  168. -10.0 10.0)
  169. (glMatrixMode GL_MODELVIEW)
  170. (glLoadIdentity)))
  171. ;;;;;;;;;;;;;;;;;;;;;;; User I/O ;;;;;;;;;;;;;;;;;;;;;;;
  172. (define (keyboard key x y)
  173. (let ((key (if (integer? key)
  174. (integer->char key)
  175. key)))
  176. (case key
  177. ((#\0) (set-octave! 0))
  178. ((#\1) (set-octave! 1))
  179. ((#\2) (set-octave! 2))
  180. ((#\3) (set-octave! 3))
  181. ((#\4) (set-octave! 4))
  182. ((#\5) (set-octave! 5))
  183. ((#\6) (set-octave! 6))
  184. ((#\7) (set-octave! 7))
  185. ((#\8) (set-octave! 8))
  186. ((#\9) (set-octave! 9))
  187. ;; On Escape, Ctl-q, q -> terminate the program
  188. ((#\x1b #\x11 #\q) (quit))
  189. (else (print `(received keyboard input ,key ,x ,y))))))
  190. (define (special-keyboard key x y)
  191. (let ((key (if (integer? key)
  192. (integer->char key)
  193. key)))
  194. (case key
  195. ((#\e) (move-image! 0 animation-velocity))
  196. ((#\g) (move-image! 0 (- animation-velocity)))
  197. ((#\f) (move-image! animation-velocity 0))
  198. ((#\d) (move-image! (- animation-velocity) 0))
  199. (else (print `(received special keyboard input ,key ,x ,y))))))
  200. ;;;;;;;;;;;;;;;;;;;;;;; Idle function (animation) ;;;;;;;;;;;;;;;;;;;;;;;
  201. (define (idle-callback)
  202. ;; (thread-sleep! 0.05)
  203. (if animation-activated
  204. (move-image! animation-velocity animation-velocity))
  205. (if (or image-modified animation-activated)
  206. (begin
  207. (set! image-modified #f)
  208. (render-scene))))
  209. ;;;;;;;;;;;;;;;;;;;;;;; Gui Initialization ;;;;;;;;;;;;;;;;;;;;;;;
  210. (define (glut-init height width)
  211. (set! image-height height)
  212. (set! image-width width)
  213. ;; (glutInit (vector) (vector))
  214. (glutInit (vector 0) (vector ""))
  215. (glutInitDisplayMode (bitwise-ior GLUT_DOUBLE GLUT_RGB))
  216. (glutInitWindowSize image-width image-height)
  217. (glutCreateWindow "Question 2: Perlin Noise")
  218. (glPointSize 1.)
  219. (glDisable GL_POINT_SMOOTH)
  220. (create-menu)
  221. (set! octaves 5)
  222. (set! display-mode grayscalify)
  223. (switch-interpolation-fun!)
  224. (set! animation-velocity (inexact->exact
  225. (ceiling (/ (max image-width image-height)
  226. 100))))
  227. (glutReshapeFunc reshape)
  228. (glutKeyboardFunc keyboard)
  229. (glutSpecialFunc special-keyboard)
  230. (glutIdleFunc idle-callback)
  231. (glutDisplayFunc render-scene))
  232. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  233. (define usage-message
  234. (string-append "Usage:\n"
  235. "question2 [image height (default: 200)] "
  236. "[image width (default: 200)]\n\n"))
  237. (define (display-instructions)
  238. (for-each (lambda (x) (display x))
  239. (list
  240. "\n"
  241. " ----- Comp521 - Assignement 2 - Question2: ----\n"
  242. " Perlin noise implementation\n"
  243. " by\n"
  244. " David St-Hilaire\n\n"
  245. usage-message
  246. "Instructions:\n"
  247. " Please use the context menu by pressing the right mouse \n"
  248. " button to get all available options. Also some keyboard \n"
  249. " shortcuts are available:\n"
  250. " 0-9 digits: Use N perlin noise octaves summation.\n"
  251. " arrows: Pan into the generated landscape.\n"
  252. " q, escape: Quit.\n\n"
  253. "Please Note:\n"
  254. " -The image can be resized/zoomed by expanding the window.\n"
  255. " -Slightly better performances can be achived by running\n"
  256. " the program with: ./question2 -:m10000 [heigth] [width].\n\n"
  257. "Please enjoy! ^_^Y\n")))
  258. (define return #f)
  259. (define (quit) (return 0))
  260. ;; (define (main)
  261. ;; (define (start heigth width)
  262. ;; (glut-init heigth width)
  263. ;; (display-instructions)
  264. ;; (call/cc (lambda (k) (set! return k) (glutMainLoop))))
  265. ;; ;; Start a debug/developpement repl in a seperate thread
  266. ;; ;; (thread-start! (make-thread (lambda () (##repl))))
  267. ;; (cond
  268. ;; ((eqv? (length (command-line)) 1) (start 200 200))
  269. ;; ((eqv? (length (command-line)) 3)
  270. ;; (start (string->number (list-ref (command-line) 1))
  271. ;; (string->number (list-ref (command-line) 2))))
  272. ;; (else
  273. ;; (display usage-message))))
  274. ;; (main)
  275. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  276. (define (start heigth width)
  277. (random-source-randomize! default-random-source)
  278. (glut-init heigth width)
  279. (display-instructions)
  280. ;; (call/cc (lambda (k) (set! return k) (glutMainLoop)))
  281. (glutMainLoop)
  282. )
  283. (switch-animation-mode!)
  284. (start 200 200)