super basic UI constraint and alignment system with a super basic "game framework"

This commit is contained in:
2023-11-21 02:52:15 +02:00
parent 129e038c19
commit 3f840fcad7
20 changed files with 989 additions and 414 deletions
+120 -213
View File
@@ -1,248 +1,155 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include <freetype/ftmm.h>
#include <glad/gl.h>
/* #include <glad/gl.h> */
#include "font.h"
#include "shader.h"
/* #include "font.h" */
/* #include "shader.h" */
Character characters[128];
/* void draw_number(Shader shader, Cell cell, int row, int column, float scale, unsigned int vao, unsigned int vbo, float *transform) { */
/* use_shader(shader); */
/* if (cell.is_locked) { */
/* set_vec3f(shader, "textColor", 44.f / 255.f, 54.f / 255.f, 57.f / 255.f); */
/* } else { */
/* set_vec3f(shader, "textColor", 110.f / 255.f, 133.f / 255.f, 183.f / 255.f); */
/* } */
/* set_mat4f(shader, "transform", transform); */
/* glActiveTexture(GL_TEXTURE0); */
/* glBindVertexArray(vao); */
int init_fonts(const char *font_path) {
FT_Library ft;
if (FT_Init_FreeType(&ft)) {
return -1;
}
/* // get ascii value of cell value and use it to index into characters */
/* Character ch = characters['0' + cell.value]; */
FT_Face face;
if (FT_New_Face(ft, font_path, 0, &face)) {
return -2;
}
/* float w = ch.size.width; */
/* float h = ch.size.height; */
/* float ratio = w / h; */
if ((face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
printf("[INFO] Got a variable font\n");
FT_MM_Var *mm;
FT_Get_MM_Var(face, &mm);
/* // draw the glyph over the entire board and then scale it down to the size */
/* // of a single cell */
/* float vert_h = 1.0; */
/* float vert_w = vert_h * ratio; */
/* // get size of a single cell in opengl coords (-1, 1) */
/* float single_cell = (1.f/9.f) * 2; */
/* // we minus 4 since we start at column and row 4 (0-indexed) */
/* float offset_x = single_cell * (column - 4); */
/* float offset_y = single_cell * (row - 4); */
FT_Set_Var_Design_Coordinates(face, mm->num_namedstyles, mm->namedstyle[mm->num_namedstyles - 4].coords);
/* // texture coords are y-flipped */
/* float vertices[6][4] = { */
/* // top left tri */
/* { ((-(vert_w) / w * ratio) * scale) + offset_x, (-vert_h / h * scale) - offset_y, 0.0f, 1.0f }, */
/* { ((-(vert_w) / w * ratio) * scale) + offset_x, ( vert_h / h * scale) - offset_y, 0.0f, 0.0f }, */
/* { (( (vert_w) / w * ratio) * scale) + offset_x, ( vert_h / h * scale) - offset_y, 1.0f, 0.0f }, */
FT_Done_MM_Var(ft, mm);
}
/* // bottom right tri */
/* { ((-(vert_w) / w * ratio) * scale) + offset_x, (-vert_h / h * scale) - offset_y, 0.0f, 1.0f }, */
/* { (( (vert_w) / w * ratio) * scale) + offset_x, ( vert_h / h * scale) - offset_y, 1.0f, 0.0f }, */
/* { (( (vert_w) / w * ratio) * scale) + offset_x, (-vert_h / h * scale) - offset_y, 1.0f, 1.0f } */
/* }; */
FT_Set_Pixel_Sizes(face, 0, 128);
/* glBindTexture(GL_TEXTURE_2D, ch.texture_id); */
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
/* glBindBuffer(GL_ARRAY_BUFFER, vbo); */
/* glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); */
for (int c = 0; c < 128; c++) {
if (FT_Load_Char(face, c, FT_LOAD_RENDER)) {
printf("[ERROR]: failed to load glyph for char '%c'\n", c);
}
/* glBindBuffer(GL_ARRAY_BUFFER, 0); */
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, face->glyph->bitmap.width,
face->glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer);
/* glDrawArrays(GL_TRIANGLES, 0, 6); */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
/* glBindVertexArray(0); */
/* glBindTexture(GL_TEXTURE_2D, 0); */
/* } */
characters[c].texture_id = texture;
characters[c].advance = face->glyph->advance.x;
characters[c].size = (Size){ .width = face->glyph->bitmap.width, .height = face->glyph->bitmap.rows };
characters[c].bearing = (Size){ .width = face->glyph->bitmap_left, .height = face->glyph->bitmap_top };
}
/* void draw_text_center(Shader shader, const char *text, Size text_size, float scale, unsigned int vao, unsigned int vbo, float *transform, float offset_x, float offset_y) { */
/* use_shader(shader); */
/* set_vec3f(shader, "textColor", 200.f / 255.f, 200.f / 255.f, 200.f / 255.f); */
/* set_mat4f(shader, "transform", transform); */
/* glActiveTexture(GL_TEXTURE0); */
/* glBindVertexArray(vao); */
glBindTexture(GL_TEXTURE_2D, 0);
/* int c = 0; */
/* int x = 0; */
/* while (text[c] != '\0') { */
/* Character ch = characters[(int)text[c]]; */
FT_Done_Face(face);
FT_Done_FreeType(ft);
/* float xpos = ((x + ch.bearing.width * scale + offset_x) / 900.f) - ((text_size.width / 2.f) * scale / 900.f); */
/* float ypos = (((ch.bearing.height - ch.size.height + offset_y) * scale) / 900.f) - ((text_size.height / 2.f) * scale / 900.f); */
return 0;
}
/* float w = (ch.size.width * scale / 900.f); */
/* float h = (ch.size.height * scale / 900.f); */
void prepare_font(unsigned int *vao, unsigned int *vbo) {
glGenVertexArrays(1, &(*vao));
glGenBuffers(1, &(*vbo));
/* float vertices[6][4] = { */
/* // top left tri */
/* { xpos, ypos + h, 0.0f, 0.0f }, */
/* { xpos, ypos, 0.0f, 1.0f }, */
/* { xpos + w, ypos, 1.0f, 1.0f }, */
glBindVertexArray(*vao);
glBindBuffer(GL_ARRAY_BUFFER, *vbo);
/* // bottom right tri */
/* { xpos, ypos + h, 0.0f, 0.0f }, */
/* { xpos + w, ypos, 1.0f, 1.0f }, */
/* { xpos + w, ypos + h, 1.0f, 0.0f } */
/* }; */
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6*4, NULL, GL_DYNAMIC_DRAW);
/* glBindTexture(GL_TEXTURE_2D, ch.texture_id); */
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
/* glBindBuffer(GL_ARRAY_BUFFER, vbo); */
/* glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); */
/* glBindBuffer(GL_ARRAY_BUFFER, 0); */
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
/* glDrawArrays(GL_TRIANGLES, 0, 6); */
Size calculate_text_size(const char *text, float scale) {
Size size = { .width = 0, .height = 0 };
float w = 0;
float h = 0;
for (uint i = 0; i < strlen(text); i++) {
Character ch = characters[(uint)text[i]];
w += ch.advance / 64.0;
if (ch.size.height > h) {
h = ch.size.height;
}
}
size.width = w * scale;
size.height = h * scale;
return size;
}
/* x += (ch.advance >> 6) * scale; */
/* c++; */
/* } */
void draw_number(Shader shader, Cell cell, int row, int column, float scale, unsigned int vao, unsigned int vbo, float *transform) {
use_shader(shader);
if (cell.is_locked) {
set_vec3f(shader, "textColor", 44.f / 255.f, 54.f / 255.f, 57.f / 255.f);
} else {
set_vec3f(shader, "textColor", 110.f / 255.f, 133.f / 255.f, 183.f / 255.f);
}
set_mat4f(shader, "transform", transform);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(vao);
/* glBindVertexArray(0); */
/* glBindTexture(GL_TEXTURE_2D, 0); */
/* } */
// get ascii value of cell value and use it to index into characters
Character ch = characters['0' + cell.value];
/* Color default_text_color = { 200.f / 255.f, 200.f / 255.f, 200.f / 255.f, 1.f }; */
float w = ch.size.width;
float h = ch.size.height;
float ratio = w / h;
/* void draw_text_at(Shader shader, const char *text, Vec2 pos, float scale, unsigned int vao, unsigned int vbo, float *projection, Color *color) { */
/* use_shader(shader); */
/* if (color != NULL) { */
/* set_vec3f(shader, "textColor", color->r / 255.f, color->g / 255.f, color->b / 255.f); */
/* } else { */
/* set_vec3f(shader, "textColor", 200.f / 255.f, 200.f / 255.f, 200.f / 255.f); */
/* } */
/* set_mat4f(shader, "transform", (float *)projection); */
/* glActiveTexture(GL_TEXTURE0); */
/* glBindVertexArray(vao); */
// draw the glyph over the entire board and then scale it down to the size
// of a single cell
float vert_h = 1.0;
float vert_w = vert_h * ratio;
// get size of a single cell in opengl coords (-1, 1)
float single_cell = (1.f/9.f) * 2;
// we minus 4 since we start at column and row 4 (0-indexed)
float offset_x = single_cell * (column - 4);
float offset_y = single_cell * (row - 4);
/* int c = 0; */
/* while (text[c] != '\0') { */
/* Character ch = characters[(int)text[c]]; */
// texture coords are y-flipped
float vertices[6][4] = {
// top left tri
{ ((-(vert_w) / w * ratio) * scale) + offset_x, (-vert_h / h * scale) - offset_y, 0.0f, 1.0f },
{ ((-(vert_w) / w * ratio) * scale) + offset_x, ( vert_h / h * scale) - offset_y, 0.0f, 0.0f },
{ (( (vert_w) / w * ratio) * scale) + offset_x, ( vert_h / h * scale) - offset_y, 1.0f, 0.0f },
/* float xpos = pos.x + ch.bearing.width * scale; */
/* float ypos = pos.y - (ch.size.height - ch.bearing.height) * scale; */
// bottom right tri
{ ((-(vert_w) / w * ratio) * scale) + offset_x, (-vert_h / h * scale) - offset_y, 0.0f, 1.0f },
{ (( (vert_w) / w * ratio) * scale) + offset_x, ( vert_h / h * scale) - offset_y, 1.0f, 0.0f },
{ (( (vert_w) / w * ratio) * scale) + offset_x, (-vert_h / h * scale) - offset_y, 1.0f, 1.0f }
};
/* float w = (ch.size.width * scale); */
/* float h = (ch.size.height * scale); */
glBindTexture(GL_TEXTURE_2D, ch.texture_id);
/* float vertices[6][4] = { */
/* // top left tri */
/* { xpos, ypos + h, 0.0f, 0.0f }, */
/* { xpos, ypos, 0.0f, 1.0f }, */
/* { xpos + w, ypos, 1.0f, 1.0f }, */
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
/* // bottom right tri */
/* { xpos, ypos + h, 0.0f, 0.0f }, */
/* { xpos + w, ypos, 1.0f, 1.0f }, */
/* { xpos + w, ypos + h, 1.0f, 0.0f } */
/* }; */
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* glBindTexture(GL_TEXTURE_2D, ch.texture_id); */
glDrawArrays(GL_TRIANGLES, 0, 6);
/* glBindBuffer(GL_ARRAY_BUFFER, vbo); */
/* glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); */
/* glBindBuffer(GL_ARRAY_BUFFER, 0); */
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
/* glDrawArrays(GL_TRIANGLES, 0, 6); */
void draw_text_center(Shader shader, const char *text, Size text_size, float scale, unsigned int vao, unsigned int vbo, float *transform, float offset_x, float offset_y) {
use_shader(shader);
set_vec3f(shader, "textColor", 200.f / 255.f, 200.f / 255.f, 200.f / 255.f);
set_mat4f(shader, "transform", transform);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(vao);
/* pos.x += (ch.advance >> 6) * scale; */
/* c++; */
/* } */
int c = 0;
int x = 0;
while (text[c] != '\0') {
Character ch = characters[(int)text[c]];
float xpos = ((x + ch.bearing.width * scale + offset_x) / 900.f) - ((text_size.width / 2.f) * scale / 900.f);
float ypos = (((ch.bearing.height - ch.size.height + offset_y) * scale) / 900.f) - ((text_size.height / 2.f) * scale / 900.f);
float w = (ch.size.width * scale / 900.f);
float h = (ch.size.height * scale / 900.f);
float vertices[6][4] = {
// top left tri
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos, ypos, 0.0f, 1.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
// bottom right tri
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
{ xpos + w, ypos + h, 1.0f, 0.0f }
};
glBindTexture(GL_TEXTURE_2D, ch.texture_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
x += (ch.advance >> 6) * scale;
c++;
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
Color default_text_color = { 200.f / 255.f, 200.f / 255.f, 200.f / 255.f, 1.f };
void draw_text_at(Shader shader, const char *text, Vec2 pos, float scale, unsigned int vao, unsigned int vbo, float *projection, Color *color) {
use_shader(shader);
if (color != NULL) {
set_vec3f(shader, "textColor", color->r / 255.f, color->g / 255.f, color->b / 255.f);
} else {
set_vec3f(shader, "textColor", 200.f / 255.f, 200.f / 255.f, 200.f / 255.f);
}
set_mat4f(shader, "transform", (float *)projection);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(vao);
int c = 0;
while (text[c] != '\0') {
Character ch = characters[(int)text[c]];
float xpos = pos.x + ch.bearing.width * scale;
float ypos = pos.y - (ch.size.height - ch.bearing.height) * scale;
float w = (ch.size.width * scale);
float h = (ch.size.height * scale);
float vertices[6][4] = {
// top left tri
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos, ypos, 0.0f, 1.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
// bottom right tri
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
{ xpos + w, ypos + h, 1.0f, 0.0f }
};
glBindTexture(GL_TEXTURE_2D, ch.texture_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
pos.x += (ch.advance >> 6) * scale;
c++;
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
/* glBindVertexArray(0); */
/* glBindTexture(GL_TEXTURE_2D, 0); */
/* } */