diff options
author | Julian T <julian@jtle.dk> | 2020-08-06 19:21:49 +0200 |
---|---|---|
committer | Julian T <julian@jtle.dk> | 2020-08-06 19:22:37 +0200 |
commit | 4348cc9581bfea05359485c5d2d074132d0271da (patch) | |
tree | 0c6d92a90ac4cf9acd326f632dcdc962ddca013a /app | |
parent | 893176a0b18a2281abe09def716ccc3db5583c3f (diff) |
Renders scenes with a single hardcoded light and green objects
Diffstat (limited to 'app')
-rw-r--r-- | app/draw.hpp | 2 | ||||
-rw-r--r-- | app/main.cpp | 19 | ||||
-rw-r--r-- | app/mainwindow.cpp | 10 | ||||
-rw-r--r-- | app/mainwindow.hpp | 8 | ||||
-rw-r--r-- | app/rendercoord.cpp | 75 | ||||
-rw-r--r-- | app/rendercoord.hpp | 61 |
6 files changed, 168 insertions, 7 deletions
diff --git a/app/draw.hpp b/app/draw.hpp index a00de79..41d5d9c 100644 --- a/app/draw.hpp +++ b/app/draw.hpp @@ -5,6 +5,8 @@ #include <qwidget.h> class DrawWidget : public QWidget { + Q_OBJECT + public: DrawWidget(unsigned width, unsigned height); void paintEvent(QPaintEvent*); diff --git a/app/main.cpp b/app/main.cpp index 15262f2..64e413a 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -3,14 +3,31 @@ #include <qpushbutton.h> #include "mainwindow.hpp" +#include "vector.hpp" +#include <scene.hpp> +#include <render.hpp> +#include <object.hpp> using namespace std; int main(int argc, char *argv[]) { QApplication a(argc, argv); + Scene scn; + scn.addShape(new Sphere(Vec3d(2, 6, -1), 1)); + scn.addShape(new Sphere(Vec3d(0, 4, -1), 1.3)); + scn.addShape(new Sphere(Vec3d(-2, 5, -2), 1.3)); + //scn.addShape(new Sphere(Vec3d(0, 7, 0), 0.5)); - MainWindow main; + scn.addShape(new Plane(Vec3d(0, 0, 0), Vec3d(0, 1, 0))); + scn.addShape(new Plane(Vec3d(0, 10, 0), Vec3d(0, 1, 0))); + scn.addShape(new Plane(Vec3d(0, 0, -5), Vec3d(0, 0, 1))); + scn.addShape(new Plane(Vec3d(-5, 0, 0), Vec3d(1, 0, 0))); + scn.addShape(new Plane(Vec3d(5, 0, 0), Vec3d(1, 0, 0))); + + Renderer render(scn, Vec3d(0, 5, 4), Vec3d(0, 5, 0), 500, 500); + + MainWindow main(render); main.show(); return a.exec(); diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp index e5f9bfb..3077168 100644 --- a/app/mainwindow.cpp +++ b/app/mainwindow.cpp @@ -1,8 +1,12 @@ #include "mainwindow.hpp" -MainWindow::MainWindow() - : drawer(500, 500) { +MainWindow::MainWindow(Renderer r) + : m_drawer(500, 500), + m_render(this, m_drawer, r) +{ + + setCentralWidget(&m_drawer); + - setCentralWidget(&drawer); } diff --git a/app/mainwindow.hpp b/app/mainwindow.hpp index a6c1be3..7e356a0 100644 --- a/app/mainwindow.hpp +++ b/app/mainwindow.hpp @@ -4,16 +4,18 @@ #include <QMainWindow> #include "draw.hpp" +#include "rendercoord.hpp" +#include <render.hpp> class MainWindow : public QMainWindow { Q_OBJECT public: - MainWindow(); + MainWindow(Renderer r); private: - DrawWidget drawer; - + DrawWidget m_drawer; + RenderCoordinator m_render; }; #endif diff --git a/app/rendercoord.cpp b/app/rendercoord.cpp new file mode 100644 index 0000000..8db7c97 --- /dev/null +++ b/app/rendercoord.cpp @@ -0,0 +1,75 @@ +#include "rendercoord.hpp" +#include <qobject.h> +#include <iostream> +#include <qrgb.h> + +#include <render.hpp> + +uint32_t colorToUint32(Color &c) { + c.clamp(); + return (0xFF << 24) + + (c.r() << 16) + + (c.g() << 8) + + c.b(); +} + +// Run by main thread +RenderThread::RenderThread(Renderer r, QObject *parent, unsigned id) + : QThread(parent), + m_lock(1), + m_render(r) +{ + m_id = id; +} + +// Run on new thread +void RenderThread::run() { + while (1) { + // Wait for work + m_work.acquire(); + + for (unsigned x = 0; x < m_render.m_width; x++) { + for (unsigned y = 0; y < m_render.m_height; y++) { + auto c = m_render.render(x, y); + m_writebuffer[x + y * m_render.m_height] = + static_cast<QRgb>(colorToUint32(c)); + } + } + + // Signal done + m_lock.release(); + emit done(m_id); + } +} + +int RenderThread::render(QRgb *buffer, unsigned samples) { + // Check if already running + if (!m_lock.tryAcquire()) { + return 1; + } + m_writebuffer = buffer; + m_samples = samples; + m_work.release(); + return 0; +} + +RenderCoordinator::RenderCoordinator(QObject *parent, DrawWidget &target, Renderer r) + : QObject(parent), + m_target(target), + m_renderer(r), + m_worker(m_renderer, this) +{ + m_worker.start(); + + QObject::connect(&m_worker, &RenderThread::done, + this, &RenderCoordinator::workerDone); + + m_worker.render(target.m_drawbuffer, 1); + +} + +void RenderCoordinator::workerDone(unsigned workerid) { + std::cout << workerid << " done!" << std::endl; + m_target.repaint(); +} + diff --git a/app/rendercoord.hpp b/app/rendercoord.hpp new file mode 100644 index 0000000..6aa8698 --- /dev/null +++ b/app/rendercoord.hpp @@ -0,0 +1,61 @@ +#ifndef RENDER_THREAD_H +#define RENDER_THREAD_H + +#include "draw.hpp" +#include <render.hpp> + +#include <qobject.h> +#include <qrgb.h> +#include <qthread.h> +#include <qsemaphore.h> +#include <vector> +// https://doc.qt.io/archives/qt-4.8/qt-threads-mandelbrot-example.html + +class RenderThread : public QThread { + Q_OBJECT + + public: + RenderThread(Renderer r, QObject *parent = nullptr, unsigned id = 0); + + // Returns 0 if successful or 1 if busy + int render(QRgb *buffer, unsigned samples); + + signals: + void done(unsigned workerid); + + protected: + void run(); + + QSemaphore m_lock; + + QRgb *m_writebuffer; + unsigned m_samples; + + Renderer m_render; + + // Value in here means work is to be done + QSemaphore m_work; + unsigned m_id; +}; + +class RenderCoordinator : public QObject { + Q_OBJECT + + public: + RenderCoordinator(QObject *parent, DrawWidget &target, Renderer r); + void setSamples(unsigned samples); + void render(); + + public slots: + void workerDone(unsigned workerid); + + private: + DrawWidget &m_target; + + Renderer m_renderer; + RenderThread m_worker; + + unsigned m_samples; +}; + +#endif |