BVH Cleanup / Changes.
Working on fixing issues with the BVH implementation. Commiting a working changes version. Code has been cleaned up considerably. A proper code review is nessacary in the near future.main
|
@ -2,42 +2,27 @@
|
|||
374 3235 1668323538168825062 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_tables.cpp.o f6dab204e07e8dcf
|
||||
2 2022 1668323499583713805 CMakeFiles/Step_3.dir/src/graphics/gl/gl.c.o 30ab06816e8637c1
|
||||
4 3390 1668323512856096078 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_demo.cpp.o 7798aba97da63e31
|
||||
3 2621 1668323537552807322 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 6470df278966c4
|
||||
2 1153 1668323498715688802 CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o d86a254d2bce8f74
|
||||
2 8763 1668323543696984256 CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o 1c68ba16e6b4d09b
|
||||
2 871 1668323498431680622 CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o 9493619f74acd06a
|
||||
2 1840 1668361409895046083 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 6470df278966c4
|
||||
1 1716 1668360835926339635 CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o d86a254d2bce8f74
|
||||
1 7565 1668362431984323343 CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o 1c68ba16e6b4d09b
|
||||
2 1499 1668360835706333174 CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o 9493619f74acd06a
|
||||
4 605 1668323535536749264 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_x11.cpp.o d1e9a2fcb31e2ec8
|
||||
0 26 1668323688289146536 build.ninja ccb5de0c063412ab
|
||||
1 920 1668323498479682005 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o 4ef77d2224f86511
|
||||
2 1403 1668323536336772303 CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o 39e9f435096d066b
|
||||
3 2335 1668323537268799144 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o 164394d360c43072
|
||||
0 26 1668358519550031316 build.ninja ccb5de0c063412ab
|
||||
1 1621 1668360835826336698 CMakeFiles/Step_3.dir/src/engine/globals.cpp.o 4ef77d2224f86511
|
||||
1 1405 1668362425824144748 CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o 39e9f435096d066b
|
||||
2 1712 1668362494026122707 CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o 164394d360c43072
|
||||
3 6633 1668323516100189511 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui.cpp.o 55e7538fd27b47be
|
||||
8763 8835 1668323543768986328 Step_3 f055ce2b85635598
|
||||
2268 2354 1668361410407060406 Step_3 f055ce2b85635598
|
||||
4 521 1668323535452746847 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_glfw.cpp.o 6aef9db88eb3d76d
|
||||
2 2720 1668323537648810087 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 11f0e227e9fda9ca
|
||||
605 1795 1668323536728783593 CMakeFiles/Step_3.dir/src/graphics/input.cpp.o 510001b0955ab019
|
||||
2 2015 1668362494330131524 CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o 11f0e227e9fda9ca
|
||||
1499 2524 1668360836734363373 CMakeFiles/Step_3.dir/src/graphics/input.cpp.o 510001b0955ab019
|
||||
5 4715 1668323514180134213 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_draw.cpp.o f89fa3d7b779872a
|
||||
521 6249 1668323541180911801 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_widgets.cpp.o 84017388bc7af144
|
||||
3 2248 1668323537180796610 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
|
||||
3 2124 1668323537056793038 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
|
||||
2 1830 1668362494146126186 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
|
||||
2 1624 1668362426044151124 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
|
||||
4 374 1668323535308742700 CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_opengl3.cpp.o 1b5f0fbe3cf8ce4e
|
||||
3 2080 1668323537012791771 CMakeFiles/Step_3.dir/src/graphics/gl/shader.cpp.o 2553d57dba16057b
|
||||
2 3101 1668323538032821145 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
|
||||
2 1369 1668323498931695025 CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o 1007c86c207ac940
|
||||
1 1102 1668324071584170088 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
|
||||
1 1373 1668324071856177907 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
|
||||
1374 1444 1668324071924179862 Step_3 f055ce2b85635598
|
||||
1 1083 1668324105033131597 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
|
||||
1083 1160 1668324105109133783 Step_3 f055ce2b85635598
|
||||
1 1080 1668324205980033050 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
|
||||
1 1310 1668324206208039601 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
|
||||
1310 1378 1668324206276041556 Step_3 f055ce2b85635598
|
||||
1 1298 1668324222400504969 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
|
||||
1298 1369 1668324222472507037 Step_3 f055ce2b85635598
|
||||
1 1075 1668324349212149162 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
|
||||
1 1305 1668324349440155714 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
|
||||
1305 1374 1668324349508157669 Step_3 f055ce2b85635598
|
||||
1 1177 1668326424977049673 CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o 330ad35a6abf06c3
|
||||
1 1405 1668326425205056279 CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o ce988de97a5cb51d
|
||||
1 1911 1668326425713070995 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
|
||||
1912 2024 1668326425821074124 Step_3 f055ce2b85635598
|
||||
2 1617 1668362426036150892 CMakeFiles/Step_3.dir/src/graphics/gl/shader.cpp.o 2553d57dba16057b
|
||||
1 2419 1668362494734143245 CMakeFiles/Step_3.dir/src/engine/main.cpp.o 641dce3f86933e2e
|
||||
2 2242 1668360836450355031 CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o 1007c86c207ac940
|
||||
2 1579 1668362569316307713 CMakeFiles/Step_3.dir/src/engine/world.cpp.o 6470df278966c4
|
||||
1579 1704 1668362569440311315 Step_3 f055ce2b85635598
|
||||
|
|
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 573 KiB |
After Width: | Height: | Size: 597 KiB |
After Width: | Height: | Size: 602 KiB |
|
@ -1,3 +1,3 @@
|
|||
Start testing: Nov 13 03:00 EST
|
||||
Start testing: Nov 13 13:02 EST
|
||||
----------------------------------------------------------
|
||||
End testing: Nov 13 03:00 EST
|
||||
End testing: Nov 13 13:02 EST
|
||||
|
|
|
@ -9,7 +9,7 @@ Size=550,680
|
|||
Collapsed=1
|
||||
|
||||
[Window][Debug Menu]
|
||||
Pos=28,35
|
||||
Pos=26,34
|
||||
Size=339,226
|
||||
Collapsed=0
|
||||
|
||||
|
|
|
@ -10,19 +10,30 @@
|
|||
#include "engine/types.h"
|
||||
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
// A currently pure header implementation of a BVH. TODO: make source file.
|
||||
// this is also for testing and might not make it into the step 2.
|
||||
|
||||
namespace Raytracing {
|
||||
|
||||
struct BVHObject {
|
||||
Object* ptr = nullptr;
|
||||
AABB aabb;
|
||||
};
|
||||
|
||||
struct BVHPartitionedSpace {
|
||||
std::vector<BVHObject> left;
|
||||
std::vector<BVHObject> right;
|
||||
};
|
||||
|
||||
struct BVHNode {
|
||||
public:
|
||||
std::vector<Object*> objs;
|
||||
std::vector<BVHObject> objs;
|
||||
AABB aabb;
|
||||
BVHNode* left;
|
||||
BVHNode* right;
|
||||
BVHNode(std::vector<Object*> objs, AABB aabb, BVHNode* left, BVHNode* right): objs(std::move(objs)), aabb(std::move(aabb)),
|
||||
BVHNode(std::vector<BVHObject> objs, AABB aabb, BVHNode* left, BVHNode* right): objs(std::move(objs)), aabb(std::move(aabb)),
|
||||
left(left), right(right) {}
|
||||
~BVHNode() {
|
||||
delete (left);
|
||||
|
@ -35,42 +46,30 @@ namespace Raytracing {
|
|||
const int MAX_TREE_DEPTH = 50;
|
||||
BVHNode* root = nullptr;
|
||||
|
||||
void del() {
|
||||
// delete copied objects
|
||||
for (auto* obj : root->objs)
|
||||
delete(obj);
|
||||
delete (root);
|
||||
}
|
||||
|
||||
// splits the objs in the vector based on the provided AABBs
|
||||
static std::pair<std::vector<Object*>, std::vector<Object*>>
|
||||
partition(const std::pair<AABB, AABB>& aabbs, const std::vector<Object*>& objs) {
|
||||
std::vector<Object*> a1;
|
||||
std::vector<Object*> a2;
|
||||
for (auto* obj: objs) {
|
||||
static BVHPartitionedSpace partition(const std::pair<AABB, AABB>& aabbs, const std::vector<BVHObject>& objs) {
|
||||
BVHPartitionedSpace space;
|
||||
for (const auto& obj: objs) {
|
||||
// if this object doesn't have an AABB, we cannot use a BVH on it
|
||||
if (obj->getAABB().isEmpty()) {
|
||||
throw std::runtime_error("Invalid AABB provided to the BVH! (Your implementation is flawed)");
|
||||
// If this ever fails we have a problem with the implementation.
|
||||
assert(obj.aabb.isEmpty());
|
||||
if (obj.aabb.intersects(aabbs.first)) {
|
||||
space.left.push_back(obj);
|
||||
} else if (obj.aabb.intersects(aabbs.second)) {
|
||||
space.right.push_back(obj);
|
||||
}
|
||||
if (obj->getAABB().intersects(aabbs.first)) {
|
||||
a1.push_back(obj);
|
||||
} else if (obj->getAABB().intersects(aabbs.second)) {
|
||||
a2.push_back(obj);
|
||||
}
|
||||
//tlog << "OBJ: " << obj->getAABB() << " " << obj->getAABB().intersects(aabbs.first) << " " << obj->getAABB().intersects(aabbs.second) << " " << objs.size() << "\n";
|
||||
}
|
||||
//tlog << "we split into two of sizes: " << a1.size() << " " << a2.size() << " orig size: " << (a1.size() + a2.size()) << "\n";
|
||||
return {a1, a2};
|
||||
return space;
|
||||
}
|
||||
|
||||
BVHNode* addObjectsRecur(const std::vector<Object*>& objects, unsigned long prevSize) {
|
||||
BVHNode* addObjectsRecur(const std::vector<BVHObject>& objects, unsigned long prevSize) {
|
||||
//ilog << "size: " << objects.size() << "\n";
|
||||
// prevSize was required to solve some really weird bugs
|
||||
// which are a TODO:
|
||||
if ((objects.size() <= 2 && !objects.empty()) || prevSize == objects.size()) {
|
||||
AABB local;
|
||||
for (const auto& obj: objects)
|
||||
local = local.expand(obj->getAABB());
|
||||
local = local.expand(obj.aabb);
|
||||
return new BVHNode(objects, local, nullptr, nullptr);
|
||||
} else if (objects.empty()) // should never reach here!!
|
||||
return nullptr;
|
||||
|
@ -81,26 +80,24 @@ namespace Raytracing {
|
|||
AABB world;
|
||||
for (const auto& obj: objects) {
|
||||
//tlog << obj->getAABB();
|
||||
world = world.expand(obj->getAABB());
|
||||
world = world.expand(obj.aabb);
|
||||
}
|
||||
//tlog << "\n";
|
||||
// then split and partition the world
|
||||
auto spltAABB = world.splitByLongestAxis();
|
||||
//dlog << "We have " << world << " being split into: \n\t" << spltAABB.first << "\n\t" << spltAABB.second << "\n";
|
||||
auto partitionedObjs = partition(spltAABB, objects);
|
||||
auto splitAABBs = world.splitByLongestAxis();
|
||||
auto partitionedObjs = partition(splitAABBs, objects);
|
||||
|
||||
BVHNode* left = nullptr;
|
||||
BVHNode* right = nullptr;
|
||||
// don't try to explore nodes which don't have anything in them.
|
||||
if (!partitionedObjs.first.empty())
|
||||
left = addObjectsRecur(partitionedObjs.first, objects.size());
|
||||
if (!partitionedObjs.second.empty())
|
||||
right = addObjectsRecur(partitionedObjs.second, objects.size());
|
||||
if (!partitionedObjs.left.empty())
|
||||
left = addObjectsRecur(partitionedObjs.left, objects.size());
|
||||
if (!partitionedObjs.right.empty())
|
||||
right = addObjectsRecur(partitionedObjs.right, objects.size());
|
||||
|
||||
return new BVHNode(objects, world, left, right);
|
||||
}
|
||||
static std::vector<Object*>
|
||||
traverseFindRayIntersection(BVHNode* node, const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) {
|
||||
static std::vector<BVHObject> traverseFindRayIntersection(BVHNode* node, const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) {
|
||||
// check for intersections on both sides of the tree
|
||||
if (node->left != nullptr) {
|
||||
if (node->left->aabb.intersects(ray, min, max))
|
||||
|
@ -125,30 +122,32 @@ namespace Raytracing {
|
|||
|
||||
void addObjects(const std::vector<Object*>& objects) {
|
||||
if (root != nullptr)
|
||||
del();
|
||||
throw std::runtime_error("BVHTree already exists. What are you trying to do?");
|
||||
// move all the object's aabb's into world position
|
||||
std::vector<Object*> objs;
|
||||
std::vector<BVHObject> objs;
|
||||
for (auto* obj: objects) {
|
||||
// we don't want to store all the AABBs which don't exist
|
||||
// ie spheres
|
||||
if (obj->getAABB().isEmpty()) {
|
||||
//tlog << "Goodbye\n";
|
||||
noAABBObjects.push_back(obj);
|
||||
continue;
|
||||
}
|
||||
Object* objCopy = obj->clone();
|
||||
objCopy->setAABB(obj->getAABB().translate(obj->getPosition()));
|
||||
objs.push_back(objCopy);
|
||||
BVHObject bvhObject;
|
||||
// returns a copy of the AABB object and assigns it in to the tree storage object
|
||||
bvhObject.aabb = obj->getAABB().translate(obj->getPosition());
|
||||
// which means we don't have to do memory management, since we are using the pointer without ownership or coping now.
|
||||
bvhObject.ptr = obj;
|
||||
objs.push_back(bvhObject);
|
||||
}
|
||||
root = addObjectsRecur(objs, -1);
|
||||
}
|
||||
|
||||
std::vector<Object*> rayIntersect(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) {
|
||||
std::vector<BVHObject> rayIntersect(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) {
|
||||
return traverseFindRayIntersection(root, ray, min, max);
|
||||
}
|
||||
|
||||
~BVHTree() {
|
||||
del();
|
||||
delete (root);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -14,11 +14,8 @@ namespace Raytracing {
|
|||
protected:
|
||||
Vec4 min;
|
||||
Vec4 max;
|
||||
bool empty = false;
|
||||
public:
|
||||
AABB() {
|
||||
empty = true;
|
||||
};
|
||||
AABB(): min({0,0,0}), max({0,0,0}) {};
|
||||
|
||||
AABB(PRECISION_TYPE minX, PRECISION_TYPE minY, PRECISION_TYPE minZ, PRECISION_TYPE maxX, PRECISION_TYPE maxY, PRECISION_TYPE maxZ):
|
||||
min{minX, minY, minZ}, max{maxX, maxY, maxZ} {
|
||||
|
@ -100,7 +97,9 @@ namespace Raytracing {
|
|||
|
||||
[[nodiscard]] PRECISION_TYPE avgDistanceFromCenter() const;
|
||||
|
||||
[[nodiscard]] inline bool isEmpty() const { return empty; }
|
||||
// Returns true if the min and max are equal, which tells us this AABB wasn't assigned
|
||||
// or was properly created. Either way it isn't responsible to use the AABB in said case.
|
||||
[[nodiscard]] inline bool isEmpty() const { return min == max; }
|
||||
|
||||
[[nodiscard]] Vec4 getMin() const { return min; }
|
||||
|
||||
|
|
|
@ -392,6 +392,10 @@ namespace Raytracing {
|
|||
return out << "Vec4{" << v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w() << "} ";
|
||||
}
|
||||
|
||||
inline bool operator==(const Vec4& left, const Vec4& right) {
|
||||
return left.x() == right.x() && left.y() == right.y() && left.z() == right.z() && left.w() == right.w();
|
||||
}
|
||||
|
||||
class Ray {
|
||||
private:
|
||||
// the starting point for our ray
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* defines
|
||||
|
@ -47,33 +49,45 @@ const double EPSILON = 0.0000001;
|
|||
/**
|
||||
* classes
|
||||
*/
|
||||
static inline double degreeeToRadian(double deg){
|
||||
return deg * PI/180.0;
|
||||
static inline double degreeeToRadian(double deg) {
|
||||
return deg * PI / 180.0;
|
||||
}
|
||||
|
||||
namespace Raytracing {
|
||||
class AlignedAllocator {
|
||||
private:
|
||||
public:
|
||||
// not sure if this actually provides a performance benefit. Testing is inconclusive
|
||||
template<typename T>
|
||||
static T* allocateCacheAligned(int number = 1) {
|
||||
void* allocatedSpace = aligned_alloc(64, sizeof(T) * number);
|
||||
return new(allocatedSpace) T[number];
|
||||
}
|
||||
};
|
||||
|
||||
class Random {
|
||||
private:
|
||||
std::random_device rd; // obtain a random number from hardware
|
||||
std::mt19937 gen;
|
||||
std::uniform_real_distribution<double> doubleDistr {0, 1};
|
||||
std::uniform_real_distribution<double> doubleDistr{0, 1};
|
||||
public:
|
||||
Random(): gen(std::mt19937(long(rd.entropy() * 691 * 691))) {}
|
||||
Random(double min, double max): gen(std::mt19937(long(rd.entropy() * 691 * 691))), doubleDistr{min, max} {}
|
||||
double getDouble(){
|
||||
double getDouble() {
|
||||
return doubleDistr(gen);
|
||||
}
|
||||
};
|
||||
|
||||
class String {
|
||||
public:
|
||||
static inline std::string toLowerCase(const std::string& s){
|
||||
static inline std::string toLowerCase(const std::string& s) {
|
||||
std::stringstream str;
|
||||
std::for_each(s.begin(), s.end(), [&str](unsigned char ch) {
|
||||
str << (char) std::tolower(ch);
|
||||
});
|
||||
return str.str();
|
||||
}
|
||||
static inline std::string toUpperCase(const std::string& s){
|
||||
static inline std::string toUpperCase(const std::string& s) {
|
||||
std::stringstream str;
|
||||
std::for_each(s.begin(), s.end(), [&str](unsigned char ch) {
|
||||
str << (char) std::toupper(ch);
|
||||
|
@ -82,7 +96,7 @@ namespace Raytracing {
|
|||
}
|
||||
// taken from https://stackoverflow.com/questions/14265581/parse-split-a-string-in-c-using-string-delimiter-standard-c
|
||||
// extended to return a vector
|
||||
static inline std::vector<std::string> split(std::string s, const std::string& delim){
|
||||
static inline std::vector<std::string> split(std::string s, const std::string& delim) {
|
||||
size_t pos = 0;
|
||||
std::vector<std::string> tokens;
|
||||
while ((pos = s.find(delim)) != std::string::npos) {
|
||||
|
@ -138,9 +152,9 @@ namespace Raytracing {
|
|||
};
|
||||
}
|
||||
|
||||
static Raytracing::Random rnd {};
|
||||
static Raytracing::Random rnd{};
|
||||
|
||||
static inline double getRandomDouble(){
|
||||
static inline double getRandomDouble() {
|
||||
return rnd.getDouble();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace Raytracing {
|
||||
|
||||
class SphereObject : public Object {
|
||||
|
@ -114,14 +115,15 @@ namespace Raytracing {
|
|||
* saving on computation
|
||||
*/
|
||||
// TODO: the above todo has been done, now we need to test the performance advantage of the BVH
|
||||
BVHTree* bvhTree = nullptr;
|
||||
std::unique_ptr<BVHTree> bvhObjects;
|
||||
std::unordered_map<std::string, Material*> materials;
|
||||
public:
|
||||
World() = default;
|
||||
World(const World& world) = delete;
|
||||
World(const World&& world) = delete;
|
||||
|
||||
// call this after you've added all the objects to the world. (Called by the raycaster class)
|
||||
// Called by the raytracer class after all objects have been added to the world
|
||||
// this allows us to generate a statically unchanging BVH for easy rendering
|
||||
void generateBVH();
|
||||
|
||||
inline void add(Object* object) { objects.push_back(object); }
|
||||
|
|
|
@ -12,24 +12,167 @@
|
|||
#include <engine/image/image.h>
|
||||
#include <config.h>
|
||||
#include <graphics/gl/shader.h>
|
||||
|
||||
#ifndef USE_GLFW
|
||||
#include <GLES3/gl32.h>
|
||||
#include <GLES3/gl3.h>
|
||||
#include <GL/gl.h>
|
||||
#include "graphics/gl/glext.h"
|
||||
|
||||
extern PFNGLCREATEVERTEXARRAYSPROC glCreateVertexArrays;
|
||||
extern PFNGLCREATEBUFFERSPROC glCreateBuffers;
|
||||
extern PFNGLNAMEDBUFFERDATAPROC glNamedBufferData;
|
||||
extern PFNGLNAMEDBUFFERSUBDATAPROC glNamedBufferSubData;
|
||||
extern PFNGLCREATEVERTEXARRAYSPROC glCreateVertexArrays;
|
||||
extern PFNGLCREATEBUFFERSPROC glCreateBuffers;
|
||||
extern PFNGLNAMEDBUFFERDATAPROC glNamedBufferData;
|
||||
extern PFNGLNAMEDBUFFERSUBDATAPROC glNamedBufferSubData;
|
||||
|
||||
extern PFNGLENABLEVERTEXARRAYATTRIBPROC glEnableVertexArrayAttrib;
|
||||
extern PFNGLVERTEXARRAYATTRIBBINDINGPROC glVertexArrayAttribBinding;
|
||||
extern PFNGLVERTEXARRAYATTRIBFORMATPROC glVertexArrayAttribFormat;
|
||||
extern PFNGLENABLEVERTEXARRAYATTRIBPROC glEnableVertexArrayAttrib;
|
||||
extern PFNGLVERTEXARRAYATTRIBBINDINGPROC glVertexArrayAttribBinding;
|
||||
extern PFNGLVERTEXARRAYATTRIBFORMATPROC glVertexArrayAttribFormat;
|
||||
#else
|
||||
|
||||
#include <graphics/gl/glad/gl.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class Shapes {
|
||||
public:
|
||||
struct cubeVertexBuilder {
|
||||
std::vector<float> cubeVerticesRaw = {
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
0.5f, -0.5f, -0.5f,
|
||||
0.5f, 0.5f, -0.5f,
|
||||
0.5f, 0.5f, -0.5f,
|
||||
-0.5f, 0.5f, -0.5f,
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
|
||||
-0.5f, -0.5f, 0.5f,
|
||||
0.5f, -0.5f, 0.5f,
|
||||
0.5f, 0.5f, 0.5f,
|
||||
0.5f, 0.5f, 0.5f,
|
||||
-0.5f, 0.5f, 0.5f,
|
||||
-0.5f, -0.5f, 0.5f,
|
||||
|
||||
-0.5f, 0.5f, 0.5f,
|
||||
-0.5f, 0.5f, -0.5f,
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
-0.5f, -0.5f, 0.5f,
|
||||
-0.5f, 0.5f, 0.5f,
|
||||
|
||||
0.5f, 0.5f, 0.5f,
|
||||
0.5f, 0.5f, -0.5f,
|
||||
0.5f, -0.5f, -0.5f,
|
||||
0.5f, -0.5f, -0.5f,
|
||||
0.5f, -0.5f, 0.5f,
|
||||
0.5f, 0.5f, 0.5f,
|
||||
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
0.5f, -0.5f, -0.5f,
|
||||
0.5f, -0.5f, 0.5f,
|
||||
0.5f, -0.5f, 0.5f,
|
||||
-0.5f, -0.5f, 0.5f,
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
|
||||
-0.5f, 0.5f, -0.5f,
|
||||
0.5f, 0.5f, -0.5f,
|
||||
0.5f, 0.5f, 0.5f,
|
||||
0.5f, 0.5f, 0.5f,
|
||||
-0.5f, 0.5f, 0.5f,
|
||||
-0.5f, 0.5f, -0.5f,
|
||||
};
|
||||
std::vector<float> cubeUVs = {
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
|
||||
0.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
0.0f, 0.0f,
|
||||
0.0f, 1.0f,
|
||||
|
||||
0.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
0.0f, 0.0f,
|
||||
0.0f, 1.0f
|
||||
};
|
||||
static cubeVertexBuilder getCubeExtends(float xRadius, float yRadius, float zRadius) {
|
||||
cubeVertexBuilder builder {};
|
||||
builder.cubeVerticesRaw = {
|
||||
-0.5f, -0.5f, -zRadius,
|
||||
0.5f, -0.5f, -zRadius,
|
||||
0.5f, 0.5f, -zRadius,
|
||||
0.5f, 0.5f, -zRadius,
|
||||
-0.5f, 0.5f, -zRadius,
|
||||
-0.5f, -0.5f, -zRadius,
|
||||
|
||||
-0.5f, -0.5f, zRadius,
|
||||
0.5f, -0.5f, zRadius,
|
||||
0.5f, 0.5f, zRadius,
|
||||
0.5f, 0.5f, zRadius,
|
||||
-0.5f, 0.5f, zRadius,
|
||||
-0.5f, -0.5f, zRadius,
|
||||
|
||||
-xRadius, 0.5f, 0.5f,
|
||||
-xRadius, 0.5f, -0.5f,
|
||||
-xRadius, -0.5f, -0.5f,
|
||||
-xRadius, -0.5f, -0.5f,
|
||||
-xRadius, -0.5f, 0.5f,
|
||||
-xRadius, 0.5f, 0.5f,
|
||||
|
||||
xRadius, 0.5f, 0.5f,
|
||||
xRadius, 0.5f, -0.5f,
|
||||
xRadius, -0.5f, -0.5f,
|
||||
xRadius, -0.5f, -0.5f,
|
||||
xRadius, -0.5f, 0.5f,
|
||||
xRadius, 0.5f, 0.5f,
|
||||
|
||||
-0.5f, -yRadius, -0.5f,
|
||||
0.5f, -yRadius, -0.5f,
|
||||
0.5f, -yRadius, 0.5f,
|
||||
0.5f, -yRadius, 0.5f,
|
||||
-0.5f, -yRadius, 0.5f,
|
||||
-0.5f, -yRadius, -0.5f,
|
||||
|
||||
-0.5f, yRadius, -0.5f,
|
||||
0.5f, yRadius, -0.5f,
|
||||
0.5f, yRadius, 0.5f,
|
||||
0.5f, yRadius, 0.5f,
|
||||
-0.5f, yRadius, 0.5f,
|
||||
-0.5f, yRadius, -0.5f,
|
||||
};
|
||||
return builder;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// since we are doing everything with raytracing
|
||||
// the purpose of these utility classes are purely for debug
|
||||
// such as drawing bounding boxes around a BVH
|
||||
|
@ -46,8 +189,8 @@ class Texture {
|
|||
unsigned char* data;
|
||||
|
||||
public:
|
||||
Texture(Texture &&) noexcept = delete; // Disable move constructor.
|
||||
Texture& operator=(Texture &&) noexcept = delete; // Disable Move Assignment
|
||||
Texture(Texture&&) noexcept = delete; // Disable move constructor.
|
||||
Texture& operator=(Texture&&) noexcept = delete; // Disable Move Assignment
|
||||
Texture();
|
||||
explicit Texture(const std::string& path);
|
||||
explicit Texture(Raytracing::Image* image);
|
||||
|
@ -66,7 +209,7 @@ class VAO {
|
|||
// vertex data
|
||||
unsigned int storeData(int attrNumber, int coordSize, int stride, long offset, int length, const float* data);
|
||||
// element data (indices)
|
||||
unsigned int storeData(int length, const unsigned int *data);
|
||||
unsigned int storeData(int length, const unsigned int* data);
|
||||
// instance data
|
||||
unsigned int createInstanceVBO(int count, int bytePerInstance);
|
||||
// used much in the same way that store data sets an attribute where the data is expected
|
||||
|
@ -78,10 +221,10 @@ class VAO {
|
|||
VAO(const VAO& that); // Disable Copy Constructor
|
||||
VAO& operator=(const VAO& that); // Disable Copy Assignment
|
||||
public:
|
||||
VAO(VAO &&) noexcept = delete; // Disable move constructor.
|
||||
VAO& operator=(VAO &&) noexcept = delete; // Disable Move Assignment
|
||||
VAO(VAO&&) noexcept = delete; // Disable move constructor.
|
||||
VAO& operator=(VAO&&) noexcept = delete; // Disable Move Assignment
|
||||
|
||||
explicit VAO(const std::vector<Raytracing::Triangle> &triangles);
|
||||
explicit VAO(const std::vector<Raytracing::Triangle>& triangles);
|
||||
VAO(const std::vector<float>& verts, const std::vector<float>& uvs, const std::vector<unsigned int>& indices);
|
||||
VAO(const std::vector<float>& verts, const std::vector<float>& uvs);
|
||||
|
||||
|
|
|
@ -5,11 +5,15 @@ in vec2 outUv;
|
|||
in vec3 outNormal;
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform int useWhite;
|
||||
|
||||
const vec3 lightDir = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
void main() {
|
||||
vec4 textureColor = texture(tex, outUv);
|
||||
//FragColor = vec4(textureColor.rgb, 1.0f);
|
||||
if (useWhite == 0)
|
||||
FragColor = vec4(vec3(1.0, 0.0f, 0.0f) * dot(lightDir, outNormal), 1.0f);
|
||||
else
|
||||
FragColor = vec4(1.0);
|
||||
}
|
|
@ -12,7 +12,7 @@ namespace Raytracing {
|
|||
delete (p);
|
||||
for (const auto& p: materials)
|
||||
delete (p.second);
|
||||
//delete(bvhTree);
|
||||
//delete(bvhObjects);
|
||||
}
|
||||
|
||||
HitData SphereObject::checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const {
|
||||
|
@ -58,25 +58,25 @@ namespace Raytracing {
|
|||
|
||||
std::pair<HitData, Object*> World::checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const {
|
||||
// actually speeds up rendering by about 110,000ms (total across 16 threads)
|
||||
if (bvhTree != nullptr){
|
||||
if (bvhObjects != nullptr){
|
||||
auto hResult = HitData{false, Vec4(), Vec4(), max};
|
||||
Object* objPtr = nullptr;
|
||||
|
||||
auto intersected = bvhTree->rayIntersect(ray, min, max);
|
||||
auto intersected = bvhObjects->rayIntersect(ray, min, max);
|
||||
|
||||
//dlog << "Intersections " << intersected.size() << " " << ray << "\n";
|
||||
|
||||
for (auto* ptr : intersected) {
|
||||
auto cResult = ptr->checkIfHit(ray, min, hResult.length);
|
||||
for (const auto& ptr : intersected) {
|
||||
auto cResult = ptr.ptr->checkIfHit(ray, min, hResult.length);
|
||||
if (cResult.hit) {
|
||||
hResult = cResult;
|
||||
objPtr = ptr;
|
||||
objPtr = ptr.ptr;
|
||||
}
|
||||
}
|
||||
// after we check the BVH, we have to check for other missing objects
|
||||
// since stuff like spheres currently don't have AABB and AABB isn't a requirement
|
||||
// for the object class (to be assigned)
|
||||
for (auto* obj: bvhTree->noAABBObjects) {
|
||||
for (auto* obj: bvhObjects->noAABBObjects) {
|
||||
// check up to the point of the last closest hit,
|
||||
// will give the closest object's hit result
|
||||
auto cResult = obj->checkIfHit(ray, min, hResult.length);
|
||||
|
@ -105,7 +105,7 @@ namespace Raytracing {
|
|||
}
|
||||
|
||||
void World::generateBVH() {
|
||||
bvhTree = new BVHTree(objects);
|
||||
bvhObjects = std::make_unique<BVHTree>(objects);
|
||||
}
|
||||
|
||||
ScatterResults DiffuseMaterial::scatter(const Ray& ray, const HitData& hitData) const {
|
||||
|
|
|
@ -14,143 +14,6 @@ extern bool* haltRaytracing;
|
|||
|
||||
namespace Raytracing {
|
||||
|
||||
struct cubeVertexBuilder {
|
||||
std::vector<float> cubeVerticesRaw = {
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
0.5f, -0.5f, -0.5f,
|
||||
0.5f, 0.5f, -0.5f,
|
||||
0.5f, 0.5f, -0.5f,
|
||||
-0.5f, 0.5f, -0.5f,
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
|
||||
-0.5f, -0.5f, 0.5f,
|
||||
0.5f, -0.5f, 0.5f,
|
||||
0.5f, 0.5f, 0.5f,
|
||||
0.5f, 0.5f, 0.5f,
|
||||
-0.5f, 0.5f, 0.5f,
|
||||
-0.5f, -0.5f, 0.5f,
|
||||
|
||||
-0.5f, 0.5f, 0.5f,
|
||||
-0.5f, 0.5f, -0.5f,
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
-0.5f, -0.5f, 0.5f,
|
||||
-0.5f, 0.5f, 0.5f,
|
||||
|
||||
0.5f, 0.5f, 0.5f,
|
||||
0.5f, 0.5f, -0.5f,
|
||||
0.5f, -0.5f, -0.5f,
|
||||
0.5f, -0.5f, -0.5f,
|
||||
0.5f, -0.5f, 0.5f,
|
||||
0.5f, 0.5f, 0.5f,
|
||||
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
0.5f, -0.5f, -0.5f,
|
||||
0.5f, -0.5f, 0.5f,
|
||||
0.5f, -0.5f, 0.5f,
|
||||
-0.5f, -0.5f, 0.5f,
|
||||
-0.5f, -0.5f, -0.5f,
|
||||
|
||||
-0.5f, 0.5f, -0.5f,
|
||||
0.5f, 0.5f, -0.5f,
|
||||
0.5f, 0.5f, 0.5f,
|
||||
0.5f, 0.5f, 0.5f,
|
||||
-0.5f, 0.5f, 0.5f,
|
||||
-0.5f, 0.5f, -0.5f,
|
||||
};
|
||||
static cubeVertexBuilder getCubeExtends(float xRadius, float yRadius, float zRadius) {
|
||||
cubeVertexBuilder builder;
|
||||
builder.cubeVerticesRaw = {
|
||||
-0.5f, -0.5f, -zRadius,
|
||||
0.5f, -0.5f, -zRadius,
|
||||
0.5f, 0.5f, -zRadius,
|
||||
0.5f, 0.5f, -zRadius,
|
||||
-0.5f, 0.5f, -zRadius,
|
||||
-0.5f, -0.5f, -zRadius,
|
||||
|
||||
-0.5f, -0.5f, zRadius,
|
||||
0.5f, -0.5f, zRadius,
|
||||
0.5f, 0.5f, zRadius,
|
||||
0.5f, 0.5f, zRadius,
|
||||
-0.5f, 0.5f, zRadius,
|
||||
-0.5f, -0.5f, zRadius,
|
||||
|
||||
-xRadius, 0.5f, 0.5f,
|
||||
-xRadius, 0.5f, -0.5f,
|
||||
-xRadius, -0.5f, -0.5f,
|
||||
-xRadius, -0.5f, -0.5f,
|
||||
-xRadius, -0.5f, 0.5f,
|
||||
-xRadius, 0.5f, 0.5f,
|
||||
|
||||
xRadius, 0.5f, 0.5f,
|
||||
xRadius, 0.5f, -0.5f,
|
||||
xRadius, -0.5f, -0.5f,
|
||||
xRadius, -0.5f, -0.5f,
|
||||
xRadius, -0.5f, 0.5f,
|
||||
xRadius, 0.5f, 0.5f,
|
||||
|
||||
-0.5f, -yRadius, -0.5f,
|
||||
0.5f, -yRadius, -0.5f,
|
||||
0.5f, -yRadius, 0.5f,
|
||||
0.5f, -yRadius, 0.5f,
|
||||
-0.5f, -yRadius, 0.5f,
|
||||
-0.5f, -yRadius, -0.5f,
|
||||
|
||||
-0.5f, yRadius, -0.5f,
|
||||
0.5f, yRadius, -0.5f,
|
||||
0.5f, yRadius, 0.5f,
|
||||
0.5f, yRadius, 0.5f,
|
||||
-0.5f, yRadius, 0.5f,
|
||||
-0.5f, yRadius, -0.5f,
|
||||
};
|
||||
return builder;
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<float> cubeUVs = {
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
|
||||
1.0f, 0.0f,
|
||||
1.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
|
||||
0.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
0.0f, 0.0f,
|
||||
0.0f, 1.0f,
|
||||
|
||||
0.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 0.0f,
|
||||
1.0f, 0.0f,
|
||||
0.0f, 0.0f,
|
||||
0.0f, 1.0f
|
||||
};
|
||||
|
||||
const std::vector<float> vertices = {
|
||||
1.0f, 1.0f, 0.0f, // top right
|
||||
1.0f, -1.0f, 0.0f, // bottom right
|
||||
|
|