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 fry sequences.deep destructors math.bitwise opengl.gl
12 game.models game.models.obj game.models.loader game.models.collada
13 prettyprint images.tga literals ;
14 FROM: alien.c-types => float ;
15 SPECIALIZED-ARRAY: float
16 SPECIALIZED-VECTOR: uint
19 GLSL-SHADER: obj-vertex-shader vertex-shader
20 uniform mat4 mv_matrix;
21 uniform mat4 p_matrix;
23 attribute vec3 POSITION;
24 attribute vec3 TEXCOORD;
25 attribute vec3 NORMAL;
27 varying vec2 texcoord_fs;
28 varying vec3 normal_fs;
29 varying vec3 world_pos_fs;
33 vec4 position = mv_matrix * vec4(POSITION, 1.0);
34 gl_Position = p_matrix * position;
35 world_pos_fs = POSITION;
36 texcoord_fs = TEXCOORD;
41 GLSL-SHADER: obj-fragment-shader fragment-shader
42 uniform mat4 mv_matrix, p_matrix;
43 uniform sampler2D map_Ka;
44 uniform sampler2D map_bump;
46 uniform vec3 view_pos;
48 varying vec2 texcoord_fs;
49 varying vec3 normal_fs;
50 varying vec3 world_pos_fs;
53 vec4 d = texture2D(map_Ka, texcoord_fs.xy);
54 vec3 b = texture2D(map_bump, texcoord_fs.xy).xyz;
56 vec3 v = normalize(view_pos - world_pos_fs);
57 vec3 l = normalize(light);
58 vec3 h = normalize(v + l);
59 float cosTh = saturate(dot(n, l));
60 gl_FragColor = d * cosTh
61 + d * 0.5 * cosTh * pow(saturate(dot(n, h)), 10.0) ;
65 GLSL-PROGRAM: obj-program
66 obj-vertex-shader obj-fragment-shader ;
68 UNIFORM-TUPLE: model-uniforms < mvp-uniforms
69 { "map_Ka" texture-uniform f }
70 { "map_bump" texture-uniform f }
71 { "Ka" vec3-uniform f }
72 { "light" vec3-uniform f }
73 { "view_pos" vec3-uniform f }
84 TUPLE: model-world < wasd-world model-path model-state ;
88 index-buffer index-count vertex-format texture bump ka ;
90 : white-image ( -- image )
91 { 1 1 } BGR ubyte-components f
92 B{ 255 255 255 } image boa ;
94 : up-image ( -- image )
95 { 1 1 } BGR ubyte-components f
96 B{ 0 0 0 } image boa ;
98 : make-texture ( pathname alt -- texture )
99 swap [ nip load-image ] [ ] if*
101 [ component-order>> ]
102 [ component-type>> ] bi
103 T{ texture-parameters
104 { wrap repeat-texcoord }
105 { min-filter filter-linear }
106 { min-mipmap-filter f } }
110 0 swap [ allocate-texture-image ] 3keep 2drop
113 : <model-buffers> ( models -- buffers )
116 [ attribute-buffer>> underlying>> static-upload draw-usage vertex-buffer byte-array>buffer ]
117 [ index-buffer>> underlying>> static-upload draw-usage index-buffer byte-array>buffer ]
118 [ index-buffer>> length ]
120 [ material>> ambient-map>> white-image make-texture ]
121 [ material>> bump-map>> up-image make-texture ]
122 [ material>> ambient-reflectivity>> ]
126 : fill-model-state ( model-state -- )
127 dup models>> <model-buffers>
131 [ vertex-buffer>> obj-program <program-instance> ]
132 [ vertex-format>> ] bi <vertex-array*>
133 ] map >>vertex-arrays drop
137 [ index-buffer>> ] [ index-count>> ] bi
138 '[ _ 0 <buffer-ptr> _ uint-indexes <index-elements> ] call
139 ] map >>index-vectors drop
141 [ [ texture>> ] map >>textures drop ]
142 [ [ bump>> ] map >>bumps drop ]
143 [ [ ka>> ] map >>kas drop ]
146 : <model-state> ( model-world -- model-state )
147 model-path>> 1array model-state new swap
148 [ load-models ] [ append ] map-reduce >>models ;
150 :: <model-uniforms> ( world -- uniforms )
152 [ textures>> ] [ bumps>> ] [ kas>> ] tri
162 : clear-screen ( -- )
165 HEX: ffffffff glClearStencil
166 flags{ GL_COLOR_BUFFER_BIT
168 GL_STENCIL_BUFFER_BIT } glClear ;
170 : draw-model ( world -- )
172 face-ccw cull-back <triangle-cull-state> set-gpu-state
173 cmp-less <depth-state> set-gpu-state
174 [ model-state>> vertex-arrays>> ]
175 [ model-state>> index-vectors>> ]
180 { "primitive-mode" [ 3drop triangles-mode ] }
181 { "uniforms" [ nip nip ] }
182 { "vertex-array" [ drop drop ] }
183 { "indexes" [ drop nip ] }
184 } 3<render-set> render
187 TUPLE: model-attributes < game-attributes model-path ;
189 M: model-world draw-world* draw-model ;
190 M: model-world wasd-movement-speed drop 1/4. ;
191 M: model-world wasd-near-plane drop 1/32. ;
192 M: model-world wasd-far-plane drop 1024.0 ;
193 M: model-world begin-game-world
195 { 0.0 0.0 2.0 } 0 0 set-wasd-view
196 [ <model-state> [ fill-model-state ] keep ] [ model-state<< ] bi ;
197 M: model-world apply-world-attributes
199 [ model-path>> >>model-path ]
203 :: open-model-viewer ( model-path -- )
207 { world-class model-world }
209 { title "Model Viewer" }
210 { pixel-format-attributes
211 { windowed double-buffered }
213 { pref-dim { 1024 768 } }
214 { tick-interval-micros 16666 }
215 { use-game-input? t }
216 { model-path model-path }