diff --git a/cudoku.c b/cudoku.c index b3f9660..e672a21 100644 --- a/cudoku.c +++ b/cudoku.c @@ -58,7 +58,7 @@ void draw_win() { /* set_width_constraint(&constraints, window.width, UI_CONSTRAINT_FIXED); */ /* set_height_constraint(&constraints, window.height, UI_CONSTRAINT_FIXED); */ - Alignment align = ALIGN_TOP_RIGHT; + Alignment align = ALIGN_CENTER; int font_size = 72.0f; Sizef text_size = calculate_text_size(win_text, font_size); @@ -67,12 +67,13 @@ void draw_win() { set_y_constraint(&constraints, 0, UI_CONSTRAINT_FIXED); set_width_constraint(&constraints, text_size.width, UI_CONSTRAINT_FIXED); set_height_constraint(&constraints, text_size.height, UI_CONSTRAINT_FIXED); + set_rotation_constraint(&constraints, get_time() * 50.f); - UIConstraints circle_const; - set_x_constraint(&circle_const, 50, UI_CONSTRAINT_FIXED); - set_y_constraint(&circle_const, 0, UI_CONSTRAINT_FIXED); - set_width_constraint(&circle_const, 70, UI_CONSTRAINT_FIXED); - set_height_constraint(&circle_const, 90, UI_CONSTRAINT_FIXED); + /* UIConstraints circle_const; */ + /* set_x_constraint(&circle_const, 50, UI_CONSTRAINT_FIXED); */ + /* set_y_constraint(&circle_const, 0, UI_CONSTRAINT_FIXED); */ + /* set_width_constraint(&circle_const, 70, UI_CONSTRAINT_FIXED); */ + /* set_height_constraint(&circle_const, 90, UI_CONSTRAINT_FIXED); */ /* draw_circle(circle_const, NULL, ALIGN_LEFT_CENTER); */ draw_quad(constraints, &bg_color, 0.0, align); @@ -84,7 +85,9 @@ void draw_win() { /* draw_triangle(constraints, &bg_color, ALIGN_CENTER); */ - draw_text(win_text, font_size, (Vec2f){0.0, 0.0}, &text_color, align); + set_width_constraint(&constraints, 1, UI_CONSTRAINT_FIXED); + set_height_constraint(&constraints, 1, UI_CONSTRAINT_FIXED); + draw_text(win_text, font_size, constraints, &text_color, align); } void set_scale_factor(int width, int height, float *x, float *y) { diff --git a/helper.c b/helper.c index f208a76..1741794 100644 --- a/helper.c +++ b/helper.c @@ -28,17 +28,33 @@ void mult_4x4(Matrix4x4 *multiplicant, Matrix4x4 *multiplier) { *multiplicant = result; } -// TODO: rotate around the center of the element -// currently we rotate around the 0, 0 point of the element +void apply_scale(Matrix4x4 *matrix, Sizef scale) { + Matrix4x4 temp = identity(); + + temp.m[0][0] = scale.width; + temp.m[1][1] = scale.height; + + mult_4x4(matrix, &temp); +} + void apply_rotation(Matrix4x4 *model, float angle) { - Matrix4x4 ident = identity(); + Matrix4x4 temp = identity(); - ident.m[0][0] = cos(angle); - ident.m[0][1] = sin(angle); - ident.m[1][0] = -sin(angle); - ident.m[1][1] = cos(angle); + temp.m[0][0] = cos(angle); + temp.m[0][1] = sin(angle); + temp.m[1][0] = -sin(angle); + temp.m[1][1] = cos(angle); - mult_4x4(model, &ident); + mult_4x4(model, &temp); +} + +void apply_translation(Matrix4x4 *matrix, Vec2f pos) { + Matrix4x4 temp = identity(); + + temp.m[3][0] = pos.x; + temp.m[3][1] = pos.y; + + mult_4x4(matrix, &temp); } Matrix4x4 orthographic_projection_2d(float left, float right, float bottom, float top) { diff --git a/helper.h b/helper.h index 60d72c6..4b789cd 100644 --- a/helper.h +++ b/helper.h @@ -1,12 +1,12 @@ #pragma once -typedef struct { - float m[4][4]; -} Matrix4x4; +#include "z_math.h" Matrix4x4 identity(); void mult_4x4(Matrix4x4 *multiplicant, Matrix4x4 *multiplier); +void apply_scale(Matrix4x4 *matrix, Sizef scale); void apply_rotation(Matrix4x4 *model, float angle); +void apply_translation(Matrix4x4 *matrix, Vec2f pos); Matrix4x4 orthographic_projection_2d(float left, float right, float bottom, float top); int max(int a, int b); float maxf(float a, float b); diff --git a/ui.c b/ui.c index b06b05c..0f83f29 100644 --- a/ui.c +++ b/ui.c @@ -314,6 +314,10 @@ void set_height_constraint(UIConstraints *constraints, float value, UIConstraint } } +void set_rotation_constraint(UIConstraints *constraints, float angle_d) { + constraints->rotation = angle_d; +} + void apply_constraints(UIConstraints constraints, Vec2f *pos, Sizef *size) { *pos = (Vec2f){constraints.x, constraints.y}; *size = (Sizef){constraints.width, constraints.height}; @@ -381,9 +385,11 @@ void draw_quad(UIConstraints constraints, Color *color, float border_radius, Ali apply_alignment(align, &pos, size); Matrix4x4 model = identity(); - apply_rotation(&model, to_radians(0)); - model.m[3][0] = pos.x; - model.m[3][1] = pos.y; + apply_translation(&model, (Vec2f){-size.width / 2.f, -size.height / 2.f}); + apply_rotation(&model, to_radians(constraints.rotation)); + apply_translation(&model, (Vec2f){size.width / 2.f, size.height / 2.f}); + + apply_translation(&model, pos); set_mat4f(font_shader, "model", (float *)model.m); @@ -438,9 +444,11 @@ void draw_triangle(UIConstraints constraints, Color *color, Alignment align) { apply_alignment(align, &pos, size); Matrix4x4 model = identity(); - apply_rotation(&model, to_radians(0)); - model.m[3][0] = pos.x; - model.m[3][1] = pos.y; + apply_translation(&model, (Vec2f){-size.width / 2.f, -size.height / 2.f}); + apply_rotation(&model, to_radians(constraints.rotation)); + apply_translation(&model, (Vec2f){size.width / 2.f, size.height / 2.f}); + + apply_translation(&model, pos); set_mat4f(font_shader, "model", (float *)model.m); @@ -461,7 +469,7 @@ void draw_triangle(UIConstraints constraints, Color *color, Alignment align) { glBindVertexArray(0); } -void draw_text(const char* text, int font_size, Vec2f pos, Color *color, Alignment alignment) { +void draw_text(const char* text, int font_size, UIConstraints constraints, Color *color, Alignment alignment) { use_shader(font_shader); if (color) { set_vec4f(font_shader, "textColor", color->r / 255.f, color->g / 255.f, color->b / 255.f, color->a / 255.f); @@ -470,17 +478,24 @@ void draw_text(const char* text, int font_size, Vec2f pos, Color *color, Alignme } set_mat4f(font_shader, "projection", (float *)zephr_context.projection.m); + Vec2f pos = { 0.f, 0.f }; + Sizef size = {0}; + + apply_constraints(constraints, &pos, &size); + Sizef text_size = calculate_text_size(text, FONT_PIXEL_SIZE); - float font_scale = (float)font_size / FONT_PIXEL_SIZE; + float font_scale = (float)font_size / FONT_PIXEL_SIZE * size.width; apply_alignment(alignment, &pos, (Sizef){ text_size.width * font_scale, text_size.height * font_scale }); Matrix4x4 model = identity(); - model.m[0][0] = font_scale; - model.m[1][1] = font_scale; - apply_rotation(&model, to_radians(0)); - model.m[3][0] = pos.x; - model.m[3][1] = pos.y; + apply_scale(&model, (Sizef){font_scale, font_scale}); + + apply_translation(&model, (Vec2f){-text_size.width * font_scale / 2.f, -text_size.height * font_scale / 2.f}); + apply_rotation(&model, to_radians(constraints.rotation)); + apply_translation(&model, (Vec2f){text_size.width *font_scale / 2.f, text_size.height * font_scale / 2.f}); + + apply_translation(&model, pos); set_mat4f(font_shader, "model", (float *)model.m); @@ -495,6 +510,10 @@ void draw_text(const char* text, int font_size, Vec2f pos, Color *color, Alignme glActiveTexture(GL_TEXTURE0); glBindVertexArray(font_vao); + // we use the original text and character sizes in the loop and then we just + // scale up or down the model matrix to get the desired font size. + // this way everything works out fine and we get to transform the text using the + // model matrix int c = 0; int x = 0; while (text[c] != '\0') { diff --git a/ui.h b/ui.h index 6b505fd..c8acfff 100644 --- a/ui.h +++ b/ui.h @@ -2,34 +2,7 @@ #include -#include "helper.h" - -typedef struct Size { - int width; - int height; -} Size; - -typedef struct Sizef { - float width; - float height; -} Sizef; - -typedef struct Vec2 { - int x; - int y; -} Vec2; - -typedef struct Vec2f { - float x; - float y; -} Vec2f; - -typedef struct Color { - float r; - float g; - float b; - float a; -} Color; +#include "z_math.h" typedef struct Character { unsigned int texture_id; @@ -70,6 +43,7 @@ typedef struct UIConstraints { float y; float width; float height; + float rotation; } UIConstraints; int init_zephr(const char* font_path, const char* window_title, Size window_size, Color *clear_color); @@ -81,8 +55,9 @@ void set_x_constraint(UIConstraints *constraints, float value, UIConstraint type void set_y_constraint(UIConstraints *constraints, float value, UIConstraint type); void set_width_constraint(UIConstraints *constraints, float value, UIConstraint type); void set_height_constraint(UIConstraints *constraints, float value, UIConstraint type); +void set_rotation_constraint(UIConstraints *constraints, float angle_d); void draw_quad(UIConstraints constraints, Color *color, float border_radius, Alignment align); void draw_circle(UIConstraints constraints, Color *color, Alignment align); void draw_triangle(UIConstraints constraints, Color *color, Alignment align); -void draw_text(const char* text, int font_size, Vec2f pos, Color *color, Alignment align); +void draw_text(const char* text, int font_size, UIConstraints constraints, Color *color, Alignment align); Sizef calculate_text_size(const char *text, int font_size); diff --git a/z_math.h b/z_math.h new file mode 100644 index 0000000..c0de527 --- /dev/null +++ b/z_math.h @@ -0,0 +1,32 @@ +#pragma once + +typedef struct { + float m[4][4]; +} Matrix4x4; + +typedef struct Size { + int width; + int height; +} Size; + +typedef struct Sizef { + float width; + float height; +} Sizef; + +typedef struct Vec2 { + int x; + int y; +} Vec2; + +typedef struct Vec2f { + float x; + float y; +} Vec2f; + +typedef struct Color { + float r; + float g; + float b; + float a; +} Color;