Font texture.
This commit is contained in:
@@ -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
|
||||||
|
@@ -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.
|
||||||
@@ -155,7 +138,7 @@ 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();
|
||||||
|
@@ -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;
|
|
||||||
}
|
}
|
@@ -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.
|
||||||
|
@@ -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"
|
||||||
|
Reference in New Issue
Block a user