1 ! (c)2009 Joe Groff bsd license
2 USING: accessors arrays combinators.tuple game.loop game.worlds
3 generalizations gpu gpu.render gpu.shaders gpu.util gpu.util.wasd
4 kernel literals math math.libm math.matrices math.order math.vectors
5 method-chains sequences ui ui.gadgets ui.gadgets.worlds
6 ui.pixel-formats audio.engine audio.loader locals ;
9 GLSL-SHADER-FILE: raytrace-vertex-shader vertex-shader "raytrace.v.glsl"
10 GLSL-SHADER-FILE: raytrace-fragment-shader fragment-shader "raytrace.f.glsl"
11 GLSL-PROGRAM: raytrace-program
12 raytrace-vertex-shader raytrace-fragment-shader
13 window-vertex-format ;
15 UNIFORM-TUPLE: sphere-uniforms
16 { "center" vec3-uniform f }
17 { "radius" float-uniform f }
18 { "color" vec4-uniform f } ;
20 UNIFORM-TUPLE: raytrace-uniforms
21 { "mv-inv-matrix" mat4-uniform f }
22 { "fov" vec2-uniform f }
24 { "spheres" sphere-uniforms 4 }
26 { "floor-height" float-uniform f }
27 { "floor-color" vec4-uniform 2 }
28 { "background-color" vec4-uniform f }
29 { "light-direction" vec3-uniform f } ;
31 CONSTANT: reflection-color { 1.0 0.0 1.0 0.0 }
39 { theta float initial: 0.0 } ;
41 TUPLE: raytrace-world < wasd-world
46 : tick-sphere ( sphere -- )
47 dup dtheta>> [ + ] curry change-theta drop ;
49 : sphere-center ( sphere -- center )
50 [ [ axis>> ] [ theta>> ] bi rotation-matrix4 ]
53 M: sphere audio-position sphere-center ; inline
54 M: sphere audio-distance radius>> fsqrt 2.0 * ; inline
56 : <sphere-uniforms> ( world -- uniforms )
57 [ wasd-mv-inv-matrix ]
61 [ [ sphere-center ] [ radius>> ] [ color>> ] tri sphere-uniforms boa ] map
64 { { 1.0 0.0 0.0 1.0 } { 1.0 1.0 1.0 1.0 } } ! floor_color
65 { 0.15 0.15 1.0 1.0 } ! background_color
66 { 0.0 -1.0 -0.1 } ! light_direction
67 raytrace-uniforms boa ;
69 CONSTANT: initial-spheres {
70 T{ sphere f { 0.0 1.0 0.0 } { 0.0 0.0 0.0 } 0.0 4.0 $ reflection-color }
71 T{ sphere f { 0.0 1.0 0.0 } { 7.0 0.0 0.0 } 0.02 1.0 { 1.0 0.0 0.0 1.0 } }
72 T{ sphere f { 0.0 0.0 -1.0 } { -9.0 0.0 0.0 } 0.03 1.0 { 0.0 1.0 0.0 1.0 } }
73 T{ sphere f { 1.0 0.0 0.0 } { 0.0 5.0 0.0 } 0.025 1.0 { 1.0 1.0 0.0 1.0 } }
76 :: set-up-audio ( world -- )
77 world audio-engine>> :> audio-engine
78 world spheres>> :> spheres
80 audio-engine world >>listener update-audio
82 audio-engine spheres first
83 "vocab:gpu/demos/raytrace/mirror-ball.aiff" read-audio t <static-audio-clip>
84 audio-engine spheres second
85 "vocab:gpu/demos/raytrace/red-ball.aiff" read-audio t <static-audio-clip>
86 audio-engine spheres third
87 "vocab:gpu/demos/raytrace/green-ball.aiff" read-audio t <static-audio-clip>
88 audio-engine spheres fourth
89 "vocab:gpu/demos/raytrace/yellow-ball.aiff" read-audio t <static-audio-clip>
93 M: raytrace-world begin-game-world
95 { -2.0 6.25 10.0 } 0.19 0.55 set-wasd-view
96 initial-spheres [ clone ] map >>spheres
97 raytrace-program <program-instance> <window-vertex-array> >>vertex-array
102 AFTER: raytrace-world resize-world
103 dup dim>> dup first2 min >float v/n fov v*n >>fov drop ;
105 AFTER: raytrace-world tick-game-world
106 spheres>> [ tick-sphere ] each ;
108 M: raytrace-world draw-world*
110 { "primitive-mode" [ drop triangle-strip-mode ] }
111 { "indexes" [ drop T{ index-range f 0 4 } ] }
112 { "uniforms" [ <sphere-uniforms> ] }
113 { "vertex-array" [ vertex-array>> ] }
114 } <render-set> render ;
116 M: raytrace-world wasd-movement-speed drop 1/4. ;
118 GAME: raytrace-game {
119 { world-class raytrace-world }
120 { title "Raytracing" }
121 { pixel-format-attributes {
126 { use-game-input? t }
127 { use-audio-engine? t }
128 { pref-dim { 1024 768 } }
129 { tick-interval-nanos $[ 60 fps ] }