Memory Conversion

main
Brett 2022-12-03 11:54:34 -05:00
parent 373134a255
commit 50714bfe52
14 changed files with 357 additions and 122 deletions

View File

@ -14,7 +14,7 @@
<option name="FUNCTION_CALL_ARGUMENTS_NEW_LINE_AFTER_LPAR" value="true" /> <option name="FUNCTION_CALL_ARGUMENTS_NEW_LINE_AFTER_LPAR" value="true" />
<option name="FUNCTION_CALL_ARGUMENTS_NEW_LINE_BEFORE_RPAR" value="true" /> <option name="FUNCTION_CALL_ARGUMENTS_NEW_LINE_BEFORE_RPAR" value="true" />
<option name="CLASS_CONSTRUCTOR_INIT_LIST_NEW_LINE_BEFORE_COLON" value="0" /> <option name="CLASS_CONSTRUCTOR_INIT_LIST_NEW_LINE_BEFORE_COLON" value="0" />
<option name="CLASS_CONSTRUCTOR_INIT_LIST_NEW_LINE_AFTER_COLON" value="1" /> <option name="CLASS_CONSTRUCTOR_INIT_LIST_NEW_LINE_AFTER_COLON" value="2" />
<option name="SUPERCLASS_LIST_BEFORE_COLON" value="0" /> <option name="SUPERCLASS_LIST_BEFORE_COLON" value="0" />
<option name="SPACE_BEFORE_INIT_LIST_COLON" value="false" /> <option name="SPACE_BEFORE_INIT_LIST_COLON" value="false" />
<option name="SPACE_BEFORE_POINTER_IN_DECLARATION" value="false" /> <option name="SPACE_BEFORE_POINTER_IN_DECLARATION" value="false" />

View File

@ -265,6 +265,14 @@ build CMakeFiles/Step_3.dir/src/opencl/cl.cpp.o: CXX_COMPILER__Step_3_Debug /hom
OBJECT_DIR = CMakeFiles/Step_3.dir OBJECT_DIR = CMakeFiles/Step_3.dir
OBJECT_FILE_DIR = CMakeFiles/Step_3.dir/src/opencl OBJECT_FILE_DIR = CMakeFiles/Step_3.dir/src/opencl
build CMakeFiles/Step_3.dir/src/opencl/open_ray_tracing.cpp.o: CXX_COMPILER__Step_3_Debug /home/brett/Documents/Brock/CS$ 3P93/Project/Step$ 3/src/opencl/open_ray_tracing.cpp || cmake_object_order_depends_target_Step_3
DEFINES = -DCL_TARGET_OPENCL_VERSION=220
DEP_FILE = CMakeFiles/Step_3.dir/src/opencl/open_ray_tracing.cpp.o.d
FLAGS = -fsanitize=address -g -march=native -g -fsanitize=address -std=gnu++20
INCLUDES = -I"/home/brett/Documents/Brock/CS 3P93/Project/Step 3/cmake-build-debug" -I"/home/brett/Documents/Brock/CS 3P93/Project/Step 3/include"
OBJECT_DIR = CMakeFiles/Step_3.dir
OBJECT_FILE_DIR = CMakeFiles/Step_3.dir/src/opencl
# ============================================================================= # =============================================================================
# Link build statements for EXECUTABLE target Step_3 # Link build statements for EXECUTABLE target Step_3
@ -273,7 +281,7 @@ build CMakeFiles/Step_3.dir/src/opencl/cl.cpp.o: CXX_COMPILER__Step_3_Debug /hom
############################################# #############################################
# Link the executable Step_3 # Link the executable Step_3
build Step_3: CXX_EXECUTABLE_LINKER__Step_3_Debug CMakeFiles/Step_3.dir/src/engine/globals.cpp.o CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o CMakeFiles/Step_3.dir/src/engine/main.cpp.o CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o CMakeFiles/Step_3.dir/src/engine/util/loaders.cpp.o CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o CMakeFiles/Step_3.dir/src/engine/world.cpp.o CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o CMakeFiles/Step_3.dir/src/graphics/gl/gl.c.o CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o CMakeFiles/Step_3.dir/src/graphics/gl/shader.cpp.o CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_demo.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_draw.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_glfw.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_opengl3.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_x11.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_tables.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_widgets.cpp.o CMakeFiles/Step_3.dir/src/graphics/input.cpp.o CMakeFiles/Step_3.dir/src/opencl/cl.cpp.o | /usr/lib/x86_64-linux-gnu/libGLU.so /usr/lib/x86_64-linux-gnu/libGLX.so /usr/lib/x86_64-linux-gnu/libglfw.so.3.3 /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/libGLX.so /usr/lib/x86_64-linux-gnu/libOpenGL.so build Step_3: CXX_EXECUTABLE_LINKER__Step_3_Debug CMakeFiles/Step_3.dir/src/engine/globals.cpp.o CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o CMakeFiles/Step_3.dir/src/engine/main.cpp.o CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o CMakeFiles/Step_3.dir/src/engine/util/loaders.cpp.o CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o CMakeFiles/Step_3.dir/src/engine/world.cpp.o CMakeFiles/Step_3.dir/src/graphics/debug_gui.cpp.o CMakeFiles/Step_3.dir/src/graphics/gl/gl.c.o CMakeFiles/Step_3.dir/src/graphics/gl/gl.cpp.o CMakeFiles/Step_3.dir/src/graphics/gl/shader.cpp.o CMakeFiles/Step_3.dir/src/graphics/graphics.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_demo.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_draw.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_glfw.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_opengl3.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_impl_x11.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_tables.cpp.o CMakeFiles/Step_3.dir/src/graphics/imgui/imgui_widgets.cpp.o CMakeFiles/Step_3.dir/src/graphics/input.cpp.o CMakeFiles/Step_3.dir/src/opencl/cl.cpp.o CMakeFiles/Step_3.dir/src/opencl/open_ray_tracing.cpp.o | /usr/lib/x86_64-linux-gnu/libGLU.so /usr/lib/x86_64-linux-gnu/libGLX.so /usr/lib/x86_64-linux-gnu/libglfw.so.3.3 /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/libGLX.so /usr/lib/x86_64-linux-gnu/libOpenGL.so
FLAGS = -fsanitize=address -g -march=native -g FLAGS = -fsanitize=address -g -march=native -g
LINK_FLAGS = -fsanitize=address LINK_FLAGS = -fsanitize=address
LINK_LIBRARIES = -lpthread /usr/lib/x86_64-linux-gnu/libGLU.so /usr/lib/x86_64-linux-gnu/libGLX.so /usr/lib/x86_64-linux-gnu/libglfw.so.3.3 /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/libGLX.so /usr/lib/x86_64-linux-gnu/libOpenGL.so LINK_LIBRARIES = -lpthread /usr/lib/x86_64-linux-gnu/libGLU.so /usr/lib/x86_64-linux-gnu/libGLX.so /usr/lib/x86_64-linux-gnu/libglfw.so.3.3 /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/libGLX.so /usr/lib/x86_64-linux-gnu/libOpenGL.so

