aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/config.hpp22
-rw-r--r--app/draw.cpp32
-rw-r--r--app/draw.hpp30
-rw-r--r--app/main.cpp48
-rw-r--r--app/mainwindow.cpp50
-rw-r--r--app/mainwindow.hpp34
-rw-r--r--app/rendercoord.cpp220
-rw-r--r--app/rendercoord.hpp93
8 files changed, 0 insertions, 529 deletions
diff --git a/app/config.hpp b/app/config.hpp
deleted file mode 100644
index 6e9962c..0000000
--- a/app/config.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef CONFIG_H
-#define CONFIG_H
-
-#include <render.hpp>
-
-class Config {
- public:
- unsigned m_width, m_height;
- unsigned m_maxhops, m_samples;
-
- unsigned m_framerate, m_workers;
-};
-
-class RendererConf : public Renderer {
- public:
- RendererConf(const Scene &scn, Vec3d eye, Vec3d target, Config &conf)
- : Renderer(scn, eye, target, conf.m_width, conf.m_height, conf.m_maxhops) {
-
- }
-};
-
-#endif
diff --git a/app/draw.cpp b/app/draw.cpp
deleted file mode 100644
index 88733ef..0000000
--- a/app/draw.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "draw.hpp"
-#include <qnamespace.h>
-#include <qpainter.h>
-#include <qglobal.h>
-#include <qimage.h>
-#include <qrgb.h>
-#include <qtimer.h>
-#include <qwindowdefs.h>
-#include <iostream>
-
-DrawWidget::DrawWidget(const Config &conf) :
- QWidget(), m_conf(conf) {
- m_drawbuffer = new QRgb[conf.m_width * conf.m_height];
-
- m_img = QImage((uchar*)m_drawbuffer, conf.m_width, conf.m_height, QImage::Format_ARGB32);
-
-}
-
-void DrawWidget::paintEvent(QPaintEvent*) {
- QPainter painter(this);
-
- auto scaled = m_img.scaled(width(), height(), Qt::KeepAspectRatio);
- painter.drawImage(0, 0, scaled);
-}
-
-void DrawWidget::redraw() {
- repaint();
-}
-
-DrawWidget::~DrawWidget() {
- delete[] m_drawbuffer;
-}
diff --git a/app/draw.hpp b/app/draw.hpp
deleted file mode 100644
index 454558c..0000000
--- a/app/draw.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef DRAW_H
-#define DRAW_H
-
-#include "config.hpp"
-#include <qimage.h>
-#include <qtimer.h>
-#include <qwidget.h>
-
-class DrawWidget : public QWidget {
- Q_OBJECT
-
- public:
- DrawWidget(const Config &conf);
- void paintEvent(QPaintEvent*);
-
- QRgb *m_drawbuffer;
- QImage m_img;
- unsigned m_width, m_height;
-
- ~DrawWidget();
- private slots:
- void redraw();
-
- private:
- unsigned char i;
-
- const Config &m_conf;
-};
-
-#endif
diff --git a/app/main.cpp b/app/main.cpp
deleted file mode 100644
index e53b8ad..0000000
--- a/app/main.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <iostream>
-#include <qapplication.h>
-#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;
- Config conf;
- conf.m_width = 500;
- conf.m_height = 500;
- conf.m_maxhops = 5;
- conf.m_samples = 100;
- conf.m_framerate = 3;
- conf.m_workers = 4;
-
-
- Material blue(Color(0.3, 0.3, 1), 1);
- Material red(Color(1, 0.3, 0.3), 1);
- Material white(Color(1, 1, 1), 1);
- Material em(Color(1, 1, 1), 0, 2);
-
- scn.addShape(new Sphere(red, Vec3d(2, 6, -1), 1));
- scn.addShape(new Sphere(white, Vec3d(0, 4, -1), 1.3));
- scn.addShape(new Sphere(white, Vec3d(-2, 5, -2), 1.3));
- scn.addShape(new Sphere(blue, Vec3d(0, 7, 0), 0.5));
-
- scn.addShape(new Plane(em, Vec3d(0, 0, 0), Vec3d(0, 1, 0)));
- scn.addShape(new Plane(white, Vec3d(0, 10, 0), Vec3d(0, 1, 0)));
- scn.addShape(new Plane(white, Vec3d(0, 0, -5), Vec3d(0, 0, 1)));
- scn.addShape(new Plane(red, Vec3d(-5, 0, 0), Vec3d(1, 0, 0)));
- scn.addShape(new Plane(blue, Vec3d(5, 0, 0), Vec3d(1, 0, 0)));
-
- RendererConf render(scn, Vec3d(0, 5, 4), Vec3d(0, 5, 0), conf);
-
- MainWindow main(render, conf);
- main.show();
-
- return a.exec();
-}
diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp
deleted file mode 100644
index eed98f9..0000000
--- a/app/mainwindow.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#include "mainwindow.hpp"
-#include <qaction.h>
-#include <qapplication.h>
-#include <qlabel.h>
-#include <qnamespace.h>
-#include <QFileDialog>
-#include <QMessageBox>
-
-MainWindow::MainWindow(Renderer r, const Config &conf)
- : m_drawer(conf),
- runstatus("Not running", this),
- m_render(this, m_drawer, r, conf, &runstatus),
- m_conf(conf)
-{
-
- setCentralWidget(&m_drawer);
-
- auto saveAct = new QAction(tr("&Save as"), this);
- saveAct->setStatusTip(tr("Save the rendered image"));
- connect(saveAct, &QAction::triggered, this, &MainWindow::saveimage);
-
- auto stopAct = new QAction(tr("&Stop"), this);
- stopAct->setStatusTip(tr("Stop and sync threads"));
- QObject::connect(stopAct, &QAction::triggered, &m_render, &RenderCoordinator::stop);
-
- fileMenu = menuBar()->addMenu(tr("&File"));
- fileMenu->addAction(saveAct);
-
- fileMenu = menuBar()->addMenu(tr("&Render"));
- fileMenu->addAction(stopAct);
-
- helpMenu = menuBar()->addMenu(tr("&Help"));
- helpMenu->addAction(tr("About Qt"), qApp, &QApplication::aboutQt);
-
- statusBar()->addWidget(&runstatus);
-}
-
-void MainWindow::saveimage() {
-
- QGuiApplication::setOverrideCursor(Qt::WaitCursor);
- QString fileName = QFileDialog::getSaveFileName(this,
- tr("Save image"), "", tr("PNG image (*.png);;All Files (*)"));
- if (fileName.isEmpty()) {
- return;
- }
-
- if (!m_drawer.m_img.save(fileName)) {
- QMessageBox::information(this, tr("Unable to save file"), "");
- }
-}
diff --git a/app/mainwindow.hpp b/app/mainwindow.hpp
deleted file mode 100644
index ffb4f08..0000000
--- a/app/mainwindow.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef MAIN_H
-#define MAIN_H
-
-#include <QMainWindow>
-#include <QLabel>
-#include <QMenuBar>
-#include <QStatusBar>
-
-#include "config.hpp"
-#include "draw.hpp"
-#include "rendercoord.hpp"
-#include <qmainwindow.h>
-#include <render.hpp>
-
-class MainWindow : public QMainWindow {
- Q_OBJECT
-
- public:
- MainWindow(Renderer r, const Config &conf);
-
- private slots:
- void saveimage();
- private:
- DrawWidget m_drawer;
- QLabel runstatus;
- RenderCoordinator m_render;
-
- QMenu *fileMenu;
- QMenu *helpMenu;
-
- const Config &m_conf;
-};
-
-#endif
diff --git a/app/rendercoord.cpp b/app/rendercoord.cpp
deleted file mode 100644
index 00a6437..0000000
--- a/app/rendercoord.cpp
+++ /dev/null
@@ -1,220 +0,0 @@
-#include "rendercoord.hpp"
-#include <algorithm>
-#include <qobject.h>
-#include <iostream>
-#include <qrgb.h>
-
-#include <qsemaphore.h>
-#include <render.hpp>
-#include <sstream>
-
-uint32_t colorToUint32(const Color &c) {
- Color cnew = Color(c);
- cnew.clamp();
- return (0xFF << 24) +
- (cnew.r() << 16) +
- (cnew.g() << 8) +
- cnew.b();
-}
-
-// Run by main thread
-RenderThread::RenderThread(Renderer r, unsigned threads, const Config &conf, QObject *parent, unsigned id)
- : QThread(parent),
- m_lock(1),
- m_render(r),
- m_conf(conf),
- m_pause(1)
-{
- m_id = id;
- m_workers = threads;
-}
-
-// Run on new thread
-void RenderThread::run() {
- while (1) {
- // Wait for work
- m_work.acquire();
-
- // Very expensive, but necesary to get live rendering
- Color *sum = new Color[m_render.m_width * m_render.m_height];
-
- m_current_samples = 0;
-
- for (int sample = 0; sample < m_samples; sample++) {
- m_current_samples = sample;
- // Probably not that smart
- m_pause.acquire();
- m_pause.release();
-
- for (unsigned y = m_id; y < m_render.m_height; y += m_workers) {
- for (unsigned x = 0; x < m_render.m_width; x++) {
- auto index = x + y * m_render.m_width;
- sum[index] += m_render.render(m_render.m_width - x, m_render.m_height - y, 1);
-
- m_writebuffer[index] = colorToUint32(sum[index] / (sample+1));
- }
- }
-
- }
-
- // Signal done
- m_lock.release();
- emit done(m_id);
- }
-}
-
-void RenderThread::pause() {
- m_pause.acquire();
-}
-
-void RenderThread::resume() {
- m_pause.release();
-}
-
-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();
- std::cout << samples << std::endl;
-
- return 0;
-}
-
-unsigned RenderThread::stop() {
- stopAt(m_current_samples);
- return m_current_samples;
-}
-
-void RenderThread::stopAt(int at) {
- m_samples = at;
-}
-
-// Running on main thread
-unsigned RenderThread::current_samples() {
- // No sync should not be a problem here.
- return m_current_samples;
-}
-
-RenderCoordinator::RenderCoordinator(QObject *parent, DrawWidget &target, Renderer r, const Config &conf, QLabel *status)
- : QObject(parent),
- m_target(target),
- m_renderer(r),
- m_timer(this),
- m_conf(conf)
-{
- m_status = status;
-
- // Create and start workers
- for (unsigned i = 0; i < conf.m_workers; i++) {
- auto thread = new RenderThread(m_renderer, conf.m_workers, conf, this, i);
-
- thread->start();
- QObject::connect(thread, &RenderThread::done, this, &RenderCoordinator::workerDone);
-
- m_workers.push_back(thread);
- }
-
- render();
-
-}
-
-void RenderCoordinator::render() {
- m_started = 0;
- for (auto thd : m_workers) {
- thd->render(m_target.m_drawbuffer, m_conf.m_samples);
- m_started++;
- }
-
- m_state = running;
- updateUi();
-
- QObject::connect(&m_timer, &QTimer::timeout, this, &RenderCoordinator::updateUi);
-
- m_timer.start(1000.0 / m_conf.m_framerate);
-}
-
-void RenderCoordinator::stop() {
- unsigned max = 0;
- for (auto thd : m_workers) {
- thd->pause();
-
- auto val = thd->current_samples();
- if (val>max) {
- max = val;
- }
- }
-
- std::cout << max << std::endl;
-
- for (auto thd : m_workers) {
- thd->stopAt(max+1);
- thd->resume();
- }
-
- m_state = stopping;
- updateUi();
-}
-
-void RenderCoordinator::workerDone(unsigned workerid) {
- std::cout << "Worker " << workerid << " done!" << std::endl;
- if (--m_started) {
- return;
- }
- std::cout << "All done :-)" << std::endl;
-
- // All workers are done
- m_state = stopped;
- m_timer.stop();
- updateUi();
-}
-
-unsigned RenderCoordinator::calcStats(unsigned *max, unsigned *min, double *avg) {
- unsigned count = 0;
- unsigned sum = 0;
- for (auto thd : m_workers) {
- auto val = thd->current_samples();
- if (min && (val < *min || !count)) {
- *min = val;
- }
- if (max && (val > *max || !count)) {
- *max = val;
- }
-
- sum += val;
- count++;
- }
-
- if (avg) {
- *avg = (double)sum / count;
- }
-
- return count;
-}
-
-
-void RenderCoordinator::updateUi() {
- m_target.repaint();
-
- if (!m_status) {
- return;
- }
-
- // Gather statictics from workers
- unsigned max;
- unsigned min;
- double avg;
- unsigned count = calcStats(&max, &min, &avg);
-
- std::ostringstream status;
- status << states[m_state] <<
- " Threads: " << count <<
- " Max: " << max << " samples" <<
- " Min: " << min << " samples" <<
- " Avg: " << avg << " samples";
-
- m_status->setText(QString::fromStdString(status.str()));
-}
diff --git a/app/rendercoord.hpp b/app/rendercoord.hpp
deleted file mode 100644
index eea1b40..0000000
--- a/app/rendercoord.hpp
+++ /dev/null
@@ -1,93 +0,0 @@
-#ifndef RENDER_THREAD_H
-#define RENDER_THREAD_H
-
-#include "draw.hpp"
-#include "config.hpp"
-#include <atomic>
-#include <qlabel.h>
-#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, unsigned threads, const Config &cfg, QObject *parent = nullptr, unsigned id = 0);
-
- // Returns 0 if successful or 1 if busy
- int render(QRgb *buffer, unsigned samples);
-
- void pause();
- void resume();
-
- unsigned stop();
- void stopAt(int at);
-
- unsigned current_samples();
-
- signals:
- void done(unsigned workerid);
-
- protected:
- void run();
-
- QSemaphore m_lock;
-
- QRgb *m_writebuffer;
- std::atomic_int m_samples;
- std::atomic_int m_current_samples;
-
- Renderer m_render;
-
- unsigned m_workers;
-
- Config const m_conf;
-
- // Value in here means work is to be done
- QSemaphore m_work;
- QSemaphore m_pause;
- unsigned m_id;
-};
-
-const std::string states[] = { "Stopped", "Running", "Stopping" };
-enum State { stopped, running, stopping };
-
-class RenderCoordinator : public QObject {
- Q_OBJECT
-
- public:
- RenderCoordinator(QObject *parent, DrawWidget &target, Renderer r, const Config &conf, QLabel *status=nullptr);
- void setSamples(unsigned samples);
- void render();
-
- public slots:
- void workerDone(unsigned workerid);
- void stop();
-
- private slots:
- void updateUi();
-
- private:
- unsigned calcStats(unsigned *max, unsigned *min, double *avg);
-
- DrawWidget &m_target;
-
- Renderer m_renderer;
- std::vector<RenderThread*> m_workers;
- unsigned m_started;
-
- QLabel *m_status;
- QTimer m_timer;
-
- State m_state;
-
- const Config &m_conf;
-};
-
-#endif