From 890c6a4da827e4e863cb51142facdb112686dadb Mon Sep 17 00:00:00 2001 From: Syndamia Date: Tue, 4 Jun 2024 14:19:20 +0300 Subject: [PATCH] [hw13-hard] Implemented scene editing --- flake.lock | 27 ++++++++++ flake.nix | 26 ++++++++++ src/color.h | 4 ++ src/main.cpp | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..25db693 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1716061101, + "narHash": "sha256-H0eCta7ahEgloGIwE/ihkyGstOGu+kQwAiHvwVoXaA0=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "e7cc61784ddf51c81487637b3031a6dd2d6673a2", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..d0a99fd --- /dev/null +++ b/flake.nix @@ -0,0 +1,26 @@ +# Този файл, заедно с flake.lock са си за моета система, да имам копие ако случайно изтрия нещо +{ + description = "hexray raytracer in FMI elective"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11"; + }; + + outputs = inputs: + let + pkgs = inputs.nixpkgs.legacyPackages."x86_64-linux"; + in { + devShells."x86_64-linux".default = pkgs.mkShell { + nativeBuildInputs = with pkgs; [ + cmake + pkg-config + ]; + + buildInputs = with pkgs; [ + SDL2 + openexr_3 + zlib + ]; + }; + }; +} diff --git a/src/color.h b/src/color.h index cf6a7f0..b7df083 100644 --- a/src/color.h +++ b/src/color.h @@ -177,3 +177,7 @@ inline Color operator / (const Color& a, float divider) float multiplier = 1.0f / divider; return Color(a.r * multiplier, a.g * multiplier, a.b * multiplier); } + +inline Color randColor() { + return Color(randDouble(), randDouble(), randDouble()); +} diff --git a/src/main.cpp b/src/main.cpp index f15c4ff..71e95c8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,6 +52,12 @@ bool needsAA[VFB_MAX_SIZE][VFB_MAX_SIZE]; std::vector buckets; const float AA_THRESH = 0.075f; +static long currentNode = 0; +static bool blink = false; +static double Ct = 5; +static double Cr = 30; +static double Cs = 1.2; + struct TraceContext { IntersectionInfo closestIntersection; Node* closestNode; @@ -108,7 +114,11 @@ Color raytrace(const Ray& ray) auto earlyResult = tc.raycast(ray); if (earlyResult) return *earlyResult; // Shading: - return tc.closestNode->shader->computeColor(ray, tc.closestIntersection); + double modifier = 1.0; + if (blink && tc.closestNode == scene.nodes[currentNode]) { + modifier = 1.2; + } + return tc.closestNode->shader->computeColor(ray, tc.closestIntersection) * modifier; } Color pathtrace(const Ray& ray, Color pathMultiplier = Color(1, 1, 1)) @@ -398,6 +408,34 @@ static void ensureDataIsVisible() } } +static void changeShader(auto first, auto last) { + auto shaderIter = std::find(first, last, scene.nodes[currentNode]->shader); + Shader* shader; + if (shaderIter + 1 == last) + shader = *first; + else + shader = shaderIter[1]; + scene.nodes[currentNode]->shader = shader; +} + +static void addGeometry(Geometry* newGeom) { + scene.geometries.push_back(newGeom); + + Lambert* shader = new Lambert(); + shader->diffuse = randColor(); + scene.shaders.push_back(shader); + + Node* node = new Node(); + node->geom = newGeom; + node->shader = shader; + node->T.translate(scene.camera->pos + scene.camera->getFrontDir() * 10.0); + scene.nodes.push_back(node); + + if (currentNode == -1) currentNode = 0; +} + +#define GUARD_EDIT if (currentNode == -1) break; + void gameloop() { scene.beginRender(); @@ -411,6 +449,7 @@ void gameloop() while (!checkForUserExit()) { scene.beginFrame(); Uint32 frameStart = SDL_GetTicks(); + blink = (frameStart / 500) % 2 == 0; // blink every half-second render(false); displayVFB(vfb); double timeDelta = (SDL_GetTicks() - frameStart) / 1000.0; @@ -448,6 +487,109 @@ void gameloop() case SDLK_F5: printf("Last frame took %.3fs\n", timeDelta); break; + + // Change current node + case SDLK_LEFTBRACKET: GUARD_EDIT + if (currentNode == 0) currentNode = scene.nodes.size() - 1; + else --currentNode; + break; + case SDLK_DELETE: GUARD_EDIT + scene.nodes.erase(scene.nodes.cbegin() + currentNode); + case SDLK_RIGHTBRACKET: GUARD_EDIT + if (scene.nodes.size() == 0) + currentNode = -1; + else + currentNode = (currentNode + 1) % scene.nodes.size(); + break; + + // Translate current node + case SDLK_q: GUARD_EDIT + scene.nodes[currentNode]->T.translate({ Ct, 0, 0 }); + break; + case SDLK_a: GUARD_EDIT + scene.nodes[currentNode]->T.translate({ 0, Ct, 0 }); + break; + case SDLK_z: GUARD_EDIT + scene.nodes[currentNode]->T.translate({ 0, 0, Ct }); + break; + + // Rotate current node + case SDLK_w: GUARD_EDIT + scene.nodes[currentNode]->T.rotate(Cr, 0, 0); + break; + case SDLK_s: GUARD_EDIT + scene.nodes[currentNode]->T.rotate(0, Cr, 0); + break; + case SDLK_x: GUARD_EDIT + scene.nodes[currentNode]->T.rotate(0, 0, Cr); + break; + + // Scale current node + case SDLK_e: GUARD_EDIT + scene.nodes[currentNode]->T.scale(Cs, 1, 1); + break; + case SDLK_d: GUARD_EDIT + scene.nodes[currentNode]->T.scale(1, Cs, 1); + break; + case SDLK_c: GUARD_EDIT + scene.nodes[currentNode]->T.scale(1, 1, Cs); + break; + + // Change Cx values + case SDLK_MINUS: + Ct *= -1; Cr *= -1; Cs *= -1; + break; + case SDLK_1: + Ct = 1; Cr = 1; Cs = 1.001; + break; + case SDLK_2: + Ct = 2; Cr = 2.5; Cs = 1.01; + break; + case SDLK_3: + Ct = 3; Cr = 5; Cs = 1.05; + break; + case SDLK_4: + Ct = 4; Cr = 15; Cs = 1.1; + break; + case SDLK_5: // defaults + Ct = 5; Cr = 30; Cs = 1.2; + break; + case SDLK_6: + Ct = 10; Cr = 60; Cs = 1.5; + break; + case SDLK_7: + Ct = 20; Cr = 90; Cs = 2.0; + break; + case SDLK_8: + Ct = 50; Cr = 180; Cs = 3.0; + break; + case SDLK_9: + Ct = 150; Cr = 270; Cs = 5.0; + break; + + // Shader change + case SDLK_n: GUARD_EDIT + changeShader(scene.shaders.cbegin(), scene.shaders.cend()); + break; + case SDLK_h: GUARD_EDIT + changeShader(scene.shaders.crbegin(), scene.shaders.crend()); + break; + + // Create objects + case SDLK_o: + addGeometry(new Sphere()); + break; + case SDLK_p: + addGeometry(new Cube()); + break; + + // Change Lambert + case SDLK_l: GUARD_EDIT { + Lambert* shader = dynamic_cast(scene.nodes[currentNode]->shader); + if (shader != NULL) + shader->diffuse = randColor(); + } + break; } } } -- 2.42.0