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/opengl.o \
src/test.o \
src/font.o
src/font.o \
src/window.o
all: test.so

Binary file not shown.

View File

@ -10,34 +10,44 @@ namespace font {
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,
font_desc const terminus[] = {
{
.path = "font/terminus_128x64_6x12.data",
.texture_width = 128,
.texture_height = 64,
.glyph_width = 6,
.glyph_height = 12,
},
{
.path = "font/terminus_128x128_8x16.data",
.texture_width = 128,
.texture_height = 128,
.glyph_width = 8,
.glyph_height = 16,
},
{
.path = "font/terminus_256x128_10x18.data",
.texture_width = 256,
.texture_height = 128,
.glyph_width = 10,
.glyph_height = 18,
},
{
.path = "font/terminus_256x128_12x24.data",
.texture_width = 256,
.texture_height = 128,
.glyph_width = 12,
.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 {
font_desc const * desc;
@ -52,5 +62,7 @@ namespace font {
void load_element_buffer();
void load_shader();
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);
}

View File

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

View File

@ -4,7 +4,7 @@
extern "C" {
#endif
void load();
void load(const char * source_path);
void draw_hud();
void draw();
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()
ffi.cdef[[
void load();
void load(const char * source_path);
void update_window(int width, int height);
void draw();
void draw_hud();
void update(float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right);
]]
test = ffi.load("./test.so")
test.load()
local source_path = love.filesystem.getSource()
test = ffi.load(source_path .. "/test.so")
test.load(source_path)
print(love.filesystem.getWorkingDirectory())
end
local update = function(dt)
@ -52,6 +54,12 @@ function love.run()
end
end
local width
local height
local flags
width, height, flags = love.window.getMode()
test.update_window(width, height)
local dt = love.timer.step()
update(dt)

View File

@ -7,6 +7,7 @@
#include "opengl.h"
#include "font.h"
#include "window.h"
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)
{
int c = ord - 32;
@ -110,7 +143,7 @@ namespace font {
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)
* XMMatrixScaling(2.0f / g_window_width, 2.0f / g_window_height, 0)
* XMMatrixTranslation(-1, 1, 0);
XMFLOAT4X4 transformf;
XMStoreFloat4x4(&transformf, transform);

View File

@ -7,8 +7,30 @@
#include "glad/gl.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");
if (f == NULL) {
fprintf(stderr, "fopen(%s): %s\n", filename, strerror(errno));

View File

@ -7,6 +7,7 @@
#include "directxmath/directxmath.h"
#include "test.h"
#include "font.h"
#include "window.h"
#include "data.inc"
@ -249,10 +250,14 @@ struct 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);
gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress);
@ -280,7 +285,9 @@ void load()
font::load_element_buffer();
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;
@ -314,7 +321,8 @@ static inline int popcount(int 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);
memcpy(buf, label, label_length);
@ -328,13 +336,20 @@ void draw_hud()
float y = 10.0f;
asdf(buf, "fov: ", "%.3f", view_state.fov);
font::draw_string(ter_8x16, buf, 10, y);
y += ter_8x16.desc->glyph_height;
int font_ix = font::best_font(font::terminus, font::terminus_length);
font::font const& ter_best = terminus_fonts[font_ix];
asdf(buf, "pitch: ", "%.9f", view_state.pitch);
font::draw_string(ter_8x16, buf, 10, y);
y += ter_8x16.desc->glyph_height;
labeled_value<float>(buf, "fov: ", "%.3f", view_state.fov);
font::draw_string(ter_best, buf, 10, y);
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()
@ -343,7 +358,7 @@ void draw()
XMMATRIX view = XMMatrixLookAtRH(view_state.eye, at, view_state.up);
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 far_z = 0.1;
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;
}