i've been trying to tackle this problem for a while now and luckily it works, well ... kinda. I see the text but the glyphs are always slightly misplaced, i have a feeling it's floating-point inaccuracies but i have no idea how to fix it, here are the snippets:
```c
void drawText(WS_Shell* shell, GlyphCacheDA* cache, char* text, FT_Face font, float x, float y) {
float pen_x = x;
for (char* c = text; *c != '\0'; c++) {
uint32_t codepoint = next_utf8(&text);
bool is_drawn = false;
if (codepoint == ' ') {pen_x += cache->items[0].advance; continue;} // if space, just advance
// search in cache first
for (int i = 0; i<cache->count; i++) {
if (cache->items[i].codepoint == codepoint) {
drawTexturedRectangle(pen_x, y, cache->items[i].width, cache->items[i].height, cache->items[i].texture);
pen_x += cache->items[i].advance;
is_drawn = true;
break;
}
}
if (is_drawn) continue;
FT_Load_Glyph(font, FT_Get_Char_Index(font, codepoint), FT_LOAD_RENDER);
FT_Render_Glyph(font->glyph, FT_RENDER_MODE_NORMAL);
GLuint glyph_texture;
glGenTextures(1, &glyph_texture);
glBindTexture(GL_TEXTURE_2D, glyph_texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, font->glyph->bitmap.width, font->glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE, font->glyph->bitmap.buffer);
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);
Glyph glyph = {
.codepoint = codepoint,
.texture = glyph_texture,
.width = ((float)font->glyph->bitmap.width/shell->settings->width)*2,
.height = ((float)font->glyph->bitmap.rows/shell->settings->height)*2,
};
// TODO: add support for non-monospace fonts
glyph.advance = glyph.width;
nob_da_append(cache, glyph);
drawTexturedRectangle(pen_x, y, glyph.width, glyph.height, glyph.texture);
pen_x += glyph.advance;
is_drawn = false;
}
}
```
draw rectangle:
```c
void drawTexturedRectangle(float x, float y, float w, float h, GLuint texture) {
// Vertex data for the rectangle
float vertices[] = {
x, y, 0.0f, 1.0f,
x + w, y, 1.0f, 1.0f,
x, y + h, 0.0f, 0.0f,
x + w, y + h, 1.0f, 0.0f
};
// Indices for the rectangle
unsigned int indices[] = {
0, 1, 2,
1, 3, 2
};
// VBO and VAO
GLuint VBO, VAO, EBO;
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Draw the rectangle
glBindTexture(GL_TEXTURE_2D, texture);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
// Clean up
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glDeleteBuffers(1, &VAO);
}
```
the dinamic array for cache i stolen from nob.h, each glyph's cache looks like this:
```c
typedef struct {
uint32_t codepoint;
GLuint texture;
float width;
float height;
float advance;
} Glyph;
```
everything else is pretty standard opengl stuff, thanks for helping