From 43f943eb25c748b7ed8f6952e25de84142424aaa Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 5 Mar 2025 14:04:50 -0600 Subject: [PATCH] Tilesets working. --- assets/textures/8x8.png | Bin 0 -> 1868 bytes assets/textures/bolder-8x8.png | Bin 1477 -> 0 bytes src/dusk/display/tileset.c | 2 +- src/dusk/display/tilesetdefs.h | 4 +- src/duskgl/CMakeLists.txt | 2 +- src/duskgl/display/shader/data/tilesets.glsl | 44 ++++++++++++------ .../display/shader/data/tilesetshaderdata.c | 25 ++++++++-- .../display/shader/data/tilesetshaderdata.h | 20 +++++--- .../shader/entityshader/entity_frag.glsl | 2 +- .../shader/entityshader/entity_vert.glsl | 5 +- .../shader/entityshader/entityshader.c | 14 ++++++ .../shader/entityshader/entityshader.h | 4 ++ .../display/shader/fragments/packed.glsl | 4 ++ src/duskgl/display/shader/fragments/quad.glsl | 10 +++- src/duskgl/display/shader/shader.c | 12 +++++ src/duskgl/display/shader/shader.h | 13 ++++++ src/duskgl/display/tilesetgl.c | 2 +- 17 files changed, 129 insertions(+), 34 deletions(-) create mode 100644 assets/textures/8x8.png delete mode 100644 assets/textures/bolder-8x8.png diff --git a/assets/textures/8x8.png b/assets/textures/8x8.png new file mode 100644 index 0000000000000000000000000000000000000000..46f927b9979aa63652572c0470f0c99e96bb771a GIT binary patch literal 1868 zcmeAS@N?(olHy`uVBq!ia0vp^91ILh2RN94teIaAdonOEGX(gAxH2$w{P^+X#*G_0 zcI+r9DEPtfV-$^szz7KeU|z^x!`IBfz{pS%0fMsg~V@97srr_TU#T# zCmmMc5V`jM|FdrX3k_1qRogBbtE= zpVx9uV0tIuHbaF?W~<|tNN+*K?pHQ~R>#s?)FO9OJEhzFITD&U{ni~urytX|bzIKl zSAMAbc$&o(=b2@ldSCX)U+SLnL{vCsU(zgAqcGEqQw2;5Up@^BR#iDw%CpBoXN_9q z>8Oy0ToZ+*_)RazT<5&pmN8wCt?b%S*}nPrR3o}C@2Y!ZANMTosd<%d`pmT|RXtah zu3!7;HADIo^EH>N+-BP+=suBr`*NGuM1xez^9!EtGj5HJX{|JAOv_qw-{JG^Q+u;KW|C!uF_*c4XH zHHePoTwzmSallz=SD_D+QupF-Z+=v@Ua^$6 z@w(i7l*6dI`QZx*=|ugnQE#gMY8raErinbVTBYqcwL>I3=jiTE zCT+iGwNGq!P3wNmi@z(<)19Av|F=i6KTguhkYUaV>Ez!v-=Du0o5+#!-gVa5>+0V) zJ5s}~WbT-o`}S>D{=}p$BfEHW-t!_ky9?ZJ!(LyRd95^-k)D)aPr32d#m zTlDY$oo_S36b?ObJM-T6-P#8)INz}qavc1hA n$sZ4A+Wg{Lzy9NI)}QjTj&h}RE^reDmJAG@u6{1-oD!MhPP)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*> diff --git a/src/dusk/display/tileset.c b/src/dusk/display/tileset.c index 2c51748..aa5de98 100644 --- a/src/dusk/display/tileset.c +++ b/src/dusk/display/tileset.c @@ -11,7 +11,7 @@ tileset_t TILESETS[TILESET_COUNT] = { // TILESET_NULL { 0, 0 }, // TILESET_FONT - { 4, 4 } + { 1, 88 } }; tilesetid_t TILESET_SLOTS[TILESET_SLOT_COUNT] = { diff --git a/src/dusk/display/tilesetdefs.h b/src/dusk/display/tilesetdefs.h index 27e7aa9..62e0b76 100644 --- a/src/dusk/display/tilesetdefs.h +++ b/src/dusk/display/tilesetdefs.h @@ -10,7 +10,7 @@ #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_ENTITIES TILESET_SLOT_1 +#define TILESET_SLOT_MAP TILESET_SLOT_2 #define TILESET_SLOT_COUNT 4 \ No newline at end of file diff --git a/src/duskgl/CMakeLists.txt b/src/duskgl/CMakeLists.txt index 91cd86d..c163e8d 100644 --- a/src/duskgl/CMakeLists.txt +++ b/src/duskgl/CMakeLists.txt @@ -30,4 +30,4 @@ add_subdirectory(display) add_subdirectory(overworld) # Assets -copytool("textures/bolder-8x8.png") \ No newline at end of file +copytool("textures/8x8.png") \ No newline at end of file diff --git a/src/duskgl/display/shader/data/tilesets.glsl b/src/duskgl/display/shader/data/tilesets.glsl index f19c0a3..39fc5e9 100644 --- a/src/duskgl/display/shader/data/tilesets.glsl +++ b/src/duskgl/display/shader/data/tilesets.glsl @@ -4,12 +4,10 @@ // https://opensource.org/licenses/MIT #include "../../../../dusk/display/tilesetdefs.h" +#include "../fragments/packed.glsl" struct Tileset { - int columns; - int rows; - int width; - int height; + uvec4 tileset; }; layout(std140) uniform b_Tilesets { @@ -18,31 +16,47 @@ layout(std140) uniform b_Tilesets { uniform sampler2D u_TilesetTextures[TILESET_SLOT_COUNT]; -vec4 tilesetGetUVs(int tilesetIndex, int col, int row) { +uint tilesetGetColumns(uint tilesetIndex) { + return packedGetU32(0u, tilesets[tilesetIndex].tileset); +} + +uint tilesetGetRows(uint tilesetIndex) { + return packedGetU32(1u, tilesets[tilesetIndex].tileset); +} + +uint tilesetGetWidth(uint tilesetIndex) { + return packedGetU32(2u, tilesets[tilesetIndex].tileset); +} + +uint tilesetGetHeight(uint tilesetIndex) { + return packedGetU32(3u, tilesets[tilesetIndex].tileset); +} + +vec4 tilesetGetUVs(uint tilesetIndex, uint col, uint row) { Tileset tileset = tilesets[tilesetIndex]; - float segWidth = 1.0 / float(tileset.columns); - float segHeight = 1.0 / float(tileset.rows); + float segWidth = 1.0 / float(tilesetGetColumns(tilesetIndex)); + float segHeight = 1.0 / float(tilesetGetRows(tilesetIndex)); float x = float(col) * segWidth; float y = float(row) * segHeight; return vec4(x, y, x + segWidth, y + segHeight); } -vec4 tilesetGetUVsByIndex(int tilesetIndex, int index) { +vec4 tilesetGetUVsByIndex(uint tilesetIndex, uint index) { Tileset tileset = tilesets[tilesetIndex]; - int col = index % tileset.columns; - int row = index / tileset.columns; + uint col = index % tilesetGetColumns(tilesetIndex); + uint row = index / tilesetGetColumns(tilesetIndex); return tilesetGetUVs(tilesetIndex, col, row); } -vec4 tilesetGetColor(int tilesetIndex, vec2 coord) { +vec4 tilesetGetColor(uint tilesetIndex, vec2 coord) { switch(tilesetIndex) { - case 0: + case 0u: return texture(u_TilesetTextures[0], coord); - case 1: + case 1u: return texture(u_TilesetTextures[1], coord); - case 2: + case 2u: return texture(u_TilesetTextures[2], coord); - case 3: + case 3u: return texture(u_TilesetTextures[3], coord); default: return vec4(1, 1, 1, 1); diff --git a/src/duskgl/display/shader/data/tilesetshaderdata.c b/src/duskgl/display/shader/data/tilesetshaderdata.c index ef9ec74..df96677 100644 --- a/src/duskgl/display/shader/data/tilesetshaderdata.c +++ b/src/duskgl/display/shader/data/tilesetshaderdata.c @@ -8,33 +8,50 @@ #include "tilesetshaderdata.h" #include "assert/assert.h" #include "util/memory.h" +#include "display/shader/shader.h" shaderbuffer_t TILESET_SHADER_DATA_BUFFER; tilesetshaderdata_t TILESET_SHADER_DATA_DATA; +GLuint TILESET_SHADER_DATA_TEXTURES[TILESET_SLOT_COUNT]; void tilesetShaderDataInit() { memoryZero(&TILESET_SHADER_DATA_DATA, sizeof(tilesetshaderdata_t)); shaderBufferInit(&TILESET_SHADER_DATA_BUFFER, sizeof(tilesetshaderdata_t)); + + assertTrue( + sizeof(tilesetshaderdata_t) == sizeof(uvec4_t) * TILESET_SLOT_COUNT, + "Tileset Shader Data size mismatch" + ); + + uint8_t i = 0; + do { + TILESET_SHADER_DATA_TEXTURES[i] = i; + } while(++i < TILESET_SLOT_COUNT); } 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]]; + tilesetid_t id = TILESET_SLOTS[i]; + if(id == TILESET_NULL) continue; + tileset_t *tileset = &TILESETS[id]; + texture_t *texture = &TILESET_GL_TEXTURES[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); + } while(++i < TILESET_SLOT_COUNT); shaderBufferBind(&TILESET_SHADER_DATA_BUFFER); shaderBufferSetData(&TILESET_SHADER_DATA_BUFFER, &TILESET_SHADER_DATA_DATA); } +void tilesetShaderTexturesBind(const GLuint uniform) { + shaderSetTextures(uniform, TILESET_SHADER_DATA_TEXTURES, TILESET_SLOT_COUNT); +} + 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 index a0825a2..604cd49 100644 --- a/src/duskgl/display/shader/data/tilesetshaderdata.h +++ b/src/duskgl/display/shader/data/tilesetshaderdata.h @@ -9,22 +9,23 @@ #include "display/shader/shaderbuffer.h" #include "display/tilesetgl.h" -#define TILESET_BLOCK_NAME "b_Tileset" +#define TILESET_SHADER_DATA_BLOCK_NAME "b_Tilesets" #define TILESET_UNIFORM_TEXTURES_NAME "u_TilesetTextures" typedef struct { - int32_t columns; - int32_t rows; - int32_t width; - int32_t height; + uint32_t columns; + uint32_t rows; + uint32_t width; + uint32_t height; } tilesetshaderdatatileset_t; typedef struct { - tilesetshaderdatatileset_t tilesets[TILESET_COUNT]; + tilesetshaderdatatileset_t tilesets[TILESET_SLOT_COUNT]; } tilesetshaderdata_t; extern shaderbuffer_t TILESET_SHADER_DATA_BUFFER; extern tilesetshaderdata_t TILESET_SHADER_DATA_DATA; +extern GLuint TILESET_SHADER_DATA_TEXTURES[]; /** * Initializes the tileset buffer and data. @@ -36,6 +37,13 @@ void tilesetShaderDataInit(); */ void tilesetShaderDataUpdate(); +/** + * Binds the tileset textures to the given uniform. + * + * @param uniform The uniform to bind the textures to. + */ +void tilesetShaderTexturesBind(const GLuint uniform); + /** * Destroys the tileset buffer. */ diff --git a/src/duskgl/display/shader/entityshader/entity_frag.glsl b/src/duskgl/display/shader/entityshader/entity_frag.glsl index 486e738..1d70729 100644 --- a/src/duskgl/display/shader/entityshader/entity_frag.glsl +++ b/src/duskgl/display/shader/entityshader/entity_frag.glsl @@ -14,6 +14,6 @@ in vec2 v_TextureCoord; out vec4 FragColor; void main() { - vec4 tColor = tilesetGetColor(0, v_TextureCoord); + vec4 tColor = tilesetGetColor(uint(TILESET_SLOT_ENTITIES), v_TextureCoord); FragColor = vec4(1, 1, 1, 1) * tColor; } diff --git a/src/duskgl/display/shader/entityshader/entity_vert.glsl b/src/duskgl/display/shader/entityshader/entity_vert.glsl index e326847..2cf084d 100644 --- a/src/duskgl/display/shader/entityshader/entity_vert.glsl +++ b/src/duskgl/display/shader/entityshader/entity_vert.glsl @@ -6,6 +6,7 @@ #include "../fragments/header.glsl" #include "../data/transforms.glsl" #include "../data/entities.glsl" +#include "../data/tilesets.glsl" // Outputs to fragment shader out vec2 v_TextureCoord; @@ -14,8 +15,10 @@ void main() { uint instanceIndex = uint(gl_InstanceID); uint indiceIndex = quadGetIndiceIndex(gl_VertexID); + vec4 tilesetUVs = tilesetGetUVsByIndex(uint(TILESET_SLOT_ENTITIES), 1u); + vec2 vert = entityGetVertice(instanceIndex, indiceIndex); - vec2 uv = quadGetTextureCoordinate(indiceIndex); + vec2 uv = quadGetTextureCoordinate(indiceIndex, tilesetUVs); gl_Position = transforms.projection * transforms.view * vec4(vert, 0.0, 1.0); v_TextureCoord = uv; diff --git a/src/duskgl/display/shader/entityshader/entityshader.c b/src/duskgl/display/shader/entityshader/entityshader.c index 051fa6d..96874e7 100644 --- a/src/duskgl/display/shader/entityshader/entityshader.c +++ b/src/duskgl/display/shader/entityshader/entityshader.c @@ -13,6 +13,7 @@ #include "entity_frag.glsl.h" #include "display/shader/data/transforms.h" #include "display/shader/data/entities.h" +#include "display/shader/data/tilesetshaderdata.h" entityshader_t ENTITY_SHADER; @@ -36,13 +37,26 @@ void entityShaderInit() { ENTITIES_BLOCK_NAME ); + ENTITY_SHADER.tilesetsBlock = shaderGetBlock( + &ENTITY_SHADER.shader, + TILESET_SHADER_DATA_BLOCK_NAME + ); + // Uniforms + ENTITY_SHADER.tilesetTexturesUniform = shaderGetUniform( + &ENTITY_SHADER.shader, + TILESET_UNIFORM_TEXTURES_NAME + ); } void entityShaderUse() { shaderUse(&ENTITY_SHADER.shader); shaderBufferBindToBlock(&TRANSFORMS_BUFFER, ENTITY_SHADER.transformsBlock); shaderBufferBindToBlock(&ENTITIES_BUFFER, ENTITY_SHADER.entitiesBlock); + shaderBufferBindToBlock( + &TILESET_SHADER_DATA_BUFFER, ENTITY_SHADER.tilesetsBlock + ); + tilesetShaderTexturesBind(ENTITY_SHADER.tilesetTexturesUniform); } void entityShaderDispose() { diff --git a/src/duskgl/display/shader/entityshader/entityshader.h b/src/duskgl/display/shader/entityshader/entityshader.h index 1662317..a243dbc 100644 --- a/src/duskgl/display/shader/entityshader/entityshader.h +++ b/src/duskgl/display/shader/entityshader/entityshader.h @@ -10,8 +10,12 @@ typedef struct { shader_t shader; + GLuint entitiesBlock; GLuint transformsBlock; + GLuint tilesetsBlock; + + GLuint tilesetTexturesUniform; } entityshader_t; extern entityshader_t ENTITY_SHADER; diff --git a/src/duskgl/display/shader/fragments/packed.glsl b/src/duskgl/display/shader/fragments/packed.glsl index fcc5928..e37f5fd 100644 --- a/src/duskgl/display/shader/fragments/packed.glsl +++ b/src/duskgl/display/shader/fragments/packed.glsl @@ -11,6 +11,10 @@ uint packedGetU8(uint position, uvec4 data) { return (subData >> (position * 8u)) & 0xFFu; } +uint packedGetU32(uint position, uvec4 data) { + return data[position]; +} + int packedGetI8(uint position, uvec4 data) { uint subData = data[position / 4u]; diff --git a/src/duskgl/display/shader/fragments/quad.glsl b/src/duskgl/display/shader/fragments/quad.glsl index 74f9d63..949fcac 100644 --- a/src/duskgl/display/shader/fragments/quad.glsl +++ b/src/duskgl/display/shader/fragments/quad.glsl @@ -14,9 +14,9 @@ uint quadGetIndiceIndex(int vertexId) { vec2 quadGetVertice(uint indiceIndex) { vec2 vert = vec2(0, 0); - if(indiceIndex == 0u || indiceIndex == 4u) { + /*if(indiceIndex == 0u || indiceIndex == 4u) { // vert = vec2(0, 0); - } else if(indiceIndex == 1u) { + } else*/ if(indiceIndex == 1u) { vert = vec2(1, 0); } else if(indiceIndex == 2u || indiceIndex == 5u) { vert = vec2(1, 1); @@ -30,4 +30,10 @@ vec2 quadGetVertice(uint indiceIndex) { vec2 quadGetTextureCoordinate(uint indiceIndex) { vec2 vert = quadGetVertice(indiceIndex); return vert; +} + +vec2 quadGetTextureCoordinate(uint indiceIndex, vec4 uv) { + vec2 vert = quadGetVertice(indiceIndex); + vert.y = 1.0 - vert.y; + return vec2(uv.x + (uv.z - uv.x) * vert.x, uv.y + (uv.w - uv.y) * vert.y); } \ No newline at end of file diff --git a/src/duskgl/display/shader/shader.c b/src/duskgl/display/shader/shader.c index 6a43e03..9c068d8 100644 --- a/src/duskgl/display/shader/shader.c +++ b/src/duskgl/display/shader/shader.c @@ -120,6 +120,18 @@ GLuint shaderGetBlock(const shader_t *shader, const char *name) { return blockIndex; } +void shaderSetTextures( + const GLuint uniform, + const GLuint *textures, + const uint8_t count +) { + assertNotNull(textures, "textures must not be NULL"); + assertTrue(count > 0, "count must be greater than 0"); + + glUniform1iv(uniform, count, textures); + assertNoGLError(); +} + void shaderDispose(shader_t *shader) { assertNotNull(shader, "shader must not be NULL"); diff --git a/src/duskgl/display/shader/shader.h b/src/duskgl/display/shader/shader.h index 1bc6395..4c84589 100644 --- a/src/duskgl/display/shader/shader.h +++ b/src/duskgl/display/shader/shader.h @@ -54,6 +54,19 @@ GLuint shaderGetUniform(const shader_t *shader, const char_t *name); */ GLuint shaderGetBlock(const shader_t *shader, const char_t *name); +/** + * Sets texture uniforms to a shader. + * + * @param uniform The uniform to set. + * @param textures The textures to set. + * @param count The number of textures to set. + */ +void shaderSetTextures( + const GLuint uniform, + const GLuint *textures, + const uint8_t count +); + /** * Disposes of a shader. * diff --git a/src/duskgl/display/tilesetgl.c b/src/duskgl/display/tilesetgl.c index 1ee87e1..ac94028 100644 --- a/src/duskgl/display/tilesetgl.c +++ b/src/duskgl/display/tilesetgl.c @@ -10,7 +10,7 @@ const char* TILESET_GL_TEXTURES_PATHS[TILESET_COUNT] = { NULL, - "textures/bolder-8x8.png" + "textures/8x8.png" }; texture_t TILESET_GL_TEXTURES[TILESET_SLOT_COUNT];