Basic scene loop
This commit is contained in:
+18
-17
@@ -16,25 +16,23 @@ ThreadPool::~ThreadPool()
|
|||||||
std::unique_lock l(queueLock);
|
std::unique_lock l(queueLock);
|
||||||
queueCV.notify_all();
|
queueCV.notify_all();
|
||||||
}
|
}
|
||||||
for(auto& worker : workers)
|
for (auto& worker : workers)
|
||||||
{
|
{
|
||||||
worker.join();
|
worker.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadPool::addJob(std::function<void()>&& job)
|
void ThreadPool::runBatch(Batch&& batch)
|
||||||
{
|
{
|
||||||
std::unique_lock l(queueLock);
|
|
||||||
taskQueue.push_back(job);
|
|
||||||
queueCV.notify_one();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadPool::waitIdle()
|
|
||||||
{
|
|
||||||
while(true)
|
|
||||||
{
|
{
|
||||||
std::unique_lock l(queueLock);
|
std::unique_lock l(queueLock);
|
||||||
if(taskQueue.empty())
|
taskQueue.push_back(batch);
|
||||||
|
queueCV.notify_one();
|
||||||
|
}
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
std::unique_lock l(queueLock);
|
||||||
|
if (taskQueue.empty())
|
||||||
return;
|
return;
|
||||||
completedCV.wait(l);
|
completedCV.wait(l);
|
||||||
}
|
}
|
||||||
@@ -42,24 +40,27 @@ void ThreadPool::waitIdle()
|
|||||||
|
|
||||||
void ThreadPool::work()
|
void ThreadPool::work()
|
||||||
{
|
{
|
||||||
while(running)
|
while (running)
|
||||||
{
|
{
|
||||||
std::function<void()> job;
|
std::function<void()> job;
|
||||||
{
|
{
|
||||||
std::unique_lock l(queueLock);
|
std::unique_lock l(queueLock);
|
||||||
if(taskQueue.empty())
|
if (taskQueue.front().jobs.empty())
|
||||||
{
|
{
|
||||||
queueCV.wait(l);
|
queueCV.wait(l);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
job = taskQueue.front();
|
job = taskQueue.front().jobs.front();
|
||||||
taskQueue.pop_front();
|
taskQueue.front().jobs.pop_front();
|
||||||
}
|
}
|
||||||
job();
|
job();
|
||||||
{
|
{
|
||||||
std::unique_lock l(queueLock);
|
std::unique_lock l(queueLock);
|
||||||
completedCV.notify_one();
|
if (taskQueue.front().jobs.empty())
|
||||||
|
{
|
||||||
|
taskQueue.pop_front();
|
||||||
|
completedCV.notify_one();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-3
@@ -4,19 +4,23 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
struct Batch
|
||||||
|
{
|
||||||
|
std::list<std::function<void()>> jobs;
|
||||||
|
};
|
||||||
|
|
||||||
class ThreadPool
|
class ThreadPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ThreadPool(uint32_t numWorkers = std::thread::hardware_concurrency());
|
ThreadPool(uint32_t numWorkers = std::thread::hardware_concurrency());
|
||||||
~ThreadPool();
|
~ThreadPool();
|
||||||
void addJob(std::function<void()>&& job);
|
void runBatch(Batch&& batch);
|
||||||
void waitIdle();
|
|
||||||
private:
|
private:
|
||||||
std::atomic_bool running = true;
|
std::atomic_bool running = true;
|
||||||
void work();
|
void work();
|
||||||
std::mutex queueLock;
|
std::mutex queueLock;
|
||||||
std::condition_variable queueCV;
|
std::condition_variable queueCV;
|
||||||
std::condition_variable completedCV;
|
std::condition_variable completedCV;
|
||||||
std::list<std::function<void()>> taskQueue;
|
std::list<Batch> taskQueue;
|
||||||
std::vector<std::thread> workers;
|
std::vector<std::thread> workers;
|
||||||
};
|
};
|
||||||
+12
-6
@@ -1,18 +1,24 @@
|
|||||||
#include "scene/BVH.h"
|
#include "scene/BVH.h"
|
||||||
|
#include "scene/Scene.h"
|
||||||
#include "util/ModelLoader.h"
|
#include "util/ModelLoader.h"
|
||||||
#include "window/Window.h"
|
#include "window/Window.h"
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
Scene scene;
|
Scene scene;
|
||||||
Window window;
|
Window window(1920, 1080);
|
||||||
|
scene.render(
|
||||||
|
Camera{
|
||||||
|
.position = glm::vec3(10, 0, 0),
|
||||||
|
.direction = glm::vec3(-1, 0, 0),
|
||||||
|
},
|
||||||
|
RenderParameter{
|
||||||
|
.width = 1920,
|
||||||
|
.height = 1080,
|
||||||
|
.numSamples = 10000,
|
||||||
|
});
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
// IMGUI....
|
|
||||||
if (Imgui.Button())
|
|
||||||
{
|
|
||||||
scene.render();
|
|
||||||
}
|
|
||||||
window.update(scene.getImage());
|
window.update(scene.getImage());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+22
-16
@@ -1,34 +1,40 @@
|
|||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
|
|
||||||
Scene::Scene(glm::vec3 cameraPos, glm::vec3 cameraDirection) : cameraPos(cameraPos), cameraDirection(cameraDirection) {}
|
Scene::Scene() {}
|
||||||
|
|
||||||
Scene::~Scene() {}
|
Scene::~Scene() {}
|
||||||
|
|
||||||
void Scene::render(int width, int height, int numSamples)
|
void Scene::render(Camera cam, RenderParameter params)
|
||||||
{
|
{
|
||||||
|
pendingCancel = true;
|
||||||
|
worker.join();
|
||||||
|
pendingCancel = false;
|
||||||
worker = std::thread(
|
worker = std::thread(
|
||||||
[&]()
|
[&]()
|
||||||
{
|
{
|
||||||
image.clear();
|
image.clear();
|
||||||
accumulator.clear();
|
accumulator.clear();
|
||||||
image.resize(width * height * 3);
|
image.resize(params.width * params.height * 3);
|
||||||
for (int samp = 0; samp < numSamples; ++samp)
|
accumulator.resize(params.width * params.height * 3);
|
||||||
|
for (int samp = 0; samp < params.numSamples; ++samp)
|
||||||
{
|
{
|
||||||
std::function<void()> job = [&]()
|
if (pendingCancel)
|
||||||
|
return;
|
||||||
|
Batch batch;
|
||||||
|
for (int w = 0; w < params.width; ++w)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> localAccumulator(width * height * 3);
|
for (int h = 0; h < params.height; ++h)
|
||||||
for (int w = 0; w < width; ++w)
|
|
||||||
{
|
{
|
||||||
for (int h = 0; h < height; ++h)
|
batch.jobs.push_back(
|
||||||
{
|
[&]()
|
||||||
if (cancel)
|
{
|
||||||
return;
|
Ray r = Ray();
|
||||||
bvh.traceRay();
|
bvh.traceRay(r);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
// lock image
|
}
|
||||||
// add result to image
|
threadPool.runBatch(std::move(batch));
|
||||||
};
|
std::memcpy(image.data(), accumulator.data(), accumulator.size());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-12
@@ -2,26 +2,26 @@
|
|||||||
#include "BVH.h"
|
#include "BVH.h"
|
||||||
#include "window/Window.h"
|
#include "window/Window.h"
|
||||||
#include "util/Camera.h"
|
#include "util/Camera.h"
|
||||||
|
#include "ThreadPool.h"
|
||||||
|
|
||||||
|
struct RenderParameter
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int numSamples;
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ray1
|
|
||||||
/// Ray2
|
|
||||||
/// Ray3
|
|
||||||
/// Ray4
|
|
||||||
/// Ray5
|
|
||||||
/// GammaResolve
|
|
||||||
/// Ray1
|
|
||||||
/// Ray2
|
|
||||||
/// Ray3
|
|
||||||
/// </summary>
|
|
||||||
class Scene
|
class Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Scene();
|
Scene();
|
||||||
~Scene();
|
~Scene();
|
||||||
void render(Camera cam, int width, int height, int numSamples);
|
void render(Camera cam, RenderParameter params);
|
||||||
constexpr const std::vector<unsigned char>& getImage() const { return image; }
|
constexpr const std::vector<unsigned char>& getImage() const { return image; }
|
||||||
private:
|
private:
|
||||||
|
std::atomic_bool pendingCancel = false;
|
||||||
|
ThreadPool threadPool;
|
||||||
|
std::thread worker;
|
||||||
// the thing being displayed
|
// the thing being displayed
|
||||||
std::vector<unsigned char> image;
|
std::vector<unsigned char> image;
|
||||||
// radiance accumulator
|
// radiance accumulator
|
||||||
|
|||||||
Reference in New Issue
Block a user