From 40c97d6eb75c804bc1dc57798ba37584ab1a4d26 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 5 Mar 2025 07:14:56 -0600 Subject: [PATCH] Working with tilesets, about to do UV wrapping. --- assets/textures/bolder-8x8.png | Bin 0 -> 1477 bytes src/dusk/display/CMakeLists.txt | 1 + src/dusk/display/tileset.c | 34 +++++++++++ src/dusk/display/tileset.h | 53 ++++++++++++++++++ src/dusk/display/tilesetdefs.h | 16 ++++++ src/dusk/overworld/overworld.c | 3 +- src/duskgl/CMakeLists.txt | 5 +- src/duskgl/display/CMakeLists.txt | 1 + src/duskgl/display/render.c | 4 +- src/duskgl/display/shader/data/CMakeLists.txt | 1 + src/duskgl/display/shader/data/tilesets.glsl | 50 +++++++++++++++++ .../display/shader/data/tilesetshaderdata.c | 40 +++++++++++++ .../display/shader/data/tilesetshaderdata.h | 42 ++++++++++++++ .../shader/entityshader/entity_frag.glsl | 4 +- src/duskgl/display/shader/shadermanager.c | 4 +- src/duskgl/display/tilesetgl.c | 32 +++++++++++ src/duskgl/display/tilesetgl.h | 18 ++++++ 17 files changed, 303 insertions(+), 5 deletions(-) create mode 100644 assets/textures/bolder-8x8.png create mode 100644 src/dusk/display/tileset.c create mode 100644 src/dusk/display/tileset.h create mode 100644 src/dusk/display/tilesetdefs.h create mode 100644 src/duskgl/display/shader/data/tilesets.glsl create mode 100644 src/duskgl/display/shader/data/tilesetshaderdata.c create mode 100644 src/duskgl/display/shader/data/tilesetshaderdata.h create mode 100644 src/duskgl/display/tilesetgl.c create mode 100644 src/duskgl/display/tilesetgl.h diff --git a/assets/textures/bolder-8x8.png b/assets/textures/bolder-8x8.png new file mode 100644 index 0000000000000000000000000000000000000000..7c28d4a288c768de2dbdc3f709d28221416658ab GIT binary patch literal 1477 zcmV;$1v>hPP)Qj6G{F*GDthVCg*#$7>|t0A zdl;6(9){(xhhaJFVOS1(7;?Foz``VyCAy_(g~W$pIqYFr4tp4u!ybm^u!mte>|t0A zdl+)Ln83m$l$5p)((iLgskWrwXCi9*lty{m&TVN5NuTnojVMftv?xQm3^kl1+WC}l zNNguVrrj>O*qM6;C~tqwIg1@EJnPu5D$RP^Vka;Kt+`Y0u-0(?pzV-z)|R*n-XE*d zeAaT;=B9M(>zK3g6V+o!wp#3kk{%iTO{S^4SFLW2FAZ453x`$L^z&|&Qw zk@dnMQR_^|k) zB19Ew3OS7cd5s=AVXgD+#~Fu2?OclFNMqne(GDfJ-n8`OOaOX^oG|gy!m6;Xk+W{+ zVC;a$PN4@xxwzCX+yP<^Q<${&FM8%<6cM%Js4C(NW24%60g*Q4u82!p5don=MB=1& z(Q9Mja`W8zVAP<(3eGS#sbNPQ4n2i!d<|5;dw|Ucr#aja9v|;1CWe0gTuJdqq4YBV4(AUV|MbR?V6;7ng;FJ3y<^fJnPYCyv?- zg|o$0`h6B@xI{o9S=cHfOU*_0d7;7?h$@a7)lSkb;4M$F;MP=ZD~?5F1ePYRn?{8n%AtYW^$Otn0B=BsMZDIC{dyC z@k$-P>5<(vs_opZSZ{*B>qOCKU2S#W7>ONQIN#PE8p4%BUH5R&X&n1KVc=v~Op5uQ z7AsBwNVIS&NN9UMe6Y{g62LgVCv4*8A`HCy&SI3b@Ts=TAu`mwrJ1m>a?KZKi5lkr z^~!MvYtuhLJtFo7CUU|{5ah5y^LPuBXG>m_ptnXY58R=vfs?VAh~a&cvNR?#mZGsb zH`XEj##{TS7NUdy?aSiQv~UyfU|sai|BVO~vqX9oLoWKM!|dtYNH!JLAl`W+`d!f* zD|B%iL8ox;#^P>ffkk#(+Iqzprrr`8rDC1Hd$yT~F}>2}_0l+rv|_KOEN`u_t?sjn zp~k^3^`d?MG`NPQ!a1Ck2BxhgNaI0x76xAl4Px{w0vNH{v%*g7%okuWqqFwe=$j7L zn>u6Q;%){-sNK63OnFT+zI(tL2LHzS%<343fa5K1>coPY+%$HD-9}@X-{D-u=7q7<=P3m<{ztweegg{s>N6kdqMmRlgDGdCsjLP ffA+*<;X(Kd2ga<}D64eY00000NkvXXu0mjfHSN*> literal 0 HcmV?d00001 diff --git a/src/dusk/display/CMakeLists.txt b/src/dusk/display/CMakeLists.txt index 7b444ad..4f9d20f 100644 --- a/src/dusk/display/CMakeLists.txt +++ b/src/dusk/display/CMakeLists.txt @@ -7,6 +7,7 @@ target_sources(${DUSK_TARGET_NAME} PRIVATE scene.c + tileset.c ) # Subdirs \ No newline at end of file diff --git a/src/dusk/display/tileset.c b/src/dusk/display/tileset.c new file mode 100644 index 0000000..2c51748 --- /dev/null +++ b/src/dusk/display/tileset.c @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "tileset.h" + +tileset_t TILESETS[TILESET_COUNT] = { + // TILESET_NULL + { 0, 0 }, + // TILESET_FONT + { 4, 4 } +}; + +tilesetid_t TILESET_SLOTS[TILESET_SLOT_COUNT] = { + TILESET_NULL, + TILESET_NULL, + TILESET_NULL, + TILESET_NULL +}; + +uint8_t tilesetGetSlot(const tilesetid_t id) { + uint8_t i = 0; + do { + if(TILESET_SLOTS[i] == id) return i; + } while(++i < TILESET_SLOT_COUNT); + return 0xFF; +} + +bool_t tilesetIsBound(const tilesetid_t id) { + return tilesetGetSlot(id) != 0xFF; +} \ No newline at end of file diff --git a/src/dusk/display/tileset.h b/src/dusk/display/tileset.h new file mode 100644 index 0000000..0cfbe5f --- /dev/null +++ b/src/dusk/display/tileset.h @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" +#include "tilesetdefs.h" + +typedef enum { + TILESET_NULL, + TILESET_FONT +} tilesetid_t; + +#define TILESET_COUNT 2 + +typedef struct { + uint8_t columns; + uint8_t rows; +} tileset_t; + +extern tileset_t TILESETS[]; +extern tilesetid_t TILESET_SLOTS[]; + +/** + * Binds a tileset to a slot. The host can also use this to say load a texture, + * or upload to VRAM. + * + * This does not guarantee anything on the game side, rendering is responsible + * for handling anything visual. + * + * @param id The tileset to bind. + * @param slot The slot to bind the tileset to. + */ +void tilesetBind(const tilesetid_t id, const uint8_t slot); + +/** + * Gets the slot that a tileset is bound to, or 0xFF if not bound. + * + * @param id The tileset to check. + * @return The slot the tileset is bound to, or 0xFF if not bound. + */ +uint8_t tilesetGetSlot(const tilesetid_t id); + +/** + * Checks if a tileset is bound to a slot. + * + * @param id The tileset to check. + * @return TRUE if the tileset is bound, FALSE otherwise. + */ +bool_t tilesetIsBound(const tilesetid_t id); \ No newline at end of file diff --git a/src/dusk/display/tilesetdefs.h b/src/dusk/display/tilesetdefs.h new file mode 100644 index 0000000..27e7aa9 --- /dev/null +++ b/src/dusk/display/tilesetdefs.h @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#define TILESET_SLOT_0 0 +#define TILESET_SLOT_1 1 +#define TILESET_SLOT_2 2 +#define TILESET_SLOT_3 3 + +#define TILESET_SLOT_ENTITIES TILESET_SLOT_0 +#define TILESET_SLOT_MAP TILESET_SLOT_1 + +#define TILESET_SLOT_COUNT 4 \ No newline at end of file diff --git a/src/dusk/overworld/overworld.c b/src/dusk/overworld/overworld.c index 7bb5bb0..eb81fe9 100644 --- a/src/dusk/overworld/overworld.c +++ b/src/dusk/overworld/overworld.c @@ -8,6 +8,7 @@ #include "overworld.h" #include "util/memory.h" #include "assert/assert.h" +#include "display/tileset.h" overworld_t OVERWORLD; @@ -24,7 +25,7 @@ void overworldInit() { } void overworldSceneInit() { - + tilesetBind(TILESET_FONT, TILESET_SLOT_ENTITIES); } void overworldSceneDeinit() { diff --git a/src/duskgl/CMakeLists.txt b/src/duskgl/CMakeLists.txt index c7f89d6..91cd86d 100644 --- a/src/duskgl/CMakeLists.txt +++ b/src/duskgl/CMakeLists.txt @@ -27,4 +27,7 @@ target_sources(${DUSK_TARGET_NAME} # Subdirs add_subdirectory(assert) add_subdirectory(display) -add_subdirectory(overworld) \ No newline at end of file +add_subdirectory(overworld) + +# Assets +copytool("textures/bolder-8x8.png") \ No newline at end of file diff --git a/src/duskgl/display/CMakeLists.txt b/src/duskgl/display/CMakeLists.txt index 931142d..87c8a01 100644 --- a/src/duskgl/display/CMakeLists.txt +++ b/src/duskgl/display/CMakeLists.txt @@ -9,6 +9,7 @@ target_sources(${DUSK_TARGET_NAME} render.c quad.c texture.c + tilesetgl.c ) # Subdirs diff --git a/src/duskgl/display/render.c b/src/duskgl/display/render.c index 39531e3..b7c39c7 100644 --- a/src/duskgl/display/render.c +++ b/src/duskgl/display/render.c @@ -12,6 +12,7 @@ #include "display/shader/shadermanager.h" #include "display/quad.h" #include "display/window.h" +#include "display/tilesetgl.h" render_t RENDER; @@ -37,8 +38,9 @@ void renderUpdate() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); assertNoGLError(); - // Update shader stuff + // Update rendering data shaderManagerUpdate(); + tilesetGLBind(); // Hand off to the scene to do its rendering. sceneRender(); diff --git a/src/duskgl/display/shader/data/CMakeLists.txt b/src/duskgl/display/shader/data/CMakeLists.txt index babf1c4..96bcc96 100644 --- a/src/duskgl/display/shader/data/CMakeLists.txt +++ b/src/duskgl/display/shader/data/CMakeLists.txt @@ -9,4 +9,5 @@ target_sources(${DUSK_TARGET_NAME} transforms.c entities.c mapshaderdata.c + tilesetshaderdata.c ) \ No newline at end of file diff --git a/src/duskgl/display/shader/data/tilesets.glsl b/src/duskgl/display/shader/data/tilesets.glsl new file mode 100644 index 0000000..f19c0a3 --- /dev/null +++ b/src/duskgl/display/shader/data/tilesets.glsl @@ -0,0 +1,50 @@ +// Copyright (c) 2025 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "../../../../dusk/display/tilesetdefs.h" + +struct Tileset { + int columns; + int rows; + int width; + int height; +}; + +layout(std140) uniform b_Tilesets { + Tileset tilesets[TILESET_SLOT_COUNT]; +}; + +uniform sampler2D u_TilesetTextures[TILESET_SLOT_COUNT]; + +vec4 tilesetGetUVs(int tilesetIndex, int col, int row) { + Tileset tileset = tilesets[tilesetIndex]; + float segWidth = 1.0 / float(tileset.columns); + float segHeight = 1.0 / float(tileset.rows); + float x = float(col) * segWidth; + float y = float(row) * segHeight; + return vec4(x, y, x + segWidth, y + segHeight); +} + +vec4 tilesetGetUVsByIndex(int tilesetIndex, int index) { + Tileset tileset = tilesets[tilesetIndex]; + int col = index % tileset.columns; + int row = index / tileset.columns; + return tilesetGetUVs(tilesetIndex, col, row); +} + +vec4 tilesetGetColor(int tilesetIndex, vec2 coord) { + switch(tilesetIndex) { + case 0: + return texture(u_TilesetTextures[0], coord); + case 1: + return texture(u_TilesetTextures[1], coord); + case 2: + return texture(u_TilesetTextures[2], coord); + case 3: + return texture(u_TilesetTextures[3], coord); + default: + return vec4(1, 1, 1, 1); + } +} \ No newline at end of file diff --git a/src/duskgl/display/shader/data/tilesetshaderdata.c b/src/duskgl/display/shader/data/tilesetshaderdata.c new file mode 100644 index 0000000..ef9ec74 --- /dev/null +++ b/src/duskgl/display/shader/data/tilesetshaderdata.c @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "tilesetshaderdata.h" +#include "assert/assert.h" +#include "util/memory.h" + +shaderbuffer_t TILESET_SHADER_DATA_BUFFER; +tilesetshaderdata_t TILESET_SHADER_DATA_DATA; + +void tilesetShaderDataInit() { + memoryZero(&TILESET_SHADER_DATA_DATA, sizeof(tilesetshaderdata_t)); + shaderBufferInit(&TILESET_SHADER_DATA_BUFFER, sizeof(tilesetshaderdata_t)); +} + +void tilesetShaderDataUpdate() { + uint8_t i = 0; + do { + if(TILESET_SLOTS[i] == TILESET_NULL) continue; + tileset_t *tileset = &TILESETS[TILESET_SLOTS[i]]; + texture_t *texture = &TILESET_GL_TEXTURES[TILESET_SLOTS[i]]; + tilesetshaderdatatileset_t *dest = &TILESET_SHADER_DATA_DATA.tilesets[i]; + + dest->columns = tileset->columns; + dest->rows = tileset->rows; + dest->width = texture->width; + dest->height = texture->height; + } while(++i < TILESET_COUNT); + + shaderBufferBind(&TILESET_SHADER_DATA_BUFFER); + shaderBufferSetData(&TILESET_SHADER_DATA_BUFFER, &TILESET_SHADER_DATA_DATA); +} + +void tilesetShaderDataDispose() { + shaderBufferDispose(&TILESET_SHADER_DATA_BUFFER); +} \ No newline at end of file diff --git a/src/duskgl/display/shader/data/tilesetshaderdata.h b/src/duskgl/display/shader/data/tilesetshaderdata.h new file mode 100644 index 0000000..a0825a2 --- /dev/null +++ b/src/duskgl/display/shader/data/tilesetshaderdata.h @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "display/shader/shaderbuffer.h" +#include "display/tilesetgl.h" + +#define TILESET_BLOCK_NAME "b_Tileset" +#define TILESET_UNIFORM_TEXTURES_NAME "u_TilesetTextures" + +typedef struct { + int32_t columns; + int32_t rows; + int32_t width; + int32_t height; +} tilesetshaderdatatileset_t; + +typedef struct { + tilesetshaderdatatileset_t tilesets[TILESET_COUNT]; +} tilesetshaderdata_t; + +extern shaderbuffer_t TILESET_SHADER_DATA_BUFFER; +extern tilesetshaderdata_t TILESET_SHADER_DATA_DATA; + +/** + * Initializes the tileset buffer and data. + */ +void tilesetShaderDataInit(); + +/** + * Updates the tileset buffer with the current data. + */ +void tilesetShaderDataUpdate(); + +/** + * Destroys the tileset buffer. + */ +void tilesetShaderDataDispose(); \ No newline at end of file diff --git a/src/duskgl/display/shader/entityshader/entity_frag.glsl b/src/duskgl/display/shader/entityshader/entity_frag.glsl index 201a9a8..486e738 100644 --- a/src/duskgl/display/shader/entityshader/entity_frag.glsl +++ b/src/duskgl/display/shader/entityshader/entity_frag.glsl @@ -5,6 +5,7 @@ #include "../fragments/header.glsl" #include "../data/entities.glsl" +#include "../data/tilesets.glsl" // Inputs from vertex shader in vec2 v_TextureCoord; @@ -13,5 +14,6 @@ in vec2 v_TextureCoord; out vec4 FragColor; void main() { - FragColor = vec4(1, 1, 1, 1); + vec4 tColor = tilesetGetColor(0, v_TextureCoord); + FragColor = vec4(1, 1, 1, 1) * tColor; } diff --git a/src/duskgl/display/shader/shadermanager.c b/src/duskgl/display/shader/shadermanager.c index dd16e22..e5775c7 100644 --- a/src/duskgl/display/shader/shadermanager.c +++ b/src/duskgl/display/shader/shadermanager.c @@ -10,13 +10,15 @@ #include "display/shader/data/transforms.h" #include "display/shader/data/entities.h" #include "display/shader/data/mapshaderdata.h" +#include "display/shader/data/tilesetshaderdata.h" #include "display/shader/entityshader/entityshader.h" #include "display/shader/mapshader/mapshader.h" shadermanagerdatacallback_t SHADER_MANAGER_DATA_CALLBACKS[] = { { transformsInit, transformsUpdate, transformsDispose }, { entitiesInit, entitiesUpdate, entitiesDispose }, - { mapShaderDataInit, mapShaderDataUpdate, mapShaderDataDispose } + { mapShaderDataInit, mapShaderDataUpdate, mapShaderDataDispose }, + { tilesetShaderDataInit, tilesetShaderDataUpdate, tilesetShaderDataDispose } }; diff --git a/src/duskgl/display/tilesetgl.c b/src/duskgl/display/tilesetgl.c new file mode 100644 index 0000000..1ee87e1 --- /dev/null +++ b/src/duskgl/display/tilesetgl.c @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "tilesetgl.h" +#include "assert/assert.h" + +const char* TILESET_GL_TEXTURES_PATHS[TILESET_COUNT] = { + NULL, + "textures/bolder-8x8.png" +}; + +texture_t TILESET_GL_TEXTURES[TILESET_SLOT_COUNT]; + +void tilesetGLBind() { + uint8_t i; + do { + if(TILESET_SLOTS[i] == TILESET_NULL) continue; + textureBind(TILESET_GL_TEXTURES + i, i); + } while(++i < TILESET_SLOT_COUNT); +} + +void tilesetBind(const tilesetid_t id, const uint8_t slot) { + assertTrue(slot < TILESET_SLOT_COUNT, "Invalid slot"); + assertTrue(id < TILESET_COUNT, "Invalid tileset id"); + + TILESET_SLOTS[slot] = id; + textureLoad(TILESET_GL_TEXTURES + slot, TILESET_GL_TEXTURES_PATHS[id]); +} \ No newline at end of file diff --git a/src/duskgl/display/tilesetgl.h b/src/duskgl/display/tilesetgl.h new file mode 100644 index 0000000..514bd4e --- /dev/null +++ b/src/duskgl/display/tilesetgl.h @@ -0,0 +1,18 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "texture.h" +#include "display/tileset.h" + +extern const char* TILESET_GL_TEXTURES_PATHS[]; +extern texture_t TILESET_GL_TEXTURES[]; + +/** + * Binds the tileset to the OpenGL context. + */ +void tilesetGLBind(); \ No newline at end of file