diff --git a/project/src/Camera.h b/project/src/Camera.h index 134b6fb..3e62779 100644 --- a/project/src/Camera.h +++ b/project/src/Camera.h @@ -34,7 +34,7 @@ namespace dae Matrix CalculateCameraToWorld() { //todo: W2 - throw std::runtime_error("Not Implemented Yet"); +// throw std::runtime_error("Not Implemented Yet"); return {}; } diff --git a/project/src/Matrix.cpp b/project/src/Matrix.cpp index a031bbf..2b0b247 100644 --- a/project/src/Matrix.cpp +++ b/project/src/Matrix.cpp @@ -103,9 +103,7 @@ namespace dae { Matrix Matrix::CreateTranslation(float x, float y, float z) { - //todo W2 - throw std::runtime_error("Not Implemented Yet"); - return {}; + return { Vector3::UnitX, Vector3::UnitY, Vector3::UnitZ, {x, y, z} }; } Matrix Matrix::CreateTranslation(const Vector3& t) @@ -115,30 +113,37 @@ namespace dae { Matrix Matrix::CreateRotationX(float pitch) { - //todo W2 - throw std::runtime_error("Not Implemented Yet"); - return {}; + return { + {1, 0, 0, 0}, + {0, cosf(pitch), -sinf(pitch), 0}, + {0, sinf(pitch), cosf(pitch), 0}, + {0, 0, 0, 1} + }; } Matrix Matrix::CreateRotationY(float yaw) { - //todo W2 - throw std::runtime_error("Not Implemented Yet"); - return {}; + return { + {cosf(yaw), 0, sinf(yaw), 0}, + {0, 1, 0, 0}, + {-sinf(yaw), 0, cosf(yaw), 0}, + {0, 0, 0, 1} + }; } Matrix Matrix::CreateRotationZ(float roll) { - //todo W2 - throw std::runtime_error("Not Implemented Yet"); - return {}; + return { + {cosf(roll), -sinf(roll), 0, 0}, + {sinf(roll), cosf(roll), 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1} + }; } Matrix Matrix::CreateRotation(const Vector3& r) { - //todo W2 - throw std::runtime_error("Not Implemented Yet"); - return {}; + return CreateRotationX(r.x) * CreateRotationY(r.y) * CreateRotationZ(r.z); } Matrix Matrix::CreateRotation(float pitch, float yaw, float roll) @@ -148,9 +153,12 @@ namespace dae { Matrix Matrix::CreateScale(float sx, float sy, float sz) { - //todo W2 - throw std::runtime_error("Not Implemented Yet"); - return {}; + return { + {sx, 0, 0, 0}, + {0, sy, 0, 0}, + {0, 0, sz, 0}, + {0, 0, 0, 1} + }; } Matrix Matrix::CreateScale(const Vector3& s) diff --git a/project/src/Renderer.cpp b/project/src/Renderer.cpp index 5352e12..7dea984 100644 --- a/project/src/Renderer.cpp +++ b/project/src/Renderer.cpp @@ -12,46 +12,45 @@ using namespace dae; -Renderer::Renderer(SDL_Window * pWindow) : - m_pWindow(pWindow), - m_pBuffer(SDL_GetWindowSurface(pWindow)) -{ - //Initialize - SDL_GetWindowSize(pWindow, &m_Width, &m_Height); - m_pBufferPixels = static_cast(m_pBuffer->pixels); +Renderer::Renderer(SDL_Window *pWindow) : + m_pWindow(pWindow), + m_pBuffer(SDL_GetWindowSurface(pWindow)) { + //Initialize + SDL_GetWindowSize(pWindow, &m_Width, &m_Height); + m_pBufferPixels = static_cast(m_pBuffer->pixels); + } -void Renderer::Render(Scene* pScene) const -{ - Camera& camera = pScene->GetCamera(); - auto& materials = pScene->GetMaterials(); - auto& lights = pScene->GetLights(); + +void Renderer::Render(Scene *pScene) const { + Camera &camera = pScene->GetCamera(); + auto &materials = pScene->GetMaterials(); + auto &lights = pScene->GetLights(); float apsectRatio = static_cast(m_Width) / m_Height; + float fov = tan((camera.fovAngle * (PI / 180.f)) / 2); + for (int px{}; px < m_Width; ++px) { + for (int py{}; py < m_Height; ++py) { + float NDCx = ((2 * ((px + 0.5) / m_Width) - 1) * apsectRatio) * fov; + float NDCy = (1 - 2 * ((py + 0.5) / m_Height)) * fov; - for (int px{}; px < m_Width; ++px) - { - for (int py{}; py < m_Height; ++py) - { - float NDCx = (2 * ((px + 0.5) / m_Width) - 1) * apsectRatio; - float NDCy = 1 - 2 * ((py + 0.5) / m_Height); - Vector3 rayDir = Vector3{ NDCx, NDCy, 1 }; - Ray ray{ Vector3(0, 0, 0), rayDir }; + Vector3 rayDir = Vector3{NDCx, NDCy, 1}; + rayDir.Normalize(); + Ray ray{camera.origin, rayDir}; //set the color based on the ray direction - ColorRGB finalColor{ 0.f, 0.f, 0.f }; + ColorRGB finalColor{0.f, 0.f, 0.f}; HitRecord closestHit{}; + Plane testPlane{{0.f, -50.f, 0.f}, {0.f, 1.f, 0.f}, 0}; +// GeometryUtils::HitTest_Plane(testPlane, ray, closestHit); pScene->GetClosestHit(ray, closestHit); - if(closestHit.didHit){ + if (closestHit.didHit) { finalColor = materials[closestHit.materialIndex]->Shade(); -// finalColor = ColorRGB(closestHit.normal.x, closestHit.normal.y, closestHit.normal.z); -// const float scaled_t = (closestHit.t - 50.f) / 40.f; -// finalColor = {scaled_t, scaled_t, scaled_t}; + } - //Update Color in Buffer finalColor.MaxToOne(); m_pBufferPixels[px + (py * m_Width)] = SDL_MapRGB(m_pBuffer->format, @@ -59,15 +58,14 @@ void Renderer::Render(Scene* pScene) const static_cast(finalColor.g * 255), static_cast(finalColor.b * 255)); - } - } + } + } - //@END - //Update SDL Surface - SDL_UpdateWindowSurface(m_pWindow); + //@END + //Update SDL Surface + SDL_UpdateWindowSurface(m_pWindow); } -bool Renderer::SaveBufferToImage() const -{ - return SDL_SaveBMP(m_pBuffer, "RayTracing_Buffer.bmp"); +bool Renderer::SaveBufferToImage() const { + return SDL_SaveBMP(m_pBuffer, "RayTracing_Buffer.bmp"); } diff --git a/project/src/Renderer.h b/project/src/Renderer.h index 02cbd44..03e541a 100644 --- a/project/src/Renderer.h +++ b/project/src/Renderer.h @@ -1,6 +1,7 @@ #pragma once #include +#include "Camera.h" struct SDL_Window; struct SDL_Surface; @@ -31,5 +32,10 @@ namespace dae int m_Width{}; int m_Height{}; + + float m_FOV{}; + + Camera m_Camera{}; + }; } diff --git a/project/src/Scene.cpp b/project/src/Scene.cpp index 136915d..397bce6 100644 --- a/project/src/Scene.cpp +++ b/project/src/Scene.cpp @@ -5,139 +5,165 @@ namespace dae { #pragma region Base Scene - //Initialize Scene with Default Solid Color Material (RED) - Scene::Scene() : - m_Materials({ new Material_SolidColor({1,0,0}) }) - { - m_SphereGeometries.reserve(32); - m_PlaneGeometries.reserve(32); - m_TriangleMeshGeometries.reserve(32); - m_Lights.reserve(32); - } - Scene::~Scene() - { - for (auto& pMaterial : m_Materials) - { - delete pMaterial; - pMaterial = nullptr; - } + //Initialize Scene with Default Solid Color Material (RED) + Scene::Scene() : + m_Materials({new Material_SolidColor({1, 0, 0})}) { + m_SphereGeometries.reserve(32); + m_PlaneGeometries.reserve(32); + m_TriangleMeshGeometries.reserve(32); + m_Lights.reserve(32); + } - m_Materials.clear(); - } + Scene::~Scene() { + for (auto &pMaterial: m_Materials) { + delete pMaterial; + pMaterial = nullptr; + } - void dae::Scene::GetClosestHit(const Ray& ray, HitRecord& closestHit) const - { + m_Materials.clear(); + } + + void dae::Scene::GetClosestHit(const Ray &ray, HitRecord &closestHit) const { closestHit.t = FLT_MAX; - for (const Sphere& sphere : m_SphereGeometries){ + for (const Plane &plane: m_PlaneGeometries) { HitRecord hitRecord{}; - if (GeometryUtils::HitTest_Sphere(sphere, ray, hitRecord) && hitRecord.t < closestHit.t){ + GeometryUtils::HitTest_Plane(plane, ray, hitRecord); + if (hitRecord.t < closestHit.t && hitRecord.didHit) { closestHit = hitRecord; } } - for (const Plane& plane : m_PlaneGeometries){ + for (const Sphere &sphere: m_SphereGeometries) { HitRecord hitRecord{}; - if(GeometryUtils::HitTest_Plane(plane, ray, hitRecord) && hitRecord.t < closestHit.t){ + GeometryUtils::HitTest_Sphere(sphere, ray, hitRecord); + if (hitRecord.t < closestHit.t && hitRecord.didHit) { closestHit = hitRecord; } } - } - bool Scene::DoesHit(const Ray& ray) const - { - //todo W2 - throw std::runtime_error("Not Implemented Yet"); - return false; - } + + } + + bool Scene::DoesHit(const Ray &ray) const { + //todo W2 + throw std::runtime_error("Not Implemented Yet"); + return false; + } #pragma region Scene Helpers - Sphere* Scene::AddSphere(const Vector3& origin, float radius, unsigned char materialIndex) - { - Sphere s; - s.origin = origin; - s.radius = radius; - s.materialIndex = materialIndex; - m_SphereGeometries.emplace_back(s); - return &m_SphereGeometries.back(); - } + Sphere *Scene::AddSphere(const Vector3 &origin, float radius, unsigned char materialIndex) { + Sphere s; + s.origin = origin; + s.radius = radius; + s.materialIndex = materialIndex; - Plane* Scene::AddPlane(const Vector3& origin, const Vector3& normal, unsigned char materialIndex) - { - Plane p; - p.origin = origin; - p.normal = normal; - p.materialIndex = materialIndex; + m_SphereGeometries.emplace_back(s); + return &m_SphereGeometries.back(); + } - m_PlaneGeometries.emplace_back(p); - return &m_PlaneGeometries.back(); - } + Plane *Scene::AddPlane(const Vector3 &origin, const Vector3 &normal, unsigned char materialIndex) { + Plane p; + p.origin = origin; + p.normal = normal; + p.materialIndex = materialIndex; - TriangleMesh* Scene::AddTriangleMesh(TriangleCullMode cullMode, unsigned char materialIndex) - { - TriangleMesh m{}; - m.cullMode = cullMode; - m.materialIndex = materialIndex; + m_PlaneGeometries.emplace_back(p); + return &m_PlaneGeometries.back(); + } - m_TriangleMeshGeometries.emplace_back(m); - return &m_TriangleMeshGeometries.back(); - } + TriangleMesh *Scene::AddTriangleMesh(TriangleCullMode cullMode, unsigned char materialIndex) { + TriangleMesh m{}; + m.cullMode = cullMode; + m.materialIndex = materialIndex; - Light* Scene::AddPointLight(const Vector3& origin, float intensity, const ColorRGB& color) - { - Light l; - l.origin = origin; - l.intensity = intensity; - l.color = color; - l.type = LightType::Point; + m_TriangleMeshGeometries.emplace_back(m); + return &m_TriangleMeshGeometries.back(); + } - m_Lights.emplace_back(l); - return &m_Lights.back(); - } + Light *Scene::AddPointLight(const Vector3 &origin, float intensity, const ColorRGB &color) { + Light l; + l.origin = origin; + l.intensity = intensity; + l.color = color; + l.type = LightType::Point; - Light* Scene::AddDirectionalLight(const Vector3& direction, float intensity, const ColorRGB& color) - { - Light l; - l.direction = direction; - l.intensity = intensity; - l.color = color; - l.type = LightType::Directional; + m_Lights.emplace_back(l); + return &m_Lights.back(); + } - m_Lights.emplace_back(l); - return &m_Lights.back(); - } + Light *Scene::AddDirectionalLight(const Vector3 &direction, float intensity, const ColorRGB &color) { + Light l; + l.direction = direction; + l.intensity = intensity; + l.color = color; + l.type = LightType::Directional; + + m_Lights.emplace_back(l); + return &m_Lights.back(); + } + + unsigned char Scene::AddMaterial(Material *pMaterial) { + m_Materials.push_back(pMaterial); + return static_cast(m_Materials.size() - 1); + } - unsigned char Scene::AddMaterial(Material* pMaterial) - { - m_Materials.push_back(pMaterial); - return static_cast(m_Materials.size() - 1); - } #pragma endregion #pragma endregion #pragma region SCENE W1 - void Scene_W1::Initialize() - { - //default: Material id0 >> SolidColor Material (RED) - constexpr unsigned char matId_Solid_Red = 0; - const unsigned char matId_Solid_Blue = AddMaterial(new Material_SolidColor{ colors::Blue }); - const unsigned char matId_Solid_Yellow = AddMaterial(new Material_SolidColor{ colors::Yellow }); - const unsigned char matId_Solid_Green = AddMaterial(new Material_SolidColor{ colors::Green }); - const unsigned char matId_Solid_Magenta = AddMaterial(new Material_SolidColor{ colors::Magenta }); + void Scene_W1::Initialize() { + //default: Material id0 >> SolidColor Material (RED) + constexpr unsigned char matId_Solid_Red = 0; + const unsigned char matId_Solid_Blue = AddMaterial(new Material_SolidColor{colors::Blue}); - //Spheres - AddSphere({ -25.f, 0.f, 100.f }, 50.f, matId_Solid_Red); - AddSphere({ 25.f, 0.f, 100.f }, 50.f, matId_Solid_Blue); + const unsigned char matId_Solid_Yellow = AddMaterial(new Material_SolidColor{colors::Yellow}); + const unsigned char matId_Solid_Green = AddMaterial(new Material_SolidColor{colors::Green}); + const unsigned char matId_Solid_Magenta = AddMaterial(new Material_SolidColor{colors::Magenta}); + + //Spheres + AddSphere({-25.f, 0.f, 100.f}, 50.f, matId_Solid_Red); + AddSphere({25.f, 0.f, 100.f}, 50.f, matId_Solid_Blue); + + //Plane + AddPlane({-75.f, 0.f, 0.f}, {1.f, 0.f, 0.f}, matId_Solid_Green); + AddPlane({75.f, 0.f, 0.f}, {-1.f, 0.f, 0.f}, matId_Solid_Green); + AddPlane({0.f, -75.f, 0.f}, {0.f, 1.f, 0.f}, matId_Solid_Yellow); + AddPlane({0.f, 75.f, 0.f}, {0.f, -1.f, 0.f}, matId_Solid_Yellow); + AddPlane({0.f, 0.f, 125.f}, {0.f, 0.f, -1.f}, matId_Solid_Magenta); + } - //Plane - AddPlane({ -75.f, 0.f, 0.f }, { 1.f, 0.f,0.f }, matId_Solid_Green); - AddPlane({ 75.f, 0.f, 0.f }, { -1.f, 0.f,0.f }, matId_Solid_Green); - AddPlane({ 0.f, -75.f, 0.f }, { 0.f, 1.f,0.f }, matId_Solid_Yellow); - AddPlane({ 0.f, 75.f, 0.f }, { 0.f, -1.f,0.f }, matId_Solid_Yellow); - AddPlane({ 0.f, 0.f, 125.f }, { 0.f, 0.f,-1.f }, matId_Solid_Magenta); - } #pragma endregion + + void Scene_W2::Initialize() { + m_Camera.origin += {0.f, 3.f, -9.f}; + m_Camera.fovAngle = 45.f; + + constexpr unsigned char matId_Solid_Red = 0; + const unsigned char matId_Solid_Blue = AddMaterial(new Material_SolidColor{colors::Blue}); + + const unsigned char matId_Solid_Yellow = AddMaterial(new Material_SolidColor{colors::Yellow}); + const unsigned char matId_Solid_Green = AddMaterial(new Material_SolidColor{colors::Green}); + const unsigned char matId_Solid_Magenta = AddMaterial(new Material_SolidColor{colors::Magenta}); + +//Plane + AddPlane({-5.f, 0.f, 0.f}, {1.f, 0.f, 0.f}, matId_Solid_Green); + AddPlane({5.f, 0.f, 0.f}, {-1.f, 0.f, 0.f}, matId_Solid_Green); + AddPlane({0.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, matId_Solid_Yellow); + AddPlane({0.f, 10.f, 0.f}, {0.f, -1.f, 0.f}, matId_Solid_Yellow); + AddPlane({0.f, 0.f, 10.f}, {0.f, 0.f, -1.f}, matId_Solid_Magenta); + +//Spheres + AddSphere({-1.75f, 1.f, 0.f}, 0.75f, matId_Solid_Red); + AddSphere({0.f, 1.f, 0.f}, 0.75f, matId_Solid_Blue); + AddSphere({1.75f, 1.f, 0.f}, 0.75f, matId_Solid_Red); + AddSphere({-1.75f, 3.f, 0.f}, 0.75f, matId_Solid_Blue); + AddSphere({0.f, 3.f, 0.f}, 0.75f, matId_Solid_Red); + AddSphere({1.75f, 3.f, 0.f}, 0.75f, matId_Solid_Blue); + + AddPointLight({0.f, 5.f, -5.f}, 70.f, colors::White); + } } diff --git a/project/src/Scene.h b/project/src/Scene.h index 38fc88e..be4cbe4 100644 --- a/project/src/Scene.h +++ b/project/src/Scene.h @@ -77,4 +77,20 @@ namespace dae void Initialize() override; }; + + //+++++++++++++++++++++++++++++++++++++++++ + //WEEK 1 Test Scene + class Scene_W2 final : public Scene + { + public: + Scene_W2() = default; + ~Scene_W2() override = default; + + Scene_W2(const Scene_W1&) = delete; + Scene_W2(Scene_W1&&) noexcept = delete; + Scene_W2& operator=(const Scene_W1&) = delete; + Scene_W2& operator=(Scene_W1&&) noexcept = delete; + + void Initialize() override; + }; } diff --git a/project/src/Utils.h b/project/src/Utils.h index d7c7897..ba0914b 100644 --- a/project/src/Utils.h +++ b/project/src/Utils.h @@ -53,8 +53,8 @@ namespace dae { float dot = Vector3::Dot(plane.normal, ray.direction); if(dot < 0) { - float t = Vector3::Dot(plane.origin - ray.origin, plane.normal) / dot; - +// float t = Vector3::Dot(plane.origin - ray.origin, plane.normal) / dot; + float t = Vector3::Dot(plane.origin - ray.origin, plane.normal) / Vector3::Dot(ray.direction, plane.normal); bool hit = t >= 0; if(hit && !ignoreHitRecord){ diff --git a/project/src/main.cpp b/project/src/main.cpp index fdc1d6e..46d144c 100644 --- a/project/src/main.cpp +++ b/project/src/main.cpp @@ -47,7 +47,7 @@ int main(int argc, char* args[]) const auto pTimer = new Timer(); const auto pRenderer = new Renderer(pWindow); - const auto pScene = new Scene_W1(); + const auto pScene = new Scene_W2(); pScene->Initialize(); //Start loop