From 99305779d54222a23961300c915ebf800d398166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asr=C4=B1n=20Do=C4=9Fan?= <33391270+Syntriax@users.noreply.github.com> Date: Thu, 9 Jan 2020 18:06:30 +0300 Subject: [PATCH] First Working Render & Vector Class Modifications Good News: It works! Bad News: 0.2 FPS --- 3DTest/Objects.hpp | 20 +++++++ 3DTest/RayMarch.hpp | 143 ++++++++++++++++++++++++++++++++++++++++++++ 3DTest/Render.hpp | 45 +++++++++++++- 3DTest/SynGame.hpp | 2 + 3DTest/Vectors.hpp | 16 +++-- 5 files changed, 218 insertions(+), 8 deletions(-) create mode 100644 3DTest/Objects.hpp create mode 100644 3DTest/RayMarch.hpp diff --git a/3DTest/Objects.hpp b/3DTest/Objects.hpp new file mode 100644 index 0000000..8cec7a7 --- /dev/null +++ b/3DTest/Objects.hpp @@ -0,0 +1,20 @@ +#include "SynGame.hpp" + +class Sphere +{ + public: + Vector3 position; + float radius; + sf::Color color; + Sphere(Vector3 = (0,0,0), float = 1.0, sf::Color = sf::Color::White); +}; + +Sphere::Sphere(Vector3 position, float radius, sf::Color color) +{ + this -> position = position; + this -> radius = radius; + this -> color = color; +} + + + diff --git a/3DTest/RayMarch.hpp b/3DTest/RayMarch.hpp new file mode 100644 index 0000000..34fc053 --- /dev/null +++ b/3DTest/RayMarch.hpp @@ -0,0 +1,143 @@ +#include "SynGame.hpp" + +class RayMarch +{ + private: + Sphere *spheres; + Sphere *closest; + Vector3 direction; + Vector3 position; + int sphereSize; + int stepLimit; + int stepCounter; + float minDistance; + float maxDistance; + float GetClosestDistance(); + Sphere *GetClosestSphere(); + public: + RayMarch(); + RayMarch(Vector3, Vector3, Sphere *, int = 0); + void SetRay(Vector3, Vector3, Sphere *, int = 0, int = 100, float = 0.01); + void SetPosition(Vector3, Vector3); + int GetStepCount(); + sf::Color FireRay(); +}; + +RayMarch::RayMarch() +{ + this -> position = (0.0, 0.0); + this -> direction = (0.0, 0.0); + this -> spheres = NULL; + stepCounter = 0; + sphereSize = 0; + minDistance = 0.01; + stepLimit = 100; + maxDistance = 100.0; +} + +RayMarch::RayMarch(Vector3 position, Vector3 direction, Sphere *spheres, int size) +{ + this -> position = position; + this -> direction = direction; + this -> spheres = spheres; + sphereSize = size; + stepCounter = 0; + minDistance = 0.01; + stepLimit = 100; + maxDistance = 100.0; +} + +void RayMarch::SetRay(Vector3 position, Vector3 direction, Sphere *spheres, int size, int stepLimit, float minDistance) +{ + this -> position = position; + this -> direction = direction; + this -> spheres = spheres; + this -> sphereSize = size; + this -> stepLimit = stepLimit; + this -> minDistance = minDistance; + stepCounter = 0; +} + +void RayMarch::SetPosition(Vector3 position, Vector3 direction) +{ + this -> position = position; + this -> direction = direction; + stepCounter = 0; + +} + +Sphere *RayMarch::GetClosestSphere() +{ + int i; + Sphere *ptr = spheres; + Sphere *closestSphere = NULL; + float closestDistance; + float distance; + + if(!ptr) return NULL; + + closestDistance = position.Distance((*ptr).position) - (*ptr).radius; + for (i = 0; i < sphereSize; i++) + { + distance = position.Distance((*ptr).position) - (*ptr).radius; + if(distance < closestDistance) + { + closestDistance = distance; + closestSphere = ptr; + } + ptr++; + } + + return closestSphere; +} + +float RayMarch::GetClosestDistance() +{ + int i; + Sphere *ptr = spheres; + float closestDistance; + float distance; + + if(!ptr) return 0.0; + closestDistance = position.Distance((*ptr).position) - (*ptr).radius; + for (i = 0; i < sphereSize; i++) + { + distance = position.Distance((*ptr).position) - (*ptr).radius; + if(distance < closestDistance) + { + closestDistance = distance; + closest = ptr; + } + ptr++; + } + + return closestDistance; +} + +int RayMarch::GetStepCount() { return stepCounter; } + +sf::Color RayMarch::FireRay() +{ + float distance; + stepCounter = 0; + + if(!spheres) return sf::Color::Black; + + for (stepCounter = 0; stepCounter < stepLimit; stepCounter++) + { + distance = GetClosestDistance(); + + if(distance <= minDistance) + return closest -> color; + + if(distance >= maxDistance) + { + sf::Uint8 val = 256 * stepCounter / stepLimit; + return sf::Color(val, val, val); + } + + position += direction * distance; + } + + return sf::Color::Black; +} diff --git a/3DTest/Render.hpp b/3DTest/Render.hpp index 67df778..2f9d140 100644 --- a/3DTest/Render.hpp +++ b/3DTest/Render.hpp @@ -7,6 +7,7 @@ class RenderWindow : public Window unsigned int pixelSize; sf::Vertex *_CreateVertexBuffer(); void ReloadScreenBuffer(); + void Render(); public: RenderWindow(unsigned int = 960, unsigned int = 540, std::string = "Window", sf::Uint32 = sf::Style::Titlebar | sf::Style::Close); ~RenderWindow(); @@ -22,17 +23,55 @@ void RenderWindow::Update() return; Window::Update(); + Render(); + window.clear(); window.draw(vertices, size.x * size.y, sf::Points); window.display(); } +void RenderWindow::Render() +{ + int y; + int x; + sf::Vertex *ptr = vertices; + Sphere spheres[9]; + spheres[0].position = Vector3( 10, 0, 0); spheres[0].radius = 1.0; + spheres[1].position = Vector3(-10, 0, 0); spheres[1].radius = 1.0; + spheres[2].position = Vector3( 0, -10, 0); spheres[2].radius = 1.0; + spheres[3].position = Vector3( 0, 10, 0); spheres[3].radius = 1.0; + spheres[4].position = Vector3( 10, 10, -10); spheres[4].radius = 1.0; + spheres[5].position = Vector3(-10,-10, -10); spheres[5].radius = 1.0; + spheres[6].position = Vector3( 10, -10, -10); spheres[6].radius = 1.0; + spheres[7].position = Vector3(-10, 10, -10); spheres[7].radius = 1.0; + spheres[8].position = Vector3(0, 0, 10); spheres[8].radius = 5; + RayMarch ray = RayMarch(); + Vector3 cameraPos(0, 0, -timer.GetTimePassed() * 2); + Vector3 rayDirection; + ray.SetRay(cameraPos, rayDirection, spheres, 9, 100); + rayDirection = (0, 0, 0); + for (y = 0; y < size.y; y++) + for (x = 0; x < size.x; x++) + { + // Change this + rayDirection.x = (float)x - (float)size.x / 2.0; + rayDirection.y = (float)y - (float)size.y / 2.0; + rayDirection.z = 1000.0; + rayDirection = rayDirection.Normalized(); + + ray.SetPosition(cameraPos, rayDirection); + + ptr -> color = ray.FireRay(); + ptr++; + } +} + sf::Vertex *RenderWindow::_CreateVertexBuffer() { int y; int x; - sf::Vertex *newBuffer = new sf::Vertex[size.x * size.y]; - sf::Vertex *ptr = newBuffer; + sf::Vertex *newVertices = new sf::Vertex[size.x * size.y]; + sf::Vertex *ptr = newVertices; for (y = 0; y < size.y; y++) for (x = 0; x < size.x; x++) @@ -41,7 +80,7 @@ sf::Vertex *RenderWindow::_CreateVertexBuffer() ptr++ -> position = sf::Vector2f(x, y); } - return newBuffer; + return newVertices; } void RenderWindow::ReloadScreenBuffer() diff --git a/3DTest/SynGame.hpp b/3DTest/SynGame.hpp index a855310..9870f57 100644 --- a/3DTest/SynGame.hpp +++ b/3DTest/SynGame.hpp @@ -9,6 +9,8 @@ #include #include "Timer.hpp" #include "Vectors.hpp" + #include "Objects.hpp" + #include "RayMarch.hpp" #include "Window.hpp" #include "Render.hpp" #endif diff --git a/3DTest/Vectors.hpp b/3DTest/Vectors.hpp index 08bac04..fe0df76 100644 --- a/3DTest/Vectors.hpp +++ b/3DTest/Vectors.hpp @@ -48,9 +48,10 @@ Vector1 Vector1::Normalized() { return Vector1(x < 0.0 ? -1.0 : 1.0); } #pragma endregion #pragma region Vector2 - class Vector2 : public Vector1 + class Vector2 { public: + float x; float y; Vector2(float = 0, float = 0); Vector2 operator+(Vector2); @@ -70,7 +71,7 @@ Vector2 Normalized(); }; - Vector2::Vector2(float x, float y) : Vector1(x) { this -> y = y; } + Vector2::Vector2(float x, float y) { this -> x = x; this -> y = y; } Vector2 Vector2::operator+ (Vector2 parameter) { Vector2 vector = Vector2(x, y); vector.x += parameter.x; vector.y += parameter.y; return vector; } Vector2 Vector2::operator- (Vector2 parameter) { Vector2 vector = Vector2(x, y); vector.x -= parameter.x; vector.y -= parameter.y; return vector; } @@ -99,9 +100,11 @@ } #pragma endregion #pragma region Vector3 - class Vector3 : public Vector2 + class Vector3 { public: + float x; + float y; float z; Vector3(float = 0, float = 0, float = 0); Vector3 operator+(Vector3); @@ -121,7 +124,7 @@ Vector3 Normalized(); }; - Vector3::Vector3(float x, float y, float z) : Vector2(x, y) { this -> z = z; } + Vector3::Vector3(float x, float y, float z) { this -> x = x; this -> y = y; this -> z = z; } Vector3 Vector3::operator+ (Vector3 parameter) { Vector3 vector = Vector3(x, y, z); vector.x += parameter.x; vector.y += parameter.y; vector.z += parameter.z; return vector; } Vector3 Vector3::operator- (Vector3 parameter) { Vector3 vector = Vector3(x, y, z); vector.x -= parameter.x; vector.y -= parameter.y; vector.z -= parameter.z; return vector; } @@ -140,7 +143,10 @@ float Vector3::Magnitude() { return sqrt(x*x+y*y+z*z); } float Vector3::Distance(Vector3 parameter) { - Vector3 distanceVector = (*this) - parameter; + Vector3 distanceVector; + distanceVector.x = x - parameter.x; + distanceVector.y = y - parameter.y; + distanceVector.z = z - parameter.z; return distanceVector.Magnitude(); } Vector3 Vector3::Normalized()