Implement regular polygon drawing
Francesco Pasa 10 months ago
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+// }