Clean up interface and add prefixes to everything

Francesco Pasa 10 months ago

examples/shapes.c   M +16 -16

 6     options.clear_color.r = 0.02;
 7     options.clear_color.g = 0.02;
 8     options.clear_color.b = 0.02;
 9-    AlbaWindow* window = create_window(&options);
10+    AlbaWindow* window = alba_create_window(&options);
11 
12     const AlbaVector tri_vertices[] = {
13         100, 100,
24         {{1, 1, 1, 0.2}, {-1, -1}},
25     };
26     uint32_t indices[] = {0, 1, 2, 0, 3, 4};
27-    draw_triangles_indexed(window, 5, tri_vertices, attributes, 6, indices);
28+    alba_draw_triangles_indexed(window, 5, tri_vertices, attributes, 6, indices);
29 
30     const AlbaColor blue = {0, 0.4, 1, 1};
31-    draw_rect_aa(window, 350, 100, 500, 150, blue);
32+    alba_draw_rect_aa(window, 350, 100, 500, 150, blue);
33 
34     const float rect_vertices[] = {350, 300, 500, 350, 450, 400, 300, 350};
35-    draw_quad(window, rect_vertices, blue);
36+    alba_draw_quad(window, rect_vertices, blue);
37 
38-    draw_regular_polygon(window, 5, 320, 240, 20, blue);
39-    draw_circle(window, 400, 240, 5, blue);
40-    draw_circle(window, 420, 240, 6, blue);
41-    draw_circle(window, 440, 240, 7, blue);
42-    draw_circle(window, 460, 240, 10, blue);
43-    draw_circle(window, 480, 240, 15, blue);
44-    draw_circle(window, 500, 240, 20, blue);
45-    draw_circle(window, 400, 640, 200, blue);
46+    alba_draw_regular_polygon(window, 5, 320, 240, 20, blue);
47+    alba_draw_circle(window, 400, 240, 5, blue);
48+    alba_draw_circle(window, 420, 240, 6, blue);
49+    alba_draw_circle(window, 440, 240, 7, blue);
50+    alba_draw_circle(window, 460, 240, 10, blue);
51+    alba_draw_circle(window, 480, 240, 15, blue);
52+    alba_draw_circle(window, 500, 240, 20, blue);
53+    alba_draw_circle(window, 400, 640, 200, blue);
54 
55-    draw_rounded_rect_aa(window, 350, 30, 500, 80, 10, blue);
56+    alba_draw_rounded_rect_aa(window, 350, 30, 500, 80, 10, blue);
57 
58-    while (!window_should_close(window))
59+    while (!alba_window_should_close(window))
60     {
61-        window_render(window);
62+        alba_window_render(window);
63     }
64 
65-    window_release(window);
66+    alba_window_release(window);
67     alba_release();
68 }

examples/text.c   M +6 -6

 7     options.clear_color.r = 0.02;
 8     options.clear_color.g = 0.02;
 9     options.clear_color.b = 0.02;
10-    AlbaWindow* window = create_window(&options);
11+    AlbaWindow* window = alba_create_window(&options);
12 
13-    draw_text(window, (AlbaVector){100, 100}, (AlbaColor)YELLOW, 0, "7 lm francesco");
14+    alba_draw_text(window, (AlbaVector){100, 100}, (AlbaColor)YELLOW, 0, "7 lm francesco");
15     // draw_text(window, (AlbaVector){100, 200}, (AlbaColor)WHITE, 0, "ß 🍔");
16-    draw_text(window, (AlbaVector){100, 200}, (AlbaColor)CYAN, 0,
17+    alba_draw_text(window, (AlbaVector){100, 200}, (AlbaColor)CYAN, 0,
18               "DESCRIPTION\n       The malloc() function allocates size bytes and returns a pointer to the allocated memory.  The memory is not initialized.  If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().         The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc(), or realloc().  Otherwise, or if free(ptr) has already been called before, undefined behavior occurs.  If ptr is NULL,        no operation is performed.         The calloc() function allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated memory.  The memory is set to zero.  If nmemb or size is 0, then calloc() returns either NULL, or a  unique  pointer  value        that can later be successfully passed to free().  If the multiplication of nmemb and size would result in integer overflow, then calloc() returns an error.  By contrast, an integer overflow would not be detected in the following call to malloc(), with        the result that an incorrectly sized block of memory would be allocated:             malloc(nmemb * size);         The realloc() function changes the size of the memory block pointed to by ptr to size bytes.  The contents will be unchanged in the range from the start of the region up to the minimum of the old and new sizes.  If the new size is larger than the  old        size, the added memory will not be initialized.  If ptr is NULL, then the call is equivalent to malloc(size), for all values of size; if size is equal to zero, and ptr is not NULL, then the call is equivalent to free(ptr).  Unless ptr is NULL, it must        have been returned by an earlier call to malloc(), calloc(), or realloc().  If the area pointed to was moved, a free(ptr) is done.         The reallocarray() function changes the size of the memory block pointed to by ptr to be large enough for an array of nmemb elements, each of which is size bytes.  It is equivalent to the call                 realloc(ptr, nmemb * size);         However, unlike that realloc() call, reallocarray() fails safely in the case where the multiplication would overflow.  If such an overflow occurs, reallocarray() returns NULL, sets errno to ENOMEM, and leaves the original block of memory unchanged.  RETURN VALUE        The malloc() and calloc() functions return a pointer to the allocated memory, which is suitably aligned for any built-in type.  On error, these functions return NULL.  N");
19 
20-    while (!window_should_close(window))
21+    while (!alba_window_should_close(window))
22     {
23-        window_render(window);
24+        alba_window_render(window);
25     }
26 
27-    window_release(window);
28+    alba_window_release(window);
29     alba_release();
30 }

