#include "dialogrender.h" #include #include #include #include #include #include #include "tools.h" #include "../lib_paysages/scenery.h" #include "../lib_paysages/auto.h" static DialogRender* _current_dialog; static void _renderStart(int width, int height, Color background) { delete _current_dialog->pixbuf; _current_dialog->pixbuf = new QImage(width, height, QImage::Format_ARGB32); _current_dialog->pixbuf->fill(colorToQColor(background).rgb()); _current_dialog->tellRenderSize(width, height); } static void _renderDraw(int x, int y, Color col) { _current_dialog->pixbuf->setPixel(x, _current_dialog->pixbuf->height() - 1 - y, colorToQColor(col).rgb()); } static void _renderUpdate(float progress) { _current_dialog->area->update(); _current_dialog->tellProgressChange(progress); } class RenderThread:public QThread { public: RenderThread(Renderer* renderer, RenderParams params):QThread() { _renderer = renderer; _params = params; } void run() { rendererStart(_renderer, _params); } private: Renderer* _renderer; RenderParams _params; }; class RenderArea:public QWidget { public: RenderArea(QWidget* parent): QWidget(parent) { setMinimumSize(800, 600); } void paintEvent(QPaintEvent* event) { QPainter painter(this); painter.drawImage(0, 0, *_current_dialog->pixbuf); } }; DialogRender::DialogRender(QWidget *parent, Renderer* renderer): QDialog(parent, Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint) { pixbuf = new QImage(1, 1, QImage::Format_ARGB32); _current_dialog = this; _render_thread = NULL; _renderer = renderer; setModal(true); setWindowTitle(tr("Paysages 3D - Render")); setLayout(new QVBoxLayout()); _scroll = new QScrollArea(this); _scroll->setAlignment(Qt::AlignCenter); area = new RenderArea(_scroll); _scroll->setWidget(area); layout()->addWidget(_scroll); _info = new QWidget(this); _info->setLayout(new QHBoxLayout()); layout()->addWidget(_info); _timer = new QLabel(QString("0:00.00"), _info); _info->layout()->addWidget(_timer); _progress = new QProgressBar(_info); _progress->setMaximumHeight(12); _progress->setMinimum(0); _progress->setMaximum(1000); _progress->setValue(0); _info->layout()->addWidget(_progress); connect(this, SIGNAL(renderSizeChanged(int, int)), this, SLOT(applyRenderSize(int, int))); connect(this, SIGNAL(progressChanged(float)), this, SLOT(applyProgress(float))); } DialogRender::~DialogRender() { if (_render_thread) { rendererInterrupt(_renderer); _render_thread->wait(); delete _render_thread; } delete pixbuf; } void DialogRender::tellRenderSize(int width, int height) { emit renderSizeChanged(width, height); } void DialogRender::tellProgressChange(float value) { emit progressChanged(value); } void DialogRender::startRender(RenderParams params) { _started = time(NULL); //applyRenderSize(params.width, params.height); rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate); _render_thread = new RenderThread(_renderer, params); _render_thread->start(); exec(); } void DialogRender::loadLastRender() { //applyRenderSize(_renderer->render_width, _renderer->render_height); _info->hide(); rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate); exec(); } void DialogRender::applyRenderSize(int width, int height) { area->setMinimumSize(width, height); area->setMaximumSize(width, height); area->resize(width, height); _scroll->setMinimumSize(width > 800 ? 820 : width + 20, height > 600 ? 620 : height + 20); } void DialogRender::applyProgress(float value) { double diff = difftime(time(NULL), _started); int hours = (int)floor(diff / 3600.0); int minutes = (int)floor((diff - 3600.0 * hours) / 60.0); int seconds = (int)floor(diff - 3600.0 * hours - 60.0 * minutes); _timer->setText(tr("%1:%2.%3").arg(hours).arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0'))); _progress->setValue((int)(value * 1000.0)); _progress->update(); }