1 ! (c)2009 Joe Groff bsd license
2 USING: accessors alien.c-types arrays classes.struct combinators
3 combinators.short-circuit game-worlds gpu gpu.buffers gpu.util.wasd
4 gpu.framebuffers gpu.render gpu.shaders gpu.state gpu.textures gpu.util
5 grouping http.client images images.loader io io.encodings.ascii io.files
6 io.files.temp kernel math math.matrices math.parser math.vectors
7 method-chains sequences specialized-arrays.float specialized-vectors.uint
8 splitting struct-vectors threads ui ui.gadgets ui.gadgets.worlds
12 GLSL-SHADER-FILE: bunny-vertex-shader vertex-shader "bunny.v.glsl"
13 GLSL-SHADER-FILE: bunny-fragment-shader fragment-shader "bunny.f.glsl"
14 GLSL-PROGRAM: bunny-program
15 bunny-vertex-shader bunny-fragment-shader ;
17 GLSL-SHADER-FILE: window-vertex-shader vertex-shader "window.v.glsl"
19 GLSL-SHADER-FILE: sobel-fragment-shader fragment-shader "sobel.f.glsl"
20 GLSL-PROGRAM: sobel-program
21 window-vertex-shader sobel-fragment-shader ;
23 GLSL-SHADER-FILE: loading-fragment-shader fragment-shader "loading.f.glsl"
24 GLSL-PROGRAM: loading-program
25 window-vertex-shader loading-fragment-shader ;
44 TUPLE: bunny-world < wasd-world
47 VERTEX-FORMAT: bunny-vertex
48 { "vertex" float-components 3 f }
49 { f float-components 1 f }
50 { "normal" float-components 3 f }
51 { f float-components 1 f } ;
52 VERTEX-STRUCT: bunny-vertex-struct bunny-vertex
54 UNIFORM-TUPLE: bunny-uniforms < mvp-uniforms
55 { "light-position" vec3-uniform f }
56 { "color" vec4-uniform f }
57 { "ambient" vec4-uniform f }
58 { "diffuse" vec4-uniform f }
59 { "shininess" float-uniform f } ;
61 UNIFORM-TUPLE: sobel-uniforms
62 { "texcoord-scale" vec2-uniform f }
63 { "color-texture" texture-uniform f }
64 { "normal-texture" texture-uniform f }
65 { "depth-texture" texture-uniform f }
66 { "line-color" vec4-uniform f } ;
68 UNIFORM-TUPLE: loading-uniforms
69 { "texcoord-scale" vec2-uniform f }
70 { "loading-texture" texture-uniform f } ;
72 : numbers ( str -- seq )
73 " " split [ string>number ] map sift ;
75 : <bunny-vertex> ( vertex -- struct )
76 bunny-vertex-struct <struct>
77 swap >float-array >>vertex ; inline
79 : (parse-bunny-model) ( vs is -- vs is )
82 { [ dup length 5 = ] [ 3 head <bunny-vertex> pick push ] }
83 { [ dup first 3 = ] [ rest over push-all ] }
85 } cond (parse-bunny-model)
88 : parse-bunny-model ( -- vertexes indexes )
89 100000 bunny-vertex-struct <struct-vector>
93 : normal ( vertexes -- normal )
94 [ [ second ] [ first ] bi v- ]
95 [ [ third ] [ first ] bi v- ] bi cross
96 vneg normalize ; inline
98 : calc-bunny-normal ( vertexes indexes -- )
100 [ [ nth vertex>> ] curry { } map-as normal ]
101 [ [ nth [ v+ ] change-normal drop ] curry with each ] 2bi ;
103 : calc-bunny-normals ( vertexes indexes -- )
105 [ calc-bunny-normal ] with each ;
107 : normalize-bunny-normals ( vertexes -- )
108 [ [ normalize ] change-normal drop ] each ;
110 : bunny-data ( filename -- vertexes indexes )
111 ascii [ parse-bunny-model ] with-file-reader
112 [ calc-bunny-normals ]
113 [ drop normalize-bunny-normals ]
116 : <bunny-buffers> ( vertexes indexes -- vertex-buffer index-buffer index-count )
117 [ underlying>> static-upload draw-usage vertex-buffer byte-array>buffer ]
119 [ underlying>> static-upload draw-usage index-buffer byte-array>buffer ]
123 : bunny-model-path ( -- path ) "bun_zipper.ply" temp-file ;
125 CONSTANT: bunny-model-url "http://factorcode.org/bun_zipper.ply"
127 : download-bunny ( -- path )
128 bunny-model-path dup exists? [
129 bunny-model-url dup print flush
133 : get-bunny-data ( bunny-state -- )
134 download-bunny bunny-data
135 [ >>vertexes ] [ >>indexes ] bi* drop ;
137 : fill-bunny-state ( bunny-state -- )
138 dup [ vertexes>> ] [ indexes>> ] bi <bunny-buffers>
139 [ bunny-program <program-instance> bunny-vertex buffer>vertex-array >>vertex-array ]
141 [ uint-indexes <index-elements> >>index-elements ] tri*
144 : <bunny-state> ( -- bunny-state )
146 dup [ get-bunny-data ] curry "Downloading bunny model" spawn drop ;
148 : bunny-loaded? ( bunny-state -- ? )
149 { [ vertexes>> ] [ indexes>> ] } 1&& ;
151 : bunny-state-filled? ( bunny-state -- ? )
152 { [ vertex-array>> ] [ index-elements>> ] } 1&& ;
154 : <sobel-state> ( window-vertex-buffer -- sobel-state )
156 swap sobel-program <program-instance> window-vertex buffer>vertex-array >>vertex-array
158 RGBA half-components T{ texture-parameters
159 { wrap clamp-texcoord-to-edge }
160 { min-filter filter-linear }
161 { min-mipmap-filter f }
162 } <texture-2d> >>color-texture
163 RGBA half-components T{ texture-parameters
164 { wrap clamp-texcoord-to-edge }
165 { min-filter filter-linear }
166 { min-mipmap-filter f }
167 } <texture-2d> >>normal-texture
168 DEPTH u-24-components T{ texture-parameters
169 { wrap clamp-texcoord-to-edge }
170 { min-filter filter-linear }
171 { min-mipmap-filter f }
172 } <texture-2d> >>depth-texture
176 [ color-texture>> 0 <texture-2d-attachment> ]
177 [ normal-texture>> 0 <texture-2d-attachment> ] bi 2array
178 ] [ depth-texture>> 0 <texture-2d-attachment> ] bi f { 1024 768 } <framebuffer> >>framebuffer ;
180 : <loading-state> ( window-vertex-buffer -- loading-state )
183 loading-program <program-instance> window-vertex buffer>vertex-array >>vertex-array
185 RGBA ubyte-components T{ texture-parameters
186 { wrap clamp-texcoord-to-edge }
187 { min-filter filter-linear }
188 { min-mipmap-filter f }
190 dup 0 "vocab:gpu/demos/bunny/loading.tiff" load-image allocate-texture-image
193 BEFORE: bunny-world begin-world
196 { -0.2 0.13 0.1 } 1.1 0.2 set-wasd-view
198 <bunny-state> >>bunny
199 <window-vertex-buffer>
200 [ <sobel-state> >>sobel ]
201 [ <loading-state> >>loading ] bi
204 : <bunny-uniforms> ( world -- uniforms )
205 [ wasd-mv-matrix ] [ wasd-p-matrix ] bi
206 { -10000.0 10000.0 10000.0 } ! light position
207 { 0.6 0.5 0.5 1.0 } ! color
208 { 0.2 0.2 0.2 0.2 } ! ambient
209 { 0.8 0.8 0.8 0.8 } ! diffuse
213 : draw-bunny ( world -- )
214 T{ depth-state { comparison cmp-less } } set-gpu-state
217 sobel>> framebuffer>> {
218 { T{ color-attachment f 0 } { 0.15 0.15 0.15 1.0 } }
219 { T{ color-attachment f 1 } { 0.0 0.0 0.0 0.0 } }
220 { depth-attachment 1.0 }
224 { "primitive-mode" [ drop triangles-mode ] }
225 { "output-attachments" [ drop { T{ color-attachment f 0 } T{ color-attachment f 1 } } ] }
226 { "uniforms" [ <bunny-uniforms> ] }
227 { "vertex-array" [ bunny>> vertex-array>> ] }
228 { "indexes" [ bunny>> index-elements>> ] }
229 { "framebuffer" [ sobel>> framebuffer>> ] }
230 } <render-set> render
233 : <sobel-uniforms> ( sobel -- uniforms )
235 [ color-texture>> ] [ normal-texture>> ] [ depth-texture>> ] tri
236 { 0.1 0.0 0.1 1.0 } ! line_color
239 : draw-sobel ( world -- )
240 T{ depth-state { comparison f } } set-gpu-state
243 { "primitive-mode" [ drop triangle-strip-mode ] }
244 { "indexes" [ drop T{ index-range f 0 4 } ] }
245 { "uniforms" [ <sobel-uniforms> ] }
246 { "vertex-array" [ vertex-array>> ] }
247 } <render-set> render ;
249 : draw-sobeled-bunny ( world -- )
250 [ draw-bunny ] [ draw-sobel ] bi ;
252 : draw-loading ( world -- )
253 T{ depth-state { comparison f } } set-gpu-state
256 { "primitive-mode" [ drop triangle-strip-mode ] }
257 { "indexes" [ drop T{ index-range f 0 4 } ] }
258 { "uniforms" [ { 1.0 -1.0 } swap texture>> loading-uniforms boa ] }
259 { "vertex-array" [ vertex-array>> ] }
260 } <render-set> render ;
262 M: bunny-world draw-world*
265 dup bunny-state-filled? [ drop ] [ fill-bunny-state ] if
267 ] [ drop draw-loading ] if ;
269 AFTER: bunny-world resize-world
270 [ sobel>> framebuffer>> ] [ dim>> ] bi resize-framebuffer ;
272 M: bunny-world pref-dim* drop { 1024 768 } ;
273 M: bunny-world tick-length drop 1000 30 /i ;
274 M: bunny-world wasd-movement-speed drop 1/160. ;
275 M: bunny-world wasd-near-plane drop 1/32. ;
276 M: bunny-world wasd-far-plane drop 256.0 ;
278 : bunny-window ( -- )
280 f T{ world-attributes
281 { world-class bunny-world }
283 { pixel-format-attributes {
286 T{ depth-bits { value 24 } }