]> gitweb.factorcode.org Git - factor.git/blob - extra/model-viewer/model-viewer.factor
Merge branch 'master' of git://github.com/slavapestov/factor
[factor.git] / extra / model-viewer / model-viewer.factor
1 ! Copyright (C) 2010 Erik Charlebois
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien.c-types arrays classes.struct combinators
4 combinators.short-circuit game.loop game.worlds gpu gpu.buffers
5 gpu.util.wasd gpu.framebuffers gpu.render gpu.shaders gpu.state
6 gpu.textures gpu.util grouping http.client images images.loader
7 io io.encodings.ascii io.files io.files.temp kernel locals math
8 math.matrices math.vectors.simd math.parser math.vectors
9 method-chains namespaces sequences splitting threads ui ui.gadgets
10 ui.gadgets.worlds ui.pixel-formats specialized-arrays
11 specialized-vectors literals fry xml
12 xml.traversal sequences.deep destructors math.bitwise opengl.gl
13 game.models.obj game.models.loader game.models.collada ;
14 FROM: alien.c-types => float ;
15 SPECIALIZED-ARRAY: float
16 SPECIALIZED-VECTOR: uint
17 IN: model-viewer
18
19 GLSL-SHADER: model-vertex-shader vertex-shader
20 uniform mat4 mv_matrix, p_matrix;
21 uniform vec3 light_position;
22
23 attribute vec3 POSITION;
24 attribute vec3 NORMAL;
25 attribute vec2 TEXCOORD;
26
27 varying vec2 texit;
28 varying vec3 norm;
29
30 void main()
31 {
32     vec4 position = mv_matrix * vec4(POSITION, 1.0);
33     gl_Position = p_matrix * position;
34     texit = TEXCOORD;
35     norm = NORMAL;
36 }
37 ;
38
39 GLSL-SHADER: model-fragment-shader fragment-shader
40 varying vec2 texit;
41 varying vec3 norm;
42 void main()
43 {
44     gl_FragColor = vec4(texit, 0, 1) + vec4(norm, 1);
45 }
46 ;
47
48 GLSL-PROGRAM: model-program
49     model-vertex-shader model-fragment-shader ;
50
51 GLSL-SHADER: debug-vertex-shader vertex-shader
52 uniform mat4 mv_matrix, p_matrix;
53 uniform vec3 light_position;
54
55 attribute vec3 POSITION;
56 attribute vec3 COLOR;
57 varying vec4 color;
58
59 void main()
60 {
61     gl_Position = p_matrix * mv_matrix * vec4(POSITION, 1.0);
62     color = vec4(COLOR, 1);
63 }
64 ;
65
66 GLSL-SHADER: debug-fragment-shader fragment-shader
67 varying vec4 color;
68 void main()
69 {
70     gl_FragColor = color;
71 }
72 ;
73
74 GLSL-PROGRAM: debug-program debug-vertex-shader debug-fragment-shader ;
75
76 UNIFORM-TUPLE: model-uniforms < mvp-uniforms
77     { "light-position" vec3-uniform  f } ;
78
79 TUPLE: model-state
80     models
81     vertex-arrays
82     index-vectors ;
83
84 TUPLE: model-world < wasd-world
85     { model-state model-state } ;
86
87 VERTEX-FORMAT: model-vertex
88     { "POSITION"   float-components 3 f }
89     { "NORMAL" float-components 3 f }
90     { "TEXCOORD" float-components 2 f } ;
91
92 VERTEX-FORMAT: debug-vertex
93     { "POSITION" float-components 3 f }
94     { "COLOR"    float-components 3 f } ;
95
96 TUPLE: vbo vertex-buffer index-buffer index-count vertex-format ;
97
98 : <model-buffers> ( models -- buffers )
99     [
100         {
101             [ attribute-buffer>> underlying>> static-upload draw-usage vertex-buffer byte-array>buffer ]
102             [ index-buffer>> underlying>> static-upload draw-usage index-buffer byte-array>buffer ]
103             [ index-buffer>> length ]
104             [ vertex-format>> ]
105         } cleave vbo boa
106     ] map ;
107
108 : fill-model-state ( model-state -- )
109     dup models>> <model-buffers>
110     [
111         [
112             [ vertex-buffer>> model-program <program-instance> ]
113             [ vertex-format>> ] bi buffer>vertex-array
114         ] map >>vertex-arrays drop
115     ]
116     [
117         [
118             [ index-buffer>> ] [ index-count>> ] bi
119             '[ _ 0 <buffer-ptr> _ uint-indexes <index-elements> ] call
120         ] map >>index-vectors drop
121     ] 2bi ;
122
123 : model-files ( -- files )
124     { "C:/Users/erikc/Downloads/test2.dae"
125       "C:/Users/erikc/Downloads/Sponza.obj" } ;
126
127 : <model-state> ( -- model-state )
128     model-state new
129     model-files [ load-models ] [ append ] map-reduce >>models ;
130
131 M: model-world begin-game-world
132     init-gpu
133     { 0.0 0.0 2.0 } 0 0 set-wasd-view
134     <model-state> [ fill-model-state drop ] [ >>model-state drop ] 2bi ;
135
136 : <model-uniforms> ( world -- uniforms )
137     [ wasd-mv-matrix ] [ wasd-p-matrix ] bi
138     { -10000.0 10000.0 10000.0 } ! light position
139     model-uniforms boa ;
140
141 : draw-line ( world from to color -- )
142     [ 3 head ] tri@ dup -rot append -rot append swap append >float-array
143     underlying>> stream-upload draw-usage vertex-buffer byte-array>buffer
144     debug-program <program-instance> debug-vertex buffer>vertex-array
145     
146     { 0 1 } >uint-array stream-upload draw-usage index-buffer byte-array>buffer
147     2 '[ _ 0 <buffer-ptr> _ uint-indexes <index-elements> ] call
148     
149     rot <model-uniforms>
150
151     {
152         { "primitive-mode"     [ 3drop lines-mode ] }
153         { "uniforms"           [ nip nip ] }
154         { "vertex-array"       [ drop drop ] }
155         { "indexes"            [ drop nip ] }
156     } 3<render-set> render ;
157
158 : draw-lines ( world lines -- )
159     3 <groups> [ first3 draw-line ] with each ; inline
160
161 : draw-axes ( world -- )
162     { { 0 0 0 } { 1 0 0 } { 1 0 0 }
163       { 0 0 0 } { 0 1 0 } { 0 1 0 }
164       { 0 0 0 } { 0 0 1 } { 0 0 1 } } draw-lines ;
165           
166 : draw-model ( world -- )
167     0 0 0 0 glClearColor 
168     1 glClearDepth
169     HEX: ffffffff glClearStencil
170     { GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT GL_STENCIL_BUFFER_BIT } flags glClear
171
172     [
173         triangle-fill dup t <triangle-state> set-gpu-state
174         face-ccw cull-back <triangle-cull-state> set-gpu-state
175         
176         cmp-less <depth-state> set-gpu-state
177         [ model-state>> vertex-arrays>> ]
178         [ model-state>> index-vectors>> ]
179         [ <model-uniforms> ]
180         tri
181         [
182             {
183                 { "primitive-mode"     [ 3drop triangles-mode ] }
184                 { "uniforms"           [ nip nip ] }
185                 { "vertex-array"       [ drop drop ] }
186                 { "indexes"            [ drop nip ] }
187             } 3<render-set> render
188         ] curry 2each
189     ]
190     [
191         cmp-always <depth-state> set-gpu-state
192         draw-axes
193     ]
194     bi ;
195
196 M: model-world draw-world*
197     draw-model ;
198
199 M: model-world wasd-movement-speed drop 1/4. ;
200 M: model-world wasd-near-plane drop 1/32. ;
201 M: model-world wasd-far-plane drop 1024.0 ;
202
203 GAME: model-viewer {
204         { world-class model-world }
205         { title "Model Viewer" }
206         { pixel-format-attributes { windowed double-buffered } }
207         { grab-input? t }
208         { use-game-input? t }
209         { pref-dim { 1024 768 } }
210         { tick-interval-micros $[ 60 fps ] }
211     } ;