run-time window aspect ratio and font resize

This commit is contained in:
Zack Buhman 2026-03-08 20:45:36 -05:00
parent c987c0330b
commit 9ed9f70ec5
11 changed files with 163 additions and 46 deletions

View File

@ -20,7 +20,8 @@ OBJS = \
src/gl.o \ src/gl.o \
src/opengl.o \ src/opengl.o \
src/test.o \ src/test.o \
src/font.o src/font.o \
src/window.o
all: test.so all: test.so

Binary file not shown.

View File

@ -10,34 +10,44 @@ namespace font {
int const glyph_height; int const glyph_height;
}; };
font_desc const ter_6x12 = { font_desc const terminus[] = {
{
.path = "font/terminus_128x64_6x12.data", .path = "font/terminus_128x64_6x12.data",
.texture_width = 128, .texture_width = 128,
.texture_height = 64, .texture_height = 64,
.glyph_width = 6, .glyph_width = 6,
.glyph_height = 12, .glyph_height = 12,
}; },
font_desc const ter_8x16 = { {
.path = "font/terminus_128x128_8x16.data", .path = "font/terminus_128x128_8x16.data",
.texture_width = 128, .texture_width = 128,
.texture_height = 128, .texture_height = 128,
.glyph_width = 8, .glyph_width = 8,
.glyph_height = 16, .glyph_height = 16,
}; },
font_desc const ter_10x18 = { {
.path = "font/terminus_256x128_10x18.data", .path = "font/terminus_256x128_10x18.data",
.texture_width = 256, .texture_width = 256,
.texture_height = 128, .texture_height = 128,
.glyph_width = 10, .glyph_width = 10,
.glyph_height = 18, .glyph_height = 18,
}; },
font_desc const ter_12x24 = { {
.path = "font/terminus_256x128_12x24.data", .path = "font/terminus_256x128_12x24.data",
.texture_width = 256, .texture_width = 256,
.texture_height = 128, .texture_height = 128,
.glyph_width = 12, .glyph_width = 12,
.glyph_height = 24, .glyph_height = 24,
},
{
.path = "font/terminus_256x256_16x32.data",
.texture_width = 256,
.texture_height = 256,
.glyph_width = 16,
.glyph_height = 32,
},
}; };
int const terminus_length = (sizeof (terminus)) / (sizeof (font_desc));
struct font { struct font {
font_desc const * desc; font_desc const * desc;
@ -52,5 +62,7 @@ namespace font {
void load_element_buffer(); void load_element_buffer();
void load_shader(); void load_shader();
font load_font(font_desc const& desc); font load_font(font_desc const& desc);
void load_fonts(font * const fonts, font_desc const * const descs, int length);
int best_font(font_desc const * const descs, int length);
void draw_string(font const& font, char const * const s, int x, int y); void draw_string(font const& font, char const * const s, int x, int y);
} }

View File

@ -4,6 +4,9 @@
extern "C" { extern "C" {
#endif #endif
extern char const * g_source_path;
extern int g_source_path_length;
void * read_file(const char * filename, int * out_size); void * read_file(const char * filename, int * out_size);
unsigned int compile_from_files(const char * vertex_path, unsigned int compile_from_files(const char * vertex_path,

View File

@ -4,7 +4,7 @@
extern "C" { extern "C" {
#endif #endif
void load(); void load(const char * source_path);
void draw_hud(); void draw_hud();
void draw(); void draw();
void update(float lx, float ly, float rx, float ry, float tl, float tr, void update(float lx, float ly, float rx, float ry, float tl, float tr,

13
include/window.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
extern float g_window_width;
extern float g_window_height;
void update_window(int width, int height);
#ifdef __cplusplus
}
#endif

View File

@ -5,15 +5,17 @@ function init()
joysticks = love.joystick.getJoysticks() joysticks = love.joystick.getJoysticks()
ffi.cdef[[ ffi.cdef[[
void load(); void load(const char * source_path);
void update_window(int width, int height);
void draw(); void draw();
void draw_hud(); void draw_hud();
void update(float lx, float ly, float rx, float ry, float tl, float tr, void update(float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right); int up, int down, int left, int right);
]] ]]
test = ffi.load("./test.so") local source_path = love.filesystem.getSource()
test.load() test = ffi.load(source_path .. "/test.so")
test.load(source_path)
print(love.filesystem.getWorkingDirectory())
end end
local update = function(dt) local update = function(dt)
@ -52,6 +54,12 @@ function love.run()
end end
end end
local width
local height
local flags
width, height, flags = love.window.getMode()
test.update_window(width, height)
local dt = love.timer.step() local dt = love.timer.step()
update(dt) update(dt)

View File

@ -7,6 +7,7 @@
#include "opengl.h" #include "opengl.h"
#include "font.h" #include "font.h"
#include "window.h"
namespace font { namespace font {
@ -94,6 +95,38 @@ namespace font {
}; };
} }
static inline int min(int a, int b)
{
return a < b ? a : b;
}
int best_font(font_desc const * const descs, int length)
{
int dimension = min(g_window_width, g_window_height);
int ideal_height = (16 * dimension) / 1024;
//printf("ideal_height: %d\n", ideal_height);
int nearest = dimension;
int nearest_ix = -1;
for (int i = 0; i < length; i++) {
font_desc const& desc = descs[i];
int distance = abs(desc.glyph_height - ideal_height);
if (distance < nearest) {
nearest = distance;
nearest_ix = i;
}
}
assert(nearest_ix != -1);
//printf("selected %d\n", descs[nearest_ix].glyph_height);
return nearest_ix;
}
void load_fonts(font * const fonts, font_desc const * const descs, int length)
{
for (int i = 0; i < length; i++) {
fonts[i] = load_font(descs[i]);
}
}
inline static XMFLOAT2 glyph_coordinate(font const& font, int ord) inline static XMFLOAT2 glyph_coordinate(font const& font, int ord)
{ {
int c = ord - 32; int c = ord - 32;
@ -110,7 +143,7 @@ namespace font {
XMMATRIX transform = XMMATRIX transform =
XMMatrixScaling(font.desc->glyph_width, font.desc->glyph_height, 0) XMMatrixScaling(font.desc->glyph_width, font.desc->glyph_height, 0)
* XMMatrixTranslation(x, -y, 0) * XMMatrixTranslation(x, -y, 0)
* XMMatrixScaling(2.0f / 1024.0f, 2.0f / 1024.0f, 0) * XMMatrixScaling(2.0f / g_window_width, 2.0f / g_window_height, 0)
* XMMatrixTranslation(-1, 1, 0); * XMMatrixTranslation(-1, 1, 0);
XMFLOAT4X4 transformf; XMFLOAT4X4 transformf;
XMStoreFloat4x4(&transformf, transform); XMStoreFloat4x4(&transformf, transform);

View File

@ -7,8 +7,30 @@
#include "glad/gl.h" #include "glad/gl.h"
#include "opengl.h" #include "opengl.h"
void * read_file(const char * filename, int * out_size) char const * g_source_path = NULL;
int g_source_path_length = 0;
char const * join_path(char * buf, const char * filename)
{ {
if (filename[0] == '/')
return filename;
int filename_length = strlen(filename);
assert(filename_length + g_source_path_length + 2 < 1024);
memcpy(buf, g_source_path, g_source_path_length);
buf[g_source_path_length] = '/';
memcpy(&buf[g_source_path_length + 1], filename, filename_length);
buf[g_source_path_length + 1 + filename_length] = 0;
return buf;
}
void * read_file(const char * r_filename, int * out_size)
{
char tmp[1024];
char const * filename = join_path(tmp, r_filename);
FILE * f = fopen(filename, "rb"); FILE * f = fopen(filename, "rb");
if (f == NULL) { if (f == NULL) {
fprintf(stderr, "fopen(%s): %s\n", filename, strerror(errno)); fprintf(stderr, "fopen(%s): %s\n", filename, strerror(errno));

View File

@ -7,6 +7,7 @@
#include "directxmath/directxmath.h" #include "directxmath/directxmath.h"
#include "test.h" #include "test.h"
#include "font.h" #include "font.h"
#include "window.h"
#include "data.inc" #include "data.inc"
@ -249,10 +250,14 @@ struct view_state {
view_state view_state; view_state view_state;
font::font ter_8x16 = {}; font::font * terminus_fonts;
void load() void load(const char * source_path)
{ {
g_source_path_length = strlen(source_path);
assert(source_path[g_source_path_length - 1] != '/');
g_source_path = source_path;
fprintf(stderr, "getproc %p\n", SDL_GL_GetProcAddress); fprintf(stderr, "getproc %p\n", SDL_GL_GetProcAddress);
gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress); gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress);
@ -280,7 +285,9 @@ void load()
font::load_element_buffer(); font::load_element_buffer();
font::load_shader(); font::load_shader();
ter_8x16 = font::load_font(font::ter_8x16);
terminus_fonts = (font::font *)malloc((sizeof (font::font)) * font::terminus_length);
font::load_fonts(terminus_fonts, font::terminus, font::terminus_length);
} }
float _ry = 0.0; float _ry = 0.0;
@ -314,7 +321,8 @@ static inline int popcount(int x)
return __builtin_popcount(x); return __builtin_popcount(x);
} }
void asdf(char * const buf, char const * const label, char const * const format, float value) template <typename T>
void labeled_value(char * const buf, char const * const label, char const * const format, T value)
{ {
const int label_length = strlen(label); const int label_length = strlen(label);
memcpy(buf, label, label_length); memcpy(buf, label, label_length);
@ -328,13 +336,20 @@ void draw_hud()
float y = 10.0f; float y = 10.0f;
asdf(buf, "fov: ", "%.3f", view_state.fov); int font_ix = font::best_font(font::terminus, font::terminus_length);
font::draw_string(ter_8x16, buf, 10, y); font::font const& ter_best = terminus_fonts[font_ix];
y += ter_8x16.desc->glyph_height;
asdf(buf, "pitch: ", "%.9f", view_state.pitch); labeled_value<float>(buf, "fov: ", "%.3f", view_state.fov);
font::draw_string(ter_8x16, buf, 10, y); font::draw_string(ter_best, buf, 10, y);
y += ter_8x16.desc->glyph_height; y += ter_best.desc->glyph_height;
labeled_value<float>(buf, "pitch: ", "%.9f", view_state.pitch);
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
labeled_value<int>(buf, "font_height: ", "%d", ter_best.desc->glyph_height);
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
} }
void draw() void draw()
@ -343,7 +358,7 @@ void draw()
XMMATRIX view = XMMatrixLookAtRH(view_state.eye, at, view_state.up); XMMATRIX view = XMMatrixLookAtRH(view_state.eye, at, view_state.up);
float fov_angle_y = XMConvertToRadians(45 * view_state.fov); float fov_angle_y = XMConvertToRadians(45 * view_state.fov);
float aspect_ratio = 1.0; float aspect_ratio = g_window_width / g_window_height;
float near_z = 1.0; float near_z = 1.0;
float far_z = 0.1; float far_z = 0.1;
XMMATRIX projection = XMMatrixPerspectiveFovRH(fov_angle_y, aspect_ratio, near_z, far_z); XMMATRIX projection = XMMatrixPerspectiveFovRH(fov_angle_y, aspect_ratio, near_z, far_z);

10
src/window.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "window.h"
float g_window_width = 1;
float g_window_height = 1;
void update_window(int width, int height)
{
g_window_width = width;
g_window_height = height;
}