diff --git a/src/dusk/display/scene.c b/src/dusk/display/scene.c index b748374..56d40df 100644 --- a/src/dusk/display/scene.c +++ b/src/dusk/display/scene.c @@ -29,7 +29,7 @@ void sceneInit(void) { } } - SCENE_CURRENT = SCENE_INITIAL; + SCENE_CURRENT = SCENE_OVERWORLD; } void sceneSet(const scene_t scene) { diff --git a/src/dusk/world/chunk.c b/src/dusk/world/chunk.c index 1deeef8..9bd2fbd 100644 --- a/src/dusk/world/chunk.c +++ b/src/dusk/world/chunk.c @@ -10,6 +10,8 @@ #include "assert/assert.h" #include "world/world.h" +void renderChunkUpdated(chunk_t *chunk); + chunkmap_t CHUNK_MAP; void chunkMapInit() { @@ -261,6 +263,9 @@ void chunkLoad(chunk_t *chunk, const uint16_t x, const uint16_t y) { entityLoad(entity, data); data++; } + + // Allow the rendering platform to know this chunk is loaded. + renderChunkUpdated(chunk); } void chunkUnload(chunk_t *chunk) { diff --git a/src/dusksdl2/display/camera/camera.c b/src/dusksdl2/display/camera/camera.c index 83bddc4..c4fb9d4 100644 --- a/src/dusksdl2/display/camera/camera.c +++ b/src/dusksdl2/display/camera/camera.c @@ -8,6 +8,8 @@ #include "camera.h" #include "display/render.h" +#include "world/overworld.h" + void cameraUIPush(void) { glPushMatrix(); glLoadIdentity(); @@ -48,4 +50,25 @@ void cameraScreenPush(void) { void cameraScreenPop(void) { glPopMatrix(); +} + +void cameraOverworldPush(void) { + glPushMatrix(); + glLoadIdentity(); + glViewport(0, 0, RENDER_WIDTH, RENDER_HEIGHT); + glOrtho( + 0.0f, (float_t)RENDER_WIDTH, + (float_t)RENDER_HEIGHT, 0.0f, + -1.0f, 1.0f + ); + + glTranslatef( + -((float_t)OVERWORLD_CAMERA_X) + ((float_t)RENDER_WIDTH / 2.0f), + -((float_t)OVERWORLD_CAMERA_Y) + ((float_t)RENDER_HEIGHT / 2.0f), + 0.0f + ); +} + +void cameraOverworldPop(void) { + glPopMatrix(); } \ No newline at end of file diff --git a/src/dusksdl2/display/camera/camera.h b/src/dusksdl2/display/camera/camera.h index 1001c50..5547f25 100644 --- a/src/dusksdl2/display/camera/camera.h +++ b/src/dusksdl2/display/camera/camera.h @@ -26,4 +26,14 @@ void cameraScreenPush(void); /** * Pops the screen space camera matrix. */ -void cameraScreenPop(void); \ No newline at end of file +void cameraScreenPop(void); + +/** + * Pushes the overworld camera matrix onto the stack. + */ +void cameraOverworldPush(void); + +/** + * Pops the overworld camera matrix. + */ +void cameraOverworldPop(void); \ No newline at end of file diff --git a/src/dusksdl2/display/mesh/quad.c b/src/dusksdl2/display/mesh/quad.c index c77d413..acf02f8 100644 --- a/src/dusksdl2/display/mesh/quad.c +++ b/src/dusksdl2/display/mesh/quad.c @@ -23,39 +23,40 @@ void quadBuffer( const float_t u1, const float_t v1 ) { + const float_t z = 0.0f; // Z coordinate for 2D rendering assertNotNull(vertices, "Vertices cannot be NULL"); // First triangle vertices[0] = (meshvertex_t) { { r, g, b, a }, // Color { u0, v0 }, // UV - { minX, minY, 0.0f } // Position + { minX, minY, z } // Position }; vertices[1] = (meshvertex_t) { { r, g, b, a }, // Color { u1, v0 }, // UV - { maxX, minY, 0.0f } // Position + { maxX, minY, z } // Position }; vertices[2] = (meshvertex_t) { { r, g, b, a }, // Color { u1, v1 }, // UV - { maxX, maxY, 0.0f } // Position + { maxX, maxY, z } // Position }; // Second triangle vertices[3] = (meshvertex_t) { { r, g, b, a }, // Color { u0, v0 }, // UV - { minX, minY, 0.0f } // Position + { minX, minY, z } // Position }; vertices[4] = (meshvertex_t) { { r, g, b, a }, // Color { u1, v1 }, // UV - { maxX, maxY, 0.0f } // Position + { maxX, maxY, z } // Position }; vertices[5] = (meshvertex_t) { { r, g, b, a }, // Color { u0, v1 }, // UV - { minX, maxY, 0.0f } // Position + { minX, maxY, z } // Position }; } \ No newline at end of file diff --git a/src/dusksdl2/display/overworld/renderoverworld.c b/src/dusksdl2/display/overworld/renderoverworld.c index 4962e33..b068c1a 100644 --- a/src/dusksdl2/display/overworld/renderoverworld.c +++ b/src/dusksdl2/display/overworld/renderoverworld.c @@ -6,11 +6,119 @@ */ #include "renderoverworld.h" +#include "util/memory.h" +#include "assert/assert.h" +#include "display/camera/camera.h" +#include "entity/entity.h" +#include "display/spritebatch/spritebatch.h" + +renderoverworld_t RENDER_OVERWORLD; void renderOverworldInit(void) { - // Initialize overworld rendering resources here + memoryZero(&RENDER_OVERWORLD, sizeof(RENDER_OVERWORLD)); + + for(uint8_t i = 0; i < CHUNK_MAP_COUNT; i++) { + renderchunk_t *chunk = &RENDER_OVERWORLD.chunks[i]; + + meshInit( + &chunk->meshBase, + GL_TRIANGLES, + CHUNK_TILE_COUNT * QUAD_VERTEX_COUNT, + chunk->verticesBase + ); + + meshInit( + &chunk->meshBaseOverlay, + GL_TRIANGLES, + CHUNK_TILE_COUNT, + chunk->verticesBaseOverlay + ); + } +} + +void renderOverworldDraw(void) { + cameraOverworldPush(); + + for(uint8_t i = 0; i < CHUNK_MAP_COUNT; i++) { + renderchunk_t *chunk = &RENDER_OVERWORLD.chunks[i]; + // meshDraw(&chunk->meshBase, 0, CHUNK_TILE_COUNT * QUAD_VERTEX_COUNT); + meshDraw(&chunk->meshBase, -1, -1); + } + + + for(uint8_t i = 0; i < ENTITY_COUNT_MAX; i++) { + entity_t *entity = &ENTITIES[i]; + if(entity->type == ENTITY_TYPE_NULL) continue; + + // Draw the entity + spriteBatchPush( + NULL, + entity->x, entity->y, + entity->x + TILE_WIDTH_HEIGHT, entity->y + TILE_WIDTH_HEIGHT, + 0xFF, 0x00, 0xFF, 0XFF, + 0.0f, 0.0f, 1.0f, 1.0f + ); + } + + spriteBatchFlush(); + cameraOverworldPop(); +} + +void renderChunkUpdated(chunk_t *chunk) { + uint8_t r, g, b; + assertNotNull(chunk, "Chunk pointer is null"); + + int32_t chunkIndex = chunk - CHUNK_MAP.chunks; + assertTrue( + chunkIndex >= 0 && chunkIndex < CHUNK_MAP_COUNT, + "Chunk index out of bounds" + ); + + for(uint32_t i = 0; i < CHUNK_TILE_COUNT; i++) { + tile_t base = chunk->tilesBase[i]; + tile_t overlay = chunk->tilesBaseOverlay[i]; + + float_t posX = (i % CHUNK_WIDTH) + (chunk->x * CHUNK_WIDTH); + float_t posY = (i / CHUNK_WIDTH) + (chunk->y * CHUNK_HEIGHT); + + switch(base) { + case 0: + r = 0; g = 0; b = 0; // Black for empty + break; + case 1: + r = 34; g = 139; b = 34; // Forest Green + break; + case 2: + r = 0; g = 191; b = 255; // Deep Sky Blue + break; + case 3: + r = 139; g = 69; b = 19; // Saddle Brown + break; + case 4: + r = 255; g = 255; b = 0; // Yellow + break; + default: + r = 255; g = 20; b = 147; // Pink for unknown + break; + } + + quadBuffer( + &RENDER_OVERWORLD.chunks[chunkIndex].verticesBase[i * QUAD_VERTEX_COUNT], + posX * TILE_WIDTH_HEIGHT, + posY * TILE_WIDTH_HEIGHT, + (posX + 1) * TILE_WIDTH_HEIGHT, + (posY + 1) * TILE_WIDTH_HEIGHT, + r, g, b, 255, + 0, 0, 1, 1 + ); + } } void renderOverworldDispose(void) { // Clean up overworld rendering resources here + for(uint8_t i = 0; i < CHUNK_MAP_COUNT; i++) { + renderchunk_t *chunk = &RENDER_OVERWORLD.chunks[i]; + meshDispose(&chunk->meshBase); + meshDispose(&chunk->meshBaseOverlay); + } } \ No newline at end of file diff --git a/src/dusksdl2/display/overworld/renderoverworld.h b/src/dusksdl2/display/overworld/renderoverworld.h index 77bd2f3..01a080d 100644 --- a/src/dusksdl2/display/overworld/renderoverworld.h +++ b/src/dusksdl2/display/overworld/renderoverworld.h @@ -7,11 +7,11 @@ #pragma once #include "world/chunk.h" -#include "display/mesh/mesh.h" +#include "display/mesh/quad.h" typedef struct { mesh_t meshBase; - meshvertex_t verticesBase[CHUNK_TILE_COUNT]; + meshvertex_t verticesBase[CHUNK_TILE_COUNT * QUAD_VERTEX_COUNT]; mesh_t meshBaseOverlay; meshvertex_t verticesBaseOverlay[CHUNK_TILE_COUNT]; @@ -28,6 +28,11 @@ extern renderoverworld_t RENDER_OVERWORLD; */ void renderOverworldInit(void); +/** + * Draws the render overworld. + */ +void renderOverworldDraw(void); + /** * Disposes of the render overworld. */ diff --git a/src/dusksdl2/display/scene/renderscene.c b/src/dusksdl2/display/scene/renderscene.c index c8f8d07..0046ee0 100644 --- a/src/dusksdl2/display/scene/renderscene.c +++ b/src/dusksdl2/display/scene/renderscene.c @@ -17,7 +17,7 @@ renderscenecallback_t RENDER_SCENE_CALLBACKS[SCENE_COUNT] = { [SCENE_OVERWORLD] = { .init = renderOverworldInit, - .draw = NULL, + .draw = renderOverworldDraw, .dispose = renderOverworldDispose }, };