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