-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathybot_oscilloscope.xtm
401 lines (332 loc) · 13.5 KB
/
ybot_oscilloscope.xtm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
;; lib-loading config
(if *impc:compiler:with-cache* (sys:load "libs/aot-cache/ybot_oscilloscope.xtm" 'quiet))
(sys:load-preload-check 'ybot_oscilloscope)
(define *xtmlib-ybot_oscilloscope-loaded* #t)
(impc:aot:suppress-aot-do
(sys:load "libs/external/gl/gl-objects.xtm")
(sys:load "libs/external/glfw3.xtm")
(sys:load "libs/core/scheduler.xtm")
(sys:load "libs/contrib/ybot/ybot_adt.xtm"))
(impc:aot:insert-forms
(sys:load "libs/external/gl/gl-objects.xtm")
(sys:load "libs/external/glfw3.xtm")
(sys:load "libs/core/scheduler.xtm")
(sys:load "libs/contrib/ybot/ybot_adt.xtm" 'quiet))
(impc:aot:insert-header "xtmybot_oscilloscope")
(impc:aot:import-ll "xtmybot_oscilloscope")
;(run_main_event_loop)
(bind-func VBO_create
(lambda (buf:float* buflen)
(let ((vbo:VBO* (halloc))
(id:GLuint* (salloc)))
(glGenBuffers 1 id)
(gl_print_error "Error creating VBO")
(tfill! vbo
(pref id 0)
GL_FLOAT
(* buflen 4) ;; sizeof(float)
(cast buf GLvoid*))
(glBindBuffer GL_ARRAY_BUFFER (VBO_id vbo))
(glBufferData GL_ARRAY_BUFFER (VBO_size vbo) (VBO_data vbo) GL_STREAM_DRAW)
(gl_print_error "Error setting VBO data")
vbo)))
(bind-val w i32 1024)
(bind-val h i32 768)
(bind-val window GLFWwindow*
;; some of the shaders in the graphics pipeline use older glsl
;; versions, so we need a "compatibility" graphics context
(begin
(glfwSetErrorCallback (convert (get_native_fptr glfw_error_callback)))
(glfw_init_and_create_interaction_window w h)))
(bind-val pixel_ratio float (glfw_get_pixel_ratio window))
;(bind-val width float (glfw_get_window_width window))
;(bind-val height float (glfw_get_window_height window))
(bind-val cx float (/ width 2.0:float))
(bind-val cy float (/ height 2.0:float))
(bind-val FRAMERATE float 60.)
(bind-val FRAMEDURATION float (/ 1. FRAMERATE))
(bind-val FRAMEDELTA float (* SAMPLERATE (/ 1. FRAMERATE)))
($ (set! FRAMERATE 60.:float))
($ (set! FRAMEDELTA (* SAMPLERATE (/ 1.:float FRAMERATE))))
;;;; Oscilloscope stuff ;;;;
;; (bind-func scope2pixelY:[float,float]*
;; (lambda (value)
;; (* cy (+ 1.0:float value))))
;; (bind-func scope2pixelX:[float,float]*
;; (lambda (value)
;; (* cx (+ 1.0:float value))))
(bind-val YBOT_SCOPE_X FIFO{float*}* (FIFO 256 8192))
(bind-val YBOT_SCOPE_Y FIFO{float*}* (FIFO 256 8192))
(bind-val YBOT_SCOPE_CARRY_T float 0.0:float)
(bind-val YBOT_SCOPE_CARRY_X float 0.0:float)
(bind-val YBOT_SCOPE_CARRY_Y float 0.0:float)
(bind-val YBOT_SCOPE_SCAN_FREQ float 5.0:float)
(bind-val YBOT_SCOPE_MUTEX i8* (mutex_create))
($ (set! YBOT_SCOPE_SCAN_FREQ 2.0:float))
(bind-func YbotScopeLog:[void,i64,float]*
(lambda (channel value)
(cond
((= 1:i32 (mutex_trylock (YBOT_SCOPE_MUTEX)))
(push YBOT_SCOPE_Y (* 3.0:float value))
(let* ((delta_t:float (/ YBOT_SCOPE_SCAN_FREQ SRf))
(t:float (+ YBOT_SCOPE_CARRY_T delta_t)))
(if (>= t 1.0:float) (set! t -1.0:float))
(set! YBOT_SCOPE_CARRY_T t)
(push YBOT_SCOPE_X t))
(mutex_unlock YBOT_SCOPE_MUTEX)
void)
(else void))))
(bind-func dsp:DSP
(lambda (in:SAMPLE time:i64 channel:i64 data:SAMPLE*)
(cond
((= channel 0)
(YbotScopeLog channel in)
void)
(else void))
(* (random) 0.05) ))
(dsp:set! dsp)
;;-------------------
(bind-val fbo FBO*)
(bind-val ss_quad_vao VAO*)
(call-as-xtlang
(let ((fbw_ptr:i32* (salloc))
(fbh_ptr:i32* (salloc)))
(glfwGetFramebufferSize window fbw_ptr fbh_ptr)
(println (set! fbo (FBO_create_with_textures (pref fbw_ptr 0) (pref fbh_ptr 0) #t)))
(set! ss_quad_vao (VAO_create_ss_quad))))
;;(bind-val scope_vertex_data |1280,float|)
(bind-val view_mat |16,float|) ;; view matrix
(bind-val scope_vbo VBO*)
(bind-val scope_vao VAO*)
(bind-val scope_prog ShaderProgram)
(bind-func reset_view_matrix
(lambda ()
(afill! view_mat
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0)))
(reset_view_matrix)
(bind-func initialise-stuff
(lambda ()
(set! scope_prog
(ShaderProgram_create
(sys_slurp_file "examples/external/shader-tutorials/triangle.vert")
(sys_slurp_file "examples/external/shader-tutorials/triangle.frag")))
void))
(initialise-stuff)
;;-------------------
(bind-val post_process_sp ShaderProgram)
(bind-func create_post_process_shader
(lambda (vsource:i8* fsource:i8*)
(set! post_process_sp (ShaderProgram_create vsource fsource))))
(create_post_process_shader
(sys:slurp-file "/Users/ybot/Documents/code/ybot/ybot_xtm_lib/framebuffer-post-process.vert")
(sys:slurp-file "/Users/ybot/Documents/code/ybot/ybot_xtm_lib/framebuffer-post-process.frag"))
(bind-val screen_vert_data |30,float|)
(bind-val screen_vbo VBO*)
(bind-val screen_vao VAO*)
(bind-val screen_prog ShaderProgram)
($ (set! screen_prog
(ShaderProgram_create
(sys_slurp_file "/Users/ybot/Documents/code/ybot/ybot_xtm_lib/background_with_transparency.vert")
(sys_slurp_file "/Users/ybot/Documents/code/ybot/ybot_xtm_lib/background_with_transparency.frag"))))
;; init data
($ (afill! screen_vert_data
;; pos colour
-1.0 -1.0 0.0 0.0 0.0
-1.0 1.0 0.0 0.0 0.0
1.0 1.0 0.0 0.0 0.0
-1.0 -1.0 0.0 0.0 0.0
1.0 -1.0 0.0 0.0 0.0
1.0 1.0 0.0 0.0 0.0)
(reset_view_matrix)
(set! screen_vbo (VBO_create (aref-ptr screen_vert_data 0) 30))
(set! screen_vao (VAO_create))
(VAO_bind_attribute screen_vao screen_vbo 0 2 5 0) ;; position
(VAO_bind_attribute screen_vao screen_vbo 1 3 5 2) ;; tex_coord
void)
;; (bind-func gl_draw
;; (let ((drawbufs_ptr:GLenum* (zalloc)))
;; (pset! drawbufs_ptr 0 GL_COLOR_ATTACHMENT0)
;; (lambda ()
;; ;; bind the second (render-to-texture) framebuffer
;; (glBindFramebuffer GL_FRAMEBUFFER (FBO_id fbo))
;; (glDrawBuffers 1 drawbufs_ptr)
;; ;; clear the framebuffer's colour and depth buffers
;; (glClear (bor GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT))
;; ;; render the triangle as normal
;; (glUseProgram sp)
;; (glBindVertexArray (VAO_id vao))
;; (glDrawArrays GL_TRIANGLES 0 3)
;; ;; bind default framebuffer
;; (glBindFramebuffer GL_FRAMEBUFFER 0)
;; ;; clear the framebuffer's colour and depth buffers
;; (glClear (bor GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT))
;; ;; our post-processing shader for the screen-space quad
;; (glUseProgram post_process_sp)
;; ;; bind the quad's VAO
;; (glBindVertexArray (VAO_id ss_quad_vao))
;; ;; activate the first texture slot and put texture from previous pass in it
;; (glActiveTexture GL_TEXTURE0)
;; (glBindTexture GL_TEXTURE_2D (FBO_color_texture fbo))
;; ;; draw the quad
;; (glDrawArrays GL_TRIANGLE_STRIP 0 4))))
(bind-func draw_frame:[void]*
(let ((drawbufs_ptr:GLenum* (zalloc)) (t:float 0.0) (y:float 0.0) (dt:float 0.0))
;;(glEnable GL_LINE_SMOOTH)
(glEnable GL_BLEND)
(glBlendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA)
(pset! drawbufs_ptr 0 GL_COLOR_ATTACHMENT0)
(lambda ()
;; bind the second (render-to-texture) framebuffer
(glBindFramebuffer GL_FRAMEBUFFER (FBO_id fbo))
(glDrawBuffers 1 drawbufs_ptr)
;; clear the framebuffer's colour and depth buffers
;;(glClear (bor GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT))
(glUseProgram screen_prog)
(let ((loc (glGetUniformLocation screen_prog "view_mat")))
(glUniformMatrix4fv loc 1 GL_FALSE (aref-ptr view_mat 0))
(VAO_bind_and_draw_arrays screen_vao GL_TRIANGLES 0 6))
;; render the scope as normal
(glUseProgram scope_prog)
(mutex_lock YBOT_SCOPE_MUTEX)
(let*
((sz:i64 (size YBOT_SCOPE_Y)) (i:i64 0) (flag:bool* (salloc)) (clean:bool #t)
(t1:float -1.0:float) (t2:float -1.0:float) (y1:float 0.0) (y2:float 0.0) (cc:i64 0)
(sample_point_vertices:float* (salloc (* 5 (+ sz 1)))))
(pset! flag 0 #t)
;;(pset! sample_point_vertices (+ (* cc 5) 0) (* y (cos (* STWOPI t))))
;;(pset! sample_point_vertices (+ (* cc 5) 1) (* y (sin (* STWOPI t))))
(pset! sample_point_vertices (+ (* cc 5) 0) t)
(pset! sample_point_vertices (+ (* cc 5) 1) y)
(pset! sample_point_vertices (+ (* cc 5) 2) 1.0)
(pset! sample_point_vertices (+ (* cc 5) 3) 1.0)
(pset! sample_point_vertices (+ (* cc 5) 4) 1.0)
(set! cc (+ cc 1))
(dotimes (i sz)
(set! y2 (pop YBOT_SCOPE_Y flag))
(set! t2 (pop YBOT_SCOPE_X flag))
(cond
(#t ;;(> t2 t) ;;clean (> t2 t1) (not (or (and (= 0.0:float t1) (= 0.0:float y1)) (and (= 0.0:float t2) (= 0.0:float y2)))))
;;(pset! sample_point_vertices (+ (* cc 5) 0) (* y2 (cos (* STWOPI t2))))
;;(pset! sample_point_vertices (+ (* cc 5) 1) (* y2 (sin (* STWOPI t2))))
(pset! sample_point_vertices (+ (* cc 5) 0) t2)
(pset! sample_point_vertices (+ (* cc 5) 1) y2)
(pset! sample_point_vertices (+ (* cc 5) 2) 1.0)
(pset! sample_point_vertices (+ (* cc 5) 3) 1.0)
(pset! sample_point_vertices (+ (* cc 5) 4) 1.0)
(set! cc (+ cc 1))
void)
(else
(set! clean #f)
void))
(set! t1 t2)
(set! y1 y2))
(set! dt (- t t2))
(set! t t2)
(set! y y2)
(cond
((> cc 1)
(set! scope_vbo (VBO_create sample_point_vertices (* 5 cc)))
(set! scope_vao (VAO_create))
(VAO_bind_attribute scope_vao scope_vbo 0 2 5 0) ;; position
(VAO_bind_attribute scope_vao scope_vbo 1 3 5 2) ;; tex_coord
;;(glClearColor 0.0 0.0 0.0 1.0)
;;(glClear GL_COLOR_BUFFER_BIT)
(glUseProgram scope_prog)
(let ((loc (glGetUniformLocation scope_prog "view_mat")))
(glUniformMatrix4fv loc 1 GL_FALSE (aref-ptr view_mat 0))
(VAO_bind_and_draw_arrays scope_vao GL_POINTS 0 (i64toi32 cc)))
void)
(else void)))
;; bind default framebuffer
(glBindFramebuffer GL_FRAMEBUFFER 0)
;; clear the framebuffer's colour and depth buffers
;;(glClear (bor GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT))
;; our post-processing shader for the screen-space quad
(glUseProgram post_process_sp)
;; bind the quad's VAO
(glBindVertexArray (VAO_id ss_quad_vao))
;; activate the first texture slot and put texture from previous pass in it
(glActiveTexture GL_TEXTURE0)
(glBindTexture GL_TEXTURE_2D (FBO_color_texture fbo))
;; draw the quad
(glDrawArrays GL_TRIANGLE_STRIP 0 4)
;; (glEnable GL_BLEND)
;; (glBlendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA)
;; (glUseProgram screen_prog)
;; (let ((loc (glGetUniformLocation screen_prog "view_mat")))
;; (glUniformMatrix4fv loc 1 GL_FALSE (aref-ptr view_mat 0))
;; (VAO_bind_and_draw_arrays screen_vao GL_TRIANGLES 0 6))
;; (mutex_lock YBOT_SCOPE_MUTEX)
;; (let*
;; ((sz:i64 (size YBOT_SCOPE_Y)) (i:i64 0) (flag:bool* (salloc))
;; (sample_point_vertices:float* (salloc (* 5 sz))))
;; (pset! flag 0 #t)
;; (dotimes (i sz)
;; (pset! sample_point_vertices (+ (* i 5) 0) (peek YBOT_SCOPE_X i))
;; (pset! sample_point_vertices (+ (* i 5) 1) (peek YBOT_SCOPE_Y i))
;; (pset! sample_point_vertices (+ (* i 5) 2) 1.0)
;; (pset! sample_point_vertices (+ (* i 5) 3) 1.0)
;; (pset! sample_point_vertices (+ (* i 5) 4) 1.0))
;; (set! scope_vbo (VBO_create sample_point_vertices (* 5 sz)))
;; (set! scope_vao (VAO_create))
;; (VAO_bind_attribute scope_vao scope_vbo 0 2 5 0) ;; position
;; (VAO_bind_attribute scope_vao scope_vbo 1 3 5 2) ;; tex_coord
;; ;;(glClearColor 0.0 0.0 0.0 1.0)
;; ;;(glClear GL_COLOR_BUFFER_BIT)
;; (glUseProgram scope_prog)
;; (let ((loc (glGetUniformLocation scope_prog "view_mat")))
;; (glUniformMatrix4fv loc 1 GL_FALSE (aref-ptr view_mat 0))
;; (VAO_bind_and_draw_arrays scope_vao GL_POINTS 0 (i64toi32 sz))))
;; (VBO_delete scope_vbo)
;; (VAO_delete scope_vao)
(mutex_unlock YBOT_SCOPE_MUTEX)
void)))
;; (bind-func nvg_draw_loop
;; (lambda (time:i64 delta:float)
;; (draw_frame)
;; ;;(glfwPollEvents)
;; (glfwSwapBuffers window)
;; (let ((next_time (+ time (convert delta))))
;; (callback next_time nvg_draw_loop next_time delta))))
;; ($ (nvg_draw_loop (now) FRAMEDELTA))
;($ (printf "%d\n" (draw_loop.go:bool)))
(bind-func draw_loop
(let ((go:bool #t) (initialised:bool #f))
(lambda (time:i64)
(cond
(go
(draw_frame)
(glfwPollEvents)
(glfwSwapBuffers window)
(let ((next_time (+ time (convert FRAMEDELTA))))
(callback next_time draw_loop next_time)
void))
(else void)))))
(bind-func run_oscilloscope:[void,bool]*
(lambda (flag:bool)
(cond
(flag
(cond
((draw_loop.go:bool)
(cond
((draw_loop.initialised:bool)
void)
(else
(draw_loop.initialised:bool #t)
(draw_loop (now)))))
(else
(draw_loop.go:bool #t)
(draw_loop (now))
void)))
(else
(draw_loop.go:bool #f)
void))))
;; to stop the draw loop, eval this version of nvg_draw_loop
;; (bind-func draw_loop
;; (lambda (time:i64)
;; (println "draw_loop callback stopped")
;; void))
;;($ (run_oscilloscope #t))