Implement regular polygon drawing

Francesco Pasa 10 months ago

demo.c   M +11 -7

 8     options.clear_color.b = 0.02;
 9     AlbaWindow* window = create_window(&options);
10 
11-    float w, h;
12-    window_get_size(window, &w, &h);
13-    printf("%f %f\n", w, h);
14-
15-    const float vertices[] = {
16+    const float tri_vertices[] = {
17         100, 100,
18         100, 400,
19         200, 100,
23         1.0, 1.0, 1.0, 0.5,
24         1.0, 1.0, 1.0, 0.2,
25     };
26-    const uint32_t indices[] = {0, 1, 2, 0, 3, 4};
27-    draw_triangles_indexed(window, 5, vertices, color, 6, indices);
28+    uint32_t indices[] = {0, 1, 2, 0, 3, 4};
29+    draw_triangles_indexed(window, 5, tri_vertices, color, 6, indices);
30+
31+    const AlbaColor blue = {0.0, 0.4, 1.0, 1.0};
32+    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_rect(window, rect_vertices, blue);
36+
37+    draw_regular_polygon(window, 5, 320, 240, 20, blue);
38 
39     while (!window_should_close(window))
40     {

include/alba.h   M +19 -12

34 // Misc
35 typedef struct
36 {
37-    double r;
38-    double g;
39-    double b;
40-    double a;
41+    float r;
42+    float g;
43+    float b;
44+    float a;
45 } AlbaColor;
46 
47 // Window
 82 void window_release(AlbaWindow* window);
 83 
 84 // Low level drawing
 85-void draw_triangles(
 86+void draw_triangles_indexed(
 87     AlbaWindow* window,
 88-    uint64_t num_vertices,
 89+    uint32_t num_vertices,
 90     const float* vertices,
 91-    const float* attributes
 92+    const float* attributes,
 93+    uint32_t num_indices,
 94+    uint32_t* indices
 95 );
 96-void draw_triangles_indexed(
 97+void draw_triangles(
 98     AlbaWindow* window,
 99-    uint64_t num_vertices,
100+    uint32_t num_vertices,
101     const float* vertices,
102-    const float* attributes,
103-    uint64_t num_indices,
104-    const uint32_t* indices
105+    const float* attributes
106 );
107 
108 // Higher level drawing
102 void draw_rect(AlbaWindow* window, const float vertices[8], AlbaColor color);
103 void draw_rect_aa(AlbaWindow* window, float x0, float y0, float x1, float y1, AlbaColor color);
104 
105+void regular_polygon_points(FloatArray* array, uint32_t num_sides, float x, float y, float r);
106+// FloatArray circle_points(float x, float y, float r);
107+
108+void draw_concave_polygon(AlbaWindow* window, float x, float y, FloatArray* contour, AlbaColor color);
109+void draw_regular_polygon(AlbaWindow* window, uint32_t num_sides, float x, float y, float r, AlbaColor color);
110+// void draw_circle(AlbaColor window, float x, float y, float r);
111+
112 #endif // ALBA_H

src/drawing.c   M +141 -6

  1+#include <math.h>
  2+#include <stdio.h>
  3 #include <stdlib.h>
  4 
  5 #include "alba.h"
  6 
  7+#define PI 3.14159265358979323846
  8+
  9 void draw_triangles_indexed(
 10     AlbaWindow* window,
 11-    const uint64_t num_vertices,
 12+    const uint32_t num_vertices,
 13     const float* vertices,
 14     const float* attributes,
 15-    const uint64_t num_indices,
 16-    const uint32_t* indices
 17+    const uint32_t num_indices,
 18+    uint32_t* indices
 19 )
 20 {
 21+    const uint32_t offset = window->new_vertices.length / 2;
 22+
 23     float_array_extend(&window->new_vertices, num_vertices * 2, vertices);
 24     float_array_extend(&window->new_attributes, num_vertices * 4, attributes);
 25+
 26+    if (offset > 0)
 27+    {
 28+        // Fix indices
 29+        for (uint32_t i = 0; i < num_indices; i++)
 30+        {
 31+            indices[i] += offset;
 32+        }
 33+    }
 34     uint32_array_extend(&window->new_indices, num_indices, indices);
 35+
 36     window->dirty = 1;
 37 }
 38 
 39 void draw_triangles(
 40     AlbaWindow* window,
 41-    const uint64_t num_vertices,
 42+    const uint32_t num_vertices,
 43     const float* vertices,
 44     const float* attributes
 45 )
 46 {
 47     uint32_t* indices = malloc(num_vertices * sizeof(uint32_t));
 48-    for (uint64_t i = 0; i < num_vertices; i++)
 49+    if (indices == NULL)
 50+    {
 51+        printf(
 52+            "error: unable to allocate %lu bytes for triangle indices\n",
 53+            num_vertices * sizeof(uint32_t)
 54+        );
 55+        return;
 56+    }
 57+
 58+    for (uint32_t i = 0; i < num_vertices; i++)
 59     {
 60         indices[i] = i;
 61     }
 62-    uint32_array_extend(&window->new_indices, num_vertices, indices);
 63+
 64+    draw_triangles_indexed(window, num_vertices, vertices, attributes, num_vertices, indices);
 65+
 66+    free(indices);
 67+}
 68+
 69+void draw_triangle(AlbaWindow* window, const float vertices[6], const AlbaColor color)
 70+{
 71+    // Does not try to consider winding order
 72+    const float attributes[] = {
 73+        color.r, color.g, color.b, color.a,
 74+        color.r, color.g, color.b, color.a,
 75+        color.r, color.g, color.b, color.a,
 76+    };
 77+    uint32_t indices[] = {0, 1, 2};
 78+    draw_triangles_indexed(window, 3, vertices, attributes, 3, indices);
 79+}
 80+
 81+void draw_rect(AlbaWindow* window, const float vertices[8], const AlbaColor color)
 82+{
 83+    // Does not try to consider winding order
 84+    const float attributes[] = {
 85+        color.r, color.g, color.b, color.a,
 86+        color.r, color.g, color.b, color.a,
 87+        color.r, color.g, color.b, color.a,
 88+        color.r, color.g, color.b, color.a,
 89+    };
 90+    uint32_t indices[] = {0, 1, 2, 0, 2, 3};
 91+    draw_triangles_indexed(window, 4, vertices, attributes, 6, indices);
 92+}
 93+
 94+void draw_rect_aa(
 95+    AlbaWindow* window,
 96+    const float x0, const float y0, const float x1, const float y1,
 97+    const AlbaColor color
 98+)
 99+{
100+    // Does not try to consider winding order
101+    const float vertices[] = {
102+        x0, y0,
103+        x0, y1,
104+        x1, y1,
105+        x1, y0,
106+    };
107+    draw_rect(window, vertices, color);
108 }
109+
110+void regular_polygon_points(FloatArray* array, const uint32_t num_sides, const float x, const float y, const float r)
111+{
112+    float_array_reserve(array, array->length + num_sides * 2);
113+
114+    const float step_angle = 2 * PI / num_sides;
115+    for (uint32_t i = 0; i < num_sides; i++)
116+    {
117+        float_array_append(array, x + r * sin(step_angle * i));
118+        float_array_append(array, y - r * cos(step_angle * i));
119+    }
120+}
121+
122+void draw_concave_polygon(AlbaWindow* window, const float x, const float y, FloatArray* contour, AlbaColor color)
123+{
124+    const uint32_t num_sides = contour->length / 2;
125+    const uint32_t num_vertices = num_sides + 1;
126+
127+    float_array_append(contour, x);
128+    float_array_append(contour, y);
129+
130+    FloatArray colors = {0};
131+    float_array_reserve(&colors, num_vertices * 4);
132+    for (uint32_t i = 0; i < num_vertices; i++)
133+    {
134+        float_array_extend(&colors, 4, (float*)&color);
135+    }
136+
137+    uint32_t* indices = malloc(num_sides * 3 * sizeof(uint32_t));
138+    for (uint32_t i = 0; i < num_vertices; i++)
139+    {
140+        indices[i * 3] = 0;
141+        indices[i * 3 + 1] = i + 1;
142+        indices[i * 3 + 2] = i + 2;
143+    }
144+    indices[num_sides * 3 - 1] = 1;
145+
146+    draw_triangles_indexed(window, num_sides + 1, contour->data, colors.data, num_sides * 3, indices);
147+
148+    free(indices);
149+}
150+
151+void draw_regular_polygon(
152+    AlbaWindow* window, const uint32_t num_sides,
153+    const float x, const float y, const float r,
154+    const AlbaColor color
155+)
156+{
157+    if (num_sides <= 2)
158+    {
159+        printf("error: invalid number of sides in call to draw_regular_polygon: %d. "
160+               "A polygon must have at least 3 sides\n", num_sides);
161+        exit(1);
162+    }
163+    FloatArray polyon = {0};
164+    regular_polygon_points(&polyon, num_sides, x, y, r);
165+    draw_concave_polygon(window, x, y, &polyon, color);
166+    printf("%p\n", &polyon.data);
167+    float_array_release(&polyon);
168+}
169+
170+// FloatArray circle_points(float x, float y, float r)
171+// {
172+//     uint32_t num_points = 10;
173+//
174+// }