diff --git a/CMakeLists.txt b/CMakeLists.txt index 262d4b8..b5ceac8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,7 @@ include_directories(${executable} file(GLOB SourceFiles ${SrcDIR}/* ${SrcDIR}/core/* - ${SrcDIR}/core/renderengine/* + ${SrcDIR}/engine/* ${SrcDIR}/display/* ${SrcDIR}/primatives/* ${SrcDIR}/util/* diff --git a/src/common.hpp b/src/common.hpp index cc8bce1..4d27b41 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -1,6 +1,8 @@ #ifndef INFERNO_COMMON_H_ #define INFERNO_COMMON_H_ +#include + #include enum OperationMode { diff --git a/src/core/renderengine/progressiverenderer.cpp b/src/core/renderengine/progressiverenderer.cpp deleted file mode 100644 index a786a2b..0000000 --- a/src/core/renderengine/progressiverenderer.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "./progressiverenderer.hpp" - -ProgressiveRenderer::ProgressiveRenderer() { - -} diff --git a/src/core/renderengine/progressiverenderer.hpp b/src/core/renderengine/progressiverenderer.hpp deleted file mode 100644 index c408390..0000000 --- a/src/core/renderengine/progressiverenderer.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef INFERNO_CORE_RENDERENGINE_PROGRESSIVERENDERER_H_ -#define INFERNO_CORE_RENDERENGINE_PROGRESSIVERENDERER_H_ - -class ProgressiveRenderer { -public: - ProgressiveRenderer(); -}; - -#endif diff --git a/src/core/renderer.cpp b/src/core/renderer.cpp index 2b8b94c..ad58374 100644 --- a/src/core/renderer.cpp +++ b/src/core/renderer.cpp @@ -2,6 +2,8 @@ #include "../pixel.hpp" #include "./renderer.hpp" +#include "../engine/progressiverenderer.hpp" + Renderer::Renderer(OperationMode mode) { m_mode = mode; } @@ -11,6 +13,19 @@ void Renderer::SetMode(OperationMode mode, int samples) { m_samples = samples; } +void Renderer::Init() { + +} + +void Renderer::Init(DisplayInterface* display) { + // Add warning + if (!display) return; + if(!m_framebuffer) { + m_framebuffer = display->Framebuffer; + } + m_interface = display; +} + void Renderer::Render() { if (m_mode == MODE_PROGRESSIVE_GUI || m_mode == MODE_PROGRESSIVE_IMG) { RenderProgressive(); @@ -32,33 +47,11 @@ void Renderer::Render(uint32_t* framebuffer) { } } -void Renderer::Init() { - -} - -void Renderer::Init(DisplayInterface* display) { - // Add warning - if (!display) return; - if(!m_framebuffer) { - m_framebuffer = display->Framebuffer; - } - m_interface = display; -} - void Renderer::RenderProgressive() { - while (m_interface->Active) { - SDL_Event e; - while (SDL_PollEvent(&e) == SDL_TRUE) - if (e.type == SDL_QUIT) m_interface->Close(); - - for (int i = 0; i < 360000; i++) { - m_interface->SetPixelSafe(rand() % m_interface->XRes, - rand() % m_interface->YRes, - rgb888(rand() % 255, rand() % 255, rand() % 255)); - } - - m_interface->Update(); - } + m_progressive = new ProgressiveRenderer(); + + m_progressive->Init(m_interface); + m_progressive->Render(); } void Renderer::RenderSamples() { diff --git a/src/core/renderer.hpp b/src/core/renderer.hpp index e32836d..cc99de9 100644 --- a/src/core/renderer.hpp +++ b/src/core/renderer.hpp @@ -5,6 +5,8 @@ class DisplayInterface; +class ProgressiveRenderer; + // Function initProgressive or whatever takes a pointer to the display class Renderer { public: @@ -27,8 +29,10 @@ private: uint32_t* m_framebuffer = nullptr; void RenderProgressive(); + ProgressiveRenderer* m_progressive = nullptr; + + void RenderSamples(); - }; #endif diff --git a/src/definitions/camera.hpp b/src/definitions/camera.hpp new file mode 100644 index 0000000..58f1259 --- /dev/null +++ b/src/definitions/camera.hpp @@ -0,0 +1,13 @@ +#ifndef INFERNO_DEFINITIONS_CAMERA_H_ +#define INFERNO_DEFINITIONS_CAMERA_H_ + +#include "../maths.hpp" + +class Camera { +public: + glm::vec3 point; + glm::vec3 look; + float fov; +}; + +#endif diff --git a/src/primatives/sphere.cpp b/src/definitions/primatives/primative.cpp similarity index 100% rename from src/primatives/sphere.cpp rename to src/definitions/primatives/primative.cpp diff --git a/src/definitions/primatives/primative.hpp b/src/definitions/primatives/primative.hpp new file mode 100644 index 0000000..43c1484 --- /dev/null +++ b/src/definitions/primatives/primative.hpp @@ -0,0 +1,44 @@ +#ifndef INFERNO_DEFINITIONS_PRIMATIVES_PRIMATIVE_H_ +#define INFERNO_DEFINITIONS_PRIMATIVES_PRIMATIVE_H_ + +#include "../maths.hpp" + +class Ray; + +enum PrimativeType { + TYPE_NONE, + TYPE_SPHERE, + TYPE_PLANE, + TYPE_TRI +}; + +class Primative { +public: + // Attributes + glm::vec3 center; + // Sphere + float radius; + // Plane + glm::vec3 normal; + + PrimativeType type = TYPE_NONE; + + // Sphere constructor + Primative(glm::vec3 center, float radius) + : center(center), radius(radius) { + type = TYPE_SPHERE; + } + + // Plane constructor + Primative(glm::vec3 center, glm::vec3 normal) + : center(center), normal(normal) { + type = TYPE_PLANE; + } + + virtual bool DoesIntersect(Ray& ray, float& t) = 0; + virtual glm::vec3 SurfaceNormal(glm::vec3 hitPoint) = 0; + virtual glm::vec2 TexCoords(glm::vec3 hitPoint) = 0; + virtual void Translate(glm::vec3 trans) = 0; +}; + +#endif diff --git a/src/definitions/primatives/sphere.cpp b/src/definitions/primatives/sphere.cpp new file mode 100644 index 0000000..5b0ed89 --- /dev/null +++ b/src/definitions/primatives/sphere.cpp @@ -0,0 +1,45 @@ +#include "sphere.hpp" +#include "ray.hpp" + +bool Sphere::DoesIntersect(Ray& ray, float& t) { + float t0, t1; // Solutions for intersect + + // glm::vec3 L = ray.origin - center; + + // float a = glm::dot(ray.direction, ray.direction); + // float b = 2 * glm::dot(ray.direction, L); + // float c = glm::dot(L, L) - radius; + + // if (!quadratic(a, b, c, t0, t1)) { + // t = INFINITY; + // return false; + // }; + + glm::vec3 l = center - ray.origin; + float tca = glm::dot(l, ray.direction); + if (tca < 0.0f) return false; + float d2 = glm::dot(l, l) - tca * tca; + if (d2 > radius * radius) return false; + float thc = sqrtf(radius * radius - d2); + t0 = tca - thc; + t1 = tca + thc; + + if (t0 < t1) t = t0; + else t = t1; + + return true; // (t0 > t1 && t1 > 0.0f) ? t1 > 0.0f : t0 > 0.0f; +} + +glm::vec3 Sphere::SurfaceNormal(glm::vec3 hitPoint) { + return glm::normalize(hitPoint - center); +} + +glm::vec2 Sphere::TexCoords(glm::vec3 hitPoint) { + glm::vec3 hit = hitPoint - center; + return { (1.0 + atan2(hit.z, hit.x) / PI) * 0.5, + acos(hit.y / radius) / PI }; +} + +void Sphere::Translate(glm::vec3 trans) { + center += trans; +} diff --git a/src/definitions/primatives/sphere.hpp b/src/definitions/primatives/sphere.hpp new file mode 100644 index 0000000..5dd1693 --- /dev/null +++ b/src/definitions/primatives/sphere.hpp @@ -0,0 +1,17 @@ +#ifndef INFERNO_DEFINITIONS_PRIMATIVES_SPHERE_H_ +#define INFERNO_DEFINITIONS_PRIMATIVES_SPHERE_H_ + +#include "primative.hpp" + +class Sphere : public Primative { + + Sphere(glm::vec3 center, float radius) + : Primative(center, radius) { } + + bool DoesIntersect(Ray& ray, float& t) override; + glm::vec3 SurfaceNormal(glm::vec3 hitPoint) override; + glm::vec2 TexCoords(glm::vec3 hitPoint) override; + void Translate(glm::vec3 trans) override; +}; + +#endif diff --git a/src/definitions/ray.cpp b/src/definitions/ray.cpp new file mode 100644 index 0000000..40ef2ca --- /dev/null +++ b/src/definitions/ray.cpp @@ -0,0 +1,8 @@ +#include "ray.hpp" + +#include "camera.hpp" +#include "scene.hpp" + +Ray GeneratePrimaryRay(int x, int y, Scene& scene, float xSubPix = 0.5f, float ySubPix = 0.5f) { + +} diff --git a/src/definitions/ray.hpp b/src/definitions/ray.hpp new file mode 100644 index 0000000..734dcea --- /dev/null +++ b/src/definitions/ray.hpp @@ -0,0 +1,16 @@ +#ifndef INFERNO_DEFINITIONS_RAY_H_ +#define INFERNO_DEFINITIONS_RAY_H_ + +#include "../maths.hpp" + +class Scene; + +class Ray { +public: + glm::vec3 origin; + glm::vec3 direction; +}; + +Ray GeneratePrimaryRay(int x, int y, Scene& scene, float xSubPix = 0.5f, float ySubPix = 0.5f); + +#endif diff --git a/src/primatives/sphere.hpp b/src/definitions/scene.cpp similarity index 100% rename from src/primatives/sphere.hpp rename to src/definitions/scene.cpp diff --git a/src/definitions/scene.hpp b/src/definitions/scene.hpp new file mode 100644 index 0000000..31d5b5f --- /dev/null +++ b/src/definitions/scene.hpp @@ -0,0 +1,14 @@ +#ifndef INFERNO_DEFINITIONS_SCENE_H_ +#define INFERNO_DEFINITIONS_SCENE_H_ + +#include + +class Camera; +class Primative; + +class Scene { + Camera* camera; + std::vector objects; +}; + +#endif diff --git a/src/display/display.hpp b/src/display/display.hpp index a511fec..0c32484 100644 --- a/src/display/display.hpp +++ b/src/display/display.hpp @@ -1,11 +1,8 @@ #ifndef INFERNO_DISPLAY_DISPLAY_H_ #define INFERNO_DISPLAY_DISPLAY_H_ -#include - -#include - -#include "./displayinterface.hpp" +#include "../common.hpp" +#include "displayinterface.hpp" class Pixel; diff --git a/src/engine/progressiverenderer.cpp b/src/engine/progressiverenderer.cpp new file mode 100644 index 0000000..888b9bb --- /dev/null +++ b/src/engine/progressiverenderer.cpp @@ -0,0 +1,31 @@ +#include "./progressiverenderer.hpp" + +#include "../common.hpp" +#include "../pixel.hpp" +#include "../display/displayinterface.hpp" + +ProgressiveRenderer::ProgressiveRenderer() { + +} + +void ProgressiveRenderer::Init(DisplayInterface* interface) { + m_interface = interface; +} + +void ProgressiveRenderer::Render() { + // RENDERING CAN ACTUALLY START + + while (m_interface->Active) { + SDL_Event e; + while (SDL_PollEvent(&e) == SDL_TRUE) + if (e.type == SDL_QUIT) m_interface->Close(); + + for (int i = 0; i < 360000; i++) { + m_interface->SetPixelSafe(rand() % m_interface->XRes, + rand() % m_interface->YRes, + rgb888(rand() % 255, rand() % 255, rand() % 255)); + } + + m_interface->Update(); + } +} diff --git a/src/engine/progressiverenderer.hpp b/src/engine/progressiverenderer.hpp new file mode 100644 index 0000000..cb80d5b --- /dev/null +++ b/src/engine/progressiverenderer.hpp @@ -0,0 +1,18 @@ +#ifndef INFERNO_ENGINE_PROGRESSIVERENDERER_H_ +#define INFERNO_ENGINE_PROGRESSIVERENDERER_H_ + +class DisplayInterface; + +class ProgressiveRenderer { +public: + ProgressiveRenderer(); + + void Init(DisplayInterface* interface); + + void Render(); + +private: + DisplayInterface* m_interface = nullptr; +}; + +#endif diff --git a/src/inferno.hpp b/src/inferno.hpp index 577d3c9..f25e2e7 100644 --- a/src/inferno.hpp +++ b/src/inferno.hpp @@ -5,7 +5,10 @@ #include #include -#include "./common.hpp" +#include "common.hpp" + +#include "definitions/camera.hpp" +#include "definitions/scene.hpp" class Display; class Renderer; diff --git a/src/maths.hpp b/src/maths.hpp new file mode 100644 index 0000000..3649279 --- /dev/null +++ b/src/maths.hpp @@ -0,0 +1,62 @@ +#ifndef INFERNO_MATHS_H_ +#define INFERNO_MATHS_H_ + +#include +#include +#include + +const float DEG2RAD = 0.01745329251994329576923690768f; +const float RAD2DEG = 57.2957795130823208767981548141f; +const float PI = 3.14159265358979323846264338327f; +const float EPSILON = 0.00001000000000000000000000000f; + + +inline float fastDegreetoRadian(const float Degree) { + return (Degree * DEG2RAD); +} + +inline float fastRadianToDegree(const float Radian) { + return (Radian * RAD2DEG); +} + +inline float getFovAdjustment(const float fov) { + return tanf(fov * PI / 360.0f); +} + +inline float getAspectRatio(const float w, const float h) { + return (float)w / (float)h; +} + +// (-b += sqrt(b^2-4ac)) / 2a +inline bool quadratic(float a, float b, float c, float& x0, float& x1) { + float discr = b * b - 4.0f * a * c; + if (discr < 0.0f) return false; + else if (discr == 0.0f) x0 = x1 = -0.5f * b / a; + else { + float q = (b > 0.0f) ? + -0.5f * (b + sqrtf(discr)) : + -0.5f * (b - sqrtf(discr)); + x0 = q / a; + x1 = c / q; + } + if (x0 > x1) std::swap(x0, x1); + + return true; +} + +inline float clamp(float n, float lower, float upper) { + return std::max(lower, std::min(n, upper)); +} + +inline void clamp(glm::vec3& col, float lower, float upper) { + clamp(col.r, lower, upper); + clamp(col.g, lower, upper); + clamp(col.b, lower, upper); +} + +inline float modulo(float x) { + return x - std::floor(x); +} + + +#endif