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_BEFORE_RPAR" value="true" />
<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="SPACE_BEFORE_INIT_LIST_COLON" 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_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
@ -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
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
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

View File

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

View File

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

View File

@ -135,7 +135,8 @@
9,
10,
11,
12
12,
13
]
}
],
@ -209,7 +210,8 @@
9,
10,
11,
12
12,
13
]
}
],
@ -292,6 +294,12 @@
"compileGroupIndex" : 0,
"path" : "src/opencl/cl.cpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "src/opencl/open_ray_tracing.cpp",
"sourceGroupIndex" : 0
}
],
"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_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
@ -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
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
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

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 normal1, normal2, normal3;
Vec4 uv1, uv2, uv3;
bool hasNormals = false;
AABB aabb;
Triangle(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& n3): vertex1(v1), vertex2(v2), vertex3(v3),
uv1(uv1), uv2(uv2), uv3(uv3),
hasNormals(true), normal1(n1), normal2(n2), normal3(n3) {}
Triangle(
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& n3
): vertex1(v1), vertex2(v2), vertex3(v3), uv1(uv1), uv2(uv2), uv3(uv3), normal1(n1), normal2(n2), normal3(n3) {}
};
// face type for model loading

View File

@ -13,9 +13,12 @@
#include "types.h"
#include <config.h>
#ifdef COMPILE_GUI
#include "graphics/gl/shader.h"
#include "graphics/debug_gui.h"
#endif
#include <utility>
@ -39,11 +42,11 @@ namespace Raytracing {
public:
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
TriangulatedModel model {data};
TriangulatedModel model{data};
this->triangles = model.triangles;
this->aabb = std::move(model.aabb);
std::vector<TriangleBVHObject> triangulatedObjects;
for (const auto& tri : triangles){
for (const auto& tri: triangles) {
TriangleBVHObject triangleObject;
triangleObject.tri = tri;
triangleObject.aabb = tri->aabb;
@ -51,11 +54,15 @@ namespace Raytracing {
triangulatedObjects.push_back(triangleObject);
}
triangleBVH = std::make_unique<TriangleBVHTree>(triangulatedObjects);
#ifdef COMPILE_GUI
#ifdef COMPILE_GUI
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;
};
@ -92,7 +99,9 @@ namespace Raytracing {
class LightMaterial : public Material {
public:
explicit LightMaterial(const Vec4& lightColor): Material(lightColor) {}
[[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;
};
@ -104,6 +113,7 @@ namespace Raytracing {
explicit TexturedMaterial(const std::string& file);
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
[[nodiscard]] Vec4 getColor(PRECISION_TYPE u, PRECISION_TYPE v) const;
~TexturedMaterial();
@ -116,6 +126,7 @@ namespace Raytracing {
Shader& worldShader;
explicit WorldConfig(Shader& shader): worldShader(shader) {}
#endif
};
@ -128,16 +139,21 @@ namespace Raytracing {
WorldConfig m_config;
public:
explicit World(WorldConfig config): m_config(config) {};
World(const World& world) = delete;
World(const World&& world) = delete;
// 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();
#ifdef COMPILE_GUI
#ifdef COMPILE_GUI
// currently disabled. TODO: BVH renderer class
void drawBVH(Shader& worldShader) {}
#endif
#endif
inline void add(Object* object) {
objects.push_back(object);
@ -150,10 +166,13 @@ namespace Raytracing {
inline void add(const std::string& materialName, Material* mat) { materials.insert({materialName, mat}); }
inline Material* getMaterial(const std::string& materialName) { return materials.at(materialName); }
[[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;
~World();
};

View File

@ -12,11 +12,6 @@
#include <engine/image/image.h>
#include <config.h>
#ifdef COMPILE_GUI
#endif
#include <engine/util/std.h>
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
* 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}
* 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
* @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)

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 <chrono>
#include "engine/util/debug.h"
#include "opencl/open_ray_tracing.h"
#include <config.h>
#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");
// not implemented yet
parser.addOption("--multi", "Enable Multi-threading\n"
parser.addOption(
"--multi", "Enable Multi-threading\n"
"\tUse multiple threads for ray tracing,\n"
"\tYou can set the max threads using -t or --threads\n");
parser.addOption({{"-t"},
"\tYou can set the max threads using -t or --threads\n"
);
parser.addOption(
{{"-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");
"\tDefaults to all cores of your cpu.\n", "0"
);
// not implemented yet
parser.addOption({{"--gui"},
parser.addOption(
{{"--gui"},
{"-g"}}, "Enable GUI\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");
"\tRequires the you compile with the option -DCOMPILE_GUI=ON. Will do nothing otherwise\n"
);
// not implemented yet
parser.addOption({{"--gpu"},
parser.addOption(
{{"--gpu"},
{"-c"}}, "Enables GPU Compute\n"
"\tWill use OpenCL compute to render the image\n");
parser.addOption("--output", "Output Directory\n"
"\tSet the output directory for the rendered image. Defaults to the local directory.\n", "./");
parser.addOption("--format", "Output Format\n"
"\tSets the output format to BMP, PNG, or JPEG. \n", "PNG");
parser.addOption("-w", "Image Width\n"
"\tSets the width of the output image.\n", "1440");
parser.addOption("-h", "Image Height\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"
"\tWill use OpenCL compute to render the image\n"
);
parser.addOption(
"--output", "Output Directory\n"
"\tSet the output directory for the rendered image. Defaults to the local directory.\n", "./"
);
parser.addOption(
"--format", "Output Format\n"
"\tSets the output format to BMP, PNG, or JPEG. \n", "PNG"
);
parser.addOption(
"-w", "Image Width\n"
"\tSets the width of the output image.\n", "1440"
);
parser.addOption(
"-h", "Image Height\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");
"\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
//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))
return 0;
if (signal(SIGTERM, [](int sig) -> void {
if (signal(
SIGTERM, [](int sig) -> void {
ilog << "Computations complete.\nHalting now...\n";
RTSignal->haltExecution = true;
}) == SIG_ERR) {
}
) == SIG_ERR) {
elog << "Unable to change signal handler.\n";
return 1;
}
if (signal(SIGINT, [](int sig) -> void {
if (signal(
SIGINT, [](int sig) -> void {
ilog << "Computations complete.\nHalting now...\n";
RTSignal->haltExecution = true;
}) == SIG_ERR) {
}
) == SIG_ERR) {
elog << "Unable to change signal handler.\n";
return 1;
}
@ -179,24 +208,16 @@ int main(int argc, char** args) {
Raytracing::RayCaster rayCaster{camera, image, world, parser};
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");
Raytracing::DisplayRenderer renderer{*window, mainImage, world, shader, worldShader, rayCaster, parser, camera};
while (!window->shouldWindowClose()) {
window->beginUpdate();
renderer.draw();
program.runKernel("drawImage", works, localWorks, 2);
program.readImage("mainImage", image);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
world.drawBVH(worldShader);

View File

@ -146,6 +146,7 @@ namespace Raytracing {
return {true, Ray{hitData.hitPoint, newRay}, getColor(hitData.u, hitData.v)};
}
Vec4 TexturedMaterial::getColor(PRECISION_TYPE u, PRECISION_TYPE v) const {
// if we are unable to load the image return the debug color.
if (!data)
@ -169,6 +170,7 @@ namespace Raytracing {
return {pixelData[0] * colorFactor, pixelData[1] * colorFactor, pixelData[2] * colorFactor};
}
TexturedMaterial::TexturedMaterial(const std::string& file): Material({}) {
// we are going to have to ignore transparency for now. TODO:?
data = stbi_load(file.c_str(), &width, &height, &channels, 0);
@ -177,13 +179,16 @@ namespace Raytracing {
else
ilog << "Loaded image " << file << " with " << width << " " << height << " " << channels << "!\n";
}
TexturedMaterial::~TexturedMaterial() {
stbi_image_free(data);
}
ScatterResults LightMaterial::scatter(const Ray& ray, const HitData& hitData) const {
// do not scatter. The light emits.
return {false, ray, baseColor};
}
Vec4 LightMaterial::emission(PRECISION_TYPE u, PRECISION_TYPE v, const Vec4& hitPoint) const {
return baseColor;
}
@ -246,20 +251,9 @@ namespace Raytracing {
auto areaVert2 = areaVert2Vec.magnitude() * fullArea;
auto areaVert3 = areaVert3Vec.magnitude() * fullArea;
// normal = theTriangle.findClosestNormal(rayIntersectionPoint - position);
if (theTriangle.hasNormals) {
// returning the closest normal is extra computation when n1 would likely be fine.
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()};
}
// since we are calculating UV coords, the hard interpolation part is already done.
// so use said calculation to determine the overall normal based on the 3 individual vertexes
normal = theTriangle.normal1 * areaVert1 + theTriangle.normal2 * areaVert2 + theTriangle.normal3 * areaVert3;
// 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!!!)

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);
}
}