Font texture.

This commit is contained in:
2025-08-12 22:32:57 -05:00
parent 2916f53e65
commit 217f00ff4c
5 changed files with 72 additions and 91 deletions

View File

@@ -10,8 +10,8 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
if(NOT DEFINED DUSK_TARGET_SYSTEM) if(NOT DEFINED DUSK_TARGET_SYSTEM)
# set(DUSK_TARGET_SYSTEM "linux") set(DUSK_TARGET_SYSTEM "linux")
set(DUSK_TARGET_SYSTEM "psp") # set(DUSK_TARGET_SYSTEM "psp")
endif() endif()
# Prep cache # Prep cache

View File

@@ -21,7 +21,6 @@ SDL_Renderer *RENDER_RENDERER;
SDL_GLContext RENDER_GL_CONTEXT; SDL_GLContext RENDER_GL_CONTEXT;
bool_t RENDER_RUNNING; bool_t RENDER_RUNNING;
static texture_t TEST_TEXTURE;
static mesh_t TRIANGLE_MESH; static mesh_t TRIANGLE_MESH;
// Interleaved in native order: COORD -> COLOR -> VERTEX // 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 &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. // Create back buffer.
// renderBackBufferInit(); // renderBackBufferInit();
// Init other things // Init other things
// renderTextInit(); renderTextInit();
// renderSceneInit(); // renderSceneInit();
// Mark ready. // Mark ready.
@@ -154,8 +137,8 @@ errorret_t renderDraw(void) {
glClearColor(0.392f, 0.584f, 0.929f, 1.0f); glClearColor(0.392f, 0.584f, 0.929f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
textureBind(&TEST_TEXTURE); textureBind(&RENDER_TEXT_TEXTURE);
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -172,7 +155,6 @@ errorret_t renderDraw(void) {
errorret_t renderDispose(void) { errorret_t renderDispose(void) {
meshDispose(&TRIANGLE_MESH); meshDispose(&TRIANGLE_MESH);
textureDispose(&TEST_TEXTURE);
// renderTextDispose(); // renderTextDispose();
// renderSceneDispose(); // renderSceneDispose();

View File

@@ -9,27 +9,27 @@
#include "render.h" #include "render.h"
#include "assert/assert.h" #include "assert/assert.h"
SDL_Texture* RENDER_TEXT_TEXTURE = NULL; texture_t RENDER_TEXT_TEXTURE;
void renderTextInit(void) { void renderTextInit(void) {
const int32_t cols = FONT_COLUMN_COUNT; const int32_t cols = FONT_COLUMN_COUNT;
const int32_t rows = (FONT_TILE_COUNT + cols - 1) / cols; const int32_t rows = (FONT_TILE_COUNT + cols - 1) / cols;
const int32_t fontWidth = cols * FONT_TILE_WIDTH; const int32_t inputFontWidth = cols * FONT_TILE_WIDTH;
const int32_t fontHeight = rows * FONT_TILE_HEIGHT; const int32_t inputFontHeight = rows * FONT_TILE_HEIGHT;
// RGBA8888 surface // Round up to nearest multiple of 4
SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat( int32_t outputFontWidth = inputFontWidth;
0, if(outputFontWidth % 4 != 0) {
fontWidth, outputFontWidth += 4 - (outputFontWidth % 4);
fontHeight, }
32,
SDL_PIXELFORMAT_RGBA32
);
assertNotNull(surface, "Failed to create surface for text rendering");
// Get the pixel format and pitch // Round up to nearest multiple of 2
const int32_t pitch_px = surface->pitch / 4; int32_t outputFontHeight = inputFontHeight;
uint32_t *pixels = (uint32_t *)surface->pixels; if(outputFontHeight % 2 != 0) {
outputFontHeight += 2 - (outputFontHeight % 2);
}
uint8_t pixels[outputFontWidth * outputFontHeight * sizeof(uint8_t) * 4];
// Buffer the pixels. // Buffer the pixels.
for(int tileIndex = 0; tileIndex < FONT_TILE_COUNT; ++tileIndex) { 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 y = 0; y < FONT_TILE_HEIGHT; ++y) {
for (int x = 0; x < FONT_TILE_WIDTH; ++x) { for (int x = 0; x < FONT_TILE_WIDTH; ++x) {
pixels[(tileY + y) * pitch_px + (tileX + x)] = ( const int32_t pixel = (tileY + y) * outputFontWidth + (tileX + x);
tile[y * FONT_TILE_WIDTH + x] ? 0xFFFFFFFF : 0x00000000 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 textureInit(
RENDER_TEXT_TEXTURE = SDL_CreateTextureFromSurface( &RENDER_TEXT_TEXTURE,
RENDER_RENDERER, outputFontWidth,
surface 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( void renderTextDrawChar(
@@ -63,31 +63,31 @@ void renderTextDrawChar(
const float_t y, const float_t y,
const char_t c const char_t c
) { ) {
int32_t tileIndex = (int32_t)(c) - FONT_CHAR_START; // int32_t tileIndex = (int32_t)(c) - FONT_CHAR_START;
assertTrue( // assertTrue(
tileIndex >= 0 && tileIndex < FONT_TILE_COUNT, // tileIndex >= 0 && tileIndex < FONT_TILE_COUNT,
"Character is out of bounds for font tiles" // "Character is out of bounds for font tiles"
); // );
assertNotNull(RENDER_TEXT_TEXTURE, "Texture cannot be NULL"); // assertNotNull(RENDER_TEXT_TEXTURE, "Texture cannot be NULL");
const int32_t tileX = (tileIndex % FONT_COLUMN_COUNT) * FONT_TILE_WIDTH; // 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 tileY = (tileIndex / FONT_COLUMN_COUNT) * FONT_TILE_HEIGHT;
SDL_Rect srcRect = { // SDL_Rect srcRect = {
.x = tileX, // .x = tileX,
.y = tileY, // .y = tileY,
.w = FONT_TILE_WIDTH, // .w = FONT_TILE_WIDTH,
.h = FONT_TILE_HEIGHT // .h = FONT_TILE_HEIGHT
}; // };
SDL_Rect dstRect = { // SDL_Rect dstRect = {
.x = (int32_t)roundf(x), // .x = (int32_t)roundf(x),
.y = (int32_t)roundf(y), // .y = (int32_t)roundf(y),
.w = FONT_TILE_WIDTH, // .w = FONT_TILE_WIDTH,
.h = FONT_TILE_HEIGHT // .h = FONT_TILE_HEIGHT
}; // };
SDL_RenderCopy(RENDER_RENDERER, RENDER_TEXT_TEXTURE, &srcRect, &dstRect); // SDL_RenderCopy(RENDER_RENDERER, RENDER_TEXT_TEXTURE, &srcRect, &dstRect);
} }
void renderTextDraw( void renderTextDraw(
@@ -95,27 +95,25 @@ void renderTextDraw(
const float_t y, const float_t y,
const char_t *text const char_t *text
) { ) {
assertNotNull(text, "Text cannot be NULL"); // assertNotNull(text, "Text cannot be NULL");
float_t posX = x; // float_t posX = x;
float_t posY = y; // float_t posY = y;
char_t c; // char_t c;
int32_t i = 0; // int32_t i = 0;
while((c = text[i++]) != '\0') { // while((c = text[i++]) != '\0') {
if(c == '\n') { // if(c == '\n') {
posX = x; // posX = x;
posY += FONT_TILE_HEIGHT; // posY += FONT_TILE_HEIGHT;
continue; // continue;
} // }
renderTextDrawChar(posX, posY, c); // renderTextDrawChar(posX, posY, c);
posX += FONT_TILE_WIDTH; // posX += FONT_TILE_WIDTH;
} // }
} }
void renderTextDispose(void) { void renderTextDispose(void) {
assertNotNull(RENDER_TEXT_TEXTURE, "Texture cannot be NULL"); textureDispose(&RENDER_TEXT_TEXTURE);
SDL_DestroyTexture(RENDER_TEXT_TEXTURE);
RENDER_TEXT_TEXTURE = NULL;
} }

View File

@@ -8,8 +8,9 @@
#pragma once #pragma once
#include "dusksdl2.h" #include "dusksdl2.h"
#include "ui/font.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. * Initializes the text rendering system.

View File

@@ -19,7 +19,7 @@ void textureInit(
assertTrue(width > 0 && height > 0, "Width and height must be greater than 0"); assertTrue(width > 0 && height > 0, "Width and height must be greater than 0");
assertNotNull(data, "Data cannot be NULL"); assertNotNull(data, "Data cannot be NULL");
#if PSP #if PSP || 1
assertTrue( assertTrue(
width % 4 == 0, width % 4 == 0,
"Width must be multiples of 4 for PSP" "Width must be multiples of 4 for PSP"
@@ -33,7 +33,7 @@ void textureInit(
memoryZero(texture, sizeof(texture_t)); memoryZero(texture, sizeof(texture_t));
texture->width = width; texture->width = width;
texture->height = height; texture->height = height;
glGenTextures(1, &texture->id); glGenTextures(1, &texture->id);
glBindTexture(GL_TEXTURE_2D, texture->id); glBindTexture(GL_TEXTURE_2D, texture->id);
glTexImage2D( glTexImage2D(