From 217f00ff4cdfe4e3d60656e6add6357fbba9629d Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Tue, 12 Aug 2025 22:32:57 -0500 Subject: [PATCH] Font texture. --- CMakeLists.txt | 4 +- src/dusksdl2/display/render.c | 24 +---- src/dusksdl2/display/rendertext.c | 128 ++++++++++++------------- src/dusksdl2/display/rendertext.h | 3 +- src/dusksdl2/display/texture/texture.c | 4 +- 5 files changed, 72 insertions(+), 91 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ef97795..261b240 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) if(NOT DEFINED DUSK_TARGET_SYSTEM) - # set(DUSK_TARGET_SYSTEM "linux") - set(DUSK_TARGET_SYSTEM "psp") + set(DUSK_TARGET_SYSTEM "linux") + # set(DUSK_TARGET_SYSTEM "psp") endif() # Prep cache diff --git a/src/dusksdl2/display/render.c b/src/dusksdl2/display/render.c index 504ee77..12c5f15 100644 --- a/src/dusksdl2/display/render.c +++ b/src/dusksdl2/display/render.c @@ -21,7 +21,6 @@ SDL_Renderer *RENDER_RENDERER; SDL_GLContext RENDER_GL_CONTEXT; bool_t RENDER_RUNNING; -static texture_t TEST_TEXTURE; static mesh_t TRIANGLE_MESH; // Interleaved in native order: COORD -> COLOR -> VERTEX @@ -98,28 +97,12 @@ errorret_t renderInit(void) { &TRIANGLE_MESH, GL_TRIANGLES, sizeof(quad) / sizeof(meshvertex_t), quad ); - // --- Create a simple 2x2 texture --- - - static const uint8_t texData4x2[] = { - // Row 0 (top/bottom depends on your convention): - 255, 0, 0, 255, // Red - 0, 255, 0, 255, // Green - 0, 255, 0, 255, // PAD: repeat Green - 0, 255, 0, 255, // PAD: repeat Green - - // Row 1: - 0, 0, 255, 255, // Blue - 255, 255, 255, 255, // White - 255, 255, 255, 255, // PAD: repeat White - 255, 255, 255, 255 // PAD: repeat White - }; - textureInit(&TEST_TEXTURE, 4, 2, texData4x2); // Create back buffer. // renderBackBufferInit(); // Init other things - // renderTextInit(); + renderTextInit(); // renderSceneInit(); // Mark ready. @@ -154,8 +137,8 @@ errorret_t renderDraw(void) { glClearColor(0.392f, 0.584f, 0.929f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - textureBind(&TEST_TEXTURE); + + textureBind(&RENDER_TEXT_TEXTURE); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -172,7 +155,6 @@ errorret_t renderDraw(void) { errorret_t renderDispose(void) { meshDispose(&TRIANGLE_MESH); - textureDispose(&TEST_TEXTURE); // renderTextDispose(); // renderSceneDispose(); diff --git a/src/dusksdl2/display/rendertext.c b/src/dusksdl2/display/rendertext.c index 6ec40b4..c045bbc 100644 --- a/src/dusksdl2/display/rendertext.c +++ b/src/dusksdl2/display/rendertext.c @@ -9,27 +9,27 @@ #include "render.h" #include "assert/assert.h" -SDL_Texture* RENDER_TEXT_TEXTURE = NULL; +texture_t RENDER_TEXT_TEXTURE; void renderTextInit(void) { const int32_t cols = FONT_COLUMN_COUNT; const int32_t rows = (FONT_TILE_COUNT + cols - 1) / cols; - const int32_t fontWidth = cols * FONT_TILE_WIDTH; - const int32_t fontHeight = rows * FONT_TILE_HEIGHT; + const int32_t inputFontWidth = cols * FONT_TILE_WIDTH; + const int32_t inputFontHeight = rows * FONT_TILE_HEIGHT; - // RGBA8888 surface - SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat( - 0, - fontWidth, - fontHeight, - 32, - SDL_PIXELFORMAT_RGBA32 - ); - assertNotNull(surface, "Failed to create surface for text rendering"); + // Round up to nearest multiple of 4 + int32_t outputFontWidth = inputFontWidth; + if(outputFontWidth % 4 != 0) { + outputFontWidth += 4 - (outputFontWidth % 4); + } - // Get the pixel format and pitch - const int32_t pitch_px = surface->pitch / 4; - uint32_t *pixels = (uint32_t *)surface->pixels; + // Round up to nearest multiple of 2 + int32_t outputFontHeight = inputFontHeight; + if(outputFontHeight % 2 != 0) { + outputFontHeight += 2 - (outputFontHeight % 2); + } + + uint8_t pixels[outputFontWidth * outputFontHeight * sizeof(uint8_t) * 4]; // Buffer the pixels. for(int tileIndex = 0; tileIndex < FONT_TILE_COUNT; ++tileIndex) { @@ -39,23 +39,23 @@ void renderTextInit(void) { for (int y = 0; y < FONT_TILE_HEIGHT; ++y) { for (int x = 0; x < FONT_TILE_WIDTH; ++x) { - pixels[(tileY + y) * pitch_px + (tileX + x)] = ( - tile[y * FONT_TILE_WIDTH + x] ? 0xFFFFFFFF : 0x00000000 - ); + const int32_t pixel = (tileY + y) * outputFontWidth + (tileX + x); + const int32_t pixelOffset = pixel * 4; + uint8_t value = tile[y * FONT_TILE_WIDTH + x]; + pixels[pixelOffset + 0] = value ? 0xFF : 0x00; // Red channel + pixels[pixelOffset + 1] = value ? 0xFF : 0x00; // Green channel + pixels[pixelOffset + 2] = value ? 0xFF : 0x00; // Blue channel + pixels[pixelOffset + 3] = 0xFF; // Alpha channel } } } - // Create texture from the surface - RENDER_TEXT_TEXTURE = SDL_CreateTextureFromSurface( - RENDER_RENDERER, - surface + textureInit( + &RENDER_TEXT_TEXTURE, + outputFontWidth, + outputFontHeight, + pixels ); - assertNotNull(RENDER_TEXT_TEXTURE, "Failed to create texture from surface"); - - // Cleanup the surface - SDL_FreeSurface(surface); - SDL_SetTextureBlendMode(RENDER_TEXT_TEXTURE, SDL_BLENDMODE_BLEND); } void renderTextDrawChar( @@ -63,31 +63,31 @@ void renderTextDrawChar( const float_t y, const char_t c ) { - int32_t tileIndex = (int32_t)(c) - FONT_CHAR_START; +// int32_t tileIndex = (int32_t)(c) - FONT_CHAR_START; - assertTrue( - tileIndex >= 0 && tileIndex < FONT_TILE_COUNT, - "Character is out of bounds for font tiles" - ); - assertNotNull(RENDER_TEXT_TEXTURE, "Texture cannot be NULL"); +// assertTrue( +// tileIndex >= 0 && tileIndex < FONT_TILE_COUNT, +// "Character is out of bounds for font tiles" +// ); +// assertNotNull(RENDER_TEXT_TEXTURE, "Texture cannot be NULL"); - const int32_t tileX = (tileIndex % FONT_COLUMN_COUNT) * FONT_TILE_WIDTH; - const int32_t tileY = (tileIndex / FONT_COLUMN_COUNT) * FONT_TILE_HEIGHT; +// const int32_t tileX = (tileIndex % FONT_COLUMN_COUNT) * FONT_TILE_WIDTH; +// const int32_t tileY = (tileIndex / FONT_COLUMN_COUNT) * FONT_TILE_HEIGHT; - SDL_Rect srcRect = { - .x = tileX, - .y = tileY, - .w = FONT_TILE_WIDTH, - .h = FONT_TILE_HEIGHT - }; +// SDL_Rect srcRect = { +// .x = tileX, +// .y = tileY, +// .w = FONT_TILE_WIDTH, +// .h = FONT_TILE_HEIGHT +// }; - SDL_Rect dstRect = { - .x = (int32_t)roundf(x), - .y = (int32_t)roundf(y), - .w = FONT_TILE_WIDTH, - .h = FONT_TILE_HEIGHT - }; - SDL_RenderCopy(RENDER_RENDERER, RENDER_TEXT_TEXTURE, &srcRect, &dstRect); +// SDL_Rect dstRect = { +// .x = (int32_t)roundf(x), +// .y = (int32_t)roundf(y), +// .w = FONT_TILE_WIDTH, +// .h = FONT_TILE_HEIGHT +// }; +// SDL_RenderCopy(RENDER_RENDERER, RENDER_TEXT_TEXTURE, &srcRect, &dstRect); } void renderTextDraw( @@ -95,27 +95,25 @@ void renderTextDraw( const float_t y, const char_t *text ) { - assertNotNull(text, "Text cannot be NULL"); +// assertNotNull(text, "Text cannot be NULL"); - float_t posX = x; - float_t posY = y; +// float_t posX = x; +// float_t posY = y; - char_t c; - int32_t i = 0; - while((c = text[i++]) != '\0') { - if(c == '\n') { - posX = x; - posY += FONT_TILE_HEIGHT; - continue; - } +// char_t c; +// int32_t i = 0; +// while((c = text[i++]) != '\0') { +// if(c == '\n') { +// posX = x; +// posY += FONT_TILE_HEIGHT; +// continue; +// } - renderTextDrawChar(posX, posY, c); - posX += FONT_TILE_WIDTH; - } +// renderTextDrawChar(posX, posY, c); +// posX += FONT_TILE_WIDTH; +// } } void renderTextDispose(void) { - assertNotNull(RENDER_TEXT_TEXTURE, "Texture cannot be NULL"); - SDL_DestroyTexture(RENDER_TEXT_TEXTURE); - RENDER_TEXT_TEXTURE = NULL; + textureDispose(&RENDER_TEXT_TEXTURE); } \ No newline at end of file diff --git a/src/dusksdl2/display/rendertext.h b/src/dusksdl2/display/rendertext.h index 499d407..9086d9f 100644 --- a/src/dusksdl2/display/rendertext.h +++ b/src/dusksdl2/display/rendertext.h @@ -8,8 +8,9 @@ #pragma once #include "dusksdl2.h" #include "ui/font.h" +#include "display/texture/texture.h" -extern SDL_Texture* RENDER_TEXT_TEXTURE; +extern texture_t RENDER_TEXT_TEXTURE; /** * Initializes the text rendering system. diff --git a/src/dusksdl2/display/texture/texture.c b/src/dusksdl2/display/texture/texture.c index ede0894..270ed34 100644 --- a/src/dusksdl2/display/texture/texture.c +++ b/src/dusksdl2/display/texture/texture.c @@ -19,7 +19,7 @@ void textureInit( assertTrue(width > 0 && height > 0, "Width and height must be greater than 0"); assertNotNull(data, "Data cannot be NULL"); - #if PSP + #if PSP || 1 assertTrue( width % 4 == 0, "Width must be multiples of 4 for PSP" @@ -33,7 +33,7 @@ void textureInit( memoryZero(texture, sizeof(texture_t)); texture->width = width; texture->height = height; - + glGenTextures(1, &texture->id); glBindTexture(GL_TEXTURE_2D, texture->id); glTexImage2D(