aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2020-08-06 19:21:49 +0200
committerJulian T <julian@jtle.dk>2020-08-06 19:22:37 +0200
commit4348cc9581bfea05359485c5d2d074132d0271da (patch)
tree0c6d92a90ac4cf9acd326f632dcdc962ddca013a /app
parent893176a0b18a2281abe09def716ccc3db5583c3f (diff)
Renders scenes with a single hardcoded light and green objects
Diffstat (limited to 'app')
-rw-r--r--app/draw.hpp2
-rw-r--r--app/main.cpp19
-rw-r--r--app/mainwindow.cpp10
-rw-r--r--app/mainwindow.hpp8
-rw-r--r--app/rendercoord.cpp75
-rw-r--r--app/rendercoord.hpp61
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