diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/draw.cpp | 6 | ||||
-rw-r--r-- | app/draw.hpp | 4 | ||||
-rw-r--r-- | app/mainwindow.cpp | 32 | ||||
-rw-r--r-- | app/mainwindow.hpp | 10 | ||||
-rw-r--r-- | app/rendercoord.cpp | 45 | ||||
-rw-r--r-- | app/rendercoord.hpp | 16 |
6 files changed, 98 insertions, 15 deletions
diff --git a/app/draw.cpp b/app/draw.cpp index 469b469..b3187be 100644 --- a/app/draw.cpp +++ b/app/draw.cpp @@ -7,16 +7,12 @@ #include <qwindowdefs.h> #include <iostream> -DrawWidget::DrawWidget(unsigned width, unsigned height) : QWidget(), m_timer(this) { +DrawWidget::DrawWidget(unsigned width, unsigned height) : QWidget() { m_width = width; m_height = height; m_drawbuffer = new QRgb[width * height]; m_img = QImage((uchar*)m_drawbuffer, width, height, QImage::Format_ARGB32); - - QObject::connect(&m_timer, &QTimer::timeout, this, &DrawWidget::redraw); - - m_timer.start(500); } void DrawWidget::paintEvent(QPaintEvent*) { diff --git a/app/draw.hpp b/app/draw.hpp index f8e93a4..cee5734 100644 --- a/app/draw.hpp +++ b/app/draw.hpp @@ -13,6 +13,7 @@ class DrawWidget : public QWidget { void paintEvent(QPaintEvent*); QRgb *m_drawbuffer; + QImage m_img; unsigned m_width, m_height; ~DrawWidget(); @@ -20,10 +21,7 @@ class DrawWidget : public QWidget { void redraw(); private: - QImage m_img; unsigned char i; - - QTimer m_timer; }; #endif diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp index 3077168..a365f38 100644 --- a/app/mainwindow.cpp +++ b/app/mainwindow.cpp @@ -1,12 +1,42 @@ #include "mainwindow.hpp" +#include <qaction.h> +#include <qapplication.h> +#include <qlabel.h> +#include <qnamespace.h> +#include <QFileDialog> +#include <QMessageBox> MainWindow::MainWindow(Renderer r) : m_drawer(500, 500), - m_render(this, m_drawer, r) + runstatus("Not running", this), + m_render(this, m_drawer, r, &runstatus) { 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); + fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(saveAct); + 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 index 7e356a0..b2566f4 100644 --- a/app/mainwindow.hpp +++ b/app/mainwindow.hpp @@ -2,9 +2,13 @@ #define MAIN_H #include <QMainWindow> +#include <QLabel> +#include <QMenuBar> +#include <QStatusBar> #include "draw.hpp" #include "rendercoord.hpp" +#include <qmainwindow.h> #include <render.hpp> class MainWindow : public QMainWindow { @@ -13,9 +17,15 @@ class MainWindow : public QMainWindow { public: MainWindow(Renderer r); + private slots: + void saveimage(); private: DrawWidget m_drawer; + QLabel runstatus; RenderCoordinator m_render; + + QMenu *fileMenu; + QMenu *helpMenu; }; #endif diff --git a/app/rendercoord.cpp b/app/rendercoord.cpp index 9c59acd..a5a3da5 100644 --- a/app/rendercoord.cpp +++ b/app/rendercoord.cpp @@ -4,6 +4,7 @@ #include <qrgb.h> #include <render.hpp> +#include <sstream> uint32_t colorToUint32(const Color &c) { Color cnew = Color(c); @@ -28,11 +29,12 @@ void RenderThread::run() { while (1) { // Wait for work m_work.acquire(); - m_render.m_sampler.seed(100); // 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 (unsigned sample = 1; sample < m_samples+1; sample++) { for (unsigned x = 0; x < m_render.m_width; x++) { for (unsigned y = 0; y < m_render.m_height; y++) { @@ -42,6 +44,8 @@ void RenderThread::run() { m_writebuffer[index] = colorToUint32(sum[index] / sample); } } + + m_current_samples = sample; } // Signal done @@ -58,15 +62,25 @@ int RenderThread::render(QRgb *buffer, unsigned samples) { m_writebuffer = buffer; m_samples = samples; m_work.release(); + return 0; } -RenderCoordinator::RenderCoordinator(QObject *parent, DrawWidget &target, Renderer r) +// 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, QLabel *status) : QObject(parent), m_target(target), m_renderer(r), - m_worker(m_renderer, this) + m_worker(m_renderer, this), + m_timer(this) { + m_status = status; + m_worker.start(); QObject::connect(&m_worker, &RenderThread::done, @@ -74,10 +88,31 @@ RenderCoordinator::RenderCoordinator(QObject *parent, DrawWidget &target, Render m_worker.render(target.m_drawbuffer, 100); + m_state = running; + updateUi(); + + QObject::connect(&m_timer, &QTimer::timeout, this, &RenderCoordinator::updateUi); + + m_timer.start(500); + } void RenderCoordinator::workerDone(unsigned workerid) { - std::cout << workerid << " done!" << std::endl; - m_target.repaint(); + m_state = stopped; + m_timer.stop(); + updateUi(); } + +void RenderCoordinator::updateUi() { + m_target.repaint(); + + if (!m_status) { + return; + } + + std::ostringstream status; + status << states[m_state] << " " << m_worker.current_samples() << " samples"; + + m_status->setText(QString::fromStdString(status.str())); +} diff --git a/app/rendercoord.hpp b/app/rendercoord.hpp index 6aa8698..113b4dc 100644 --- a/app/rendercoord.hpp +++ b/app/rendercoord.hpp @@ -2,6 +2,7 @@ #define RENDER_THREAD_H #include "draw.hpp" +#include <qlabel.h> #include <render.hpp> #include <qobject.h> @@ -19,6 +20,7 @@ class RenderThread : public QThread { // Returns 0 if successful or 1 if busy int render(QRgb *buffer, unsigned samples); + unsigned current_samples(); signals: void done(unsigned workerid); @@ -30,6 +32,7 @@ class RenderThread : public QThread { QRgb *m_writebuffer; unsigned m_samples; + unsigned m_current_samples; Renderer m_render; @@ -38,23 +41,34 @@ class RenderThread : public QThread { unsigned m_id; }; +const std::string states[] = { "Stopped", "Running" }; +enum State { stopped, running }; + class RenderCoordinator : public QObject { Q_OBJECT public: - RenderCoordinator(QObject *parent, DrawWidget &target, Renderer r); + RenderCoordinator(QObject *parent, DrawWidget &target, Renderer r, QLabel *status=nullptr); void setSamples(unsigned samples); void render(); public slots: void workerDone(unsigned workerid); + private slots: + void updateUi(); + private: DrawWidget &m_target; Renderer m_renderer; RenderThread m_worker; + QLabel *m_status; + QTimer m_timer; + + State m_state; + unsigned m_samples; }; |