View File

@ -39,7 +39,7 @@
{ {
"directoryIndex" : 0, "directoryIndex" : 0,
"id" : "Step_3::@6890427a1f51a3e7e1df", "id" : "Step_3::@6890427a1f51a3e7e1df",
"jsonFile" : "target-Step_3-Release-c12458f55cdccc68bac1.json", "jsonFile" : "target-Step_3-Release-0e16299909ee4154184a.json",
"name" : "Step_3", "name" : "Step_3",
"projectIndex" : 0 "projectIndex" : 0
} }

View File

@ -26,7 +26,7 @@
"objects" : "objects" :
[ [
{ {
"jsonFile" : "codemodel-v2-36be696f440eeb8e54fd.json", "jsonFile" : "codemodel-v2-73be07f725d3293e1a94.json",
"kind" : "codemodel", "kind" : "codemodel",
"version" : "version" :
{ {
@ -86,7 +86,7 @@
}, },
"codemodel-v2" : "codemodel-v2" :
{ {
"jsonFile" : "codemodel-v2-36be696f440eeb8e54fd.json", "jsonFile" : "codemodel-v2-73be07f725d3293e1a94.json",
"kind" : "codemodel", "kind" : "codemodel",
"version" : "version" :
{ {

View File

@ -135,7 +135,8 @@
9, 9,
10, 10,
11, 11,
12 12,
13
] ]
} }
], ],
@ -209,7 +210,8 @@
9, 9,
10, 10,
11, 11,
12 12,
13
] ]
} }
], ],
@ -292,6 +294,12 @@
"compileGroupIndex" : 0, "compileGroupIndex" : 0,
"path" : "src/opencl/cl.cpp", "path" : "src/opencl/cl.cpp",
"sourceGroupIndex" : 0 "sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "src/opencl/open_ray_tracing.cpp",
"sourceGroupIndex" : 0
} }
], ],
"type" : "EXECUTABLE" "type" : "EXECUTABLE"

View File

