From 09072ae42ba9709d50dd0b96dd9616bc55932341 Mon Sep 17 00:00:00 2001 From: alfrh02 <alfred.n.hall@gmail.com> Date: Sun, 22 Dec 2024 18:31:04 +0000 Subject: [PATCH] a0.10_9 Misc changes and big shader optimisation & cleanup + added gradient check before light calculation; + circles now indicate where lights are located when in lighting mode; + added controls section to README; + added tool icon in lower-left for better usability; * renamed light.size to light.radius for clarity; * organised lighting.frag into functions; * changed to use 'out vec4 fragColor' rather than deprecated gl_FragColor; - removed uApple & uSmoothShadows shader uniforms (no more manual toggling of soft/hard shadows); --- CMakeLists.txt | 2 +- README.md | 34 ++++++++--- build.sh | 8 ++- res/shaders/broken.frag | 10 ++-- res/shaders/lighting.frag | 97 ++++++++++++++++++-------------- res/{ => textures}/brush.png | Bin res/{ => textures}/canvas.png | Bin res/{ => textures}/cursor.png | Bin res/textures/icons/drawing.png | Bin 0 -> 608 bytes res/textures/icons/lighting.png | Bin 0 -> 603 bytes res/textures/icons/viewing.png | Bin 0 -> 598 bytes src/config.h.in | 2 + src/game.cpp | 86 +++++++++++++--------------- src/game.h | 5 +- src/main.cpp | 2 +- 15 files changed, 140 insertions(+), 106 deletions(-) rename res/{ => textures}/brush.png (100%) rename res/{ => textures}/canvas.png (100%) rename res/{ => textures}/cursor.png (100%) create mode 100644 res/textures/icons/drawing.png create mode 100644 res/textures/icons/lighting.png create mode 100644 res/textures/icons/viewing.png diff --git a/CMakeLists.txt b/CMakeLists.txt index edbc75d..ace25c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED NO) set(CMAKE_CXX_EXTENSIONS OFF) # major, minor, patch, and _STAGE_ (0 = alpha, 1 = beta, 2 = gamma/release) -project(radiance_cascades VERSION 0.10.8.0) +project(radiance_cascades VERSION 0.10.9.0) configure_file(src/config.h.in config.h) diff --git a/README.md b/README.md index 99329c6..1431b43 100644 --- a/README.md +++ b/README.md @@ -3,27 +3,27 @@ 1. [Requirements](#requirements) 2. [Setup (macOS, Linux)](#setup-macos-linux) 3. [Setup (Windows)](#setup-windows-visual-studio) +3. [Controls](#controls) -2D lighting demo. +2D lighting demo. Intended for 1080p displays. -Maze image texture initially generated via [mazegenerator.net](https://www.mazegenerator.net/). +Maze image texture initially generated via [mazegenerator.net](https://www.mazegenerator.net/). ## Requirements - CMake 3.25 - A C++11 (or higher) compiler - Raylib 5.5 (provided via CMake if not installed system-wide) + - If Raylib is not [installed](https://github.com/raysan5/raylib#build-and-installation) on your machine, CMake will download and build Raylib for you in the build directory. This currently builds and runs on macOS, Arch Linux (on X11), and Windows. No planned support for Wayland :P -## Setup (macOS, Linux) - -If Raylib is not installed on your machine, CMake will download and build Raylib for you in the build directory. +## Setup (macOS, Linux) ```bash -# run the convenience build script +# run the convenience build script ./build.sh # to build without running -./build.sh -r # to build and run the resulting binary +./build.sh -r # to build and run the resulting binary # or build it manually via CMake mkdir build @@ -36,8 +36,6 @@ cd .. # run the resulting binary in the source directory, not the build director ## Setup (Windows Visual Studio) -If Raylib is not installed on your machine, CMake will download and build Raylib for you in the build directory. - Via command prompt: ```bash @@ -49,3 +47,21 @@ cmake .. This will generate a VS solution file (.sln) for you to use for compilation. Make sure to run any resulting .exe from the project root directory. + +## Controls + +1, 2, & 3 toggles between drawing, lighting, and viewing mode. + +Scrolling up or down increase brush/light size depending on if you are in drawing or lighting mode. + +C clears the canvas if in drawing mode, and removes all lights if in lighting mode. + +R resets the canvas to the original maze layout if in drawing mode, and resets to the starting lights if in lighting mode. + +F3 to open the debug UI. When the debug UI is open, scrolling the mouse will change the amount of shadow cascades. + +Left-mouse-button erases in drawing mode, or deletes nearby lights when in lighting mode. + +Right-mouse-button draws in drawing mode, or places a light when in lighting mode. + +Middle-mouse-button can be used to move lights around in any mode. diff --git a/build.sh b/build.sh index 220a62f..d1e9175 100755 --- a/build.sh +++ b/build.sh @@ -9,6 +9,10 @@ cmake .. make popd -while getopts "r" arg; do - ./build/radiance_cascades +while getopts ":r" arg; do + case ${arg} in + r) + ./build/radiance_cascades + ;; + esac done diff --git a/res/shaders/broken.frag b/res/shaders/broken.frag index ae255d6..a9c5009 100644 --- a/res/shaders/broken.frag +++ b/res/shaders/broken.frag @@ -4,21 +4,23 @@ #define PRIMARY vec4(1.0f, 0.0f, 1.0f, 1.0f) #define SECONDARY vec4(0.0f, 0.0f, 0.0f, 1.0f) +out vec4 fragColor; + // checkerboard pattern void main() { vec2 pos = mod(gl_FragCoord.xy,vec2(N)); if ((pos.x > N/2) && (pos.y > N/2)){ - gl_FragColor = PRIMARY; + fragColor = PRIMARY; } else if ((pos.x < N/2) && (pos.y < N/2)){ - gl_FragColor = PRIMARY; + fragColor = PRIMARY; } else if ((pos.x < N/2) && (pos.y > N/2)){ - gl_FragColor = SECONDARY; + fragColor = SECONDARY; } else if ((pos.x > N/2) && (pos.y < N/2)){ - gl_FragColor = SECONDARY; + fragColor = SECONDARY; } } diff --git a/res/shaders/lighting.frag b/res/shaders/lighting.frag index 2b640ad..d413e38 100644 --- a/res/shaders/lighting.frag +++ b/res/shaders/lighting.frag @@ -1,81 +1,96 @@ #version 330 core +#define VIEWER_OUT_OF_SIGHT_BRIGHTNESS 0.015 +#define VIEWER_GRADIENT_RADIUS 450 + struct Light { vec2 position; vec3 color; - float size; + float radius; }; in vec2 fragTexCoord; -out vec4 finalColor; +out vec4 fragColor; +// data +uniform Light lights[128]; +uniform int uLightsAmount; uniform sampler2D uOcclusionMask; uniform float uTime; -uniform int uLightsAmount; uniform vec2 uResolution; uniform vec2 uPlayerLocation; -uniform int uApple; -uniform int uSmoothShadows; -uniform int uCascadeAmount; +// config +uniform int uCascadeAmount; // the amount of cascades primarily affects performance & light leakage. Thicker walls = less cascades needed, thinner walls = more cascades needed uniform int uViewing; -uniform Light lights[64]; - // sourced from https://gist.github.com/companje/29408948f1e8be54dd5733a74ca49bb9 float map(float value, float min1, float max1, float min2, float max2) { return min2 + (value - min1) * (max2 - min2) / (max1 - min1); } // this technique is sourced from https://www.shadertoy.com/view/tddXzj -float terrain(vec2 p, vec2 normalisedLightPos, int smoothShadows) +float terrain(vec2 p, vec2 position, bool smoothShadows) { - if (smoothShadows == 1) { - if (uApple == 0) return mix(map(distance(uResolution * normalisedLightPos, gl_FragCoord.xy), 0.0, uResolution.x, 0.9, 1.0), 1.0, step(0.25, texture(uOcclusionMask, p).x)); + if (smoothShadows) { + // increased opacity closer to the light source + return mix( + map( + distance(position, gl_FragCoord.xy), + 0.0, + ((uResolution.x < uResolution.y) ? uResolution.y : uResolution.x) * 500, + 0.9, + 1.0 + ), + 1.0, + step(0.25, texture(uOcclusionMask, p).x) + ); } return step(0.25, texture(uOcclusionMask, p).x); // hard shadows } -void main() { - vec3 result = vec3(0.0); - - for (int i = 0; i < uLightsAmount; i++) { - vec2 normalisedLightPos = lights[i].position/uResolution; - float brightness = 1.0; - - for (float j = 0.0; j < uCascadeAmount; j++) { - float t = j / uCascadeAmount; - float h = terrain(mix(fragTexCoord, normalisedLightPos, t), normalisedLightPos, uSmoothShadows); - brightness *= h; - } +vec3 calcVisibility(vec2 position, float gradientRadius = 300, vec3 rgb = vec3(1.0), bool smoothShadows = true) { + // no need to bother calculating light if the light value will be overridden by the gradient anyway + if (distance(fragTexCoord*uResolution, position) > gradientRadius) return vec3(0); - // radial gradient - adapted from https://www.shadertoy.com/view/4tjSWh + float brightness = 1.0; - if (uApple == 1) { - brightness *= 1.0 - smoothstep(0.0, 0.5, length(fragTexCoord - normalisedLightPos)); - } else { - brightness *= 1.0 - distance(uResolution.xy * vec2(normalisedLightPos.x, 1.0 - normalisedLightPos.y), gl_FragCoord.xy) * 2/lights[i].size; - } + vec2 normalisedPos = position/uResolution; - if (brightness > 0) result += brightness * lights[i].color; + for (float j = 0.0; j < uCascadeAmount; j++) { + float t = j / uCascadeAmount; + float h = terrain(mix(fragTexCoord, normalisedPos, t), position, smoothShadows); + brightness *= h; } - if (uViewing == 1) { - vec2 normalisedPlayerPos = uPlayerLocation/uResolution; - vec3 visible = vec3(1.0); + // radial gradient - adapted from https://www.shadertoy.com/view/4tjSWh + brightness *= 1.0 - distance(vec2(position.x, uResolution.y - position.y), gl_FragCoord.xy) * 1/gradientRadius; + + return (brightness > 0) ? brightness * rgb : vec3(0); +} - for (float j = 0.0; j < uCascadeAmount; j++) { - float t = j / uCascadeAmount; - float h = terrain(mix(fragTexCoord, normalisedPlayerPos, t), normalisedPlayerPos, 0); - visible *= h; - } +void main() { + vec3 result = vec3(0.0); - visible = mix(texture(uOcclusionMask, fragTexCoord).xyz * 0.015, result.xyz, visible); + for (int i = 0; i < uLightsAmount; i++) { + result += calcVisibility(lights[i].position, lights[i].radius, lights[i].color); + } - gl_FragColor = vec4(visible, 1.0f); + if (uViewing == 1) { + fragColor = vec4( + mix( + texture(uOcclusionMask, fragTexCoord).xyz * VIEWER_OUT_OF_SIGHT_BRIGHTNESS, + result.xyz, + calcVisibility(uPlayerLocation, VIEWER_GRADIENT_RADIUS, vec3(1.0), false) + ), + 1.0 + ); } else { // combine light result w/ underlying occlusion mask texture - gl_FragColor = vec4(result * step(0.25, texture(uOcclusionMask, fragTexCoord)).xxx, 1.0f); + fragColor = vec4( + result * step(0.25, texture(uOcclusionMask, fragTexCoord)).xxx, + 1.0 + ); } } diff --git a/res/brush.png b/res/textures/brush.png similarity index 100% rename from res/brush.png rename to res/textures/brush.png diff --git a/res/canvas.png b/res/textures/canvas.png similarity index 100% rename from res/canvas.png rename to res/textures/canvas.png diff --git a/res/cursor.png b/res/textures/cursor.png similarity index 100% rename from res/cursor.png rename to res/textures/cursor.png diff --git a/res/textures/icons/drawing.png b/res/textures/icons/drawing.png new file mode 100644 index 0000000000000000000000000000000000000000..8cd2f5971f37e44bd716860169bc6cb2dd0413b9 GIT binary patch literal 608 zcmV-m0-ybfP)<h;3K|Lk000e1NJLTq000O8000OG1^@s6#1FoU0004mX+uL$Nkc;* zaB^>EX>4Tx04R}tkv&MmKpe$iTcsiu1xqR7kfA!+MMWHI6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfc5qU3krMxx6k5c1aNLh~_a1le0DrT}RI?`msG4PD zQb{3~UloF{2qA(YL=lmgsn3aG8lL0p9zMR_#d((Zxj)B%QZO0d6NnQ`H!R`};+aiL z=e$oGW@SksJ|~_q=z_$LT$f#b<6Lss&ojeDHZxBgCKgIvEO#+08!GWMaZFJ)%J=77 zRyc2QR;zW^z9)ZSsGzMZbDicWQdq<iL<o>kM+H?_h|{W(Vj@HPNe};s;}^*#ldA$o zjs?`9LUR1zfAG6ovp6;BCWVqf?~84Ji~+%2pw+PL?_=9;odAJn;7aTGYfWJGlk`SM ziyZ-j+rY(jN0aw}%N-#4q)Ue6NCBGuVi9;hqi@Os!?!^Hn%i4@AEysMmbyyc00)P_ zc!{#tJ>K2d-P^xs+Wq|ijo)&yH;)Fy00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=nNJR9T5+^Ig<bY02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{001~iL_t&-(}j;o4gfF+0-65*&-7HIcH<@kB%&tU&NnYu u0w)-O8~iQ+j0FHXjAm|cUu2`NNYVr(A}8?)$|-OF0000<MNUMnLSTY}?(rP} literal 0 HcmV?d00001 diff --git a/res/textures/icons/lighting.png b/res/textures/icons/lighting.png new file mode 100644 index 0000000000000000000000000000000000000000..199857ea2cf6adfa1641e7cc3cd663aa9fcb18e9 GIT binary patch literal 603 zcmV-h0;K(kP)<h;3K|Lk000e1NJLTq000O8000OG1^@s6#1FoU0004mX+uL$Nkc;* zaB^>EX>4Tx04R}tkv&MmKpe$iTcsiu1xqR7kfA!+MMWHI6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfc5qU3krMxx6k5c1aNLh~_a1le0DrT}RI?`msG4PD zQb{3~UloF{2qA(YL=lmgsn3aG8lL0p9zMR_#d((Zxj)B%QZO0d6NnQ`H!R`};+aiL z=e$oGW@SksJ|~_q=z_$LT$f#b<6Lss&ojeDHZxBgCKgIvEO#+08!GWMaZFJ)%J=77 zRyc2QR;zW^z9)ZSsGzMZbDicWQdq<iL<o>kM+H?_h|{W(Vj@HPNe};s;}^*#ldA$o zjs?`9LUR1zfAG6ovp6;BCWVqf?~84Ji~+%2pw+PL?_=9;odAJn;7aTGYfWJGlk`SM ziyZ-j+rY(jN0aw}%N-#4q)Ue6NCBGuVi9;hqi@Os!?!^Hn%i4@AEysMmbyyc00)P_ zc!{#tJ>K2d-P^xs+Wq|ijo)&yH;)Fy00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=nNJR9Ss}0W!wM&02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{001*dL_t&-(_>&j0{@|a0UJP;z)%Dez@~@^Ss^1MBO|(Q pCUlb+85tSzx`CiW@mhfm003nmH`ke>Xs!SN002ovPDHLkV1m0}?&|;m literal 0 HcmV?d00001 diff --git a/res/textures/icons/viewing.png b/res/textures/icons/viewing.png new file mode 100644 index 0000000000000000000000000000000000000000..98febe04add1536acc25f9b8f85b3d5de9351fbf GIT binary patch literal 598 zcmV-c0;&CpP)<h;3K|Lk000e1NJLTq000O8000OG1^@s6#1FoU0004mX+uL$Nkc;* zaB^>EX>4Tx04R}tkv&MmKpe$iTcsiu1xqR7kfA!+MMWHI6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfc5qU3krMxx6k5c1aNLh~_a1le0DrT}RI?`msG4PD zQb{3~UloF{2qA(YL=lmgsn3aG8lL0p9zMR_#d((Zxj)B%QZO0d6NnQ`H!R`};+aiL z=e$oGW@SksJ|~_q=z_$LT$f#b<6Lss&ojeDHZxBgCKgIvEO#+08!GWMaZFJ)%J=77 zRyc2QR;zW^z9)ZSsGzMZbDicWQdq<iL<o>kM+H?_h|{W(Vj@HPNe};s;}^*#ldA$o zjs?`9LUR1zfAG6ovp6;BCWVqf?~84Ji~+%2pw+PL?_=9;odAJn;7aTGYfWJGlk`SM ziyZ-j+rY(jN0aw}%N-#4q)Ue6NCBGuVi9;hqi@Os!?!^Hn%i4@AEysMmbyyc00)P_ zc!{#tJ>K2d-P^xs+Wq|ijo)&yH;)Fy00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=nNJRBqF}=)jt3L02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{001sYL_t&-(_>&D02pD6|NsC0N0DG;gv((_qKF|&{)Yl& kJ`)2m0G}1aIT9ZL0LpA9<^FB#F#rGn07*qoM6N<$g4|{B7ytkO literal 0 HcmV?d00001 diff --git a/src/config.h.in b/src/config.h.in index 0ab63c3..08dd400 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -18,3 +18,5 @@ #define SCREEN_WIDTH 800 #define SCREEN_HEIGHT 600 + +#define CURSOR_SIZE 0.1 diff --git a/src/game.cpp b/src/game.cpp index 97aff39..dd49af3 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -10,19 +10,16 @@ void placeLights(std::vector<Light>* lights, int N = 4, float d = 256.0) { Light l; l.position = Vector2{ SCREEN_WIDTH/2 + std::sin(t) * d, SCREEN_HEIGHT/2 + std::cos(t) * d}; l.color = Vector3{ std::sin(t), std::cos(t), 1.0 }; - l.size = 600; + l.radius = 300; lights->push_back(l); } } Game::Game() { debug = false; - smoothShadows = true; mode = DRAWING; - cascadeAmount = 512; - #if __APPLE__ - cascadeAmount = 128; - #endif + + currentToolIcon = LoadTextureFromImage(LoadImage("res/textures/icons/drawing.png")); lightingShader = LoadShader(0, "res/shaders/lighting.frag"); if (!IsShaderValid(lightingShader)) { @@ -31,14 +28,16 @@ Game::Game() { lightingShader = LoadShader(0, "res/shaders/broken.frag"); } - cursor.img = LoadImage("res/cursor.png"); + cascadeAmount = 512; + + cursor.img = LoadImage("res/textures/cursor.png"); cursor.tex = LoadTextureFromImage(cursor.img); - brush.img = LoadImage("res/brush.png"); + brush.img = LoadImage("res/textures/brush.png"); brush.tex = LoadTextureFromImage(brush.img); brush.scale = 0.25; - canvas.img = LoadImage("res/canvas.png"); + canvas.img = LoadImage("res/textures/canvas.png"); canvas.tex = LoadTextureFromImage(canvas.img); placeLights(&lights); @@ -60,13 +59,6 @@ void Game::update() { SetShaderValue(lightingShader, GetShaderLocation(lightingShader, "uLightsAmount"), &lightsAmount, SHADER_UNIFORM_INT); SetShaderValue(lightingShader, GetShaderLocation(lightingShader, "uCascadeAmount"), &cascadeAmount, SHADER_UNIFORM_INT); - int apple = 0; - #ifdef __APPLE__ - apple = 1; - #endif - SetShaderValue(lightingShader, GetShaderLocation(lightingShader, "uApple"), &apple, SHADER_UNIFORM_INT); - SetShaderValue(lightingShader, GetShaderLocation(lightingShader, "uSmoothShadows"), &smoothShadows, SHADER_UNIFORM_INT); - int viewing = 0; if (mode == VIEWING) viewing = 1; SetShaderValue(lightingShader, GetShaderLocation(lightingShader, "uViewing"), &viewing, SHADER_UNIFORM_INT); @@ -84,8 +76,7 @@ void Game::render() { for (int i = 0; i < lights.size(); i++) { SetShaderValue(lightingShader, GetShaderLocation(lightingShader, TextFormat("lights[%i].position", i)), &lights[i].position, SHADER_UNIFORM_VEC2); SetShaderValue(lightingShader, GetShaderLocation(lightingShader, TextFormat("lights[%i].color", i)), &lights[i].color, SHADER_UNIFORM_VEC3); - SetShaderValue(lightingShader, GetShaderLocation(lightingShader, TextFormat("lights[%i].size", i)), &lights[i].size, SHADER_UNIFORM_FLOAT); - if (debug) DrawCircleLinesV(lights[i].position, lights[i].size/64, GREEN); + SetShaderValue(lightingShader, GetShaderLocation(lightingShader, TextFormat("lights[%i].radius", i)), &lights[i].radius, SHADER_UNIFORM_FLOAT); } } @@ -97,7 +88,9 @@ void Game::renderUI() { if (mode == LIGHTING) str = "LIGHTING"; else if (mode == VIEWING) str = "VIEWING"; - DrawText(str.c_str(), 0, SCREEN_HEIGHT - 8, 1, ColorFromHSV(0.0, 0.0, 1.0 - v)); + DrawTexture(currentToolIcon, 0, SCREEN_HEIGHT-8, WHITE); + + DrawText(str.c_str(), 12, SCREEN_HEIGHT - 8, 1, ColorFromHSV(0.0, 0.0, 1.0 - v)); switch (mode) { case DRAWING: @@ -109,12 +102,13 @@ void Game::renderUI() { Color{ 0, 0, 0, 64} ); break; case LIGHTING: - DrawCircleLines(GetMouseX(), GetMouseY(), (brush.scale*1200)/64, ColorFromNormalized(Vector4{ std::sin(time), std::cos(time), 1.0, 0.5 })); + DrawCircleLines(GetMouseX(), GetMouseY(), (brush.scale*600*2)/64, ColorFromNormalized(Vector4{ std::sin(time), std::cos(time), 1.0, 0.5 })); + for (int i = 0; i < lights.size(); i++) { + DrawCircleLinesV(lights[i].position, lights[i].radius/64*2, GREEN); + } break; } - #define CURSOR_SIZE 0.1 - DrawTextureEx(cursor.tex, Vector2{ (float)(GetMouseX() - cursor.img.width/2*CURSOR_SIZE), (float)(GetMouseY() - cursor.img.height/2*CURSOR_SIZE) }, @@ -127,17 +121,22 @@ void Game::renderUI() { DrawText(TextFormat("%i FPS", GetFPS()), 0, 0, 1, GREEN); DrawText(TextFormat("%i lights", lights.size()), 0, 8, 1, GREEN); - if (mode == DRAWING) DrawText(TextFormat("%f brush scale", brush.scale), 0, 32, 1, GREEN); - else if (mode == LIGHTING) DrawText(TextFormat("%f light size", brush.scale * 2400), 0, 32, 1, GREEN); + if (mode == DRAWING) DrawText(TextFormat("%f brush scale", brush.scale), 0, 32, 1, GREEN); + else if (mode == LIGHTING) DrawText(TextFormat("%f light size (diameter)", brush.scale * 600 * 2), 0, 32, 1, GREEN); DrawText(TextFormat("%i cascades", cascadeAmount), 0, 40, 1, GREEN); - if (smoothShadows) DrawText("smoothShadows ON", 0, 48, 1, GREEN); } void Game::processKeyboardInput() { auto changeMode = [this](Mode m) { mode = m; timeSinceModeSwitch = GetTime(); + if (m == DRAWING) + currentToolIcon = LoadTextureFromImage(LoadImage("res/textures/icons/drawing.png")); + else if (m == LIGHTING) + currentToolIcon = LoadTextureFromImage(LoadImage("res/textures/icons/lighting.png")); + else + currentToolIcon = LoadTextureFromImage(LoadImage("res/textures/icons/viewing.png")); }; if (IsKeyPressed(KEY_ONE)) changeMode(DRAWING); @@ -150,7 +149,6 @@ void Game::processKeyboardInput() { if (!DirectoryExists("screenshots")) MakeDirectory("screenshots"); TakeScreenshot("screenshots/screenshot.png"); } - if (IsKeyPressed(KEY_S)) (smoothShadows == 0) ? smoothShadows = 1 : smoothShadows = 0; // clearing if (IsKeyPressed(KEY_C)) { @@ -169,9 +167,18 @@ void Game::processKeyboardInput() { // replacing if (IsKeyPressed(KEY_R)) { - if (mode == DRAWING) { + if (IsKeyDown(KEY_LEFT_CONTROL)) { + // reloading + printf("Reloading shaders.\n"); + UnloadShader(lightingShader); + lightingShader = LoadShader(0, "res/shaders/lighting.frag"); + if (!IsShaderValid(lightingShader)) { + UnloadShader(lightingShader); + lightingShader = LoadShader(0, "res/shaders/broken.frag"); + } + } else if (mode == DRAWING) { printf("Replacing canvas.\n"); - canvas.img = LoadImage("res/canvas.png"); + canvas.img = LoadImage("res/textures/canvas.png"); RELOAD_CANVAS(); } else if (mode == LIGHTING) { printf("Replacing lights.\n"); @@ -179,19 +186,6 @@ void Game::processKeyboardInput() { placeLights(&lights); } } - - if (IsKeyDown(KEY_LEFT_CONTROL)) { - // reloading - if (IsKeyPressed(KEY_R)) { - printf("Reloading shaders.\n"); - UnloadShader(lightingShader); - lightingShader = LoadShader(0, "res/shaders/lighting.frag"); - if (!IsShaderValid(lightingShader)) { - UnloadShader(lightingShader); - lightingShader = LoadShader(0, "res/shaders/broken.frag"); - } - } - } } void Game::processMouseInput() { @@ -219,9 +213,9 @@ void Game::processMouseInput() { ImageDraw(&canvas.img, brush.img, Rectangle{ 0, 0, (float)canvas.img.width, (float)canvas.img.height }, - Rectangle{ static_cast<float>(GetMouseX() - brush.img.width/2 * brush.scale), + Rectangle{ static_cast<float>(GetMouseX() - brush.img.width/2 * brush.scale), static_cast<float>(GetMouseY() - brush.img.height/2 * brush.scale), - static_cast<float>(brush.img.width * brush.scale), + static_cast<float>(brush.img.width * brush.scale), static_cast<float>(brush.img.height * brush.scale) }, BLACK); RELOAD_CANVAS(); @@ -229,9 +223,9 @@ void Game::processMouseInput() { ImageDraw(&canvas.img, brush.img, Rectangle{ 0, 0, (float)canvas.img.width, (float)canvas.img.height }, - Rectangle{ static_cast<float>(GetMouseX() - brush.img.width/2 * brush.scale), + Rectangle{ static_cast<float>(GetMouseX() - brush.img.width/2 * brush.scale), static_cast<float>(GetMouseY() - brush.img.height/2 * brush.scale), - static_cast<float>(brush.img.width * brush.scale), + static_cast<float>(brush.img.width * brush.scale), static_cast<float>(brush.img.height * brush.scale) }, WHITE); RELOAD_CANVAS(); @@ -242,7 +236,7 @@ void Game::processMouseInput() { Light l; l.position = Vector2{ static_cast<float>(GetMouseX()), static_cast<float>(GetMouseY()) }; l.color = Vector3{ std::sin(time), std::cos(time), 1.0 }; - l.size = brush.scale * 1200; + l.radius = brush.scale * 600; lights.push_back(l); } else if (IsMouseButtonDown(1)) { for (int i = 0; i < lights.size(); i++) { diff --git a/src/game.h b/src/game.h index 4f35038..4ddaad8 100644 --- a/src/game.h +++ b/src/game.h @@ -11,7 +11,7 @@ struct Light { Vector2 position; Vector3 color; - float size; // in pixels + float radius; // in pixels }; class Game { @@ -25,13 +25,14 @@ class Game { private: Shader lightingShader; - int smoothShadows; int cascadeAmount; bool debug; float time; double timeSinceModeSwitch; + Texture2D currentToolIcon; + std::vector<Light> lights; enum Mode { diff --git a/src/main.cpp b/src/main.cpp index 2a18daa..1d1c5de 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,7 +14,7 @@ int main() { InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, title.c_str()); SetTargetFPS(GetMonitorRefreshRate(GetCurrentMonitor())); - SetTraceLogLevel(LOG_ERROR); + SetTraceLogLevel(LOG_WARNING); Game game; -- GitLab