1 USING: accessors arrays combinators kernel literals multiline
2 opengl opengl.capabilities opengl.demo-support
3 opengl.framebuffers opengl.gl opengl.shaders opengl.textures
4 sequences ui ui.gadgets.worlds ui.pixel-formats ;
7 STRING: plane-vertex-shader
8 varying vec3 object_position;
12 object_position = gl_Vertex.xyz;
13 gl_Position = ftransform();
17 STRING: plane-fragment-shader
18 uniform float checker_size_inv;
19 uniform vec4 checker_color_1, checker_color_2;
20 varying vec3 object_position;
25 vec3 pprime = checker_size_inv * object_position;
26 return fract((floor(pprime.x) + floor(pprime.z)) * 0.5) == 0.0;
32 float distance_factor = (gl_FragCoord.z * 0.5 + 0.5);
33 distance_factor = pow(distance_factor, 500.0)*0.5;
35 gl_FragColor = checker_color(object_position)
36 ? mix(checker_color_1, checker_color_2, distance_factor)
37 : mix(checker_color_2, checker_color_1, distance_factor);
41 STRING: sphere-vertex-shader
42 attribute vec3 center;
43 attribute float radius;
44 attribute vec4 surface_color;
45 varying float vradius;
46 varying vec3 sphere_position;
47 varying vec4 world_position, vcolor;
52 world_position = gl_ModelViewMatrix * vec4(center, 1);
53 sphere_position = gl_Vertex.xyz;
55 gl_Position = gl_ProjectionMatrix * (world_position + vec4(sphere_position * radius, 0));
57 vcolor = surface_color;
62 STRING: sphere-solid-color-fragment-shader
63 uniform vec3 light_position;
66 const vec4 ambient = vec4(0.25, 0.2, 0.25, 1.0);
67 const vec4 diffuse = vec4(0.75, 0.8, 0.75, 1.0);
70 sphere_color(vec3 point, vec3 normal)
72 vec3 transformed_light_position = (gl_ModelViewMatrix * vec4(light_position, 1)).xyz;
73 vec3 direction = normalize(transformed_light_position - point);
74 float d = max(0.0, dot(normal, direction));
76 return ambient * vcolor + diffuse * vec4(d * vcolor.rgb, vcolor.a);
80 STRING: sphere-texture-fragment-shader
81 uniform samplerCube surface_texture;
84 sphere_color(vec3 point, vec3 normal)
86 vec3 reflect = reflect(normalize(point), normal);
87 return textureCube(surface_texture, reflect * gl_NormalMatrix);
91 STRING: sphere-main-fragment-shader
92 varying float vradius;
93 varying vec3 sphere_position;
94 varying vec4 world_position;
96 vec4 sphere_color(vec3 point, vec3 normal);
101 float radius = length(sphere_position);
102 if(radius > 1.0) discard;
104 vec3 surface = sphere_position + vec3(0.0, 0.0, sqrt(1.0 - radius*radius));
105 vec4 world_surface = world_position + vec4(surface * vradius, 0);
106 vec4 transformed_surface = gl_ProjectionMatrix * world_surface;
108 gl_FragDepth = (transformed_surface.z/transformed_surface.w + 1.0) * 0.5;
109 gl_FragColor = sphere_color(world_surface.xyz, surface);
113 TUPLE: spheres-world < demo-world
114 plane-program solid-sphere-program texture-sphere-program
115 reflection-framebuffer reflection-depthbuffer
118 M: spheres-world near-plane
120 M: spheres-world far-plane
122 M: spheres-world distance-step
125 : (reflection-dim) ( -- w h )
128 : (make-reflection-texture) ( -- texture )
130 GL_TEXTURE_CUBE_MAP swap glBindTexture
131 GL_TEXTURE_CUBE_MAP GL_TEXTURE_MAG_FILTER GL_LINEAR glTexParameteri
132 GL_TEXTURE_CUBE_MAP GL_TEXTURE_MIN_FILTER GL_LINEAR glTexParameteri
133 GL_TEXTURE_CUBE_MAP GL_TEXTURE_WRAP_S GL_CLAMP glTexParameteri
134 GL_TEXTURE_CUBE_MAP GL_TEXTURE_WRAP_T GL_CLAMP glTexParameteri
135 GL_TEXTURE_CUBE_MAP GL_TEXTURE_WRAP_R GL_CLAMP glTexParameteri
137 GL_TEXTURE_CUBE_MAP_POSITIVE_X
138 GL_TEXTURE_CUBE_MAP_POSITIVE_Y
139 GL_TEXTURE_CUBE_MAP_POSITIVE_Z
140 GL_TEXTURE_CUBE_MAP_NEGATIVE_X
141 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
142 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
144 [ 0 GL_RGBA8 (reflection-dim) 0 GL_RGBA GL_UNSIGNED_BYTE f glTexImage2D ]
148 : (make-reflection-depthbuffer) ( -- depthbuffer )
150 GL_RENDERBUFFER swap glBindRenderbuffer
151 GL_RENDERBUFFER GL_DEPTH_COMPONENT32 (reflection-dim) glRenderbufferStorage
154 : (make-reflection-framebuffer) ( depthbuffer -- framebuffer )
155 gen-framebuffer dup [
156 swap [ GL_DRAW_FRAMEBUFFER GL_DEPTH_ATTACHMENT GL_RENDERBUFFER ] dip
157 glFramebufferRenderbuffer
160 : (plane-program) ( -- program )
161 plane-vertex-shader plane-fragment-shader <simple-gl-program> ;
162 : (solid-sphere-program) ( -- program )
163 sphere-vertex-shader <vertex-shader> check-gl-shader
164 sphere-solid-color-fragment-shader <fragment-shader> check-gl-shader
165 sphere-main-fragment-shader <fragment-shader> check-gl-shader
166 3array <gl-program> check-gl-program ;
167 : (texture-sphere-program) ( -- program )
168 sphere-vertex-shader <vertex-shader> check-gl-shader
169 sphere-texture-fragment-shader <fragment-shader> check-gl-shader
170 sphere-main-fragment-shader <fragment-shader> check-gl-shader
171 3array <gl-program> check-gl-program ;
173 M: spheres-world begin-world
174 "2.0" { "GL_ARB_shader_objects" } require-gl-version-or-extensions
175 { "GL_EXT_framebuffer_object" } require-gl-extensions
176 GL_DEPTH_TEST glEnable
177 GL_VERTEX_ARRAY glEnableClientState
178 0.15 0.15 1.0 1.0 glClearColor
179 20.0 10.0 20.0 set-demo-orientation
180 (plane-program) >>plane-program
181 (solid-sphere-program) >>solid-sphere-program
182 (texture-sphere-program) >>texture-sphere-program
183 (make-reflection-texture) >>reflection-texture
184 (make-reflection-depthbuffer) [ >>reflection-depthbuffer ] keep
185 (make-reflection-framebuffer) >>reflection-framebuffer
188 M: spheres-world end-world
190 [ reflection-framebuffer>> [ delete-framebuffer ] when* ]
191 [ reflection-depthbuffer>> [ delete-renderbuffer ] when* ]
192 [ reflection-texture>> [ delete-texture ] when* ]
193 [ solid-sphere-program>> [ delete-gl-program ] when* ]
194 [ texture-sphere-program>> [ delete-gl-program ] when* ]
195 [ plane-program>> [ delete-gl-program ] when* ]
198 :: (draw-sphere) ( program center radius -- )
199 program "center" glGetAttribLocation center first3 glVertexAttrib3f
200 program "radius" glGetAttribLocation radius glVertexAttrib1f
201 { -1.0 -1.0 } { 2.0 2.0 } gl-fill-rect ;
203 :: (draw-colored-sphere) ( program center radius surfacecolor -- )
204 program "surface_color" glGetAttribLocation surfacecolor first4 glVertexAttrib4f
205 program center radius (draw-sphere) ;
207 : sphere-scene ( gadget -- )
208 flags{ GL_DEPTH_BUFFER_BIT GL_COLOR_BUFFER_BIT } glClear
210 solid-sphere-program>> [
212 [ "light_position" glGetUniformLocation 0.0 0.0 100.0 glUniform3f ]
213 [ { 7.0 0.0 0.0 } 1.0 { 1.0 0.0 0.0 1.0 } (draw-colored-sphere) ]
214 [ { -7.0 0.0 0.0 } 1.0 { 0.0 1.0 0.0 1.0 } (draw-colored-sphere) ]
215 [ { 0.0 0.0 7.0 } 1.0 { 0.0 0.0 1.0 1.0 } (draw-colored-sphere) ]
216 [ { 0.0 0.0 -7.0 } 1.0 { 1.0 1.0 0.0 1.0 } (draw-colored-sphere) ]
217 [ { 0.0 7.0 0.0 } 1.0 { 1.0 0.0 1.0 1.0 } (draw-colored-sphere) ]
218 [ { 0.0 -7.0 0.0 } 1.0 { 0.0 1.0 1.0 1.0 } (draw-colored-sphere) ]
224 [ "checker_size_inv" glGetUniformLocation 0.125 glUniform1f ]
225 [ "checker_color_1" glGetUniformLocation 1.0 0.0 0.0 1.0 glUniform4f ]
226 [ "checker_color_2" glGetUniformLocation 1.0 1.0 1.0 1.0 glUniform4f ]
229 -1000.0 -30.0 1000.0 glVertex3f
230 -1000.0 -30.0 -1000.0 glVertex3f
231 1000.0 -30.0 -1000.0 glVertex3f
232 1000.0 -30.0 1000.0 glVertex3f
237 : reflection-frustum ( gadget -- -x x -y y near far )
238 [ near-plane ] [ far-plane ] bi
239 [ drop dup [ -+ ] bi@ ] 2keep ;
241 : (reflection-face) ( gadget face -- )
242 swap reflection-texture>> [
245 ] 2dip 0 glFramebufferTexture2D
248 : (draw-reflection-texture) ( gadget -- )
249 dup reflection-framebuffer>> [ {
250 [ drop { 0 0 } (reflection-dim) 2array gl-viewport ]
252 GL_PROJECTION glMatrixMode
253 glPushMatrix glLoadIdentity
254 reflection-frustum glFrustum
255 GL_MODELVIEW glMatrixMode
257 180.0 0.0 0.0 1.0 glRotatef
259 [ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z (reflection-face) ]
261 [ GL_TEXTURE_CUBE_MAP_POSITIVE_X (reflection-face)
262 90.0 0.0 1.0 0.0 glRotatef ]
264 [ GL_TEXTURE_CUBE_MAP_POSITIVE_Z (reflection-face)
265 90.0 0.0 1.0 0.0 glRotatef glPushMatrix ]
267 [ GL_TEXTURE_CUBE_MAP_NEGATIVE_X (reflection-face)
268 90.0 0.0 1.0 0.0 glRotatef ]
270 [ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y (reflection-face)
271 glPopMatrix glPushMatrix -90.0 1.0 0.0 0.0 glRotatef ]
273 [ GL_TEXTURE_CUBE_MAP_POSITIVE_Y (reflection-face)
274 glPopMatrix 90.0 1.0 0.0 0.0 glRotatef ]
277 [ { 0 0 } ] dip dim>> gl-viewport
278 GL_PROJECTION glMatrixMode
281 } cleave ] with-framebuffer ;
283 M: spheres-world draw-world*
285 [ (draw-reflection-texture) ]
286 [ demo-world-set-matrix ]
288 [ reflection-texture>> GL_TEXTURE_CUBE_MAP GL_TEXTURE0 bind-texture-unit ]
290 texture-sphere-program>> [
291 [ "surface_texture" glGetUniformLocation 0 glUniform1i ]
292 [ { 0.0 0.0 0.0 } 4.0 (draw-sphere) ]
298 MAIN-WINDOW: spheres-window {
299 { world-class spheres-world }
301 { pixel-format-attributes {
304 T{ depth-bits { value 16 } }
306 { pref-dim { 640 480 } }