@ -153,6 +153,14 @@ build CMakeFiles/Step_3.dir/src/opencl/cl.cpp.o: CXX_COMPILER__Step_3_Release /h
OBJECT_DIR = CMakeFiles/Step_3.dir OBJECT_DIR = CMakeFiles/Step_3.dir
OBJECT_FILE_DIR = CMakeFiles/Step_3.dir/src/opencl OBJECT_FILE_DIR = CMakeFiles/Step_3.dir/src/opencl
build CMakeFiles/Step_3.dir/src/opencl/open_ray_tracing.cpp.o: CXX_COMPILER__Step_3_Release /home/brett/Documents/Brock/CS$ 3P93/Project/Step$ 3/src/opencl/open_ray_tracing.cpp || cmake_object_order_depends_target_Step_3
DEFINES = -DCL_TARGET_OPENCL_VERSION=220
DEP_FILE = CMakeFiles/Step_3.dir/src/opencl/open_ray_tracing.cpp.o.d
FLAGS = -march=native -O3 -DNDEBUG -std=gnu++20
INCLUDES = -I"/home/brett/Documents/Brock/CS 3P93/Project/Step 3/cmake-build-release-mpi" -I/usr/lib/x86_64-linux-gnu/openmpi/include -I/usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -I"/home/brett/Documents/Brock/CS 3P93/Project/Step 3/include"
OBJECT_DIR = CMakeFiles/Step_3.dir
OBJECT_FILE_DIR = CMakeFiles/Step_3.dir/src/opencl
# ============================================================================= # =============================================================================
# Link build statements for EXECUTABLE target Step_3 # Link build statements for EXECUTABLE target Step_3
@ -161,7 +169,7 @@ build CMakeFiles/Step_3.dir/src/opencl/cl.cpp.o: CXX_COMPILER__Step_3_Release /h
############################################# #############################################
# Link the executable Step_3 # Link the executable Step_3
build Step_3: CXX_EXECUTABLE_LINKER__Step_3_Release CMakeFiles/Step_3.dir/src/engine/globals.cpp.o CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o CMakeFiles/Step_3.dir/src/engine/main.cpp.o CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o CMakeFiles/Step_3.dir/src/engine/util/loaders.cpp.o CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o CMakeFiles/Step_3.dir/src/engine/world.cpp.o CMakeFiles/Step_3.dir/src/opencl/cl.cpp.o | /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi_cxx.so /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi.so build Step_3: CXX_EXECUTABLE_LINKER__Step_3_Release CMakeFiles/Step_3.dir/src/engine/globals.cpp.o CMakeFiles/Step_3.dir/src/engine/image/image.cpp.o CMakeFiles/Step_3.dir/src/engine/main.cpp.o CMakeFiles/Step_3.dir/src/engine/math/bvh.cpp.o CMakeFiles/Step_3.dir/src/engine/math/colliders.cpp.o CMakeFiles/Step_3.dir/src/engine/mpi.cpp.o CMakeFiles/Step_3.dir/src/engine/raytracing.cpp.o CMakeFiles/Step_3.dir/src/engine/util/debug.cpp.o CMakeFiles/Step_3.dir/src/engine/util/loaders.cpp.o CMakeFiles/Step_3.dir/src/engine/util/models.cpp.o CMakeFiles/Step_3.dir/src/engine/util/parser.cpp.o CMakeFiles/Step_3.dir/src/engine/world.cpp.o CMakeFiles/Step_3.dir/src/opencl/cl.cpp.o CMakeFiles/Step_3.dir/src/opencl/open_ray_tracing.cpp.o | /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi_cxx.so /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi.so
FLAGS = -march=native -O3 -DNDEBUG FLAGS = -march=native -O3 -DNDEBUG
LINK_LIBRARIES = -Wl,-rpath,/usr/lib/x86_64-linux-gnu/openmpi/lib -lpthread /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi_cxx.so /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi.so LINK_LIBRARIES = -Wl,-rpath,/usr/lib/x86_64-linux-gnu/openmpi/lib -lpthread /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/libOpenCL.so /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi_cxx.so /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi.so
OBJECT_DIR = CMakeFiles/Step_3.dir OBJECT_DIR = CMakeFiles/Step_3.dir

View File

@ -0,0 +1,59 @@
/*
* Created by Brett Terpstra 6920201 on 03/12/22.
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*/
#ifndef STEP_3_MEMORY_UTIL_H
#define STEP_3_MEMORY_UTIL_H
#include <engine/util/std.h>
#define ENDIAN_FLIP
namespace Raytracing {
class MemoryConvert {
private:
public:
/**
* returns the bytes from the double ordered based on if ENDIAN_FLIP is defined or not
*/
inline static std::vector<unsigned char> getDoubleBytes(double d) {
std::vector<unsigned char> bytes;
auto* doubleAsBytes = reinterpret_cast<unsigned char*>(&d);
#ifdef ENDIAN_FLIP
for (int i = 0; i < sizeof(double); i++)
bytes.push_back(doubleAsBytes[i]);
#else
for (int i = 0; i < sizeof(double); i++)
bytes.push_back(doubleAsBytes[sizeof(double) - i]);
#endif
return bytes;
}
/**
* Note: this is used for the GPU and it is assumed that you are using double precision values.
* Anything else is undefined. (Should be fine though since upcasting is fine)
* @param array array to write into
* @param offset offset of where to start writing into. Will update this value as it moves through the vector
* @param vec the vector to write
*/
inline static void writeVectorBytes(unsigned char* array, size_t& offset, const Vec4& vec) {
auto x = getDoubleBytes(vec.x());
auto y = getDoubleBytes(vec.y());
auto z = getDoubleBytes(vec.z());
auto w = getDoubleBytes(vec.w());
// write the bytes as a packed vector.
for (auto b: x)
array[offset++] = b;
for (auto b: y)
array[offset++] = b;
for (auto b: z)
array[offset++] = b;
for (auto b: w)
array[offset++] = b;
}
};
}
#endif //STEP_3_MEMORY_UTIL_H

View File

