From 122997c58c13709cf72dc6e381c73c1eae95e743 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Sun, 2 Mar 2025 17:29:00 -0600 Subject: [PATCH] Map shader base, add memory util. --- src/dusk/assert/assert.c | 78 +++++++++---------- src/dusk/assert/assert.h | 5 +- src/dusk/display/scene.c | 3 +- src/dusk/game.c | 3 +- src/dusk/overworld/entity.c | 5 +- src/dusk/overworld/entity.h | 2 +- src/dusk/overworld/overworld.c | 11 ++- src/dusk/overworld/overworld.h | 7 +- src/dusk/overworld/overworlddefs.h | 5 +- src/dusk/overworld/player.c | 10 +-- src/dusk/overworld/tile.h | 15 ++++ src/dusk/util/CMakeLists.txt | 1 + src/dusk/util/memory.c | 52 +++++++++++++ src/dusk/util/memory.h | 67 ++++++++++++++++ src/duskgl/assert/assertgl.c | 3 +- src/duskgl/asset.c | 5 +- src/duskgl/display/CMakeLists.txt | 1 - src/duskgl/display/render.c | 4 +- src/duskgl/display/shader/CMakeLists.txt | 1 + src/duskgl/display/shader/data/CMakeLists.txt | 1 + src/duskgl/display/shader/data/entities.c | 10 +-- src/duskgl/display/shader/data/map.c | 43 ++++++++++ src/duskgl/display/shader/data/map.glsl | 42 ++++++++++ src/duskgl/display/shader/data/map.h | 44 +++++++++++ .../shader/entityshader/entity_vert.glsl | 2 +- .../shader/entityshader/entityshader.c | 3 +- src/duskgl/display/shader/fragments/quad.glsl | 8 ++ .../display/shader/mapshader/CMakeLists.txt | 14 ++++ .../display/shader/mapshader/map_frag.glsl | 16 ++++ .../display/shader/mapshader/map_vert.glsl | 22 ++++++ .../display/shader/mapshader/mapshader.c | 50 ++++++++++++ .../display/shader/mapshader/mapshader.h | 32 ++++++++ src/duskgl/display/shader/shadermanager.c | 8 +- src/duskgl/display/texture.c | 5 +- src/duskgl/overworld/overworld.c | 8 +- 35 files changed, 511 insertions(+), 75 deletions(-) create mode 100644 src/dusk/overworld/tile.h create mode 100644 src/dusk/util/memory.c create mode 100644 src/dusk/util/memory.h create mode 100644 src/duskgl/display/shader/data/map.c create mode 100644 src/duskgl/display/shader/data/map.glsl create mode 100644 src/duskgl/display/shader/data/map.h create mode 100644 src/duskgl/display/shader/mapshader/CMakeLists.txt create mode 100644 src/duskgl/display/shader/mapshader/map_frag.glsl create mode 100644 src/duskgl/display/shader/mapshader/map_vert.glsl create mode 100644 src/duskgl/display/shader/mapshader/mapshader.c create mode 100644 src/duskgl/display/shader/mapshader/mapshader.h diff --git a/src/dusk/assert/assert.c b/src/dusk/assert/assert.c index 31cbba0..77bade8 100644 --- a/src/dusk/assert/assert.c +++ b/src/dusk/assert/assert.c @@ -82,43 +82,43 @@ void assertDeprecatedImpl( assertUnreachableImpl(file, line, message); } -void assertMemoryRangeMatchesImpl( - const char *file, - const int32_t line, - const void *start, - const void *end, - const size_t size, - const char *message -) { - assertTrueImpl( - file, - line, - start != NULL, - "Start pointer is NULL" - ); - assertTrueImpl( - file, - line, - end != NULL, - "End pointer is NULL" - ); - assertTrueImpl( - file, - line, - size > 0, - "Size is 0" - ); - assertTrueImpl( - file, - line, - start < end, - "Start pointer is not before end pointer" - ); +// void assertMemoryRangeMatchesImpl( +// const char *file, +// const int32_t line, +// const void *start, +// const void *end, +// const size_t size, +// const char *message +// ) { +// assertTrueImpl( +// file, +// line, +// start != NULL, +// "Start pointer is NULL" +// ); +// assertTrueImpl( +// file, +// line, +// end != NULL, +// "End pointer is NULL" +// ); +// assertTrueImpl( +// file, +// line, +// size > 0, +// "Size is 0" +// ); +// assertTrueImpl( +// file, +// line, +// start < end, +// "Start pointer is not before end pointer" +// ); - assertTrueImpl( - file, - line, - ((uintptr_t)end - (uintptr_t)start) == size, - message - ); -} \ No newline at end of file +// assertTrueImpl( +// file, +// line, +// ((uintptr_t)end - (uintptr_t)start) == size, +// message +// ); +// } \ No newline at end of file diff --git a/src/dusk/assert/assert.h b/src/dusk/assert/assert.h index 88b2e25..b98d192 100644 --- a/src/dusk/assert/assert.h +++ b/src/dusk/assert/assert.h @@ -126,7 +126,4 @@ void assertMemoryRangeMatchesImpl( assertTrue(strlen(str) <= len, message) #define assertStrLenMin(str, len, message) \ - assertTrue(strlen(str) >= len, message) - -#define assertMemoryRangeMatches(start, end, size, message) \ - assertMemoryRangeMatchesImpl(__FILE__, __LINE__, start, end, size, message) + assertTrue(strlen(str) >= len, message) \ No newline at end of file diff --git a/src/dusk/display/scene.c b/src/dusk/display/scene.c index 2456da3..6a37a55 100644 --- a/src/dusk/display/scene.c +++ b/src/dusk/display/scene.c @@ -7,6 +7,7 @@ #include "scene.h" #include "assert/assert.h" +#include "util/memory.h" #include "overworld/overworld.h" scenetypecallback_t SCENE_CALLBACKS[] = { @@ -26,7 +27,7 @@ scenetypecallback_t SCENE_CALLBACKS[] = { scene_t SCENE; void sceneInit() { - memset(&SCENE, 0, sizeof(scene_t)); + memoryZero(&SCENE, sizeof(scene_t)); for(uint8_t i = 0; i < SCENE_TYPE_COUNT; i++) { if(SCENE_CALLBACKS[i].onInit) SCENE_CALLBACKS[i].onInit(); diff --git a/src/dusk/game.c b/src/dusk/game.c index e82f32e..a57acf3 100644 --- a/src/dusk/game.c +++ b/src/dusk/game.c @@ -8,11 +8,12 @@ #include "game.h" #include "input.h" #include "display/scene.h" +#include "util/memory.h" game_t GAME; void gameInit() { - memset(&GAME, 0, sizeof(game_t)); + memoryZero(&GAME, sizeof(game_t)); inputInit(); sceneInit(); diff --git a/src/dusk/overworld/entity.c b/src/dusk/overworld/entity.c index fc337f2..a073ac4 100644 --- a/src/dusk/overworld/entity.c +++ b/src/dusk/overworld/entity.c @@ -7,6 +7,7 @@ #include "entity.h" #include "assert/assert.h" +#include "util/memory.h" #include "overworlddefs.h" entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = { @@ -24,7 +25,7 @@ void entityInit( assertTrue(type < ENTITY_TYPE_COUNT, "Invalid entity type"); // Init values - memset(ent, 0, sizeof(entity_t)); + memoryZero(ent, sizeof(entity_t)); ent->type = type; // Call init @@ -35,7 +36,6 @@ void entityInit( void entityUpdate(entity_t *ent) { assertNotNull(ent, "Entity cannot be NULL"); assertTrue(ent->type < ENTITY_TYPE_COUNT, "Invalid entity type"); - assertNotNull(ENTITY_CALLBACKS[ent->type].update, "Entity type update err."); ENTITY_CALLBACKS[ent->type].update(ent); @@ -64,6 +64,7 @@ void entityTurn(entity_t *ent, const facingdir_t dir) { void entityMove(entity_t *ent, const facingdir_t dir) { assertNotNull(ent, "Entity cannot be NULL"); + if(entityIsMoving(ent)) return; entityTurn(ent, dir); diff --git a/src/dusk/overworld/entity.h b/src/dusk/overworld/entity.h index bcd421b..f62bdee 100644 --- a/src/dusk/overworld/entity.h +++ b/src/dusk/overworld/entity.h @@ -39,7 +39,7 @@ typedef struct _entity_t { }; } entity_t; -#define ENTITY_MOVE_SPEED 4 +#define ENTITY_MOVE_SPEED 3 /** * Initializes an entity. diff --git a/src/dusk/overworld/overworld.c b/src/dusk/overworld/overworld.c index b64a409..9ce369c 100644 --- a/src/dusk/overworld/overworld.c +++ b/src/dusk/overworld/overworld.c @@ -6,13 +6,22 @@ */ #include "overworld.h" +#include "util/memory.h" +#include "assert/assert.h" overworld_t OVERWORLD; void overworldInit() { - memset(&OVERWORLD, 0, sizeof(overworld_t)); + memoryZero(&OVERWORLD, sizeof(overworld_t)); // Test + OVERWORLD.mapWidth = 16; + OVERWORLD.mapHeight = 16; + assertTrue( + OVERWORLD.mapWidth * OVERWORLD.mapHeight <= OVERWORLD_TILE_COUNT_MAX, + "Map size exceeds tile count." + ); + entityInit(OVERWORLD.entities + OVERWORLD.entityCount++, ENTITY_TYPE_PLAYER); } diff --git a/src/dusk/overworld/overworld.h b/src/dusk/overworld/overworld.h index 1b4b1c9..d9097ae 100644 --- a/src/dusk/overworld/overworld.h +++ b/src/dusk/overworld/overworld.h @@ -6,12 +6,17 @@ */ #pragma once -#include "entity.h" #include "overworlddefs.h" +#include "entity.h" +#include "tile.h" typedef struct { entity_t entities[OVERWORLD_ENTITY_COUNT_MAX]; uint8_t entityCount; + + tileid_t tileIds[OVERWORLD_TILE_COUNT_MAX]; + tiledata_t tileData[OVERWORLD_TILE_COUNT_MAX]; + uint8_t mapWidth, mapHeight; } overworld_t; extern overworld_t OVERWORLD; diff --git a/src/dusk/overworld/overworlddefs.h b/src/dusk/overworld/overworlddefs.h index dc27e3a..dcb35b2 100644 --- a/src/dusk/overworld/overworlddefs.h +++ b/src/dusk/overworld/overworlddefs.h @@ -5,7 +5,10 @@ * https://opensource.org/licenses/MIT */ +#define OVERWORLD_ENTITY_COUNT_MAX 32 #define OVERWORLD_ENTITY_WIDTH 32 #define OVERWORLD_ENTITY_HEIGHT 32 -#define OVERWORLD_ENTITY_COUNT_MAX 32 \ No newline at end of file +#define OVERWORLD_TILE_COUNT_MAX 256 +#define OVERWORLD_TILE_WIDTH OVERWORLD_ENTITY_WIDTH +#define OVERWORLD_TILE_HEIGHT OVERWORLD_ENTITY_HEIGHT \ No newline at end of file diff --git a/src/dusk/overworld/player.c b/src/dusk/overworld/player.c index 72b02d7..96b8b81 100644 --- a/src/dusk/overworld/player.c +++ b/src/dusk/overworld/player.c @@ -17,14 +17,14 @@ void playerInit(entity_t *ent) { void playerUpdate(entity_t *ent) { assertNotNull(ent, "Entity cannot be NULL"); - - if(inputWasPressed(INPUT_RIGHT)) { + + if(inputIsDown(INPUT_RIGHT)) { entityMove(ent, FACING_DIRECTION_EAST); - } else if(inputWasPressed(INPUT_LEFT)) { + } else if(inputIsDown(INPUT_LEFT)) { entityMove(ent, FACING_DIRECTION_WEST); - } else if(inputWasPressed(INPUT_UP)) { + } else if(inputIsDown(INPUT_UP)) { entityMove(ent, FACING_DIRECTION_NORTH); - } else if(inputWasPressed(INPUT_DOWN)) { + } else if(inputIsDown(INPUT_DOWN)) { entityMove(ent, FACING_DIRECTION_SOUTH); } } \ No newline at end of file diff --git a/src/dusk/overworld/tile.h b/src/dusk/overworld/tile.h new file mode 100644 index 0000000..f2e4040 --- /dev/null +++ b/src/dusk/overworld/tile.h @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" + +typedef uint8_t tileid_t; + +typedef struct { + uint32_t nothing; +} tiledata_t; \ No newline at end of file diff --git a/src/dusk/util/CMakeLists.txt b/src/dusk/util/CMakeLists.txt index 566421c..524bbb1 100644 --- a/src/dusk/util/CMakeLists.txt +++ b/src/dusk/util/CMakeLists.txt @@ -8,4 +8,5 @@ target_sources(${DUSK_TARGET_NAME} PRIVATE math.c random.c + memory.c ) \ No newline at end of file diff --git a/src/dusk/util/memory.c b/src/dusk/util/memory.c new file mode 100644 index 0000000..736c1b6 --- /dev/null +++ b/src/dusk/util/memory.c @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "memory.h" +#include "assert/assert.h" + +void * memoryAllocate(const size_t size) { + void *ptr = malloc(size); + assertNotNull(ptr, "Failed to allocate memory."); + return ptr; +} + +void memoryFree(void *ptr) { + assertNotNull(ptr, "Cannot free NULL memory."); + free(ptr); +} + +void memoryCopy(void *dest, const void *src, const size_t size) { + assertNotNull(dest, "Cannot copy to NULL memory."); + assertNotNull(src, "Cannot copy from NULL memory."); + assertTrue(size > 0, "Cannot copy 0 bytes of memory."); + assertTrue(dest != src, "Cannot copy memory to itself."); + memcpy(dest, src, size); +} + +void memorySet(void *dest, const uint8_t value, const size_t size) { + assertNotNull(dest, "Cannot set NULL memory."); + assertTrue(size > 0, "Cannot set 0 bytes of memory."); + memset(dest, value, size); +} + +void memoryZero(void *dest, const size_t size) { + memorySet(dest, 0, size); +} + +void memoryCopyRangeSafe( + void *dest, + const void *start, + const void *end, + const size_t sizeMax +) { + assertFalse(start == end, "Start and end pointers are the same."); + assertTrue(end > start, "End pointer is not after start pointer."); + + size_t copy = (size_t)end - (size_t)start; + assertTrue(copy <= sizeMax, "Size of memory to copy is too large."); + memoryCopy(dest, start, copy); +} \ No newline at end of file diff --git a/src/dusk/util/memory.h b/src/dusk/util/memory.h new file mode 100644 index 0000000..142c85e --- /dev/null +++ b/src/dusk/util/memory.h @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" + +/** + * Allocates memory. + * + * @param size The size of the memory to allocate. + * @return The allocated memory. + */ +void * memoryAllocate(const size_t size); + +/** + * Frees memory. + * + * @param ptr The memory to free. + */ +void memoryFree(void *ptr); + +/** + * Copies memory. + * + * @param dest The destination to copy to. + * @param src The source to copy from. + * @param size The size of the memory to copy. + */ +void memoryCopy(void *dest, const void *src, const size_t size); + +/** + * Sets memory. + * + * @param dest The destination to set. + * @param value The value to set. + * @param size The size of the memory to set. + */ +void memorySet(void *dest, const uint8_t value, const size_t size); + +/** + * Zeroes memory. + * + * @param dest The destination to zero. + * @param size The size of the memory to zero. + */ +void memoryZero(void *dest, const size_t size); + +/** + * Copies memory, ensuring that the memory range is as expected, typically this + * is done if you're trying to reshape data in a buffer. Extremely useful in + * copying data to a shader buffer. + * + * @param dest The destination to copy to. + * @param start The start of the source to copy from. + * @param end The end of the source to copy from. + * @param sizeMax The maximum size of the memory to copy. + */ +void memoryCopyRangeSafe( + void *dest, + const void *start, + const void *end, + const size_t sizeMax +); \ No newline at end of file diff --git a/src/duskgl/assert/assertgl.c b/src/duskgl/assert/assertgl.c index 7da4b4c..3a94ff2 100644 --- a/src/duskgl/assert/assertgl.c +++ b/src/duskgl/assert/assertgl.c @@ -7,6 +7,7 @@ #include "assert/assertgl.h" #include "assert/assert.h" +#include "util/memory.h" void assertNotGLErrorCheck(const char_t *file, const int32_t line) { assertNotNull(file, "File is an invlaid string"); @@ -18,7 +19,7 @@ void assertNotGLErrorCheck(const char_t *file, const int32_t line) { while((errorCode = glGetError()) != GL_NO_ERROR) { if(errorCount == 0) { - buffer = malloc(sizeof(char_t) * 4096); + buffer = memoryAllocate(sizeof(char_t) * 4096); sprintf(buffer, "assertNotGLErrorCheck: %s:%d\n", file, line); } diff --git a/src/duskgl/asset.c b/src/duskgl/asset.c index a985842..107524c 100644 --- a/src/duskgl/asset.c +++ b/src/duskgl/asset.c @@ -8,6 +8,7 @@ #include "asset.h" #include "assert/assert.h" #include "util/math.h" +#include "util/memory.h" asset_t ASSET; @@ -18,7 +19,7 @@ void assetInit() { EXECUTABLE_DIRECTORY }; - memset(&ASSET, 0, sizeof(asset_t)); + memoryZero(&ASSET, sizeof(asset_t)); // Try and find the asset file. for(int32_t i = 0; i < sizeof(scanLocations) / sizeof(char_t*); i++) { @@ -171,7 +172,7 @@ void assetDispose() { assertNotNull(ASSET.file, "Asset disposing but file is NULL?"); fclose(ASSET.file); - memset(&ASSET, 0, sizeof(asset_t)); + memoryZero(&ASSET, sizeof(asset_t)); } // Libarchive callbacks diff --git a/src/duskgl/display/CMakeLists.txt b/src/duskgl/display/CMakeLists.txt index bd907eb..931142d 100644 --- a/src/duskgl/display/CMakeLists.txt +++ b/src/duskgl/display/CMakeLists.txt @@ -6,7 +6,6 @@ # Sources target_sources(${DUSK_TARGET_NAME} PRIVATE - framebuffer.c render.c quad.c texture.c diff --git a/src/duskgl/display/render.c b/src/duskgl/display/render.c index c0e266f..d264d77 100644 --- a/src/duskgl/display/render.c +++ b/src/duskgl/display/render.c @@ -6,6 +6,7 @@ */ #include "assert/assertgl.h" +#include "util/memory.h" #include "render.h" #include "display/scene.h" #include "display/shader/shadermanager.h" @@ -15,7 +16,7 @@ render_t RENDER; void renderInit() { - memset(&RENDER, 0, sizeof(render_t)); + memoryZero(&RENDER, sizeof(render_t)); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); assertNoGLError(); @@ -26,6 +27,7 @@ void renderInit() { void renderUpdate() { glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); + assertNoGLError(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); assertNoGLError(); diff --git a/src/duskgl/display/shader/CMakeLists.txt b/src/duskgl/display/shader/CMakeLists.txt index fc94c69..8a7dff5 100644 --- a/src/duskgl/display/shader/CMakeLists.txt +++ b/src/duskgl/display/shader/CMakeLists.txt @@ -14,4 +14,5 @@ target_sources(${DUSK_TARGET_NAME} # Subdirs add_subdirectory(data) add_subdirectory(entityshader) +add_subdirectory(mapshader) add_subdirectory(fragments) \ No newline at end of file diff --git a/src/duskgl/display/shader/data/CMakeLists.txt b/src/duskgl/display/shader/data/CMakeLists.txt index 2f0ccee..e9ef5a3 100644 --- a/src/duskgl/display/shader/data/CMakeLists.txt +++ b/src/duskgl/display/shader/data/CMakeLists.txt @@ -8,4 +8,5 @@ target_sources(${DUSK_TARGET_NAME} PRIVATE transforms.c entities.c + map.c ) \ No newline at end of file diff --git a/src/duskgl/display/shader/data/entities.c b/src/duskgl/display/shader/data/entities.c index cf42929..c3e288a 100644 --- a/src/duskgl/display/shader/data/entities.c +++ b/src/duskgl/display/shader/data/entities.c @@ -8,6 +8,7 @@ #include "entities.h" #include "overworld/overworld.h" #include "assert/assert.h" +#include "util/memory.h" shaderbuffer_t ENTITIES_BUFFER; entitiesdata_t ENTITIES_DATA; @@ -27,13 +28,12 @@ void entitiesUpdate() { entitiesdataent_t *dst = &ENTITIES_DATA.entities[i]; // Copy position data. - assertMemoryRangeMatches( + memoryCopyRangeSafe( + &dst->position, &src->x, - &src->direction, - sizeof(uint_t), - "Entity data is not packed correctly any more." + &src->subY + sizeof(uint8_t), + sizeof(uint_t) ); - memcpy(&dst->position, &src->x, sizeof(uint_t)); } } diff --git a/src/duskgl/display/shader/data/map.c b/src/duskgl/display/shader/data/map.c new file mode 100644 index 0000000..527e6b7 --- /dev/null +++ b/src/duskgl/display/shader/data/map.c @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "map.h" +#include "util/memory.h" + +shaderbuffer_t MAP_BUFFER; +mapdata_t MAP_DATA; + +void mapInit() { + memset(&MAP_DATA, 0, sizeof(mapdata_t)); + shaderBufferInit(&MAP_BUFFER, sizeof(mapdata_t)); +} + +void mapUpdate() { + + // Copy map size. + memoryCopyRangeSafe( + &MAP_DATA.mapSize, + &OVERWORLD.mapWidth, + &OVERWORLD.mapHeight + sizeof(uint8_t), + sizeof(uint_t) + ); + + // Copy tile ids. + memoryCopyRangeSafe( + &MAP_DATA.tileIds, + &OVERWORLD.tileIds[0], + &OVERWORLD.tileIds[OVERWORLD.mapWidth * OVERWORLD.mapHeight], + OVERWORLD_TILE_COUNT_MAX * sizeof(tileid_t) + ); + + shaderBufferBind(&MAP_BUFFER); + shaderBufferSetData(&MAP_BUFFER, &MAP_DATA); +} + +void mapDispose() { + shaderBufferDispose(&MAP_BUFFER); +} \ No newline at end of file diff --git a/src/duskgl/display/shader/data/map.glsl b/src/duskgl/display/shader/data/map.glsl new file mode 100644 index 0000000..50baaec --- /dev/null +++ b/src/duskgl/display/shader/data/map.glsl @@ -0,0 +1,42 @@ +// Copyright (c) 2025 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "../../../../dusk/overworld/overworlddefs.h" +#include "../fragments/packed.glsl" +#include "../fragments/quad.glsl" + +#define MAP_PACKED_SIZE 4 + +struct TileData { + uint nothing; + uvec3 _padding0; +}; + +layout(std140) uniform b_Map { + uint mapSize; + uint mapTileIds[OVERWORLD_TILE_COUNT_MAX / MAP_PACKED_SIZE]; + TileData mapTileData[OVERWORLD_TILE_COUNT_MAX]; + uvec3 _padding0; +}; + +vec2 mapTileGetSize() { + return vec2(float(OVERWORLD_TILE_WIDTH), float(OVERWORLD_TILE_HEIGHT)); +} + +vec2 mapGetVertice(uint instanceIndex, uint indiceIndex) { + vec2 quad = quadGetVertice(indiceIndex); + + uint mapWidth = packedGetU8(0u, mapSize); + uint mapHeight = packedGetU8(1u, mapSize); + + quad += vec2( + float(instanceIndex % mapWidth), + float(instanceIndex / mapWidth) + ); + + quad *= mapTileGetSize(); + + return quad; +} \ No newline at end of file diff --git a/src/duskgl/display/shader/data/map.h b/src/duskgl/display/shader/data/map.h new file mode 100644 index 0000000..91ad00c --- /dev/null +++ b/src/duskgl/display/shader/data/map.h @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma ocne +#include "display/shader/shaderbuffer.h" +#include "overworld/overworld.h" + +#define MAP_BLOCK_NAME "b_Map" +#define MAP_PACKED_SIZE 4 + +typedef struct { + uint32_t nothing; + uvec3_t _padding0; +} maptiledata_t; + +typedef struct { + uint_t mapSize; + uvec3_t _padding0; + + uint32_t tileIds[OVERWORLD_TILE_COUNT_MAX / MAP_PACKED_SIZE]; + maptiledata_t tileData[OVERWORLD_TILE_COUNT_MAX]; +} mapdata_t; + +extern shaderbuffer_t MAP_BUFFER; +extern mapdata_t MAP_DATA; + +/** + * Initializes the map buffer and data. + */ +void mapInit(); + +/** + * Updates the map buffer with the current data. + */ +void mapUpdate(); + +/** + * Destroys the map buffer. + */ +void mapDispose(); \ No newline at end of file diff --git a/src/duskgl/display/shader/entityshader/entity_vert.glsl b/src/duskgl/display/shader/entityshader/entity_vert.glsl index 825e29d..e326847 100644 --- a/src/duskgl/display/shader/entityshader/entity_vert.glsl +++ b/src/duskgl/display/shader/entityshader/entity_vert.glsl @@ -12,7 +12,7 @@ out vec2 v_TextureCoord; void main() { uint instanceIndex = uint(gl_InstanceID); - uint indiceIndex = uint(gl_VertexID % 6); + uint indiceIndex = quadGetIndiceIndex(gl_VertexID); vec2 vert = entityGetVertice(instanceIndex, indiceIndex); vec2 uv = quadGetTextureCoordinate(indiceIndex); diff --git a/src/duskgl/display/shader/entityshader/entityshader.c b/src/duskgl/display/shader/entityshader/entityshader.c index 78578bb..d62402e 100644 --- a/src/duskgl/display/shader/entityshader/entityshader.c +++ b/src/duskgl/display/shader/entityshader/entityshader.c @@ -7,6 +7,7 @@ #include "assert/assert.h" #include "assert/assertgl.h" +#include "util/memory.h" #include "entityshader.h" #include "entity_vert.glsl.h" #include "entity_frag.glsl.h" @@ -16,7 +17,7 @@ entityshader_t ENTITY_SHADER; void entityShaderInit() { - memset(&ENTITY_SHADER, 0, sizeof(entityshader_t)); + memoryZero(&ENTITY_SHADER, sizeof(entityshader_t)); shaderInit( &ENTITY_SHADER.shader, diff --git a/src/duskgl/display/shader/fragments/quad.glsl b/src/duskgl/display/shader/fragments/quad.glsl index b64b682..74f9d63 100644 --- a/src/duskgl/display/shader/fragments/quad.glsl +++ b/src/duskgl/display/shader/fragments/quad.glsl @@ -3,6 +3,14 @@ // This software is released under the MIT License. // https://opensource.org/licenses/MIT +uint quadGetIndiceIndex(uint vertexId) { + return vertexId % 6u; +} + +uint quadGetIndiceIndex(int vertexId) { + return quadGetIndiceIndex(uint(vertexId)); +} + vec2 quadGetVertice(uint indiceIndex) { vec2 vert = vec2(0, 0); diff --git a/src/duskgl/display/shader/mapshader/CMakeLists.txt b/src/duskgl/display/shader/mapshader/CMakeLists.txt new file mode 100644 index 0000000..dd93833 --- /dev/null +++ b/src/duskgl/display/shader/mapshader/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Shaders +glsltool(map_vert.glsl) +glsltool(map_frag.glsl) + +# Sources +target_sources(${DUSK_TARGET_NAME} + PRIVATE + mapshader.c +) \ No newline at end of file diff --git a/src/duskgl/display/shader/mapshader/map_frag.glsl b/src/duskgl/display/shader/mapshader/map_frag.glsl new file mode 100644 index 0000000..683eb7c --- /dev/null +++ b/src/duskgl/display/shader/mapshader/map_frag.glsl @@ -0,0 +1,16 @@ +// Copyright (c) 2025 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "../fragments/header.glsl" + +// Inputs from vertex shader +in vec2 v_TextureCoord; + +// Frag pixel color +out vec4 FragColor; + +void main() { + FragColor = vec4(1, 0, 0, 1); +} diff --git a/src/duskgl/display/shader/mapshader/map_vert.glsl b/src/duskgl/display/shader/mapshader/map_vert.glsl new file mode 100644 index 0000000..bdd351d --- /dev/null +++ b/src/duskgl/display/shader/mapshader/map_vert.glsl @@ -0,0 +1,22 @@ +// Copyright (c) 2025 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "../fragments/header.glsl" +#include "../data/transforms.glsl" +#include "../data/map.glsl" + +// Outputs to fragment shader +out vec2 v_TextureCoord; + +void main() { + uint instanceIndex = uint(gl_InstanceID); + uint indiceIndex = quadGetIndiceIndex(gl_VertexID); + + vec2 vert = mapGetVertice(instanceIndex, indiceIndex); + vec2 uv = quadGetTextureCoordinate(indiceIndex); + + gl_Position = transforms.projection * transforms.view * vec4(vert, 0.0, 1.0); + v_TextureCoord = uv; +} \ No newline at end of file diff --git a/src/duskgl/display/shader/mapshader/mapshader.c b/src/duskgl/display/shader/mapshader/mapshader.c new file mode 100644 index 0000000..4c213a1 --- /dev/null +++ b/src/duskgl/display/shader/mapshader/mapshader.c @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "mapshader.h" +#include "util/memory.h" +#include "display/shader/data/map.h" +#include "display/shader/data/transforms.h" +#include "map_vert.glsl.h" +#include "map_frag.glsl.h" + +mapshader_t MAP_SHADER; + +void mapShaderInit() { + memoryZero(&MAP_SHADER, sizeof(mapshader_t)); + + shaderInit( + &MAP_SHADER.shader, + map_vertShaderSource, + map_fragShaderSource + ); + + // Uniform blocks + MAP_SHADER.mapBlock = shaderGetBlock( + &MAP_SHADER.shader, + MAP_BLOCK_NAME + ); + + MAP_SHADER.transformsBlock = shaderGetBlock( + &MAP_SHADER.shader, + TRANSFORMS_BLOCK_NAME + ); + + // Bind + shaderBufferBindToBlock(&MAP_BUFFER, MAP_SHADER.mapBlock); + shaderBufferBindToBlock(&TRANSFORMS_BUFFER, MAP_SHADER.transformsBlock); +} + +void mapShaderUse() { + shaderUse(&MAP_SHADER.shader); + shaderBufferBindToBlock(&MAP_BUFFER, MAP_SHADER.mapBlock); + shaderBufferBindToBlock(&TRANSFORMS_BUFFER, MAP_SHADER.transformsBlock); +} + +void mapShaderDispose() { + shaderDispose(&MAP_SHADER.shader); +} \ No newline at end of file diff --git a/src/duskgl/display/shader/mapshader/mapshader.h b/src/duskgl/display/shader/mapshader/mapshader.h new file mode 100644 index 0000000..09e01ce --- /dev/null +++ b/src/duskgl/display/shader/mapshader/mapshader.h @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "display/shader/shader.h" + +typedef struct { + shader_t shader; + GLuint mapBlock; + GLuint transformsBlock; +} mapshader_t; + +extern mapshader_t MAP_SHADER; + +/** + * Initializes the map shader. + */ +void mapShaderInit(); + +/** + * Uses the map shader. + */ +void mapShaderUse(); + +/** + * Destroys the map shader. + */ +void mapShaderDispose(); \ No newline at end of file diff --git a/src/duskgl/display/shader/shadermanager.c b/src/duskgl/display/shader/shadermanager.c index 0cfd479..93f8257 100644 --- a/src/duskgl/display/shader/shadermanager.c +++ b/src/duskgl/display/shader/shadermanager.c @@ -9,16 +9,20 @@ #include "assert/assert.h" #include "display/shader/data/transforms.h" #include "display/shader/data/entities.h" +#include "display/shader/data/map.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 } + { entitiesInit, entitiesUpdate, entitiesDispose }, + { mapInit, mapUpdate, mapDispose } }; shadermanagershadercallback_t SHADER_MANAGER_SHADER_CALLBACKS[] = { - { entityShaderInit, entityShaderDispose } + { entityShaderInit, entityShaderDispose }, + { mapShaderInit, mapShaderDispose } }; void shaderManagerInit() { diff --git a/src/duskgl/display/texture.c b/src/duskgl/display/texture.c index bc09e8d..765708c 100644 --- a/src/duskgl/display/texture.c +++ b/src/duskgl/display/texture.c @@ -10,6 +10,7 @@ #include "assert/assertgl.h" #include "asset.h" #include "util/math.h" +#include "util/memory.h" #define TEXTURE_BUFFER_SIZE 32768 @@ -37,7 +38,7 @@ void textureLoad( // Decode the image. I can probably stream this in the future. size_t dataSize = ihdr.width * ihdr.height * 4;// 4 for RGBA - uint8_t *data = (uint8_t *)malloc(dataSize); + uint8_t *data = (uint8_t *)memoryAllocate(dataSize); assertNotNull(data, "Failed to allocate memory for texture data."); spng_decode_image(ctx, data, dataSize, SPNG_FMT_RGBA8, 0); @@ -59,7 +60,7 @@ void textureLoad( 0, GL_RGBA, GL_UNSIGNED_BYTE, data ); assertNoGLError(); - free(data); + memoryFree(data); // Setup texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); diff --git a/src/duskgl/overworld/overworld.c b/src/duskgl/overworld/overworld.c index 87979f1..64c9e04 100644 --- a/src/duskgl/overworld/overworld.c +++ b/src/duskgl/overworld/overworld.c @@ -8,10 +8,12 @@ #include "overworld/overworld.h" #include "display/quad.h" #include "display/shader/entityshader/entityshader.h" +#include "display/shader/mapshader/mapshader.h" void overworldRender() { - entityShaderUse(); + mapShaderUse(); + quadRender(OVERWORLD.mapWidth * OVERWORLD.mapHeight); - // Set entity data. - quadRender(1); + // entityShaderUse(); + // quadRender(OVERWORLD.entityCount); } \ No newline at end of file