From 2916f53e65e87c7215f0fd837e7b98e693385ad1 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Tue, 12 Aug 2025 21:24:57 -0500 Subject: [PATCH] PSP textures --- src/dusksdl2/display/CMakeLists.txt | 3 +- src/dusksdl2/display/render.c | 37 +++++++++--- src/dusksdl2/display/texture/CMakeLists.txt | 13 +++++ src/dusksdl2/display/texture/texture.c | 65 +++++++++++++++++++++ src/dusksdl2/display/texture/texture.h | 44 ++++++++++++++ 5 files changed, 154 insertions(+), 8 deletions(-) create mode 100644 src/dusksdl2/display/texture/CMakeLists.txt create mode 100644 src/dusksdl2/display/texture/texture.c create mode 100644 src/dusksdl2/display/texture/texture.h diff --git a/src/dusksdl2/display/CMakeLists.txt b/src/dusksdl2/display/CMakeLists.txt index f2e37f3..380cb30 100644 --- a/src/dusksdl2/display/CMakeLists.txt +++ b/src/dusksdl2/display/CMakeLists.txt @@ -14,4 +14,5 @@ target_sources(${DUSK_TARGET_NAME} ) # Subdirs -add_subdirectory(mesh) \ No newline at end of file +add_subdirectory(mesh) +add_subdirectory(texture) \ No newline at end of file diff --git a/src/dusksdl2/display/render.c b/src/dusksdl2/display/render.c index f432f17..504ee77 100644 --- a/src/dusksdl2/display/render.c +++ b/src/dusksdl2/display/render.c @@ -13,6 +13,7 @@ #include "console/console.h" #include "dusksdl2input.h" #include "renderscene.h" +#include "display/texture/texture.h" #include "display/mesh/mesh.h" SDL_Window *RENDER_WINDOW; @@ -20,6 +21,7 @@ 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 @@ -32,14 +34,14 @@ static const meshvertex_t tri[3] = { static const meshvertex_t quad[6] = { // First triangle - { { 0xFF, 0, 0, 0xFF }, { 0.0f, 0.0f }, { -1.0f, -1.0f, 0.0f } }, // Red - { { 0, 0xFF, 0, 0xFF }, { 1.0f, 0.0f }, { 1.0f, -1.0f, 0.0f } }, // Green - { { 0, 0, 0xFF, 0xFF }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f } }, // Blue + { { 0xFF, 0xFF, 0xFF, 0xFF }, { 0.0f, 0.0f }, { -1.0f, -1.0f, 0.0f } }, // Red + { { 0xFF, 0xFF, 0xFF, 0xFF }, { 1.0f, 0.0f }, { 1.0f, -1.0f, 0.0f } }, // Green + { { 0xFF, 0xFF, 0xFF, 0xFF }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f } }, // Blue // Second triangle - { { 0xFF, 0, 0, 0xFF }, { 0.0f, 0.0f }, { -1.0f, -1.0f, 0.0f } }, // Red - { { 0, 0, 0xFF, 0xFF }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f } }, // Blue - { { 0, 0xFF, 0, 0xFF }, { 0.0f, 1.0f }, { -1.0f, 1.0f, 0.0f } } // Green + { { 0xFF, 0xFF, 0xFF, 0xFF }, { 0.0f, 0.0f }, { -1.0f, -1.0f, 0.0f } }, // Red + { { 0xFF, 0xFF, 0xFF, 0xFF }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f } }, // Blue + { { 0xFF, 0xFF, 0xFF, 0xFF }, { 0.0f, 1.0f }, { -1.0f, 1.0f, 0.0f } } // Green }; errorret_t renderInit(void) { @@ -90,13 +92,29 @@ errorret_t renderInit(void) { glDisable(GL_CULL_FACE); glDisable(GL_BLEND); glDisable(GL_LIGHTING);// PSP defaults this on? + glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); - meshInit( &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(); @@ -137,11 +155,14 @@ 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); + glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); meshDraw(&TRIANGLE_MESH, -1, -1); + textureBind(NULL); // Present the renderer (swap OpenGL buffers) SDL_GL_SwapWindow(RENDER_WINDOW); @@ -151,6 +172,8 @@ errorret_t renderDraw(void) { errorret_t renderDispose(void) { meshDispose(&TRIANGLE_MESH); + textureDispose(&TEST_TEXTURE); + // renderTextDispose(); // renderSceneDispose(); // renderBackBufferDispose(); diff --git a/src/dusksdl2/display/texture/CMakeLists.txt b/src/dusksdl2/display/texture/CMakeLists.txt new file mode 100644 index 0000000..369aaac --- /dev/null +++ b/src/dusksdl2/display/texture/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (c) 2025 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Sources +target_sources(${DUSK_TARGET_NAME} + PRIVATE + texture.c +) + +# Subdirs +# add_subdirectory(draw) \ No newline at end of file diff --git a/src/dusksdl2/display/texture/texture.c b/src/dusksdl2/display/texture/texture.c new file mode 100644 index 0000000..ede0894 --- /dev/null +++ b/src/dusksdl2/display/texture/texture.c @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "texture.h" +#include "assert/assert.h" +#include "util/memory.h" + +void textureInit( + texture_t *texture, + const int32_t width, + const int32_t height, + const uint8_t *data +) { + assertNotNull(texture, "Texture cannot be NULL"); + assertTrue(width > 0 && height > 0, "Width and height must be greater than 0"); + assertNotNull(data, "Data cannot be NULL"); + + #if PSP + assertTrue( + width % 4 == 0, + "Width must be multiples of 4 for PSP" + ); + assertTrue( + height % 2 == 0, + "Height must be multiples of 2 for PSP" + ); + #endif + + memoryZero(texture, sizeof(texture_t)); + texture->width = width; + texture->height = height; + + glGenTextures(1, &texture->id); + glBindTexture(GL_TEXTURE_2D, texture->id); + glTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, data + ); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + +} + +void textureBind(const texture_t *texture) { + if(texture == NULL) { + glBindTexture(GL_TEXTURE_2D, 0); + return; + } + + glBindTexture(GL_TEXTURE_2D, texture->id); +} + +void textureDispose(texture_t *texture) { + assertNotNull(texture, "Texture cannot be NULL"); + assertTrue(texture->id != 0, "Texture ID must not be 0"); + + glDeleteTextures(1, &texture->id); +} \ No newline at end of file diff --git a/src/dusksdl2/display/texture/texture.h b/src/dusksdl2/display/texture/texture.h new file mode 100644 index 0000000..713b370 --- /dev/null +++ b/src/dusksdl2/display/texture/texture.h @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusksdl2.h" + +typedef struct { + GLuint id; + int32_t width; + int32_t height; +} texture_t; + +/** + * Initializes a texture. + * + * @param texture The texture to initialize. + * @param width The width of the texture. + * @param height The height of the texture. + * @param data The pixel data for the texture. + */ +void textureInit( + texture_t *texture, + const int32_t width, + const int32_t height, + const uint8_t *data +); + +/** + * Binds a texture for rendering. + * + * @param texture The texture to bind. + */ +void textureBind(const texture_t *texture); + +/** + * Disposes a texture. + * + * @param texture The texture to dispose. + */ +void textureDispose(texture_t *texture); \ No newline at end of file