@ -18,14 +18,12 @@ namespace Raytracing {
Vec4 vertex1, vertex2, vertex3; Vec4 vertex1, vertex2, vertex3;
Vec4 normal1, normal2, normal3; Vec4 normal1, normal2, normal3;
Vec4 uv1, uv2, uv3; Vec4 uv1, uv2, uv3;
bool hasNormals = false;
AABB aabb; AABB aabb;
Triangle(const Vec4& v1, const Vec4& v2, const Vec4& v3, Triangle(
const Vec4& uv1, const Vec4& uv2, const Vec4& uv3, const Vec4& v1, const Vec4& v2, const Vec4& v3, const Vec4& uv1, const Vec4& uv2, const Vec4& uv3, const Vec4& n1, const Vec4& n2,
const Vec4& n1, const Vec4& n2, const Vec4& n3): vertex1(v1), vertex2(v2), vertex3(v3), const Vec4& n3
uv1(uv1), uv2(uv2), uv3(uv3), ): vertex1(v1), vertex2(v2), vertex3(v3), uv1(uv1), uv2(uv2), uv3(uv3), normal1(n1), normal2(n2), normal3(n3) {}
hasNormals(true), normal1(n1), normal2(n2), normal3(n3) {}
}; };
// face type for model loading // face type for model loading
@ -34,7 +32,7 @@ namespace Raytracing {
int uv1, uv2, uv3; int uv1, uv2, uv3;
int n1, n2, n3; int n1, n2, n3;
}; };
struct ModelData { struct ModelData {
// storing all this data is memory inefficient // storing all this data is memory inefficient
// since normals and vertices are only vec3s // since normals and vertices are only vec3s
@ -49,10 +47,10 @@ namespace Raytracing {
struct TriangulatedModel { struct TriangulatedModel {
std::vector<std::shared_ptr<Triangle>> triangles; std::vector<std::shared_ptr<Triangle>> triangles;
AABB aabb; AABB aabb;
explicit TriangulatedModel(const ModelData& data); explicit TriangulatedModel(const ModelData& data);
}; };
class OBJLoader { class OBJLoader {
private: private:
public: public:

View File

@ -13,25 +13,28 @@
#include "types.h" #include "types.h"
#include <config.h> #include <config.h>
#ifdef COMPILE_GUI #ifdef COMPILE_GUI
#include "graphics/gl/shader.h" #include "graphics/gl/shader.h"
#include "graphics/debug_gui.h" #include "graphics/debug_gui.h"
#endif #endif
#include <utility> #include <utility>
namespace Raytracing { namespace Raytracing {
class SphereObject : public Object { class SphereObject : public Object {
private: private:
PRECISION_TYPE radius; PRECISION_TYPE radius;
public: public:
SphereObject(const Vec4& position, PRECISION_TYPE radius, Material* material): radius(radius), Object(material, position) {} SphereObject(const Vec4& position, PRECISION_TYPE radius, Material* material): radius(radius), Object(material, position) {}
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const; [[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const;
}; };
class ModelObject : public Object { class ModelObject : public Object {
private: private:
std::vector<std::shared_ptr<Triangle>> triangles; std::vector<std::shared_ptr<Triangle>> triangles;
@ -39,11 +42,11 @@ namespace Raytracing {
public: public:
ModelObject(const Vec4& position, ModelData& data, Material* material): Object(material, position) { ModelObject(const Vec4& position, ModelData& data, Material* material): Object(material, position) {
// since all of this occurs before the main ray tracing algorithm it's fine to do sequentially // since all of this occurs before the main ray tracing algorithm it's fine to do sequentially
TriangulatedModel model {data}; TriangulatedModel model{data};
this->triangles = model.triangles; this->triangles = model.triangles;
this->aabb = std::move(model.aabb); this->aabb = std::move(model.aabb);
std::vector<TriangleBVHObject> triangulatedObjects; std::vector<TriangleBVHObject> triangulatedObjects;
for (const auto& tri : triangles){ for (const auto& tri: triangles) {
TriangleBVHObject triangleObject; TriangleBVHObject triangleObject;
triangleObject.tri = tri; triangleObject.tri = tri;
triangleObject.aabb = tri->aabb; triangleObject.aabb = tri->aabb;
@ -51,59 +54,66 @@ namespace Raytracing {
triangulatedObjects.push_back(triangleObject); triangulatedObjects.push_back(triangleObject);
} }
triangleBVH = std::make_unique<TriangleBVHTree>(triangulatedObjects); triangleBVH = std::make_unique<TriangleBVHTree>(triangulatedObjects);
#ifdef COMPILE_GUI #ifdef COMPILE_GUI
vao = new VAO(triangles); vao = new VAO(triangles);
#endif #endif
} }
[[nodiscard]] virtual DebugBVHData getBVHTree(){return {triangleBVH.get(), false}; }
[[nodiscard]] virtual DebugBVHData getBVHTree() { return {triangleBVH.get(), false}; }
[[nodiscard]] virtual std::vector<std::shared_ptr<Triangle>> getTriangles() { return triangles; }
[[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const; [[nodiscard]] virtual HitData checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const;
}; };
class DiffuseMaterial : public Material { class DiffuseMaterial : public Material {
private: private:
public: public:
explicit DiffuseMaterial(const Vec4& scatterColor): Material(scatterColor) {} explicit DiffuseMaterial(const Vec4& scatterColor): Material(scatterColor) {}
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override; [[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
}; };
class MetalMaterial : public Material { class MetalMaterial : public Material {
protected: protected:
static inline Vec4 reflect(const Vec4& incomingVector, const Vec4& normal) { static inline Vec4 reflect(const Vec4& incomingVector, const Vec4& normal) {
return incomingVector - 2 * Vec4::dot(incomingVector, normal) * normal; return incomingVector - 2 * Vec4::dot(incomingVector, normal) * normal;
} }
public: public:
explicit MetalMaterial(const Vec4& metalColor): Material(metalColor) {} explicit MetalMaterial(const Vec4& metalColor): Material(metalColor) {}
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override; [[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
}; };
class BrushedMetalMaterial : public MetalMaterial { class BrushedMetalMaterial : public MetalMaterial {
private: private:
PRECISION_TYPE fuzzyness; PRECISION_TYPE fuzzyness;
public: public:
explicit BrushedMetalMaterial(const Vec4& metalColor, PRECISION_TYPE fuzzyness): MetalMaterial(metalColor), fuzzyness(fuzzyness) {} explicit BrushedMetalMaterial(const Vec4& metalColor, PRECISION_TYPE fuzzyness): MetalMaterial(metalColor), fuzzyness(fuzzyness) {}
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override; [[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
}; };
class LightMaterial : public Material { class LightMaterial : public Material {
public: public:
explicit LightMaterial(const Vec4& lightColor): Material(lightColor) {} explicit LightMaterial(const Vec4& lightColor): Material(lightColor) {}
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override; [[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
[[nodiscard]] virtual Vec4 emission(PRECISION_TYPE u, PRECISION_TYPE v, const Vec4& hitPoint) const override; [[nodiscard]] virtual Vec4 emission(PRECISION_TYPE u, PRECISION_TYPE v, const Vec4& hitPoint) const override;
}; };
class TexturedMaterial : public Material { class TexturedMaterial : public Material {
protected: protected:
int width{}, height{}, channels{}; int width{}, height{}, channels{};
unsigned char* data; unsigned char* data;
public: public:
explicit TexturedMaterial(const std::string& file); explicit TexturedMaterial(const std::string& file);
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override; [[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
[[nodiscard]] Vec4 getColor(PRECISION_TYPE u, PRECISION_TYPE v) const; [[nodiscard]] Vec4 getColor(PRECISION_TYPE u, PRECISION_TYPE v) const;
~TexturedMaterial(); ~TexturedMaterial();
@ -116,9 +126,10 @@ namespace Raytracing {
Shader& worldShader; Shader& worldShader;
explicit WorldConfig(Shader& shader): worldShader(shader) {} explicit WorldConfig(Shader& shader): worldShader(shader) {}
#endif #endif
}; };
class World { class World {
private: private:
// store all the objects in the world, // store all the objects in the world,
@ -128,34 +139,42 @@ namespace Raytracing {
WorldConfig m_config; WorldConfig m_config;
public: public:
explicit World(WorldConfig config): m_config(config) {}; explicit World(WorldConfig config): m_config(config) {};
World(const World& world) = delete; World(const World& world) = delete;
World(const World&& world) = delete; World(const World&& world) = delete;
// Called by the raytracer class after all objects have been added to the world // 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 // this allows us to generate a statically unchanging BVH for easy rendering
void generateBVH(); void generateBVH();
#ifdef COMPILE_GUI
// currently disabled. TODO: BVH renderer class
void drawBVH(Shader& worldShader) {}
#endif
inline void add(Object* object) {
objects.push_back(object);
#ifdef COMPILE_GUI #ifdef COMPILE_GUI
if (object->getBVHTree().bvhTree != nullptr && !object->getBVHTree().isRegular)
new DebugBVH{(TriangleBVHTree*) object->getBVHTree().bvhTree, m_config.worldShader}; // currently disabled. TODO: BVH renderer class
void drawBVH(Shader& worldShader) {}
#endif #endif
}
inline void add(Object* object) {
objects.push_back(object);
#ifdef COMPILE_GUI
if (object->getBVHTree().bvhTree != nullptr && !object->getBVHTree().isRegular)
new DebugBVH{(TriangleBVHTree*) object->getBVHTree().bvhTree, m_config.worldShader};
#endif
}
inline void add(const std::string& materialName, Material* mat) { materials.insert({materialName, mat}); } inline void add(const std::string& materialName, Material* mat) { materials.insert({materialName, mat}); }
inline Material* getMaterial(const std::string& materialName) { return materials.at(materialName); } inline Material* getMaterial(const std::string& materialName) { return materials.at(materialName); }
[[nodiscard]] inline BVHTree* getBVH() { return bvhObjects.get(); } [[nodiscard]] inline BVHTree* getBVH() { return bvhObjects.get(); }
[[nodiscard]] inline std::vector<Object*> getObjectsInWorld(){return objects; }
[[nodiscard]] inline std::vector<Object*> getObjectsInWorld() { return objects; }
[[nodiscard]] virtual std::pair<HitData, Object*> checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const; [[nodiscard]] virtual std::pair<HitData, Object*> checkIfHit(const Ray& ray, PRECISION_TYPE min, PRECISION_TYPE max) const;
~World(); ~World();
}; };
} }

View File

@ -12,11 +12,6 @@
#include <engine/image/image.h> #include <engine/image/image.h>
#include <config.h> #include <config.h>
#ifdef COMPILE_GUI
#endif
#include <engine/util/std.h> #include <engine/util/std.h>
namespace Raytracing { namespace Raytracing {
@ -111,7 +106,7 @@ namespace Raytracing {
* globalWorkSize and localWorkSize must be an array of workDim size which specify the work size for each kernel * globalWorkSize and localWorkSize must be an array of workDim size which specify the work size for each kernel
* For example a work dim of 2 allows for two separate work sizes to be set per dimension. * For example a work dim of 2 allows for two separate work sizes to be set per dimension.
* An image is two dimensional and so global work size would be {width of image, height of image} * An image is two dimensional and so global work size would be {width of image, height of image}
* and local work size would be {8, 8} for a total of 64 (again recommended). Alternatively specify CL_D2_64_LOCAL_SIZE * and local work size would be size_t localWork = {8, 8} for a total of 64 (again recommended).
* The resulting execution causes get_global_id(0) to run [0, width) times and get_global_id(1) to run [0, height) times * The resulting execution causes get_global_id(0) to run [0, width) times and get_global_id(1) to run [0, height) times
* @param kernel kernel function name to call * @param kernel kernel function name to call
* @param globalWorkSize the total number of times to execute the kernel function code. Corresponds to the result of get_global_id(dim) * @param globalWorkSize the total number of times to execute the kernel function code. Corresponds to the result of get_global_id(dim)

View File

@ -0,0 +1,43 @@
/*
* Created by Brett Terpstra 6920201 on 03/12/22.
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*
* contains the opencl raytracing code. The file name is a pun (I hope that was implied otherwise I guess I'm lame)
*/
#ifndef STEP_3_OPEN_RAY_TRACING_H
#define STEP_3_OPEN_RAY_TRACING_H
#include <engine/util/std.h>
#include <config.h>
#include <engine/image/image.h>
#include <engine/types.h>
#include <engine/world.h>
#include <engine/util/memory_util.h>
#ifdef COMPILE_OPENCL
#include <opencl/cl.h>
namespace Raytracing {
class OpenClRaytracer {
private:
CLProgram* program;
Image& image;
size_t localWorks[2]{8, 8};
public:
OpenClRaytracer(const std::string& programLocation, Image& image, World& world);
~OpenClRaytracer();
void storeObjects(const std::vector<Object*>& objects, size_t totalWorldBytes);
void run();
};
}
#endif
#endif //STEP_3_OPEN_RAY_TRACING_H

View File

@ -5,6 +5,7 @@
#include "engine/world.h" #include "engine/world.h"
#include <chrono> #include <chrono>
#include "engine/util/debug.h" #include "engine/util/debug.h"
#include "opencl/open_ray_tracing.h"
#include <config.h> #include <config.h>
#include <csignal> #include <csignal>
@ -51,39 +52,63 @@ int main(int argc, char** args) {
parser.addOption("--single", "Enable Single Thread\n\tUse a single thread for ray tracing\n", "true"); parser.addOption("--single", "Enable Single Thread\n\tUse a single thread for ray tracing\n", "true");
// not implemented yet // not implemented yet
parser.addOption("--multi", "Enable Multi-threading\n" parser.addOption(
"\tUse multiple threads for ray tracing,\n" "--multi", "Enable Multi-threading\n"
"\tYou can set the max threads using -t or --threads\n"); "\tUse multiple threads for ray tracing,\n"
parser.addOption({{"-t"}, "\tYou can set the max threads using -t or --threads\n"
{"--threads"}}, "Max Usable Threads\n" );
"\tSet the max threads the ray tracer will attempt to use.\n" parser.addOption(
"\tDefaults to all cores of your cpu.\n", "0"); {{"-t"},
{"--threads"}}, "Max Usable Threads\n"
"\tSet the max threads the ray tracer will attempt to use.\n"
"\tDefaults to all cores of your cpu.\n", "0"
);
// not implemented yet // not implemented yet
parser.addOption({{"--gui"}, parser.addOption(
{"-g"}}, "Enable GUI\n" {{"--gui"},
"\tWill create a GUI using X11 and display the image there.\n" {"-g"}}, "Enable GUI\n"
"\tRequires the you compile with the option -DCOMPILE_GUI=ON. Will do nothing otherwise\n"); "\tWill create a GUI using X11 and display the image there.\n"
"\tRequires the you compile with the option -DCOMPILE_GUI=ON. Will do nothing otherwise\n"
);
// not implemented yet // not implemented yet
parser.addOption({{"--gpu"}, parser.addOption(
{"-c"}}, "Enables GPU Compute\n" {{"--gpu"},
"\tWill use OpenCL compute to render the image\n"); {"-c"}}, "Enables GPU Compute\n"
parser.addOption("--output", "Output Directory\n" "\tWill use OpenCL compute to render the image\n"
"\tSet the output directory for the rendered image. Defaults to the local directory.\n", "./"); );
parser.addOption("--format", "Output Format\n" parser.addOption(
"\tSets the output format to BMP, PNG, or JPEG. \n", "PNG"); "--output", "Output Directory\n"
parser.addOption("-w", "Image Width\n" "\tSet the output directory for the rendered image. Defaults to the local directory.\n", "./"
"\tSets the width of the output image.\n", "1440"); );
parser.addOption("-h", "Image Height\n" parser.addOption(
"\tSets the height of the output image.\n", "720"); "--format", "Output Format\n"
parser.addOption("--fov", "Camera FOV\n" "\tSets the output format to BMP, PNG, or JPEG. \n", "PNG"
"\tSets the FOV used to render the camera.\n", "90"); );
parser.addOption("--resources", "Resources Directory\n" parser.addOption(
"\tSets the directory where the resources are stored.\n" "-w", "Image Width\n"
"\tThis can be relative.Must have trailing '/' \n", "../resources/"); "\tSets the width of the output image.\n", "1440"
parser.addOption("--mpi", "Use OpenMPI\n" );
"\tTells the raycaster to use OpenMPI to run the raycaster algorithm\n"); parser.addOption(
parser.addOption("--openmp", "Use OpenMP\n" "-h", "Image Height\n"
"\tTells the raycaster to use OpenMP to run the raycaster algorithm\n"); "\tSets the height of the output image.\n", "720"
);
parser.addOption(
"--fov", "Camera FOV\n"
"\tSets the FOV used to render the camera.\n", "90"
);
parser.addOption(
"--resources", "Resources Directory\n"
"\tSets the directory where the resources are stored.\n"
"\tThis can be relative.Must have trailing '/' \n", "../resources/"
);
parser.addOption(
"--mpi", "Use OpenMPI\n"
"\tTells the raycaster to use OpenMPI to run the raycaster algorithm\n"
);
parser.addOption(
"--openmp", "Use OpenMP\n"
"\tTells the raycaster to use OpenMP to run the raycaster algorithm\n"
);
// disabled because don't currently have a way to parse vectors. TODO // disabled because don't currently have a way to parse vectors. TODO
//parser.addOption("--position", "Camera Position\n\tSets the position used to render the scene with the camera.\n", "{0, 0, 0}"); //parser.addOption("--position", "Camera Position\n\tSets the position used to render the scene with the camera.\n", "{0, 0, 0}");
@ -93,17 +118,21 @@ int main(int argc, char** args) {
if (parser.parse(args, argc)) if (parser.parse(args, argc))
return 0; return 0;
if (signal(SIGTERM, [](int sig) -> void { if (signal(
ilog << "Computations complete.\nHalting now...\n"; SIGTERM, [](int sig) -> void {
RTSignal->haltExecution = true; ilog << "Computations complete.\nHalting now...\n";
}) == SIG_ERR) { RTSignal->haltExecution = true;
}
) == SIG_ERR) {
elog << "Unable to change signal handler.\n"; elog << "Unable to change signal handler.\n";
return 1; return 1;
} }
if (signal(SIGINT, [](int sig) -> void { if (signal(
ilog << "Computations complete.\nHalting now...\n"; SIGINT, [](int sig) -> void {
RTSignal->haltExecution = true; ilog << "Computations complete.\nHalting now...\n";
}) == SIG_ERR) { RTSignal->haltExecution = true;
}
) == SIG_ERR) {
elog << "Unable to change signal handler.\n"; elog << "Unable to change signal handler.\n";
return 1; return 1;
} }
@ -179,24 +208,16 @@ int main(int argc, char** args) {
Raytracing::RayCaster rayCaster{camera, image, world, parser}; Raytracing::RayCaster rayCaster{camera, image, world, parser};
Texture mainImage(&image); Texture mainImage(&image);
CLProgram program(parser.getOptionValue("--resources") + "opencl/image.cl");
OpenCL::createCLProgram(program);
program.createKernel("drawImage");
program.createImage("mainImage", image.getWidth(), image.getHeight());
program.setKernelArgument("drawImage", "mainImage", 0);
program.setKernelArgument("drawImage", "mainImage", 1);
size_t works[2]{(size_t) image.getWidth(), (size_t) image.getHeight()};
size_t localWorks[2]{8, 8};
OpenClRaytracer openClRaytracer{parser.getOptionValue("--resources") + "opencl/raytracer.cl", image, world};
openClRaytracer.run();
Shader shader("../resources/shaders/basic.vs", "../resources/shaders/basic.fs"); Shader shader("../resources/shaders/basic.vs", "../resources/shaders/basic.fs");
Raytracing::DisplayRenderer renderer{*window, mainImage, world, shader, worldShader, rayCaster, parser, camera}; Raytracing::DisplayRenderer renderer{*window, mainImage, world, shader, worldShader, rayCaster, parser, camera};
while (!window->shouldWindowClose()) { while (!window->shouldWindowClose()) {
window->beginUpdate(); window->beginUpdate();
renderer.draw(); renderer.draw();
program.runKernel("drawImage", works, localWorks, 2);
program.readImage("mainImage", image);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
world.drawBVH(worldShader); world.drawBVH(worldShader);

View File

@ -146,6 +146,7 @@ namespace Raytracing {
return {true, Ray{hitData.hitPoint, newRay}, getColor(hitData.u, hitData.v)}; return {true, Ray{hitData.hitPoint, newRay}, getColor(hitData.u, hitData.v)};
} }
Vec4 TexturedMaterial::getColor(PRECISION_TYPE u, PRECISION_TYPE v) const { Vec4 TexturedMaterial::getColor(PRECISION_TYPE u, PRECISION_TYPE v) const {
// if we are unable to load the image return the debug color. // if we are unable to load the image return the debug color.
if (!data) if (!data)
@ -169,6 +170,7 @@ namespace Raytracing {
return {pixelData[0] * colorFactor, pixelData[1] * colorFactor, pixelData[2] * colorFactor}; return {pixelData[0] * colorFactor, pixelData[1] * colorFactor, pixelData[2] * colorFactor};
} }
TexturedMaterial::TexturedMaterial(const std::string& file): Material({}) { TexturedMaterial::TexturedMaterial(const std::string& file): Material({}) {
// we are going to have to ignore transparency for now. TODO:? // we are going to have to ignore transparency for now. TODO:?
data = stbi_load(file.c_str(), &width, &height, &channels, 0); data = stbi_load(file.c_str(), &width, &height, &channels, 0);
@ -177,13 +179,16 @@ namespace Raytracing {
else else
ilog << "Loaded image " << file << " with " << width << " " << height << " " << channels << "!\n"; ilog << "Loaded image " << file << " with " << width << " " << height << " " << channels << "!\n";
} }
TexturedMaterial::~TexturedMaterial() { TexturedMaterial::~TexturedMaterial() {
stbi_image_free(data); stbi_image_free(data);
} }
ScatterResults LightMaterial::scatter(const Ray& ray, const HitData& hitData) const { ScatterResults LightMaterial::scatter(const Ray& ray, const HitData& hitData) const {
// do not scatter. The light emits. // do not scatter. The light emits.
return {false, ray, baseColor}; return {false, ray, baseColor};
} }
Vec4 LightMaterial::emission(PRECISION_TYPE u, PRECISION_TYPE v, const Vec4& hitPoint) const { Vec4 LightMaterial::emission(PRECISION_TYPE u, PRECISION_TYPE v, const Vec4& hitPoint) const {
return baseColor; return baseColor;
} }
@ -246,20 +251,9 @@ namespace Raytracing {
auto areaVert2 = areaVert2Vec.magnitude() * fullArea; auto areaVert2 = areaVert2Vec.magnitude() * fullArea;
auto areaVert3 = areaVert3Vec.magnitude() * fullArea; auto areaVert3 = areaVert3Vec.magnitude() * fullArea;
// normal = theTriangle.findClosestNormal(rayIntersectionPoint - position); // since we are calculating UV coords, the hard interpolation part is already done.
if (theTriangle.hasNormals) { // so use said calculation to determine the overall normal based on the 3 individual vertexes
// returning the closest normal is extra computation when n1 would likely be fine. normal = theTriangle.normal1 * areaVert1 + theTriangle.normal2 * areaVert2 + theTriangle.normal3 * areaVert3;
normal = theTriangle.normal1;
// the above point still stands, but since we have to compute the berry centric factors anyway
// we can use them in the same way to use from for UVs to get the correct normal.
// but since the three normals should always be facing the same way anyway, so we really don't need to do this.
// I'm keeping this here in case that fact changes.
//normal = theTriangle.normal1 * areaVert1 + theTriangle.normal2 * areaVert2 + theTriangle.normal3 * areaVert3;
} else {
// standard points to normal algorithm but using already computed edges
normal = Vec4{edge1.y() * edge2.z(), edge1.z() * edge2.x(), edge1.x() * edge2.y()} -
Vec4{edge1.z() * edge2.y(), edge1.x() * edge2.z(), edge1.y() * edge2.x()};
}
// that area is how much each UV factors into the final UV coord // that area is how much each UV factors into the final UV coord
// since the z and w component isn't used it's best to do this individually. (Where's that TODO on lower order vectors!!!) // since the z and w component isn't used it's best to do this individually. (Where's that TODO on lower order vectors!!!)

View File

@ -0,0 +1,82 @@
/*
* Created by Brett Terpstra 6920201 on 03/12/22.
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*/
#include <opencl/open_ray_tracing.h>
namespace Raytracing {
// we aren't sending the triangle AABB only the vertex information
constexpr size_t triangleNumOfBytes = sizeof(Triangle) - sizeof(AABB);
constexpr size_t aabbNumOfBytes = sizeof(AABB);
OpenClRaytracer::OpenClRaytracer(const std::string& programLocation, Image& image, World& world): image(image) {
auto objectsInWorld = world.getObjectsInWorld();
program = new CLProgram(programLocation);
OpenCL::createCLProgram(*program);
program->createKernel("raycast");
program->createImage("outputImage", image.getWidth(), image.getHeight());
size_t totalWorldBytes = 0;
for (auto* object: objectsInWorld) {
auto model = dynamic_cast<ModelObject*>(object);
if (model == nullptr)
continue;
auto triangles = model->getTriangles();
// non-model objects are not supported by the OpenCL renderer.
totalWorldBytes += triangles.size() * (triangleNumOfBytes);
// only add AABB bytes from model objects.
totalWorldBytes += aabbNumOfBytes;
}
program->createBuffer("objects", CL_MEM_READ_WRITE, totalWorldBytes);
storeObjects(objectsInWorld, totalWorldBytes);
program->setKernelArgument("raycast", "outputImage", 0);
program->setKernelArgument("raycast", "objects", 0);
}
OpenClRaytracer::~OpenClRaytracer() {
delete (program);
}
void OpenClRaytracer::storeObjects(const std::vector<Object*>& objects, size_t totalWorldBytes) {
size_t currentIndex = 0;
auto buffer = new unsigned char[totalWorldBytes];
for (auto* object: objects) {
auto model = dynamic_cast<ModelObject*>(object);
// we cannot write non-triangle based objects, as a result we will just pretend they don't exist.
if (model == nullptr)
continue;
auto triangles = model->getTriangles();
// write all the triangles from the model into the buffer
for (auto& triangle: triangles) {
// write vertex
MemoryConvert::writeVectorBytes(buffer, currentIndex, triangle->vertex1);
MemoryConvert::writeVectorBytes(buffer, currentIndex, triangle->vertex2);
MemoryConvert::writeVectorBytes(buffer, currentIndex, triangle->vertex3);
// next in the struct is normals
MemoryConvert::writeVectorBytes(buffer, currentIndex, triangle->normal1);
MemoryConvert::writeVectorBytes(buffer, currentIndex, triangle->normal2);
MemoryConvert::writeVectorBytes(buffer, currentIndex, triangle->normal3);
// finally the UVs
MemoryConvert::writeVectorBytes(buffer, currentIndex, triangle->uv1);
MemoryConvert::writeVectorBytes(buffer, currentIndex, triangle->uv2);
MemoryConvert::writeVectorBytes(buffer, currentIndex, triangle->uv3);
}
// finally we want to pack the object's AABB in. Just in case I have time to do a GPU BVH
MemoryConvert::writeVectorBytes(buffer, currentIndex, model->getAABB().getMin());
MemoryConvert::writeVectorBytes(buffer, currentIndex, model->getAABB().getMax());
}
// send the buffer to the GPU
program->writeBuffer("objects", totalWorldBytes, buffer);
delete[] buffer;
}
void OpenClRaytracer::run() {
size_t works[2]{(size_t) image.getWidth(), (size_t) image.getHeight()};
program->runKernel("raycast", works, localWorks, 2);
program->readImage("outputImage", image);
}
}