Mercurial > public > algo-animator
comparison main.c @ 13:074bde2db09a
printing text with custom font but incorrect letters
author | Dennis C. M. <dennis@denniscm.com> |
---|---|
date | Sat, 24 Jun 2023 13:39:21 +0100 |
parents | 9ba546527bc2 |
children | d055228ca9a6 |
comparison
equal
deleted
inserted
replaced
12:9ba546527bc2 | 13:074bde2db09a |
---|---|
2 #include <stdlib.h> | 2 #include <stdlib.h> |
3 #include <GL/glut.h> | 3 #include <GL/glut.h> |
4 #include <math.h> | 4 #include <math.h> |
5 #include <time.h> | 5 #include <time.h> |
6 #include <stdbool.h> | 6 #include <stdbool.h> |
7 #include <ft2build.h> | |
8 #include FT_FREETYPE_H | |
7 | 9 |
8 | 10 |
9 #define WINDOW_HEIGHT 1080 | 11 #define WINDOW_HEIGHT 1080 |
10 #define WINDOW_WIDTH 1920 | 12 #define WINDOW_WIDTH 1920 |
11 #define OFFSET 150 | 13 #define OFFSET 150 |
12 #define RECT_WIDTH 5 | 14 #define RECT_WIDTH 5 |
13 #define SPACE 1 | 15 #define SPACE 1 |
14 | 16 |
15 | 17 |
16 // Globals | 18 /* Global variables */ |
19 | |
20 FT_Library ft_library; | |
21 FT_Face ft_face; | |
22 | |
17 char algos[4][50] = { | 23 char algos[4][50] = { |
18 "Bubble sort", | 24 "Bubble sort", |
19 "Selection sort", | 25 "Selection sort", |
20 "Insertion sort", | 26 "Insertion sort", |
21 "Quick sort" | 27 "Quick sort" |
29 int* arr; | 35 int* arr; |
30 | 36 |
31 bool run; | 37 bool run; |
32 | 38 |
33 | 39 |
34 // Algos | 40 /* Algorithms */ |
35 | 41 |
42 // Bubble sort | |
36 struct BubbleSortInfo { | 43 struct BubbleSortInfo { |
37 int step; | 44 int step; |
38 int i; | 45 int i; |
39 }; | 46 }; |
40 | 47 |
55 bs.step++; | 62 bs.step++; |
56 bs.i = 0; | 63 bs.i = 0; |
57 } | 64 } |
58 } | 65 } |
59 | 66 |
67 | |
68 /* Helper functions */ | |
60 | 69 |
61 void create_array() { | 70 void create_array() { |
62 arr_size = floor((WINDOW_WIDTH - RECT_WIDTH) / (RECT_WIDTH + SPACE)) + 1; | 71 arr_size = floor((WINDOW_WIDTH - RECT_WIDTH) / (RECT_WIDTH + SPACE)) + 1; |
63 arr = (int*)malloc(arr_size * sizeof(int)); | 72 arr = (int*)malloc(arr_size * sizeof(int)); |
64 | 73 |
92 if (selection >= lower && selection <= upper) { | 101 if (selection >= lower && selection <= upper) { |
93 selected_algo = selection; | 102 selected_algo = selection; |
94 } | 103 } |
95 } | 104 } |
96 | 105 |
97 // GL and GLUT | 106 |
98 void setup() { | 107 /* Render functions */ |
99 | |
100 // Set background dark | |
101 glClearColor(0.0, 0.0, 0.0, 1.0); | |
102 | |
103 // Set point color and size to 1 pixel | |
104 glColor3f(0.0, 1.0, 0.0); | |
105 glPointSize(5.0); | |
106 | |
107 // Matrix projection and reset with identity | |
108 glMatrixMode(GL_PROJECTION); | |
109 glLoadIdentity(); | |
110 | |
111 /* | |
112 * Creates projection matrix | |
113 * x increases from left to right (0 to WINDOW_WIDTH) | |
114 * y increases from bottom to top (0 to WINDOW_HEIGHT) | |
115 */ | |
116 gluOrtho2D(0, WINDOW_WIDTH, 0, WINDOW_HEIGHT); | |
117 | |
118 } | |
119 | |
120 | 108 |
121 void render_text(int x, int y, char* text) { | 109 void render_text(int x, int y, char* text) { |
122 glRasterPos2f(x, y); | 110 glRasterPos2f(x, y); |
123 | 111 |
124 for (const char *c = text; *c; ++c) { | 112 // Get glyph index from character code |
125 glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *c); | 113 FT_UInt glyph_index = FT_Get_Char_Index(ft_face, 'o'); |
126 } | 114 |
115 // Load glyph image | |
116 if (FT_Load_Glyph(ft_face, glyph_index, FT_LOAD_DEFAULT)) { | |
117 fprintf(stderr, "Failed to load glyph.\n"); | |
118 exit(1); | |
119 } | |
120 | |
121 | |
122 // Render glyph | |
123 if (FT_Render_Glyph(ft_face->glyph, FT_RENDER_MODE_NORMAL)) { | |
124 fprintf(stderr, "Failed to load glyph.\n"); | |
125 exit(1); | |
126 } | |
127 | |
128 FT_GlyphSlot ft_slot = ft_face->glyph; | |
129 FT_Bitmap* glyph_bitmap = &ft_slot->bitmap; | |
130 | |
131 glDrawPixels(glyph_bitmap->width, glyph_bitmap->rows, GL_LUMINANCE, GL_UNSIGNED_BYTE, glyph_bitmap->buffer); | |
127 } | 132 } |
128 | 133 |
129 | 134 |
130 void display() { | 135 void display() { |
131 glClear(GL_COLOR_BUFFER_BIT); | 136 glClear(GL_COLOR_BUFFER_BIT); |
153 | 158 |
154 // Render text | 159 // Render text |
155 char text[256]; | 160 char text[256]; |
156 | 161 |
157 sprintf(text, "Algorithm: %s", algos[selected_algo]); | 162 sprintf(text, "Algorithm: %s", algos[selected_algo]); |
158 render_text(20, OFFSET - 50, text); | 163 render_text(20, WINDOW_HEIGHT - 50, text); |
159 | 164 |
160 sprintf(text, "Number of elements: %i", arr_size); | 165 sprintf(text, "Number of elements: %i", arr_size); |
161 render_text(20, OFFSET - 75, text); | 166 render_text(20, WINDOW_HEIGHT - 75, text); |
162 | 167 |
163 sprintf(text, "Iterations: %i", iter_counter); | 168 sprintf(text, "Iterations: %i", iter_counter); |
164 render_text(20, OFFSET - 100, text); | 169 render_text(20, WINDOW_HEIGHT - 100, text); |
165 | 170 |
166 | 171 render_text(20, OFFSET - 50, "Press 'a' or 's' to select an algorithm"); |
167 render_text(WINDOW_WIDTH - 500, OFFSET - 50, "Press 'a' or 's' to select an algorithm"); | 172 render_text(20, OFFSET - 75, "Press 'enter' to run the algorithm"); |
168 render_text(WINDOW_WIDTH - 500, OFFSET - 75, "Press 'enter' to run the algorithm"); | 173 render_text(20, OFFSET - 100, "Press 'r' to reset array"); |
169 render_text(WINDOW_WIDTH - 500, OFFSET - 100, "Press 'r' to reset array"); | |
170 | 174 |
171 glutSwapBuffers(); | 175 glutSwapBuffers(); |
172 } | 176 } |
173 | 177 |
178 | |
179 /* Refresh function */ | |
174 | 180 |
175 void idle() { | 181 void idle() { |
176 if (run) { | 182 if (run) { |
177 bubble_sort(); | 183 bubble_sort(); |
178 refresh_counter++; | 184 refresh_counter++; |
190 if (array_sorted()) { | 196 if (array_sorted()) { |
191 run = false; | 197 run = false; |
192 } | 198 } |
193 } | 199 } |
194 | 200 |
201 | |
202 /* User input handler */ | |
195 | 203 |
196 void keyboard(unsigned char key, int x, int y) { | 204 void keyboard(unsigned char key, int x, int y) { |
197 | 205 |
198 // s | 206 // s |
199 if (key == 115) { | 207 if (key == 115) { |
219 run = true; | 227 run = true; |
220 } | 228 } |
221 } | 229 } |
222 | 230 |
223 | 231 |
232 /* Set up functions */ | |
233 | |
234 void init_gl() { | |
235 | |
236 // Set background dark | |
237 glClearColor(0.0, 0.0, 0.0, 1.0); | |
238 | |
239 // Set point color and size to 1 pixel | |
240 glColor3f(1.0, 0.7569, 0.0); | |
241 glPointSize(5.0); | |
242 | |
243 // Matrix projection and reset with identity | |
244 glMatrixMode(GL_PROJECTION); | |
245 glLoadIdentity(); | |
246 | |
247 /* | |
248 * Creates projection matrix | |
249 * x increases from left to right (0 to WINDOW_WIDTH) | |
250 * y increases from bottom to top (0 to WINDOW_HEIGHT) | |
251 */ | |
252 gluOrtho2D(0, WINDOW_WIDTH, 0, WINDOW_HEIGHT); | |
253 } | |
254 | |
255 | |
256 void init_freetype() { | |
257 | |
258 // Init library | |
259 if (FT_Init_FreeType(&ft_library)) { | |
260 fprintf(stderr, "Failed to initialize FreeType library\n"); | |
261 exit(1); | |
262 } | |
263 | |
264 // Load font | |
265 if (FT_New_Face(ft_library, "JetBrainsMono-Medium.ttf", 0, &ft_face)) { | |
266 fprintf(stderr, "Failed to load font\n"); | |
267 exit(1); | |
268 } | |
269 | |
270 // Set font size | |
271 if (FT_Set_Pixel_Sizes(ft_face, 0, 24)) { | |
272 fprintf(stderr, "Failed to set font size.\n"); | |
273 FT_Done_Face(ft_face); | |
274 FT_Done_FreeType(ft_library); | |
275 | |
276 exit(1); | |
277 } | |
278 } | |
279 | |
280 | |
224 int main(int argc, char** argv) { | 281 int main(int argc, char** argv) { |
225 create_array(); | 282 create_array(); |
226 | 283 |
227 glutInit(&argc, argv); | 284 glutInit(&argc, argv); |
228 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); | 285 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); |
229 glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); | 286 glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); |
230 glutCreateWindow("OpenGL Window"); | 287 glutCreateWindow("Algorithm animator"); |
231 setup(); | 288 |
289 init_gl(); | |
290 init_freetype(); | |
291 | |
232 glutDisplayFunc(display); | 292 glutDisplayFunc(display); |
233 glutKeyboardFunc(keyboard); | 293 glutKeyboardFunc(keyboard); |
234 glutIdleFunc(idle); | 294 glutIdleFunc(idle); |
235 glutMainLoop(); | 295 glutMainLoop(); |
236 | 296 |
237 free(arr); | 297 free(arr); |
238 | 298 |
239 return 0; | 299 return 0; |
240 } | 300 } |
241 | |
242 |