mirror of
https://github.com/IllusionMan1212/cudoku.git
synced 2026-10-24 18:12:25 +00:00
batch grid text and help overlay text
This commit is contained in:
@@ -10,3 +10,5 @@ DEPS=3rdparty/glad/include/glad/gl.h 3rdparty/glad/include/glad/glx.h 3rdparty/s
|
|||||||
$(BIN): $(OBJ)
|
$(BIN): $(OBJ)
|
||||||
$(CC) -o $@ $(OBJ) $(LDFLAGS)
|
$(CC) -o $@ $(OBJ) $(LDFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm $(OBJ) $(BIN)
|
||||||
|
|||||||
@@ -102,6 +102,9 @@ void draw_board(Cudoku *game, Size window_size) {
|
|||||||
set_width_constraint(&constraints, 1, UI_CONSTRAINT_FIXED);
|
set_width_constraint(&constraints, 1, UI_CONSTRAINT_FIXED);
|
||||||
set_height_constraint(&constraints, 1, UI_CONSTRAINT_FIXED);
|
set_height_constraint(&constraints, 1, UI_CONSTRAINT_FIXED);
|
||||||
|
|
||||||
|
GlyphInstanceList batch;
|
||||||
|
new_glyph_instance_list(&batch, 81);
|
||||||
|
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
for (int j = 0; j < 9; j++) {
|
for (int j = 0; j < 9; j++) {
|
||||||
if (!game->board[i][j].value) {
|
if (!game->board[i][j].value) {
|
||||||
@@ -113,12 +116,14 @@ void draw_board(Cudoku *game, Size window_size) {
|
|||||||
set_y_constraint(&constraints, i * 100 + cell_size.height / 2.f - text_size.height / 2.f, UI_CONSTRAINT_FIXED);
|
set_y_constraint(&constraints, i * 100 + cell_size.height / 2.f - text_size.height / 2.f, UI_CONSTRAINT_FIXED);
|
||||||
set_x_constraint(&constraints, j * 100 + cell_size.width / 2.f - text_size.width / 2.f, UI_CONSTRAINT_FIXED);
|
set_x_constraint(&constraints, j * 100 + cell_size.width / 2.f - text_size.width / 2.f, UI_CONSTRAINT_FIXED);
|
||||||
if (game->board[i][j].is_locked) {
|
if (game->board[i][j].is_locked) {
|
||||||
draw_text(num, 72.f, constraints, NULL, ALIGN_TOP_LEFT);
|
add_text_instance(&batch, num, 72.f, constraints, NULL, ALIGN_TOP_LEFT);
|
||||||
} else {
|
} else {
|
||||||
draw_text(num, 72.f, constraints, &selection_color, ALIGN_TOP_LEFT);
|
add_text_instance(&batch, num, 72.f, constraints, &selection_color, ALIGN_TOP_LEFT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw_text_batch(&batch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,13 +563,16 @@ void draw_help(Timer *timer) {
|
|||||||
set_height_constraint(&constraints, size.height, UI_CONSTRAINT_FIXED);
|
set_height_constraint(&constraints, size.height, UI_CONSTRAINT_FIXED);
|
||||||
draw_quad(constraints, &bg_color, 0.0, ALIGN_TOP_LEFT);
|
draw_quad(constraints, &bg_color, 0.0, ALIGN_TOP_LEFT);
|
||||||
|
|
||||||
|
GlyphInstanceList batch;
|
||||||
|
new_glyph_instance_list(&batch, 100);
|
||||||
|
|
||||||
set_x_constraint(&constraints, text_padding, UI_CONSTRAINT_FIXED);
|
set_x_constraint(&constraints, text_padding, UI_CONSTRAINT_FIXED);
|
||||||
for (int i = 0; i < HELP_TEXT_SIZE; i++) {
|
for (int i = 0; i < HELP_TEXT_SIZE; i++) {
|
||||||
Sizef text_size = calculate_text_size(help_texts[i], help_font_size);
|
Sizef text_size = calculate_text_size(help_texts[i], help_font_size);
|
||||||
set_y_constraint(&constraints, total_help_texts_height, UI_CONSTRAINT_FIXED);
|
set_y_constraint(&constraints, total_help_texts_height, UI_CONSTRAINT_FIXED);
|
||||||
set_width_constraint(&constraints, 1, UI_CONSTRAINT_FIXED);
|
set_width_constraint(&constraints, 1, UI_CONSTRAINT_FIXED);
|
||||||
set_height_constraint(&constraints, 1, UI_CONSTRAINT_FIXED);
|
set_height_constraint(&constraints, 1, UI_CONSTRAINT_FIXED);
|
||||||
draw_text(help_texts[i], help_font_size, constraints, &text_color, ALIGN_TOP_LEFT);
|
add_text_instance(&batch, help_texts[i], help_font_size, constraints, &text_color, ALIGN_TOP_LEFT);
|
||||||
|
|
||||||
total_help_texts_height += text_size.height + text_padding;
|
total_help_texts_height += text_size.height + text_padding;
|
||||||
}
|
}
|
||||||
@@ -575,8 +583,10 @@ void draw_help(Timer *timer) {
|
|||||||
Sizef closing_in_text_size = calculate_text_size(closing_in_text, closing_in_font_size);
|
Sizef closing_in_text_size = calculate_text_size(closing_in_text, closing_in_font_size);
|
||||||
set_x_constraint(&constraints, overlay_width - closing_in_text_size.width - text_padding, UI_CONSTRAINT_FIXED);
|
set_x_constraint(&constraints, overlay_width - closing_in_text_size.width - text_padding, UI_CONSTRAINT_FIXED);
|
||||||
set_y_constraint(&constraints, text_padding, UI_CONSTRAINT_FIXED);
|
set_y_constraint(&constraints, text_padding, UI_CONSTRAINT_FIXED);
|
||||||
draw_text(closing_in_text, closing_in_font_size, constraints, &closing_in_text_color, ALIGN_TOP_LEFT);
|
add_text_instance(&batch, closing_in_text, closing_in_font_size, constraints, &closing_in_text_color, ALIGN_TOP_LEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw_text_batch(&batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_timer(Timer *timer) {
|
void draw_timer(Timer *timer) {
|
||||||
|
|||||||
@@ -18,21 +18,36 @@ Shader font_shader;
|
|||||||
unsigned int font_vao;
|
unsigned int font_vao;
|
||||||
unsigned int font_instance_vbo;
|
unsigned int font_instance_vbo;
|
||||||
|
|
||||||
|
void extend_glyph_instance_list(GlyphInstanceList *dest, GlyphInstanceList *src) {
|
||||||
|
if (dest->size + src->size >= dest->capacity) {
|
||||||
|
dest->capacity = dest->size + src->size;
|
||||||
|
GlyphInstance* temp = realloc(dest->data, dest->capacity * sizeof(GlyphInstance));
|
||||||
|
if (!temp) {
|
||||||
|
printf("[FATAL] Failed to reallocate memory for glyph instance list\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
dest->data = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dest->data + dest->size, src->data, src->size * sizeof(GlyphInstance));
|
||||||
|
dest->size += src->size;
|
||||||
|
}
|
||||||
|
|
||||||
void new_glyph_instance_list(GlyphInstanceList *list, uint capacity) {
|
void new_glyph_instance_list(GlyphInstanceList *list, uint capacity) {
|
||||||
list->size = 0;
|
list->size = 0;
|
||||||
list->capacity = capacity;
|
list->capacity = capacity;
|
||||||
list->data = malloc(list->capacity * sizeof(TextInstance));
|
list->data = malloc(list->capacity * sizeof(GlyphInstance));
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_glyph_instance_list(GlyphInstanceList *list) {
|
void clear_glyph_instance_list(GlyphInstanceList *list) {
|
||||||
list->size = 0;
|
list->size = 0;
|
||||||
memset(list->data, 0, list->size * sizeof(TextInstance));
|
memset(list->data, 0, list->size * sizeof(GlyphInstance));
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_glyph_instance(GlyphInstanceList *list, TextInstance instance) {
|
void add_glyph_instance(GlyphInstanceList *list, GlyphInstance instance) {
|
||||||
if (list->size >= list->capacity) {
|
if (list->size >= list->capacity) {
|
||||||
list->capacity *= 2;
|
list->capacity *= 2;
|
||||||
TextInstance* temp = realloc(list->data, list->capacity * sizeof(TextInstance));
|
GlyphInstance* temp = realloc(list->data, list->capacity * sizeof(GlyphInstance));
|
||||||
if (!temp) {
|
if (!temp) {
|
||||||
printf("[FATAL] Failed to reallocate memory for glyph instance list\n");
|
printf("[FATAL] Failed to reallocate memory for glyph instance list\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -201,22 +216,22 @@ int init_fonts(const char *font_path) {
|
|||||||
// font instance vbo
|
// font instance vbo
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, font_instance_vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, font_instance_vbo);
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(TextInstance), (void *)0);
|
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(GlyphInstance), (void *)0);
|
||||||
glVertexAttribDivisor(1, 1);
|
glVertexAttribDivisor(1, 1);
|
||||||
glEnableVertexAttribArray(2);
|
glEnableVertexAttribArray(2);
|
||||||
glVertexAttribIPointer(2, 1, GL_INT, sizeof(TextInstance), (void *)sizeof(Vec4f));
|
glVertexAttribIPointer(2, 1, GL_INT, sizeof(GlyphInstance), (void *)sizeof(Vec4f));
|
||||||
glVertexAttribDivisor(2, 1);
|
glVertexAttribDivisor(2, 1);
|
||||||
glEnableVertexAttribArray(3);
|
glEnableVertexAttribArray(3);
|
||||||
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(TextInstance), (void *)(sizeof(Vec4f) + sizeof(int)));
|
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(GlyphInstance), (void *)(sizeof(Vec4f) + sizeof(int)));
|
||||||
glVertexAttribDivisor(3, 1);
|
glVertexAttribDivisor(3, 1);
|
||||||
glEnableVertexAttribArray(4);
|
glEnableVertexAttribArray(4);
|
||||||
glEnableVertexAttribArray(5);
|
glEnableVertexAttribArray(5);
|
||||||
glEnableVertexAttribArray(6);
|
glEnableVertexAttribArray(6);
|
||||||
glEnableVertexAttribArray(7);
|
glEnableVertexAttribArray(7);
|
||||||
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(TextInstance), (void *)(sizeof(Vec4f) * 2 + sizeof(int)));
|
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(GlyphInstance), (void *)(sizeof(Vec4f) * 2 + sizeof(int)));
|
||||||
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(TextInstance), (void *)(sizeof(Vec4f) * 3 + sizeof(int)));
|
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(GlyphInstance), (void *)(sizeof(Vec4f) * 3 + sizeof(int)));
|
||||||
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(TextInstance), (void *)(sizeof(Vec4f) * 4 + sizeof(int)));
|
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(GlyphInstance), (void *)(sizeof(Vec4f) * 4 + sizeof(int)));
|
||||||
glVertexAttribPointer(7, 4, GL_FLOAT, GL_FALSE, sizeof(TextInstance), (void *)(sizeof(Vec4f) * 5 + sizeof(int)));
|
glVertexAttribPointer(7, 4, GL_FLOAT, GL_FALSE, sizeof(GlyphInstance), (void *)(sizeof(Vec4f) * 5 + sizeof(int)));
|
||||||
glVertexAttribDivisor(4, 1);
|
glVertexAttribDivisor(4, 1);
|
||||||
glVertexAttribDivisor(5, 1);
|
glVertexAttribDivisor(5, 1);
|
||||||
glVertexAttribDivisor(6, 1);
|
glVertexAttribDivisor(6, 1);
|
||||||
@@ -281,7 +296,7 @@ Sizef calculate_text_size(const char *text, int font_size) {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_text(const char* text, int font_size, UIConstraints constraints, const Color *color, Alignment alignment) {
|
GlyphInstanceList get_glyph_instance_list_from_text(const char *text, int font_size, UIConstraints constraints, const Color *color, Alignment alignment) {
|
||||||
use_shader(font_shader);
|
use_shader(font_shader);
|
||||||
Color text_color = { 0, 0, 0, 1.f };
|
Color text_color = { 0, 0, 0, 1.f };
|
||||||
if (color) {
|
if (color) {
|
||||||
@@ -333,7 +348,7 @@ void draw_text(const char* text, int font_size, UIConstraints constraints, const
|
|||||||
float xpos = (x + (ch.bearing.width - first_char_bearing_w));
|
float xpos = (x + (ch.bearing.width - first_char_bearing_w));
|
||||||
float ypos = (text_size.height - ch.bearing.height - (text_size.height - max_bearing_h));
|
float ypos = (text_size.height - ch.bearing.height - (text_size.height - max_bearing_h));
|
||||||
|
|
||||||
TextInstance instance = {
|
GlyphInstance instance = {
|
||||||
.position = (Vec4f){xpos, ypos, ch.size.width, ch.size.height},
|
.position = (Vec4f){xpos, ypos, ch.size.width, ch.size.height},
|
||||||
.tex_coords_index = (int)text[c] - 32,
|
.tex_coords_index = (int)text[c] - 32,
|
||||||
.color = text_color,
|
.color = text_color,
|
||||||
@@ -348,12 +363,18 @@ void draw_text(const char* text, int font_size, UIConstraints constraints, const
|
|||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return glyph_instance_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_text(const char* text, int font_size, UIConstraints constraints, const Color *color, Alignment alignment) {
|
||||||
|
GlyphInstanceList glyph_instance_list = get_glyph_instance_list_from_text(text, font_size, constraints, color, alignment);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, zephr_context.font.atlas_texture_id);
|
glBindTexture(GL_TEXTURE_2D, zephr_context.font.atlas_texture_id);
|
||||||
glBindVertexArray(font_vao);
|
glBindVertexArray(font_vao);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, font_instance_vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, font_instance_vbo);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(TextInstance) * glyph_instance_list.size, glyph_instance_list.data, GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(GlyphInstance) * glyph_instance_list.size, glyph_instance_list.data, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL, glyph_instance_list.size);
|
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL, glyph_instance_list.size);
|
||||||
|
|
||||||
@@ -362,3 +383,27 @@ void draw_text(const char* text, int font_size, UIConstraints constraints, const
|
|||||||
|
|
||||||
free(glyph_instance_list.data);
|
free(glyph_instance_list.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void draw_text_batch(GlyphInstanceList *batch) {
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, zephr_context.font.atlas_texture_id);
|
||||||
|
glBindVertexArray(font_vao);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, font_instance_vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(GlyphInstance) * batch->size, batch->data, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL, batch->size);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
free(batch->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_text_instance(GlyphInstanceList *batch, const char* text, int font_size, UIConstraints constraints, const Color *color, Alignment alignment) {
|
||||||
|
GlyphInstanceList glyph_instance_list = get_glyph_instance_list_from_text(text, font_size, constraints, color, alignment);
|
||||||
|
|
||||||
|
extend_glyph_instance_list(batch, &glyph_instance_list);
|
||||||
|
|
||||||
|
free(glyph_instance_list.data);
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,14 +19,17 @@ typedef struct TextInstance {
|
|||||||
int tex_coords_index;
|
int tex_coords_index;
|
||||||
Color color;
|
Color color;
|
||||||
float model[4][4];
|
float model[4][4];
|
||||||
} TextInstance;
|
} GlyphInstance;
|
||||||
|
|
||||||
typedef struct GlyphInstanceList {
|
typedef struct GlyphInstanceList {
|
||||||
TextInstance *data;
|
GlyphInstance *data;
|
||||||
int size;
|
int size;
|
||||||
int capacity;
|
int capacity;
|
||||||
} GlyphInstanceList;
|
} GlyphInstanceList;
|
||||||
|
|
||||||
|
void new_glyph_instance_list(GlyphInstanceList *list, uint capacity);
|
||||||
int init_fonts(const char *font_path);
|
int init_fonts(const char *font_path);
|
||||||
Sizef calculate_text_size(const char *text, int font_size);
|
Sizef calculate_text_size(const char *text, int font_size);
|
||||||
void draw_text(const char* text, int font_size, UIConstraints constraints, const Color *color, Alignment alignment);
|
void draw_text(const char* text, int font_size, UIConstraints constraints, const Color *color, Alignment alignment);
|
||||||
|
void add_text_instance(GlyphInstanceList *batch, const char* text, int font_size, UIConstraints constraints, const Color *color, Alignment alignment);
|
||||||
|
void draw_text_batch(GlyphInstanceList *batch);
|
||||||
|
|||||||
Reference in New Issue
Block a user