From a0e922975ab678ab81d1a4ce09c3b7a9ac251a34 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sun, 8 Mar 2026 16:53:03 -0500 Subject: [PATCH] font rendering --- Makefile | 3 +- font/terminus_128x128_8x16.data | Bin 0 -> 16384 bytes font/terminus_128x64_6x12.data | Bin 0 -> 8192 bytes font/terminus_256x128_10x18.data | Bin 0 -> 32768 bytes font/terminus_256x128_12x24.data | Bin 0 -> 32768 bytes include/font.h | 56 ++++++++++++ main.lua | 2 +- minecraft/gen/mc.sh | 9 +- shader/font.frag | 18 ++++ shader/font.vert | 39 ++++++++ src/font.cpp | 152 +++++++++++++++++++++++++++++++ src/test.cpp | 13 +++ 12 files changed, 286 insertions(+), 6 deletions(-) create mode 100644 font/terminus_128x128_8x16.data create mode 100644 font/terminus_128x64_6x12.data create mode 100644 font/terminus_256x128_10x18.data create mode 100644 font/terminus_256x128_12x24.data create mode 100644 include/font.h create mode 100644 shader/font.frag create mode 100644 shader/font.vert create mode 100644 src/font.cpp diff --git a/Makefile b/Makefile index 4a75195..151c32e 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,8 @@ LDFLAGS += $(shell pkg-config --libs glfw3) OBJS = \ src/gl.o \ src/opengl.o \ - src/test.o + src/test.o \ + src/font.o all: test.so diff --git a/font/terminus_128x128_8x16.data b/font/terminus_128x128_8x16.data new file mode 100644 index 0000000000000000000000000000000000000000..00b05559e7726a900d166edf430ef3ea773540f4 GIT binary patch literal 16384 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 GoWL)-)&&3n literal 0 HcmV?d00001 diff --git a/font/terminus_256x128_10x18.data b/font/terminus_256x128_10x18.data new file mode 100644 index 0000000000000000000000000000000000000000..246d05a44084bc585c86e02b6e630ccad2a9c515 GIT binary patch literal 32768 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 literal 0 HcmV?d00001 diff --git a/include/font.h b/include/font.h new file mode 100644 index 0000000..718f912 --- /dev/null +++ b/include/font.h @@ -0,0 +1,56 @@ +#pragma once + +namespace font { + + struct font_desc { + char const * const path; + int const texture_width; + int const texture_height; + int const glyph_width; + int const glyph_height; + }; + + font_desc const ter_6x12 = { + .path = "font/terminus_128x64_6x12.data", + .texture_width = 128, + .texture_height = 64, + .glyph_width = 6, + .glyph_height = 12, + }; + font_desc const ter_8x16 = { + .path = "font/terminus_128x128_8x16.data", + .texture_width = 128, + .texture_height = 128, + .glyph_width = 8, + .glyph_height = 16, + }; + font_desc const ter_10x18 = { + .path = "font/terminus_256x128_10x18.data", + .texture_width = 256, + .texture_height = 128, + .glyph_width = 10, + .glyph_height = 18, + }; + font_desc const ter_12x24 = { + .path = "font/terminus_256x128_12x24.data", + .texture_width = 256, + .texture_height = 128, + .glyph_width = 12, + .glyph_height = 24, + }; + + struct font { + font_desc const * desc; + unsigned int texture; + int stride; + struct { + float width; + float height; + } cell; + }; + + void load_element_buffer(); + void load_shader(); + font load_font(font_desc const& desc); + void draw_string(font const& font, char const * const s, int x, int y); +} diff --git a/main.lua b/main.lua index 9bf1941..4f7a2d7 100644 --- a/main.lua +++ b/main.lua @@ -58,6 +58,6 @@ function love.run() love.graphics.present() love.timer.sleep(0.001) local fps = love.timer.getFPS( ) - print(fps) + --print(fps) end end diff --git a/minecraft/gen/mc.sh b/minecraft/gen/mc.sh index 3ab7461..7d30bd2 100644 --- a/minecraft/gen/mc.sh +++ b/minecraft/gen/mc.sh @@ -1,6 +1,7 @@ set -eux cd ./minecraft/gen -python mc.py ~/Love2DWorld/region/r.0.0.mcr ../region.0.0 & -python mc.py ~/Love2DWorld/region/r.-1.-1.mcr ../region.-1.-1 & -python mc.py ~/Love2DWorld/region/r.0.-1.mcr ../region.0.-1 & -python mc.py ~/Love2DWorld/region/r.-1.0.mcr ../region.-1.0 & +PYTHON=pypy3.11 +$PYTHON mc.py ~/Love2DWorld/region/r.0.0.mcr ../region.0.0 & +$PYTHON mc.py ~/Love2DWorld/region/r.-1.-1.mcr ../region.-1.-1 & +$PYTHON mc.py ~/Love2DWorld/region/r.0.-1.mcr ../region.0.-1 & +$PYTHON mc.py ~/Love2DWorld/region/r.-1.0.mcr ../region.-1.0 & diff --git a/shader/font.frag b/shader/font.frag new file mode 100644 index 0000000..af8d1db --- /dev/null +++ b/shader/font.frag @@ -0,0 +1,18 @@ +#version 330 core + +uniform sampler2D TextureSampler; + +uniform vec2 Cell; +uniform vec2 Glyph; + +out vec4 g_color; + +in vec4 PixelTexture; + +void main() +{ + vec4 sample = texture(TextureSampler, PixelTexture.xy * Cell + Cell * Glyph); + float px = sample.x == 0.0 ? 0.0 : 1.0; + + g_color = vec4(vec3(px), 1.0); +} diff --git a/shader/font.vert b/shader/font.vert new file mode 100644 index 0000000..3b8b299 --- /dev/null +++ b/shader/font.vert @@ -0,0 +1,39 @@ +#version 330 core + +const vec2 vtx[4] = vec2[](vec2(-1.0, 1.0), // tl + vec2( 1.0, 1.0), // tr + vec2( 1.0, -1.0), // br + vec2(-1.0, -1.0)); // bl + +/* +tl tr + br + +0 1 2 +tr tl br +1 0 2 + +tl +bl br + +2 1 3 +br tl bl +2 0 3 + +1 0 2 3 +*/ + +uniform mat4 Transform; + +out vec4 PixelTexture; + +void main() +{ + vec2 vertex = vtx[gl_VertexID]; + + PixelTexture = vec4(vertex * vec2(0.5, -0.5) + 0.5, 0, 0); + + vertex = vertex * vec2(0.5, 0.5) + vec2(0.5, -0.5); + + gl_Position = Transform * vec4(vertex, 0.0, 1.0); +} diff --git a/src/font.cpp b/src/font.cpp new file mode 100644 index 0000000..6eb2adf --- /dev/null +++ b/src/font.cpp @@ -0,0 +1,152 @@ +#include +#include +#include + +#include "directxmath/directxmath.h" +#include "glad/gl.h" +#include "opengl.h" + +#include "font.h" + +namespace font { + + struct location { + struct { + unsigned int transform; + unsigned int texture_sampler; + unsigned int cell; + unsigned int glyph; + } uniform; + }; + + static location location; + + static unsigned int font_program = -1; + + static unsigned int vertex_array_object = -1; + static unsigned int index_buffer = -1; + + void load_element_buffer() + { + uint8_t const data[] = { + 1, 0, 2, 3, + }; + int const data_size = (sizeof (data)); + + glGenBuffers(1, &index_buffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, data_size, data, GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + glGenVertexArrays(1, &vertex_array_object); + } + + void load_shader() + { + unsigned int program = compile_from_files("shader/font.vert", + NULL, // geom + "shader/font.frag"); + + location.uniform.transform = glGetUniformLocation(program, "Transform"); + location.uniform.texture_sampler = glGetUniformLocation(program, "TextureSampler"); + location.uniform.cell = glGetUniformLocation(program, "Cell"); + location.uniform.glyph = glGetUniformLocation(program, "Glyph"); + printf("font uniforms:\n transform %u\n texture_sampler %u\n cell %u\n glyph %u\n", + location.uniform.transform, + location.uniform.texture_sampler, + location.uniform.cell, + location.uniform.glyph + ); + + font_program = program; + } + + font load_font(font_desc const& desc) + { + unsigned int texture; + glGenTextures(1, &texture); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + int texture_data_size; + void * texture_data = read_file(desc.path, &texture_data_size); + assert(texture_data != nullptr); + + int width = desc.texture_width; + int height = desc.texture_height; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, texture_data); + + free(texture_data); + + glBindTexture(GL_TEXTURE_2D, 0); + + return (font){ + .desc = &desc, + .texture = texture, + .stride = desc.texture_width / desc.glyph_width, + .cell = { (float)desc.glyph_width / (float)desc.texture_width, + (float)desc.glyph_height / (float)desc.texture_height }, + }; + } + + inline static XMFLOAT2 glyph_coordinate(font const& font, int ord) + { + int c = ord - 32; + int x = c % font.stride; + int y = c / font.stride; + XMVECTOR coord = XMVectorSet(x, y, 0, 0); + XMFLOAT2 coordf; + XMStoreFloat2(&coordf, coord); + return coordf; + } + + inline static XMFLOAT4X4 glyph_transform(font const& font, int x, int y) + { + XMMATRIX transform = + XMMatrixScaling(font.desc->glyph_width, font.desc->glyph_height, 0) + * XMMatrixTranslation(x, -y, 0) + * XMMatrixScaling(2.0f / 1024.0f, 2.0f / 1024.0f, 0) + * XMMatrixTranslation(-1, 1, 0); + XMFLOAT4X4 transformf; + XMStoreFloat4x4(&transformf, transform); + return transformf; + } + + void draw_string(font const& font, char const * const s, int x, int y) + { + glUseProgram(font_program); + glDepthFunc(GL_ALWAYS); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, font.texture); + + glUniform1i(location.uniform.texture_sampler, 0); + glUniform2fv(location.uniform.cell, 1, (float *)&font.cell); + + glBindVertexArray(vertex_array_object); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer); + + int i = 0; + while (s[i] != 0) { + char c = s[i]; + if (c <= 0x20 || c > 0x7f) + continue; + + XMFLOAT4X4 transform = glyph_transform(font, x, y); + glUniformMatrix4fv(location.uniform.transform, 1, GL_FALSE, (float *)&transform); + XMFLOAT2 glyph = glyph_coordinate(font, c); + glUniform2fv(location.uniform.glyph, 1, (float *)&glyph); + + glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0); + + x += font.desc->glyph_width; + + i += 1; + } + } +} diff --git a/src/test.cpp b/src/test.cpp index 752468e..ab334f4 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -6,6 +6,7 @@ #include "opengl.h" #include "directxmath/directxmath.h" #include "test.h" +#include "font.h" #include "data.inc" @@ -246,6 +247,8 @@ struct view_state { view_state view_state; +font::font ter_8x16 = {}; + void load() { fprintf(stderr, "getproc %p\n", SDL_GL_GetProcAddress); @@ -266,6 +269,14 @@ void load() //unsigned int textures_layout = glGetUniformBlockIndex(test_program, "TexturesLayout"); //glUniformBlockBinding(test_program, textures_layout, 0); //printf("textures_layout %d\n", textures_layout); + + ////////////////////////////////////////////////////////////////////// + // font + ////////////////////////////////////////////////////////////////////// + + font::load_element_buffer(); + font::load_shader(); + ter_8x16 = font::load_font(font::ter_8x16); } void update(float lx, float ly, float rx, float ry, float tl, float tr, @@ -357,4 +368,6 @@ void draw() glDrawElementsInstancedBaseInstance(GL_TRIANGLES, element_count, GL_UNSIGNED_BYTE, indices, instance_count, base_instance); } } + + font::draw_string(ter_8x16, "test", 10, 10); }