Browse Source

Interactive mandelbrot: use quadtree table for nicer previews

cpsdqs 11 months ago
parent
commit
e6c8125cfe
Signed by: cpsdqs <cpsdqs@gmail.com> GPG key ID: 3F59586BB7448DD1
1 changed files with 60 additions and 29 deletions
  1. 60 29
      examples/mandelbrot/mandelbrot-interactive.csn

+ 60 - 29
examples/mandelbrot/mandelbrot-interactive.csn View File

@@ -5,10 +5,6 @@
5 5
     (def H 768)
6 6
     (def MAXITER 50)
7 7
 
8
-    ; size of big pixels
9
-    (def COL_SKIP 8)
10
-    (def ROW_SKIP 8)
11
-
12 8
     (lds @cout "Interactive Mandelbrot\n")
13 9
     (lds @cout "----------------------\n")
14 10
     (lds @cout "Navigate using WASD, zoom using Q/E\n")
@@ -20,8 +16,46 @@
20 16
     (sym mb_y r3)
21 17
     (sym mb_s r4)
22 18
     (sym mb_row r5)
23
-    (sym mb_col_skip r6)
24
-    (sym mb_row_skip r7)
19
+
20
+    ; index into the skip/size table
21
+    (sym mb_skip_index r6)
22
+
23
+    ; size of big pixels
24
+    (def COL_SKIP 8)
25
+    (def ROW_SKIP 8)
26
+    ; incrementally renders 1x1, 2x2, 4x4, ...
27
+    (def MB_SKIP_TABLE_SIZE 80)
28
+    (def MB_SKIP_REPEAT_INDEX 16)
29
+    (sym mb_skip_table_x r7)
30
+    (sym mb_skip_table_y r8)
31
+    (sym mb_size_table r12)
32
+    (mkbf mb_skip_table_x (
33
+        0 4 0 4 2 6 0 2 4 6 2 6 0 2 4 6
34
+        ; 8x8 grid
35
+        1 3 5 7 1 3 5 7 1 3 5 7 1 3 5 7
36
+        0 2 4 6 0 2 4 6 0 2 4 6 0 2 4 6
37
+        1 3 5 7 1 3 5 7 1 3 5 7 1 3 5 7
38
+        ; do top left pixels again
39
+        0 2 4 6 0 2 4 6 0 2 4 6 0 2 4 6
40
+    ))
41
+    (mkbf mb_skip_table_y (
42
+        0 0 4 4 0 0 2 2 2 2 4 4 6 6 6 6
43
+        ; 8x8 grid
44
+        0 0 0 0 2 2 2 2 4 4 4 4 6 6 6 6
45
+        1 1 1 1 3 3 3 3 5 5 5 5 7 7 7 7
46
+        1 1 1 1 3 3 3 3 5 5 5 5 7 7 7 7
47
+        ; do top left pixels again
48
+        0 0 0 0 2 2 2 2 4 4 4 4 6 6 6 6
49
+    ))
50
+    (mkbf mb_size_table (
51
+        8 4 4 4 2 2 2 2 2 2 2 2 2 2 2 2
52
+        ; 8x8 grid
53
+        1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
54
+        1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
55
+        1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
56
+        ; do top left pixels again
57
+        1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
58
+    ))
25 59
 
26 60
     (ld mb_x 0.0)
27 61
     (ld mb_y 0.0)
@@ -31,13 +65,13 @@
31 65
     (ld is_first_render 1)
32 66
 
33 67
     ; render row
34
-    ; big - is this the first render? if yes, use big pixels
35
-    ; col - mb_col_skip column offset
68
+    ; size - pixel size
69
+    ; col - column offset
36 70
     ; px - offset x
37 71
     ; py - offset y
38 72
     ; scale - scaling
39 73
     ; row - row position
40
-    (proc render_row big col px py scale row
74
+    (proc render_row size col px py scale row
41 75
         (sym gradient r9)
42 76
         (mkbf gradient (
43 77
             0x421e0f 0x19071a 0x09012f 0x040449 0x000764 0x0c2c8a 0x1852b1 0x397dd1 
@@ -57,13 +91,7 @@
57 91
                 )
58 92
                 (else? (ld r0 0))
59 93
             )
60
-            (cmp big 1)
61
-            (j.ne :not_big)
62
-            (sc-rect x y COL_SKIP ROW_SKIP r0)
63
-            (j :was_big)
64
-            (:not_big)
65
-            (sc-wr x y r0)
66
-            (:was_big)
94
+            (sc-rect x y size size r0)
67 95
             (add x COL_SKIP)
68 96
             (cmp x W)
69 97
             (j.lt :col)
@@ -126,14 +154,19 @@
126 154
 
127 155
         ; mark this as a first render and reset col_skip and row_skip
128 156
         (ld is_first_render 1)
129
-        (ld mb_col_skip 0)
130
-        (ld mb_row_skip 0)
157
+        (ld mb_skip_index 0)
131 158
     (:did_not_move)
132 159
 
133
-    ; render row mb_row + mb_row_skip
160
+    (sym mb_col_skip r9)
161
+    (sym mb_row_skip r11)
162
+    (bfrd mb_col_skip @mb_skip_table_x mb_skip_index)
163
+    (bfrd mb_row_skip @mb_skip_table_y mb_skip_index)
164
+    (bfrd r1 @mb_size_table mb_skip_index)
165
+
166
+    ; render row mb_row + row skip
134 167
     (ld r0 mb_row)
135 168
     (add r0 mb_row_skip)
136
-    (call render_row is_first_render mb_col_skip mb_x mb_y mb_s r0)
169
+    (call render_row r1 mb_col_skip mb_x mb_y mb_s r0)
137 170
 
138 171
     (cmp mb_row H)
139 172
         (j.ge :render_done)
@@ -143,16 +176,14 @@
143 176
     (:render_done)
144 177
         ; otherwise, this frame is done
145 178
         (ld mb_row 0)
146
-        (add mb_col_skip 1)
179
+        (add mb_skip_index 1)
147 180
         (ld is_first_render 0)
148
-        (mod mb_col_skip COL_SKIP)
149
-
150
-        ; if mb_col_skip wrapped back to zero increase mb_row_skip
151
-        (cmp mb_col_skip 0)
152
-        (j.ne :not_col)
153
-        (add mb_row_skip 1)
154
-        (mod mb_row_skip ROW_SKIP)
155
-        (:not_col)
181
+
182
+        (cmp mb_skip_index MB_SKIP_TABLE_SIZE)
183
+            ; if skip index is out of bounds, go back to repeating area
184
+            (j.lt :not_end)
185
+            (ld mb_skip_index MB_SKIP_REPEAT_INDEX)
186
+        (:not_end)
156 187
     (:render_not_done)
157 188
     (j :slp)
158 189