]> gitweb.factorcode.org Git - factor.git/blob - extra/gpu/demos/raytrace/raytrace.factor
Fixes #2966
[factor.git] / extra / gpu / demos / raytrace / raytrace.factor
1 ! Copyright (C) 2009 Joe Groff.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays audio.engine audio.loader game.loop
4 game.worlds gpu gpu.render gpu.shaders gpu.util gpu.util.wasd
5 kernel literals math math.libm math.matrices
6 math.matrices.extras math.order math.vectors method-chains
7 sequences ui.gadgets.worlds ui.pixel-formats ;
8 IN: gpu.demos.raytrace
9
10 GLSL-SHADER-FILE: raytrace-vertex-shader vertex-shader "raytrace.v.glsl"
11 GLSL-SHADER-FILE: raytrace-fragment-shader fragment-shader "raytrace.f.glsl"
12 GLSL-PROGRAM: raytrace-program
13     raytrace-vertex-shader raytrace-fragment-shader
14     window-vertex-format ;
15
16 UNIFORM-TUPLE: sphere-uniforms
17     { "center" vec3-uniform  f }
18     { "radius" float-uniform f }
19     { "color"  vec4-uniform  f } ;
20
21 UNIFORM-TUPLE: raytrace-uniforms
22     { "mv-inv-matrix"    mat4-uniform f }
23     { "fov"              vec2-uniform f }
24
25     { "spheres"          sphere-uniforms 4 }
26
27     { "floor-height"     float-uniform f }
28     { "floor-color"      vec4-uniform 2 }
29     { "background-color" vec4-uniform f }
30     { "light-direction"  vec3-uniform f } ;
31
32 CONSTANT: reflection-color { 1.0 0.0 1.0 0.0 }
33
34 TUPLE: sphere
35     { axis array }
36     { home array }
37     { dtheta float }
38     { radius float }
39     { color array }
40     { theta float initial: 0.0 } ;
41
42 TUPLE: raytrace-world < wasd-world
43     fov
44     spheres
45     vertex-array ;
46
47 : tick-sphere ( sphere -- )
48     dup dtheta>> [ + ] curry change-theta drop ;
49
50 : sphere-center ( sphere -- center )
51     [ [ axis>> ] [ theta>> ] bi <rotation-matrix4> ]
52     [ home>> ] bi mdotv ;
53
54 M: sphere audio-position sphere-center ; inline
55 M: sphere audio-distance radius>> fsqrt 2.0 * ; inline
56
57 : <sphere-uniforms> ( world -- uniforms )
58     [ wasd-mv-inv-matrix ]
59     [ fov>> ]
60     [
61         spheres>>
62         [ [ sphere-center ] [ radius>> ] [ color>> ] tri sphere-uniforms boa ] map
63     ] tri
64     -30.0 ! floor_height
65     { { 1.0 0.0 0.0 1.0 } { 1.0 1.0 1.0 1.0 } } ! floor_color
66     { 0.15 0.15 1.0 1.0 } ! background_color
67     { 0.0 -1.0 -0.1 } ! light_direction
68     raytrace-uniforms boa ;
69
70 CONSTANT: initial-spheres {
71     T{ sphere f { 0.0 1.0  0.0 } {  0.0 0.0 0.0 } 0.0   4.0 $ reflection-color  }
72     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 } }
73     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 } }
74     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 } }
75 }
76
77 :: set-up-audio ( world -- )
78     world audio-engine>> :> audio-engine
79     world spheres>> :> spheres
80
81     audio-engine world >>listener update-audio
82
83     audio-engine spheres first
84     "vocab:gpu/demos/raytrace/mirror-ball.aiff" read-audio t <static-audio-clip>
85     audio-engine spheres second
86     "vocab:gpu/demos/raytrace/red-ball.aiff" read-audio t <static-audio-clip>
87     audio-engine spheres third
88     "vocab:gpu/demos/raytrace/green-ball.aiff" read-audio t <static-audio-clip>
89     audio-engine spheres fourth
90     "vocab:gpu/demos/raytrace/yellow-ball.aiff" read-audio t <static-audio-clip>
91
92     4array play-clips ;
93
94 M: raytrace-world begin-game-world
95     init-gpu
96     { -2.0 6.25 10.0 } 0.19 0.55 set-wasd-view
97     initial-spheres [ clone ] map >>spheres
98     raytrace-program <program-instance> <window-vertex-array> >>vertex-array
99     set-up-audio ;
100
101 CONSTANT: fov 0.7
102
103 AFTER: raytrace-world resize-world
104     dup dim>> dup first2 min >float v/n fov v*n >>fov drop ;
105
106 AFTER: raytrace-world tick-game-world
107     spheres>> [ tick-sphere ] each ;
108
109 M: raytrace-world draw-world*
110     {
111         { "primitive-mode" [ drop triangle-strip-mode    ] }
112         { "indexes"        [ drop T{ index-range f 0 4 } ] }
113         { "uniforms"       [ <sphere-uniforms>           ] }
114         { "vertex-array"   [ vertex-array>>              ] }
115     } <render-set> render ;
116
117 M: raytrace-world wasd-movement-speed drop 1/4. ;
118
119 GAME: raytrace-game {
120         { world-class raytrace-world }
121         { title "Raytracing" }
122         { pixel-format-attributes {
123             windowed
124             double-buffered
125         } }
126         { grab-input? t }
127         { use-game-input? t }
128         { use-audio-engine? t }
129         { pref-dim { 1024 768 } }
130         { tick-interval-nanos $[ 60 fps ] }
131     } ;