include/alba.h   M +42 -71

13     uint64_t length;
14     uint64_t capacity;
15     void* data;
16-} DynArray;
17-
18-DynArray dynarray_new(uint64_t element_size, uint64_t capacity);
19-void dynarray_reserve(DynArray* array, uint64_t request);
20-void dynarray_append(DynArray* array, const void* value);
21-void dynarray_extend(DynArray* array, uint64_t size, const void* data);
22-void dynarray_release(const DynArray* array);
23-void dynarray_clear(DynArray* array);
24-void dynarray_sort(const DynArray* array, uint32_t (*is_before_pivot)(void* pivot, void* elem));
25-void dynarray_print(const DynArray* array, void (*print_element)(void* element));
26-
27-// Misc
28+} AlbaDynArray;
29+
30+AlbaDynArray dynarray_new(uint64_t element_size, uint64_t capacity);
31+void alba_dynarray_reserve(AlbaDynArray* array, uint64_t request);
32+void alba_dynarray_append(AlbaDynArray* array, const void* value);
33+void alba_dynarray_extend(AlbaDynArray* array, uint64_t size, const void* data);
34+void alba_dynarray_release(const AlbaDynArray* array);
35+void alba_dynarray_clear(AlbaDynArray* array);
36+void alba_dynarray_sort(const AlbaDynArray* array, uint32_t (*is_before_pivot)(void* pivot, void* elem));
37+void alba_dynarray_print(const AlbaDynArray* array, void (*print_element)(void* element));
38+
39+// Helper structures
40 typedef struct
41 {
42     float r, g, b, a;
40 #define MAGENTA {1, 0, 1, 1}
41 #define CYAN {0, 1, 1, 1}
42 
43-void color_print(const AlbaColor* color);
44+void alba_color_print(const AlbaColor* color);
45 
46 typedef struct
47 {
48     float x, y;
49 } AlbaVector;
50 
51-void vector_print(const AlbaVector* vector);
52+void alba_vector_print(const AlbaVector* vector);
53 
54-inline AlbaVector vector_add(const AlbaVector a, const AlbaVector b)
55+inline AlbaVector alba_vector_add(const AlbaVector a, const AlbaVector b)
56 {
57     return (AlbaVector){a.x + b.x, a.y + b.y};
58 }
59 
60-inline AlbaVector vector_sub(const AlbaVector a, const AlbaVector b)
61+inline AlbaVector alba_vector_sub(const AlbaVector a, const AlbaVector b)
62 {
63     return (AlbaVector){a.x - b.x, a.y - b.y};
64 }
65 
66-inline AlbaVector vector_mul(const AlbaVector a, const AlbaVector b)
67+inline AlbaVector alba_vector_mul(const AlbaVector a, const AlbaVector b)
68 {
69     return (AlbaVector){a.x * b.x, a.y * b.y};
70 }
71 
72-inline AlbaVector vector_div(const AlbaVector a, const AlbaVector b)
73+inline AlbaVector alba_vector_div(const AlbaVector a, const AlbaVector b)
74 {
75     return (AlbaVector){a.x / b.x, a.y / b.y};
76 }
75     AlbaVector uv;
76 } AlbaAttribute;
77 
78-void attribute_print(const AlbaAttribute* attribute);
79+void alba_attribute_print(const AlbaAttribute* attribute);
80 
81 // Window
82 typedef struct
 86     AlbaColor clear_color;
 87 } AlbaWindowOptions;
 88 
 89-// TODO: make opaque
 90-typedef struct
 91-{
 92-    // if set, the next frame will update the buffers
 93-    int dirty;
 94-    DynArray new_vertices;
 95-    WGPUBuffer vertices;
 96-    DynArray new_attributes;
 97-    WGPUBuffer attributes;
 98-    DynArray new_indices;
 99-    WGPUBuffer indices;
100-    WGPUBuffer uniforms;
101-    WGPUTexture texture;
102-    WGPURenderPipeline pipeline;
103-    WGPUBindGroup bind_group;
104-} RenderPassData;
105-
106-// TODO: make opaque
107-typedef struct
108-{
109-    AlbaWindowOptions options;
110-    GLFWwindow* glfw_window;
111-    AlbaVector size;
112-    AlbaVector scale;
113-    WGPUInstance instance;
114-    WGPUSurface surface;
115-    WGPUAdapter adapter;
116-    WGPUDevice device;
117-    WGPUQueue queue;
118-    WGPUShaderModule shaders;
119-    RenderPassData drawing;
120-    RenderPassData text;
121-} AlbaWindow;
122-
123-AlbaWindow* create_window(const AlbaWindowOptions* options);
124-uint32_t window_should_close(const AlbaWindow* window);
125+typedef struct RenderPassDataImpl RenderPassData;
126+typedef struct AlbaWindowImpl AlbaWindow;
127+
128+AlbaWindow* alba_create_window(const AlbaWindowOptions* options);
129+uint32_t alba_window_should_close(const AlbaWindow* window);
130+// TODO: think about API here, use AlbaVector
131 // Returns window size, in scaled coordinates (e.g. will honor
132 // the windowing system scaling). The point at this coordinate
133 // is at the bottom right of the window.
134-void window_get_size(const AlbaWindow* window, float* width, float* height);
135-void window_render(AlbaWindow* window);
136-void window_release(AlbaWindow* window);
137+void alba_window_get_size(const AlbaWindow* window, float* width, float* height);
138+void alba_window_render(AlbaWindow* window);
139+void alba_window_release(AlbaWindow* window);
140 
141 void alba_release();
142 
143 // Low level drawing
144-void draw_triangles_indexed(
145+void alba_draw_triangles_indexed(
146     AlbaWindow* window,
147     uint32_t num_vertices,
148     const AlbaVector* vertices,
110     uint32_t num_indices,
111     uint32_t* indices
112 );
113-void draw_triangles(
114+void alba_draw_triangles(
115     AlbaWindow* window,
116     uint32_t num_vertices,
117     const AlbaVector* vertices,
118 );
119 
120 // Higher level drawing
121-void draw_triangle(AlbaWindow* window, const AlbaVector vertices[3], AlbaColor color);
122-void draw_quad(AlbaWindow* window, const AlbaVector vertices[4], AlbaColor color);
123-void draw_rect_aa(AlbaWindow* window, float x0, float y0, float x1, float y1, AlbaColor color);
124+void alba_draw_triangle(AlbaWindow* window, const AlbaVector vertices[3], AlbaColor color);
125+void alba_draw_quad(AlbaWindow* window, const AlbaVector vertices[4], AlbaColor color);
126+void alba_draw_rect_aa(AlbaWindow* window, float x0, float y0, float x1, float y1, AlbaColor color);
127 
128-void generate_regular_polygon(DynArray* array, uint32_t num_sides, float x, float y, float r);
129-void generate_circle(DynArray* array, float x, float y, float r);
130-void generate_rounded_rect_aa(DynArray* array, float x0, float y0, float x1, float y1, float r);
131+void alba_generate_regular_polygon(AlbaDynArray* array, uint32_t num_sides, float x, float y, float r);
132+void alba_generate_circle(AlbaDynArray* array, float x, float y, float r);
133+void alba_generate_rounded_rect_aa(AlbaDynArray* array, float x0, float y0, float x1, float y1, float r);
134 
135-void draw_concave_polygon(AlbaWindow* window, float x, float y, const DynArray* contour, AlbaColor color);
136-void draw_regular_polygon(AlbaWindow* window, uint32_t num_sides, float x, float y, float r, AlbaColor color);
137-void draw_circle(AlbaWindow* window, float x, float y, float r, AlbaColor color);
138-void draw_rounded_rect_aa(AlbaWindow* window, float x0, float y0, float x1, float y1, float r, AlbaColor color);
139+void alba_draw_concave_polygon(AlbaWindow* window, float x, float y, const AlbaDynArray* contour, AlbaColor color);
140+void alba_draw_regular_polygon(AlbaWindow* window, uint32_t num_sides, float x, float y, float r, AlbaColor color);
141+void alba_draw_circle(AlbaWindow* window, float x, float y, float r, AlbaColor color);
142+void alba_draw_rounded_rect_aa(AlbaWindow* window, float x0, float y0, float x1, float y1, float r, AlbaColor color);
143 
144-void draw_text(
145+// Text drawing
146+void alba_draw_text(
147     AlbaWindow* window,
148     AlbaVector pos, AlbaColor color,
149     uint64_t length, const char* text

src/atlas.c   M +22 -22

 9 
10 int compare_glyph(const void* va, const void* vb, void* udata)
11 {
12-    const Glyph* a = va;
13-    const Glyph* b = vb;
14+    const AlbaGlyph* a = va;
15+    const AlbaGlyph* b = vb;
16     return a->character - b->character;
17 }
18 
19 void free_glyph(void* vglyph)
20 {
21-    const Glyph* glyph = vglyph;
22+    const AlbaGlyph* glyph = vglyph;
23     free(glyph->bitmap.buffer);
24 }
25 
26-Atlas atlas_new(const uint32_t capacity)
27+AlbaAtlas atlas_new(const uint32_t capacity)
28 {
29-    Atlas atlas = {0};
30-    atlas.glyphs = hashmap_new(sizeof(Glyph), capacity, 0, 0, hash_glyph, compare_glyph, free_glyph, NULL);
31+    AlbaAtlas atlas = {0};
32+    atlas.glyphs = hashmap_new(sizeof(AlbaGlyph), capacity, 0, 0, hash_glyph, compare_glyph, free_glyph, NULL);
33     if (capacity != 0)
34     {
35         atlas_reserve(&atlas, capacity);
31     return atlas;
32 }
33 
34-void atlas_reserve(Atlas* atlas, const uint32_t capacity)
35+void atlas_reserve(AlbaAtlas* atlas, const uint32_t capacity)
36 {
37-    dynarray_reserve(&atlas->glyph_sizes, capacity * 4);
38+    alba_dynarray_reserve(&atlas->glyph_sizes, capacity * 4);
39 }
40 
41-void atlas_append(Atlas* atlas, const FT_Face face, const uint32_t character)
42+void atlas_append(AlbaAtlas* atlas, const FT_Face face, const uint32_t character)
43 {
44     const FT_Long glyph_index = FT_Load_Char(face, character, FT_LOAD_RENDER);
45 
46     const FT_Bitmap* bitmap = &face->glyph->bitmap;
47-    Glyph glyph = {
48+    AlbaGlyph glyph = {
49         .character = character,
50         .glyph_index = glyph_index,
51         .metrics = face->glyph->metrics,
61 
62 uint32_t sort_by_height_desc(void* vpivot, void* velem)
63 {
64-    const Glyph** pivot = vpivot;
65-    const Glyph** elem = velem;
66+    const AlbaGlyph** pivot = vpivot;
67+    const AlbaGlyph** elem = velem;
68     return (*elem)->bitmap.rows > (*pivot)->bitmap.rows;
69 }
70 
138 }
139 
140 // TODO: mutex?
141-void atlas_generate_image(Atlas* atlas)
142+void atlas_generate_image(AlbaAtlas* atlas)
143 {
144     if (atlas->dirty == 0) return;
145 
146     // Sort caracters by height
147     size_t iter = 0;
148-    Glyph* glyph;
149-    DynArray glyphs = dynarray_new(sizeof(Glyph*), hashmap_count(atlas->glyphs));
150+    AlbaGlyph* glyph;
151+    AlbaDynArray glyphs = dynarray_new(sizeof(AlbaGlyph*), hashmap_count(atlas->glyphs));
152     while (hashmap_iter(atlas->glyphs, &iter, (void**)&glyph))
153     {
154-        dynarray_append(&glyphs, &glyph);
155+        alba_dynarray_append(&glyphs, &glyph);
156     }
157-    dynarray_sort(&glyphs, sort_by_height_desc);
158+    alba_dynarray_sort(&glyphs, sort_by_height_desc);
159 
160     // Calculate minimum size that fits the characters
161     uint32_t image_size = 256;
162         uint32_t row_height = 0;
163         for (uint32_t i = 0; i < glyphs.length; i++)
164         {
165-            glyph = ((Glyph**)glyphs.data)[i];
166+            glyph = ((AlbaGlyph**)glyphs.data)[i];
167 
168             // Go to new line
169             if (x + glyph->bitmap.width > image_size)
206     uint32_t row_height = 0;
207     for (uint32_t i = 0; i < glyphs.length; i++)
208     {
209-        glyph = ((Glyph**)glyphs.data)[i];
210+        glyph = ((AlbaGlyph**)glyphs.data)[i];
211 
212         if (x + glyph->bitmap.width > image_size)
213         {
233 
234     // write_png("test.png", image_size, image_size, 32, atlas->image);
235 
236-    dynarray_release(&glyphs);
237+    alba_dynarray_release(&glyphs);
238 
239     atlas->dirty = 0;
240 }
241 
242-void atlas_release(const Atlas* atlas)
243+void atlas_release(const AlbaAtlas* atlas)
244 {
245     hashmap_free(atlas->glyphs);
246-    dynarray_release(&atlas->glyph_sizes);
247+    alba_dynarray_release(&atlas->glyph_sizes);
248     if (atlas->image != NULL)
249     {
250         free(atlas->image);

src/drawing.c   M +44 -44

19 {
20     const uint32_t offset = data->new_vertices.length;
21 
22-    dynarray_extend(&data->new_vertices, num_vertices, vertices);
23-    dynarray_extend(&data->new_attributes, num_vertices, attributes);
24+    alba_dynarray_extend(&data->new_vertices, num_vertices, vertices);
25+    alba_dynarray_extend(&data->new_attributes, num_vertices, attributes);
26 
27     if (offset > 0)
28     {
30             indices[i] += offset;
31         }
32     }
33-    dynarray_extend(&data->new_indices, num_indices, indices);
34+    alba_dynarray_extend(&data->new_indices, num_indices, indices);
35 
36     data->dirty = 1;
37 }
38 
39-void draw_triangles_indexed(
40+void alba_draw_triangles_indexed(
41     AlbaWindow* window,
42     const uint32_t num_vertices,
43     const AlbaVector* vertices,
47     draw_triangles_indexed_render_pass(&window->drawing, num_vertices, vertices, attributes, num_indices, indices);
48 }
49 
50-void draw_triangles(
51+void alba_draw_triangles(
52     AlbaWindow* window,
53     const uint32_t num_vertices,
54     const AlbaVector* vertices,
69         indices[i] = i;
70     }
71 
72-    draw_triangles_indexed(window, num_vertices, vertices, attributes, num_vertices, indices);
73+    alba_draw_triangles_indexed(window, num_vertices, vertices, attributes, num_vertices, indices);
74 
75     free(indices);
76 }
77 
78-void draw_triangle(AlbaWindow* window, const AlbaVector vertices[3], const AlbaColor color)
79+void alba_draw_triangle(AlbaWindow* window, const AlbaVector vertices[3], const AlbaColor color)
80 {
81     const AlbaAttribute attributes[] = {
82         color, NO_TEXTURE,
83     };
84     // Does not try to consider winding order
85     uint32_t indices[] = {0, 1, 2};
86-    draw_triangles_indexed(window, 3, vertices, attributes, 3, indices);
87+    alba_draw_triangles_indexed(window, 3, vertices, attributes, 3, indices);
88 }
89 
90-void draw_quad(AlbaWindow* window, const AlbaVector vertices[4], const AlbaColor color)
91+void alba_draw_quad(AlbaWindow* window, const AlbaVector vertices[4], const AlbaColor color)
92 {
93     const AlbaAttribute attributes[] = {
94         color, NO_TEXTURE,
 96     };
 97     // Does not try to consider winding order
 98     uint32_t indices[] = {0, 1, 2, 0, 2, 3};
 99-    draw_triangles_indexed(window, 4, vertices, attributes, 6, indices);
100+    alba_draw_triangles_indexed(window, 4, vertices, attributes, 6, indices);
101 }
102 
103-void draw_rect_aa(
104+void alba_draw_rect_aa(
105     AlbaWindow* window,
106     const float x0, const float y0, const float x1, const float y1,
107     const AlbaColor color
122         x1, y1,
123         x1, y0,
124     };
125-    draw_quad(window, vertices, color);
126+    alba_draw_quad(window, vertices, color);
127 }
128 
129-void generate_regular_polygon(
130-    DynArray* array, const uint32_t num_sides,
131+void alba_generate_regular_polygon(
132+    AlbaDynArray* array, const uint32_t num_sides,
133     const float x, const float y, const float r)
134 {
135-    dynarray_reserve(array, array->length + num_sides);
136+    alba_dynarray_reserve(array, array->length + num_sides);
137 
138     const float step_angle = 2 * PI / num_sides;
139     for (uint32_t i = 0; i < num_sides; i++)
140     {
141-        dynarray_append(
142+        alba_dynarray_append(
143             array,
144             &(AlbaVector){
145                 x + r * sin(step_angle * i),
144     }
145 }
146 
147-void generate_circle(DynArray* array, const float x, const float y, const float r)
148+void alba_generate_circle(AlbaDynArray* array, const float x, const float y, const float r)
149 {
150     const uint32_t num_sides = round(PI / acos(1 - MAX_ERROR / r));
151-    generate_regular_polygon(array, num_sides, x, y, r);
152+    alba_generate_regular_polygon(array, num_sides, x, y, r);
153 }
154 
155-void generate_rounded_rect_aa(
156-    DynArray* array,
157+void alba_generate_rounded_rect_aa(
158+    AlbaDynArray* array,
159     const float x0, const float y0, const float x1, const float y1,
160     float r
161 )
165     if (x1 - x0 < r) r = (x1 - x0) / 2;
166     if (y1 - y0 < r) r = (y1 - y0) / 2;
167 
168-    dynarray_reserve(array, array->length + num_sides);
169+    alba_dynarray_reserve(array, array->length + num_sides);
170 
171     uint32_t i = 0;
172     for (; i < num_sides_per_corner + 1; i++)
173     {
174-        dynarray_append(
175+        alba_dynarray_append(
176             array, &(AlbaVector){
177                 x0 + r - r * sin(step_angle * i),
178                 y0 + r - r * cos(step_angle * i)
180 
181     for (; i < 2 * num_sides_per_corner + 1; i++)
182     {
183-        dynarray_append(
184+        alba_dynarray_append(
185             array, &(AlbaVector){
186                 x0 + r - r * sin(step_angle * i),
187                 y1 - r - r * cos(step_angle * i)
190 
191     for (; i < 3 * num_sides_per_corner + 1; i++)
192     {
193-        dynarray_append(
194+        alba_dynarray_append(
195             array, &(AlbaVector){
196                 x1 - r - r * sin(step_angle * i),
197                 y1 - r - r * cos(step_angle * i)
200 
201     for (; i < 4 * num_sides_per_corner + 1; i++)
202     {
203-        dynarray_append(
204+        alba_dynarray_append(
205             array, &(AlbaVector){
206                 x1 - r - r * sin(step_angle * i),
207                 y0 + r - r * cos(step_angle * i)
208     }
209 }
210 
211-void draw_concave_polygon(AlbaWindow* window, const float x, const float y, const DynArray* contour,
212+void alba_draw_concave_polygon(AlbaWindow* window, const float x, const float y, const AlbaDynArray* contour,
213                           const AlbaColor color)
214 {
215     const uint32_t num_sides = contour->length;
216     const uint32_t num_triangles = num_sides - 2;
217 
218-    DynArray attributes = dynarray_new(sizeof(AlbaAttribute), num_sides);
219+    AlbaDynArray attributes = dynarray_new(sizeof(AlbaAttribute), num_sides);
220     for (uint32_t i = 0; i < num_sides; i++)
221     {
222-        dynarray_append(&attributes, &(AlbaAttribute){color, NO_TEXTURE});
223+        alba_dynarray_append(&attributes, &(AlbaAttribute){color, NO_TEXTURE});
224     }
225 
226     uint32_t* indices = malloc(num_triangles * 3 * sizeof(uint32_t));
228         indices[i * 3 + 2] = i + 2;
229     }
230 
231-    draw_triangles_indexed(
232+    alba_draw_triangles_indexed(
233         window,
234         num_sides, contour->data, attributes.data,
235         num_triangles * 3, indices
237     free(indices);
238 }
239 
240-void draw_regular_polygon(
241+void alba_draw_regular_polygon(
242     AlbaWindow* window, const uint32_t num_sides,
243     const float x, const float y, const float r,
244     const AlbaColor color
250         exit(1);
251     }
252 
253-    DynArray polygon = dynarray_new(sizeof(AlbaVector), 0);
254-    generate_regular_polygon(&polygon, num_sides, x, y, r);
255-    draw_concave_polygon(window, x, y, &polygon, color);
256-    dynarray_release(&polygon);
257+    AlbaDynArray polygon = dynarray_new(sizeof(AlbaVector), 0);
258+    alba_generate_regular_polygon(&polygon, num_sides, x, y, r);
259+    alba_draw_concave_polygon(window, x, y, &polygon, color);
260+    alba_dynarray_release(&polygon);
261 }
262 
263-void draw_circle(AlbaWindow* window, const float x, const float y, const float r, const AlbaColor color)
264+void alba_draw_circle(AlbaWindow* window, const float x, const float y, const float r, const AlbaColor color)
265 {
266-    DynArray circle = dynarray_new(sizeof(AlbaVector), 0);
267-    generate_circle(&circle, x, y, r);
268-    draw_concave_polygon(window, x, y, &circle, color);
269-    dynarray_release(&circle);
270+    AlbaDynArray circle = dynarray_new(sizeof(AlbaVector), 0);
271+    alba_generate_circle(&circle, x, y, r);
272+    alba_draw_concave_polygon(window, x, y, &circle, color);
273+    alba_dynarray_release(&circle);
274 }
275 
276 
277-void draw_rounded_rect_aa(
278+void alba_draw_rounded_rect_aa(
279     AlbaWindow* window,
280     const float x0, const float y0, const float x1, const float y1,
281     const float r, const AlbaColor color)
282 {
283     if (r == 0)
284     {
285-        draw_rect_aa(window, x0, y0, x1, y1, color);
286+        alba_draw_rect_aa(window, x0, y0, x1, y1, color);
287         return;
288     }
289 
290-    DynArray contour = dynarray_new(sizeof(AlbaVector), 0);
291-    generate_rounded_rect_aa(&contour, x0, y0, x1, y1, r);
292-    draw_concave_polygon(window, (x0 + x1) / 2, (y0 + y1) / 2, &contour, color);
293+    AlbaDynArray contour = dynarray_new(sizeof(AlbaVector), 0);
294+    alba_generate_rounded_rect_aa(&contour, x0, y0, x1, y1, r);
295+    alba_draw_concave_polygon(window, (x0 + x1) / 2, (y0 + y1) / 2, &contour, color);
296 }

src/dynarray.c   M +11 -11

 5 #include <stdlib.h>
 6 #include <string.h>
 7 
 8-DynArray dynarray_new(const uint64_t element_size, const uint64_t capacity)
 9+AlbaDynArray dynarray_new(const uint64_t element_size, const uint64_t capacity)
10 {
11-    DynArray array = {0};
12+    AlbaDynArray array = {0};
13     array.element_size = element_size;
14     if (capacity > 0)
15     {
17     return array;
18 }
19 
20-void dynarray_reserve(DynArray* array, const uint64_t request)
21+void alba_dynarray_reserve(AlbaDynArray* array, const uint64_t request)
22 {
23     if (array->capacity > request) return;
24     if (array->capacity == 0) array->capacity = 16;
28     array->data = reallocarray(array->data, array->capacity, array->element_size);
29 }
30 
31-void dynarray_append(DynArray* array, const void* value)
32+void alba_dynarray_append(AlbaDynArray* array, const void* value)
33 {
34-    dynarray_extend(array, 1, value);
35+    alba_dynarray_extend(array, 1, value);
36 }
37 
38-void dynarray_extend(DynArray* array, const uint64_t size, const void* data)
39+void alba_dynarray_extend(AlbaDynArray* array, const uint64_t size, const void* data)
40 {
41-    dynarray_reserve(array, array->length + size);
42+    alba_dynarray_reserve(array, array->length + size);
43     memcpy(array->data + array->length * array->element_size, data, size * array->element_size);
44     array->length += size;
45 }
46 
47-void dynarray_release(const DynArray* array)
48+void alba_dynarray_release(const AlbaDynArray* array)
49 {
50     free(array->data);
51 }
52 
53-void dynarray_clear(DynArray* array)
54+void alba_dynarray_clear(AlbaDynArray* array)
55 {
56     array->length = 0;
57 }
 93     quicksort(element_size, length - num_elem_before - 1, data + size_before + element_size, is_before_pivot, temp);
 94 }
 95 
 96-void dynarray_sort(const DynArray* array, uint32_t (*is_before_pivot)(void* pivot, void* elem))
 97+void alba_dynarray_sort(const AlbaDynArray* array, uint32_t (*is_before_pivot)(void* pivot, void* elem))
 98 {
 99     void* temp = malloc(array->element_size);
100     quicksort(array->element_size, array->length, array->data, is_before_pivot, temp);
101     free(temp);
102 }
103 
104-void dynarray_print(const DynArray* array, void (*print_element)(void* element))
105+void alba_dynarray_print(const AlbaDynArray* array, void (*print_element)(void* element))
106 {
107     printf("len: %lu\n", array->length);
108     for (uint64_t i = 0; i < array->length; i++)

src/glfw_surface.c   M +1

1 #include "alba.h"
2+#include "internal.h"
3 
4 #include <stdio.h>
5 #include <stdlib.h>

src/helpers.c   M +5 -5

 2 
 3 #include <stdio.h>
 4 
 5-void color_print(const AlbaColor* color)
 6+void alba_color_print(const AlbaColor* color)
 7 {
 8     printf("AlbaColor{%f, %f, %f, %f}\n", color->r, color->g, color->b, color->a);
 9 }
10 
11-void vector_print(const AlbaVector* vector)
12+void alba_vector_print(const AlbaVector* vector)
13 {
14     printf("AlbaVector{%f, %f}\n", vector->x, vector->y);
15 }
16 
17-void attribute_print(const AlbaAttribute* attribute)
18+void alba_attribute_print(const AlbaAttribute* attribute)
19 {
20     printf("AlbaAttribute{\n    ");
21-    color_print(&attribute->color);
22+    alba_color_print(&attribute->color);
23     printf("    ");
24-    vector_print(&attribute->uv);
25+    alba_vector_print(&attribute->uv);
26     printf("}\n");
27 }

src/internal.h   M +40 -8

 7 
 8 #define NO_TEXTURE {-1, -1}
 9 
10+typedef struct RenderPassDataImpl
11+{
12+    // if set, the next frame will update the buffers
13+    int dirty;
14+    AlbaDynArray new_vertices;
15+    WGPUBuffer vertices;
16+    AlbaDynArray new_attributes;
17+    WGPUBuffer attributes;
18+    AlbaDynArray new_indices;
19+    WGPUBuffer indices;
20+    WGPUBuffer uniforms;
21+    WGPUTexture texture;
22+    WGPURenderPipeline pipeline;
23+    WGPUBindGroup bind_group;
24+} RenderPassData;
25+
26+typedef struct AlbaWindowImpl
27+{
28+    AlbaWindowOptions options;
29+    GLFWwindow* glfw_window;
30+    AlbaVector size;
31+    AlbaVector scale;
32+    WGPUInstance instance;
33+    WGPUSurface surface;
34+    WGPUAdapter adapter;
35+    WGPUDevice device;
36+    WGPUQueue queue;
37+    WGPUShaderModule shaders;
38+    RenderPassData drawing;
39+    RenderPassData text;
40+} AlbaWindow;
41+
42 // Atlas
43 typedef struct
44 {
48     FT_Bitmap bitmap;
49     AlbaVector start;
50     AlbaVector end;
51-} Glyph;
52+} AlbaGlyph;
53 
54 typedef struct
55 {
56     struct hashmap* glyphs;
57     int dirty;
58-    DynArray glyph_sizes; // in w, h order
59+    AlbaDynArray glyph_sizes; // in w, h order
60     AlbaVector size;
61     uint8_t* image;
62-} Atlas;
63+} AlbaAtlas;
64 
65-Atlas atlas_new(uint32_t capacity);
66-void atlas_reserve(Atlas* atlas, uint32_t capacity);
67-void atlas_append(Atlas* atlas, FT_Face face, uint32_t character);
68-void atlas_generate_image(Atlas* atlas);
69-void atlas_release(const Atlas* atlas);
70+AlbaAtlas atlas_new(uint32_t capacity);
71+void atlas_reserve(AlbaAtlas* atlas, uint32_t capacity);
72+void atlas_append(AlbaAtlas* atlas, FT_Face face, uint32_t character);
73+void atlas_generate_image(AlbaAtlas* atlas);
74+void atlas_release(const AlbaAtlas* atlas);
75 
76 // Helpers
77 WGPUTexture create_texture(

src/text.c   M +12 -12

10 
11 static FT_Library freetype = NULL;
12 static FT_Face roboto = NULL;
13-Atlas atlas;
14+AlbaAtlas atlas;
15 pthread_mutex_t freetype_mutex = PTHREAD_MUTEX_INITIALIZER;
16 
17 void initialize_freetype()
48     pthread_mutex_unlock(&freetype_mutex);
49 }
50 
51-void atlas_add_chars(Atlas* atlas, uint64_t length, const char* text)
52+void atlas_add_chars(AlbaAtlas* atlas, uint64_t length, const char* text)
53 {
54     for (uint64_t i = 0; i < length; i++)
55     {
62 }
63 
64 void atlas_generate_text_geometry(
65-    const Atlas* atlas,
66+    const AlbaAtlas* atlas,
67     const AlbaVector pos, const AlbaColor color,
68     uint64_t length, const char* text,
69-    DynArray* vertices, DynArray* attributes, DynArray* indices
70+    AlbaDynArray* vertices, AlbaDynArray* attributes, AlbaDynArray* indices
71 )
72 {
73     AlbaVector current = pos;
73     {
74         // TODO: mutex?
75         const FT_Long character = text[i]; // TODO: unicode
76-        const Glyph* glyph = hashmap_get(atlas->glyphs, &character);
77+        const AlbaGlyph* glyph = hashmap_get(atlas->glyphs, &character);
78         if (glyph == NULL)
79         {
80             fprintf(stderr, "error: unable to find glyph for character '%s'\n", (char*)&character);
86             current.y - metrics.horiBearingY / 64,
87         };
88         const uint32_t vertex_count = vertices->length;
89-        dynarray_extend(
90+        alba_dynarray_extend(
91             vertices, 4, (AlbaVector[]){
92                 origin,
93                 origin.x, origin.y + metrics.height / 64,
 94                 origin.x + metrics.width / 64, origin.y,
 95             });
 96 
 97-        dynarray_extend(
 98+        alba_dynarray_extend(
 99             attributes, 4, (AlbaAttribute[]){
100                 {color, glyph->start},
101                 {color, (AlbaVector){glyph->start.x, glyph->end.y}},
102                 {color, (AlbaVector){glyph->end.x, glyph->start.y}},
103             });
104 
105-        dynarray_extend(
106+        alba_dynarray_extend(
107             indices, 6, (uint32_t[]){
108                 // first triangle
109                 vertex_count,
119     }
120 }
121 
122-void draw_text(
123+void alba_draw_text(
124     AlbaWindow* window,
125     const AlbaVector pos, const AlbaColor color,
126     uint64_t length, const char* text
147     );
148     window->text.dirty = 1;
149 
150-    DynArray vertices = dynarray_new(sizeof(AlbaVector), length * 4);
151-    DynArray attributes = dynarray_new(sizeof(AlbaAttribute), length * 4);
152-    DynArray indices = dynarray_new(sizeof(uint32_t), length * 6);
153+    AlbaDynArray vertices = dynarray_new(sizeof(AlbaVector), length * 4);
154+    AlbaDynArray attributes = dynarray_new(sizeof(AlbaAttribute), length * 4);
155+    AlbaDynArray indices = dynarray_new(sizeof(uint32_t), length * 6);
156 
157     atlas_generate_text_geometry(
158         &atlas,

src/window.c   M +10 -10

340     data->new_indices = dynarray_new(sizeof(uint32_t), 0);
341 }
342 
343-AlbaWindow* create_window(const AlbaWindowOptions* options)
344+AlbaWindow* alba_create_window(const AlbaWindowOptions* options)
345 {
346     pthread_mutex_lock(&glfw_mutex);
347     if (!glfw_initialized)
417     return window;
418 }
419 
420-uint32_t window_should_close(const AlbaWindow* window)
421+uint32_t alba_window_should_close(const AlbaWindow* window)
422 {
423     const int should_close = glfwWindowShouldClose(window->glfw_window);
424     if (!should_close)
427     return should_close;
428 }
429 
430-void window_release(AlbaWindow* window)
431+void alba_window_release(AlbaWindow* window)
432 {
433     // TODO: destroy render pass
434     wgpuBufferDestroy(window->drawing.uniforms);
435 
436     wgpuBufferDestroy(window->drawing.vertices);
437     wgpuBufferRelease(window->drawing.vertices);
438-    dynarray_release(&window->drawing.new_vertices);
439+    alba_dynarray_release(&window->drawing.new_vertices);
440 
441     wgpuBufferDestroy(window->drawing.attributes);
442     wgpuBufferRelease(window->drawing.attributes);
443-    dynarray_release(&window->drawing.new_attributes);
444+    alba_dynarray_release(&window->drawing.new_attributes);
445 
446     wgpuBufferDestroy(window->drawing.indices);
447     wgpuBufferRelease(window->drawing.indices);
448-    dynarray_release(&window->drawing.new_indices);
449+    alba_dynarray_release(&window->drawing.new_indices);
450 
451     wgpuBindGroupRelease(window->drawing.bind_group);
452     wgpuRenderPipelineRelease(window->drawing.pipeline);
504     }
505 }
506 
507-WGPUBuffer update_buffer(const AlbaWindow* window, WGPUBuffer buffer, WGPUBufferUsage usage, DynArray data)
508+WGPUBuffer update_buffer(const AlbaWindow* window, WGPUBuffer buffer, WGPUBufferUsage usage, AlbaDynArray data)
509 {
510     // Deallocate old buffer if any
511     clear_buffer(buffer);
512     // Copy data to new buffer
513     buffer = create_buffer(window, data.length * data.element_size, data.data, usage);
514     // Clear local copy for next frame
515-    dynarray_clear(&data);
516+    alba_dynarray_clear(&data);
517     return buffer;
518 }
519 
584     wgpuCommandEncoderRelease(encoder);
585 }
586 
587-void window_render(AlbaWindow* window)
588+void alba_window_render(AlbaWindow* window)
589 {
590     WGPUSurfaceTexture frame;
591     wgpuSurfaceGetCurrentTexture(window->surface, &frame);
636 }
637 
638 
639-void window_get_size(const AlbaWindow* window, float* width, float* height)
640+void alba_window_get_size(const AlbaWindow* window, float* width, float* height)
641 {
642     int raw_width, raw_height;
643     float x_scale, y_scale;

tests/test_dynarray.c   M +7 -7

 4 
 5 START_TEST(test_dynarray_new)
 6 {
 7-    DynArray array = dynarray_new(sizeof(float), 0);
 8+    AlbaDynArray array = dynarray_new(sizeof(float), 0);
 9     ck_assert_int_eq(array.element_size, sizeof(float));
10     ck_assert_int_eq(array.capacity, 0);
11     ck_assert_int_eq(array.length, 0);
14 
15 START_TEST(test_dynarray_extend)
16 {
17-    DynArray array = dynarray_new(sizeof(float), 0);
18-    dynarray_extend(&array, 2, &(float[]){1.0, 2.0});
19+    AlbaDynArray array = dynarray_new(sizeof(float), 0);
20+    alba_dynarray_extend(&array, 2, &(float[]){1.0, 2.0});
21 
22     ck_assert_int_eq(array.element_size, sizeof(float));
23     ck_assert_int_eq(array.capacity, 16);
23     ck_assert_float_eq(((float*)array.data)[0], 1.0);
24     ck_assert_float_eq(((float*)array.data)[1], 2.0);
25 
26-    dynarray_extend(&array, 2, &(float[]){3.0, 4.0});
27+    alba_dynarray_extend(&array, 2, &(float[]){3.0, 4.0});
28     ck_assert_int_eq(array.capacity, 16);
29     ck_assert_int_eq(array.length, 4);
30     ck_assert_float_eq(((float*)array.data)[0], 1.0);
43 
44 START_TEST(test_dynarray_sort)
45 {
46-    DynArray array = dynarray_new(sizeof(float), 0);
47+    AlbaDynArray array = dynarray_new(sizeof(float), 0);
48     const float values[] = {7, 2.3, 5, 6, 2, 3, 4, 9, 1, 4};
49-    dynarray_extend(&array, 10, values);
50+    alba_dynarray_extend(&array, 10, values);
51 
52     ck_assert_int_eq(array.element_size, sizeof(float));
53     ck_assert_int_eq(array.length, 10);
54     ck_assert_int_eq(array.capacity, 16);
55 
56-    dynarray_sort(&array, compare_floats);
57+    alba_dynarray_sort(&array, compare_floats);
58 
59     ck_assert_float_eq(((float*)array.data) [0], 1);
60     ck_assert_float_eq(((float*)array.data) [1], 2);