Browse Source

Interactive mandelbrot: use quadtree table for nicer previews

master
cpsdqs 2 years ago
parent
commit
e6c8125cfe
Signed by: cpsdqs GPG Key ID: 3F59586BB7448DD1
  1. 89
      examples/mandelbrot/mandelbrot-interactive.csn

89
examples/mandelbrot/mandelbrot-interactive.csn

@ -5,10 +5,6 @@
(def H 768)
(def MAXITER 50)
; size of big pixels
(def COL_SKIP 8)
(def ROW_SKIP 8)
(lds @cout "Interactive Mandelbrot\n")
(lds @cout "----------------------\n")
(lds @cout "Navigate using WASD, zoom using Q/E\n")
@ -20,8 +16,46 @@
(sym mb_y r3)
(sym mb_s r4)
(sym mb_row r5)
(sym mb_col_skip r6)
(sym mb_row_skip r7)
; index into the skip/size table
(sym mb_skip_index r6)
; size of big pixels
(def COL_SKIP 8)
(def ROW_SKIP 8)
; incrementally renders 1x1, 2x2, 4x4, ...
(def MB_SKIP_TABLE_SIZE 80)
(def MB_SKIP_REPEAT_INDEX 16)
(sym mb_skip_table_x r7)
(sym mb_skip_table_y r8)
(sym mb_size_table r12)
(mkbf mb_skip_table_x (
0 4 0 4 2 6 0 2 4 6 2 6 0 2 4 6
; 8x8 grid
1 3 5 7 1 3 5 7 1 3 5 7 1 3 5 7
0 2 4 6 0 2 4 6 0 2 4 6 0 2 4 6
1 3 5 7 1 3 5 7 1 3 5 7 1 3 5 7
; do top left pixels again
0 2 4 6 0 2 4 6 0 2 4 6 0 2 4 6
))
(mkbf mb_skip_table_y (
0 0 4 4 0 0 2 2 2 2 4 4 6 6 6 6
; 8x8 grid
0 0 0 0 2 2 2 2 4 4 4 4 6 6 6 6
1 1 1 1 3 3 3 3 5 5 5 5 7 7 7 7
1 1 1 1 3 3 3 3 5 5 5 5 7 7 7 7
; do top left pixels again
0 0 0 0 2 2 2 2 4 4 4 4 6 6 6 6
))
(mkbf mb_size_table (
8 4 4 4 2 2 2 2 2 2 2 2 2 2 2 2
; 8x8 grid
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
; do top left pixels again
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
))
(ld mb_x 0.0)
(ld mb_y 0.0)
@ -31,13 +65,13 @@
(ld is_first_render 1)
; render row
; big - is this the first render? if yes, use big pixels
; col - mb_col_skip column offset
; size - pixel size
; col - column offset
; px - offset x
; py - offset y
; scale - scaling
; row - row position
(proc render_row big col px py scale row
(proc render_row size col px py scale row
(sym gradient r9)
(mkbf gradient (
0x421e0f 0x19071a 0x09012f 0x040449 0x000764 0x0c2c8a 0x1852b1 0x397dd1
@ -57,13 +91,7 @@
)
(else? (ld r0 0))
)
(cmp big 1)
(j.ne :not_big)
(sc-rect x y COL_SKIP ROW_SKIP r0)
(j :was_big)
(:not_big)
(sc-wr x y r0)
(:was_big)
(sc-rect x y size size r0)
(add x COL_SKIP)
(cmp x W)
(j.lt :col)
@ -126,14 +154,19 @@
; mark this as a first render and reset col_skip and row_skip
(ld is_first_render 1)
(ld mb_col_skip 0)
(ld mb_row_skip 0)
(ld mb_skip_index 0)
(:did_not_move)
; render row mb_row + mb_row_skip
(sym mb_col_skip r9)
(sym mb_row_skip r11)
(bfrd mb_col_skip @mb_skip_table_x mb_skip_index)
(bfrd mb_row_skip @mb_skip_table_y mb_skip_index)
(bfrd r1 @mb_size_table mb_skip_index)
; render row mb_row + row skip
(ld r0 mb_row)
(add r0 mb_row_skip)
(call render_row is_first_render mb_col_skip mb_x mb_y mb_s r0)
(call render_row r1 mb_col_skip mb_x mb_y mb_s r0)
(cmp mb_row H)
(j.ge :render_done)
@ -143,16 +176,14 @@
(:render_done)
; otherwise, this frame is done
(ld mb_row 0)
(add mb_col_skip 1)
(add mb_skip_index 1)
(ld is_first_render 0)
(mod mb_col_skip COL_SKIP)
; if mb_col_skip wrapped back to zero increase mb_row_skip
(cmp mb_col_skip 0)
(j.ne :not_col)
(add mb_row_skip 1)
(mod mb_row_skip ROW_SKIP)
(:not_col)
(cmp mb_skip_index MB_SKIP_TABLE_SIZE)
; if skip index is out of bounds, go back to repeating area
(j.lt :not_end)
(ld mb_skip_index MB_SKIP_REPEAT_INDEX)
(:not_end)
(:render_not_done)
(j :slp)

Loading…
Cancel
Save