]> gitweb.factorcode.org Git - factor.git/blob - extra/fluids/fluids.factor
Merge branch 'master' of git://github.com/slavapestov/factor into techniques
[factor.git] / extra / fluids / fluids.factor
1 ! Copyright (C) 2010 Erik Charlebois.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays classes.struct destructors game.loop
4 game.worlds gpu gpu.buffers gpu.framebuffers gpu.render gpu.shaders
5 gpu.state gpu.textures gpu.util images images.loader kernel literals
6 locals make math math.rectangles math.vectors namespaces opengl.gl
7 sequences specialized-arrays ui.gadgets.worlds images.ppm
8 ui.gestures ui.pixel-formats images.pgm gpu.effects.blur ;
9 FROM: alien.c-types => float ;
10 SPECIALIZED-ARRAY: float
11 IN: fluids
12
13 STRUCT: float2_t
14     { x float }
15     { y float } ;
16
17 : f2+ ( lhs rhs -- res )
18     [ [ x>> ] bi@ + ]
19     [ [ y>> ] bi@ + ]
20     2bi float2_t <struct-boa> ; inline
21
22 : f2- ( lhs rhs -- res )
23     [ [ x>> ] bi@ - ]
24     [ [ y>> ] bi@ - ]
25     2bi float2_t <struct-boa> ; inline
26
27 : f2*n ( lhs rhs -- res ) 
28     [ [ x>> ] dip * ]
29     [ [ y>> ] dip * ]
30     2bi float2_t <struct-boa> ; inline
31
32 STRUCT: particle_t
33     { p  float2_t }
34     { p' float2_t }
35     { m  float    } ;
36 SPECIALIZED-ARRAY: particle_t
37
38 CONSTANT: gravity S{ float2_t f 0.0 -0.1 }
39
40 :: verlet-integrate-particle ( p dt -- p' )
41     p p>> 2.0 f2*n :> v1
42     p p'>> :> v2
43     gravity dt dt * 1.0 p m>> 2.0 * / * f2*n :> v3
44     v1 v2 f2- v3 f2+
45     p p m>> particle_t <struct-boa> ; inline
46
47 CONSTANT: initial-particles
48 particle_t-array{
49     S{ particle_t f S{ float2_t f 0.5 0.6 } S{ float2_t f 0.499 0.599 } 1.0 }
50     S{ particle_t f S{ float2_t f 0.5 0.6 } S{ float2_t f 0.501 0.599 } 3.0 }
51     
52     S{ particle_t f S{ float2_t f 0.5 0.5 } S{ float2_t f 0.5 0.5 } 2.0 }
53     S{ particle_t f S{ float2_t f 0.5 0.6 } S{ float2_t f 0.5 0.599 } 1.0 }
54     S{ particle_t f S{ float2_t f 0.6 0.5 } S{ float2_t f 0.6 0.5 } 3.0 }
55     S{ particle_t f S{ float2_t f 0.7 0.5 } S{ float2_t f 0.7 0.5 } 1.0 }
56     S{ particle_t f S{ float2_t f 0.1 0.5 } S{ float2_t f 0.1 0.5 } 5.0 }
57     S{ particle_t f S{ float2_t f 0.2 0.5 } S{ float2_t f 0.2 0.5 } 1.0 }
58     S{ particle_t f S{ float2_t f 0.3 0.3 } S{ float2_t f 0.3 0.3 } 4.0 }
59     S{ particle_t f S{ float2_t f 0.5 0.15 } S{ float2_t f 0.5 0.15 } 1.0 }
60     S{ particle_t f S{ float2_t f 0.5 0.1 } S{ float2_t f 0.5 0.1 } 9.0 }
61 }
62
63 : integrate-particles! ( particles dt -- particles )
64     [ verlet-integrate-particle ] curry map! ;
65
66 TUPLE: fluids-world < game-world
67     particles texture framebuffer color-texture ramp { paused boolean initial: f } ;
68
69 : make-texture ( pathname -- texture )
70     load-image
71     [
72         [ component-order>> ]
73         [ component-type>> ] bi
74         T{ texture-parameters
75            { wrap clamp-texcoord-to-edge }
76            { min-filter filter-nearest }
77            { mag-filter filter-nearest }
78            { min-mipmap-filter f } }
79         <texture-2d>
80     ]
81     [
82         0 swap [ allocate-texture-image ] 3keep 2drop
83     ] bi ;
84
85 SYMBOL: fluid
86
87 : integrate ( world -- )
88     particles>> $[ 60 fps 1000000 /f ] integrate-particles! drop ;
89
90 : pause ( -- )
91     fluid get [ not ] change-paused drop ;
92
93 : step ( -- )
94     fluid get paused>> [ fluid get integrate ] when ;
95
96 M: fluids-world begin-game-world
97     dup fluid set
98     init-gpu
99     initial-particles clone >>particles
100     "C:/Users/erikc/Pictures/particle2.pgm" make-texture >>texture
101     "C:/Users/erikc/Pictures/colors.ppm" make-texture >>ramp
102
103     RGB float-components T{ texture-parameters
104                            { wrap clamp-texcoord-to-edge }
105                            { min-filter filter-linear }
106                            { min-mipmap-filter f }
107     } <texture-2d> >>color-texture
108
109     dup color-texture>> 0 <texture-2d-attachment> 1array f f { 320 240 } <framebuffer> >>framebuffer
110     drop ;
111
112 M: fluids-world end-game-world
113     framebuffer>> dispose ;
114
115 M: fluids-world tick-game-world
116     dup paused>> [ drop ] [ integrate ] if ;
117
118 M:: fluids-world draw-world* ( world -- )
119     world framebuffer>> { { default-attachment { 0 0 0 } } } clear-framebuffer
120     system-framebuffer { { default-attachment { 0 0 0 } } } clear-framebuffer
121
122     f eq-add func-one func-one <blend-mode> dup <blend-state> set-gpu-state
123     f origin-upper-left 1.0 <point-state> set-gpu-state
124     world particles>> [
125         [ p>> [ x>> , ] [ y>> , ] bi ] each
126     ] curry float-array{ } make :> verts
127     
128     { 0 0 } { 320 240 } <rect> <viewport-state> set-gpu-state
129     GL_POINT_SPRITE glEnable
130     world verts {
131         { "primitive-mode" [ 2drop points-mode ] }
132         { "uniforms"       [ drop texture>> 50.0 window-point-uniforms boa ] }
133         { "vertex-array"   [ nip stream-upload draw-usage vertex-buffer byte-array>buffer &dispose window-point-program <program-instance> &dispose <vertex-array> &dispose ] }
134         { "indexes"        [ nip length 2 / 0 swap <index-range> ] }
135         { "framebuffer"    [ drop framebuffer>> ] }
136     } 2<render-set> render
137     
138     world color-texture>> gaussian-blur
139     { 0 0 } { 640 480 } <rect> <viewport-state> set-gpu-state
140     world ramp>> {
141         { "primitive-mode" [ 2drop triangle-strip-mode ] }
142         { "uniforms"       [ step-uniforms boa ] }
143         { "vertex-array"   [ 2drop <window-vertex-buffer> step-program <program-instance> <vertex-array> ] }
144         { "indexes"        [ 2drop T{ index-range f 0 4 } ] }
145     } 2<render-set> render
146     ;
147
148 GAME: fluids {
149     { world-class fluids-world }
150     { title "Fluids Test" }
151     { pixel-format-attributes {
152         windowed double-buffered T{ depth-bits { value 24 } } } }
153     { pref-dim { 640 480 } }
154     { tick-interval-micros $[ 60 fps ] }
155 } ;
156
157 MAIN: fluids
158
159 fluids-world H{
160     { T{ button-down } [ [
161         hand-loc get { 640 480 } v/ 2 v*n 1 v-n { 1 -1 } v* first2 float2_t <struct-boa>
162         dup 2.0 particle_t <struct-boa> suffix
163     ] change-particles drop ] }
164 } set-gestures