diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0c915d9..3fba944 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,9 @@ target_sources(RayTracer PRIVATE - main.cpp) + main.cpp + Minimal.h + ThreadPool.h + ThreadPool.cpp) add_subdirectory(scene/) add_subdirectory(window/) diff --git a/src/ThreadPool.cpp b/src/ThreadPool.cpp new file mode 100644 index 0000000..7a3f3e4 --- /dev/null +++ b/src/ThreadPool.cpp @@ -0,0 +1,65 @@ +#include "ThreadPool.h" +#include + +ThreadPool::ThreadPool(uint32_t numThreads) +{ + for (uint32_t i = 0; i < numThreads; ++i) + { + workers.push_back(std::thread(&ThreadPool::work, this)); + } +} + +ThreadPool::~ThreadPool() +{ + running.store(false); + { + std::unique_lock l(queueLock); + queueCV.notify_all(); + } + for(auto& worker : workers) + { + worker.join(); + } +} + +void ThreadPool::addJob(std::function&& job) +{ + std::unique_lock l(queueLock); + taskQueue.push_back(job); + queueCV.notify_one(); +} + +void ThreadPool::waitIdle() +{ + while(true) + { + std::unique_lock l(queueLock); + if(taskQueue.empty()) + return; + completedCV.wait(l); + } +} + +void ThreadPool::work() +{ + while(running) + { + std::function job; + { + std::unique_lock l(queueLock); + if(taskQueue.empty()) + { + queueCV.wait(l); + continue; + } + job = taskQueue.front(); + taskQueue.pop_front(); + } + job(); + { + std::unique_lock l(queueLock); + completedCV.notify_one(); + } + } +} + diff --git a/src/ThreadPool.h b/src/ThreadPool.h new file mode 100644 index 0000000..1aaea19 --- /dev/null +++ b/src/ThreadPool.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include +#include +#include + +class ThreadPool +{ +public: + ThreadPool(uint32_t numWorkers = std::thread::hardware_concurrency()); + ~ThreadPool(); + void addJob(std::function&& job); + void waitIdle(); +private: + std::atomic_bool running = true; + void work(); + std::mutex queueLock; + std::condition_variable queueCV; + std::condition_variable completedCV; + std::list> taskQueue; + std::vector workers; +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 02e2172..78051bf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,7 +9,7 @@ int main() bvh.generate(); Window w(1920, 1080); std::vector texture(1920 * 1080 * 3); - for (int j = 10; j < 100; ++j) + for (int j = 100; j < 200; ++j) { for (int i = 0; i < 1920; ++i) { diff --git a/src/scene/AABB.h b/src/scene/AABB.h index 6aed089..e0f9c5a 100644 --- a/src/scene/AABB.h +++ b/src/scene/AABB.h @@ -2,6 +2,7 @@ #include #include #include +#include "util/Ray.h" struct AABB { @@ -42,6 +43,11 @@ struct AABB max = glm::vec3(std::max(max.x, transformed.x), std::max(max.y, transformed.y), std::max(max.z, transformed.z)); } } + bool intersects(Ray ray) + { + assert(false && "TODO"); + return false; + } static AABB combine(AABB lhs, AABB rhs) { AABB result = { diff --git a/src/scene/BVH.cpp b/src/scene/BVH.cpp index f3f9542..6379e6c 100644 --- a/src/scene/BVH.cpp +++ b/src/scene/BVH.cpp @@ -1,5 +1,6 @@ #include "BVH.h" -#include +#include +#include void BVH::addModel(PModel model, glm::mat4 transform) { @@ -54,3 +55,35 @@ void BVH::generate() } hierarchy = std::move(pendingNodes[0]); } + +std::optional BVH::traceRay(Ray ray) +{ +} + +std::vector BVH::generateIntersections(PNode& currentNode, Ray ray) +{ + if(!currentNode->aabb.intersects(ray)) + { + return {}; + } + if(currentNode->model != nullptr) + { + auto result = currentNode->model->intersect(ray); + if(result.has_value()) + { + return {*result}; + } + else + { + return {}; + } + } + auto leftResults = generateIntersections(currentNode->left, ray); + auto rightResults = generateIntersections(currentNode->right, ray); + + for(auto it : rightResults) + { + leftResults.push_back(it); + } + return leftResults; +} \ No newline at end of file diff --git a/src/scene/BVH.h b/src/scene/BVH.h index 1c258cb..8f27686 100644 --- a/src/scene/BVH.h +++ b/src/scene/BVH.h @@ -3,6 +3,8 @@ #include "util/Model.h" #include #include +#include "util/Ray.h" + class BVH { @@ -11,6 +13,8 @@ class BVH void addModels(std::vector models, glm::mat4 transform); void generate(); + std::optional traceRay(Ray ray); + private: DECLARE_REF(Node) struct Node @@ -24,4 +28,6 @@ class BVH }; PNode hierarchy; std::vector models; + + std::vector generateIntersections(PNode& currentNode, Ray ray); }; \ No newline at end of file diff --git a/src/scene/Scene.cpp b/src/scene/Scene.cpp index 7e0ed7c..99ffeae 100644 --- a/src/scene/Scene.cpp +++ b/src/scene/Scene.cpp @@ -1,3 +1,9 @@ #include "Scene.h" +Scene::Scene() + : window(1920, 1080) +{ + +} + void Scene::render() {} diff --git a/src/scene/Scene.h b/src/scene/Scene.h index 066c874..e99dce6 100644 --- a/src/scene/Scene.h +++ b/src/scene/Scene.h @@ -5,9 +5,11 @@ class Scene { public: + Scene(); + ~Scene(); void render(); private: Window window; - std::vector image; + std::vector image; BVH bvh; }; \ No newline at end of file diff --git a/src/util/Model.cpp b/src/util/Model.cpp index e69de29..59833a9 100644 --- a/src/util/Model.cpp +++ b/src/util/Model.cpp @@ -0,0 +1,6 @@ +#include "Model.h" + +std::optional Model::intersect(Ray ray) +{ + return {}; +} \ No newline at end of file diff --git a/src/util/Model.h b/src/util/Model.h index 8d884d4..c08bfd4 100644 --- a/src/util/Model.h +++ b/src/util/Model.h @@ -3,11 +3,24 @@ #include "scene/AABB.h" #include +// material infos +// shading parameter +// hit data +struct IntersectionInfo +{ + float t; + glm::vec3 position; + glm::vec3 normal; + glm::vec3 albedo; + glm::vec3 emissive; + //.... +}; class Model { public: AABB boundingBox; std::vector positions; std::vector indices; + std::optional intersect(Ray ray); }; DECLARE_REF(Model) \ No newline at end of file diff --git a/src/window/Window.cpp b/src/window/Window.cpp index 529bc11..189166d 100644 --- a/src/window/Window.cpp +++ b/src/window/Window.cpp @@ -18,18 +18,8 @@ Window::Window(int width, int height) : width(width), height(height) glBindVertexArray(vao); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); - std::vector texture(1920 * 1080 * 4); - for (int j = 0; j < 1080; ++j) - { - for (int i = 0; i < 1920; ++i) - { - texture[(j * 1920 + i) * 3] = 0xff; - texture[(j * 1920 + i) * 3 + 1] = 0xff; - texture[(j * 1920 + i) * 3 + 2] = 0x0; - texture[(j * 1920 + i) * 3 + 2] = 0xff; - } - } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture.data()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); program = glCreateProgram(); vertShader = glCreateShader(GL_VERTEX_SHADER); fragShader = glCreateShader(GL_FRAGMENT_SHADER); @@ -90,7 +80,7 @@ void Window::update(const std::vector& textureData) { glClear(GL_COLOR_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, texture); - //glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, textureData.data()); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, textureData.data()); glUseProgram(program); glDrawArrays(GL_TRIANGLES, 0, 3); glfwSwapBuffers(window);