From 22cd090f92f6b1d75637778871cb227ead6666b7 Mon Sep 17 00:00:00 2001 From: Sheldon Lee Date: Mon, 1 May 2023 00:10:01 +0100 Subject: [PATCH] Implement basic shading and colors. CameraRay struct now stores information about tile intersection. --- camera.cpp | 3 +-- camera.h | 2 ++ firstperson.cpp | 27 ++++++++++++++++++++++++++- level.cpp | 29 ++++++++++++++++++++--------- level.h | 16 +++++++++++++++- minimap.cpp | 17 ++++++++++++++++- view.cpp | 4 ++-- 7 files changed, 82 insertions(+), 16 deletions(-) diff --git a/camera.cpp b/camera.cpp index 8f02e33..40ec8e0 100644 --- a/camera.cpp +++ b/camera.cpp @@ -2,7 +2,6 @@ #include #include "maths.h" -#include "level.h" #define ROTATION_SPEED PI #define TRANSLATIONAL_SPEED 1.f @@ -59,7 +58,7 @@ static void castRays(Camera* camera) float rayDirection = camera->direction - camera->fov/2.f + rayDirectionStep/2.f; for (unsigned int i = 0; i < camera->resolution; i++) { camera->rays[i].direction = rayDirection; - camera->rays[i].distance = level_rayCastDistance(camera->pos, rayDirection); + camera->rays[i].distance = level_rayCast(camera->pos, rayDirection, &camera->rays[i].tileData); rayDirection += rayDirectionStep; } diff --git a/camera.h b/camera.h index 78bf997..461c22a 100644 --- a/camera.h +++ b/camera.h @@ -2,11 +2,13 @@ #define CAMERA_H #include +#include "level.h" typedef struct { float direction; float distance; + TileData tileData; } CameraRay; typedef struct diff --git a/firstperson.cpp b/firstperson.cpp index a5791cd..0fef513 100644 --- a/firstperson.cpp +++ b/firstperson.cpp @@ -39,9 +39,34 @@ void firstperson_update(sf::RenderTarget* renderTarget, Camera* camera) distanceScale = (distanceScale > 1.f)? 1.f : distanceScale; float brightness = 255.f*(1.f-distanceScale); + switch (camera->rays[i].tileData.side) { + case NORTH: + break; + case EAST: + case WEST: + brightness *= 0.9; + break; + case SOUTH: + brightness *= 0.8; + break; + } + + sf::Color color(brightness, brightness, brightness); + switch (camera->rays[i].tileData.value) { + case 2: + color *= sf::Color::Red; + break; + case 3: + color *= sf::Color::Green; + break; + case 4: + color *= sf::Color::Blue; + break; + }; + sf::RectangleShape rectangle(sf::Vector2f(columnWidth, columnHeight)); rectangle.setPosition(sf::Vector2f(i*columnWidth, centeredHeight)); - rectangle.setFillColor(sf::Color(brightness, brightness, brightness)); + rectangle.setFillColor(color); renderTexture.draw(rectangle); } diff --git a/level.cpp b/level.cpp index ae1779e..e0f1c45 100644 --- a/level.cpp +++ b/level.cpp @@ -5,17 +5,17 @@ #define WIDTH 10 #define HEIGHT 10 -static float castRay(sf::Vector2f point, float direction); +static float castRay(sf::Vector2f point, float direction, TileData* tileData); static void getGridIndex(sf::Vector2f point, int* x, int* y); static unsigned int level[WIDTH * HEIGHT] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, + 1, 1, 1, 0, 0, 0, 0, 2, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, - 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, + 1, 0, 0, 1, 0, 0, 0, 3, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, - 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, + 1, 0, 0, 1, 0, 0, 0, 4, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -36,9 +36,10 @@ void level_end() return; } -float level_rayCastDistance(sf::Vector2f point, float direction) +float level_rayCast(sf::Vector2f point, float direction, TileData* tileData) { - return castRay(point, direction); + if (!tileData) return -1.f; + return castRay(point, direction, tileData); } void level_getDimensions(unsigned int* width, unsigned int* height) @@ -55,7 +56,7 @@ unsigned int level_getGridValue(unsigned int x, unsigned int y) return level[y * HEIGHT + x]; } -static float castRay(sf::Vector2f point, float direction) +static float castRay(sf::Vector2f point, float direction, TileData* tileData) { int indexX, indexY; getGridIndex(point, &indexX, &indexY); @@ -125,7 +126,12 @@ static float castRay(sf::Vector2f point, float direction) if (!(inLevel0 || inLevel1)) break; if (horizontalRayDist < verticalRayDist) { - if (level[indexY0 * WIDTH + indexX0]) return horizontalRayDist; + unsigned int gridValue = level[indexY0 * WIDTH + indexX0]; + if (gridValue) { + tileData->value = gridValue; + tileData->side = goingDown? NORTH : SOUTH; + return horizontalRayDist; + } horizontalProjectedX += horizontalStepX; horizontalProjectedY += horizontalStepY; @@ -133,7 +139,12 @@ static float castRay(sf::Vector2f point, float direction) horizontalRayDist += std::abs(horizontalStepY/horizontalDistCoeff); } else { - if (level[indexY1 * WIDTH + indexX1]) return verticalRayDist; + unsigned int gridValue = level[indexY1 * WIDTH + indexX1]; + if (gridValue) { + tileData->value = gridValue; + tileData->side = goingRight? WEST : EAST; + return verticalRayDist; + } verticalProjectedX += verticalStepX; verticalProjectedY += verticalStepY; diff --git a/level.h b/level.h index 856a65e..8e2ec8c 100644 --- a/level.h +++ b/level.h @@ -3,9 +3,23 @@ #include +enum level_tileSide +{ + NORTH, + EAST, + SOUTH, + WEST +}; + +typedef struct +{ + unsigned int value; + level_tileSide side; +} TileData; + int level_init(); void level_end(); -float level_rayCastDistance(sf::Vector2f point, float direction); +float level_rayCast(sf::Vector2f point, float direction, TileData* tileData); void level_getDimensions(unsigned int* width, unsigned int* height); unsigned int level_getGridValue(unsigned int x, unsigned int y); diff --git a/minimap.cpp b/minimap.cpp index cfb51b0..a3b66ef 100644 --- a/minimap.cpp +++ b/minimap.cpp @@ -97,10 +97,25 @@ static void drawGrid(sf::RenderTarget* renderTarget, unsigned int tileSize) { for (unsigned int x = 0; x < gridWidth; x++) { for (unsigned int y = 0; y < gridHeight; y++) { - if (!level_getGridValue(x, y)) continue; + unsigned int value = level_getGridValue(x, y); + if (!value) continue; + + sf::Color color(255, 255, 255); + switch (value) { + case 2: + color = sf::Color::Red; + break; + case 3: + color = sf::Color::Green; + break; + case 4: + color = sf::Color::Blue; + break; + }; sf::RectangleShape rectangle(sf::Vector2f(tileSize, tileSize)); rectangle.setPosition((float)x * tileSize, (float)y * tileSize); + rectangle.setFillColor(color); renderTarget->draw(rectangle); } } diff --git a/view.cpp b/view.cpp index 7cae58e..8a9708c 100644 --- a/view.cpp +++ b/view.cpp @@ -7,7 +7,7 @@ #include "minimap.h" #include "firstperson.h" -#define MINIMAP_SIZE 720 +#define MINIMAP_SIZE 480 #define VIEW_SIZE MINIMAP_SIZE*2 static int handleKeyCode(sf::Keyboard::Key key); @@ -21,7 +21,7 @@ static sf::Clock timer; int view_init() { printf("view_init()\n"); - if (!camera_init(&camera, sf::Vector2f(10.f/2.f, 10.f/2.f), 0.f, 128, 0.5f*PI)) return 0; + if (!camera_init(&camera, sf::Vector2f(10.f/2.f, 10.f/2.f), 0.f, 2<<7, 0.5f*PI)) return 0; if (!minimap_init(MINIMAP_SIZE)) return 0; if (!firstperson_init(VIEW_SIZE, MINIMAP_SIZE)) return 0;