2012-01-06 16:09:03 +00:00
|
|
|
#include "dialogrender.h"
|
|
|
|
|
2012-06-15 09:31:11 +00:00
|
|
|
#include <math.h>
|
2012-01-06 16:09:03 +00:00
|
|
|
#include <QVBoxLayout>
|
|
|
|
#include <QImage>
|
|
|
|
#include <QColor>
|
|
|
|
#include <QPainter>
|
2012-06-15 09:31:11 +00:00
|
|
|
#include <QMessageBox>
|
2013-02-05 21:25:30 +00:00
|
|
|
#include <QFileDialog>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QListWidget>
|
|
|
|
#include <QPushButton>
|
2012-01-29 21:45:58 +00:00
|
|
|
#include "tools.h"
|
2012-01-06 16:09:03 +00:00
|
|
|
|
2013-10-29 20:28:59 +00:00
|
|
|
#include "Scenery.h"
|
2012-01-06 16:09:03 +00:00
|
|
|
|
|
|
|
static DialogRender* _current_dialog;
|
|
|
|
|
2012-01-29 21:45:58 +00:00
|
|
|
static void _renderStart(int width, int height, Color background)
|
2012-01-06 16:09:03 +00:00
|
|
|
{
|
2012-12-24 14:13:19 +00:00
|
|
|
_current_dialog->pixbuf_lock->lock();
|
2012-04-02 19:38:59 +00:00
|
|
|
delete _current_dialog->pixbuf;
|
|
|
|
_current_dialog->pixbuf = new QImage(width, height, QImage::Format_ARGB32);
|
2012-01-29 21:45:58 +00:00
|
|
|
_current_dialog->pixbuf->fill(colorToQColor(background).rgb());
|
2012-12-24 14:13:19 +00:00
|
|
|
_current_dialog->pixbuf_lock->unlock();
|
|
|
|
|
2012-06-13 20:38:01 +00:00
|
|
|
_current_dialog->tellRenderSize(width, height);
|
2012-01-06 16:09:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void _renderDraw(int x, int y, Color col)
|
|
|
|
{
|
2012-01-29 21:45:58 +00:00
|
|
|
_current_dialog->pixbuf->setPixel(x, _current_dialog->pixbuf->height() - 1 - y, colorToQColor(col).rgb());
|
2012-01-06 16:09:03 +00:00
|
|
|
}
|
|
|
|
|
2012-06-17 09:40:40 +00:00
|
|
|
static void _renderUpdate(double progress)
|
2012-01-06 16:09:03 +00:00
|
|
|
{
|
|
|
|
_current_dialog->area->update();
|
2012-06-15 09:31:11 +00:00
|
|
|
_current_dialog->tellProgressChange(progress);
|
2012-01-06 16:09:03 +00:00
|
|
|
}
|
|
|
|
|
2012-01-29 21:45:58 +00:00
|
|
|
class RenderThread:public QThread
|
|
|
|
{
|
|
|
|
public:
|
2013-02-06 16:08:46 +00:00
|
|
|
RenderThread(DialogRender* dialog, Renderer* renderer, RenderParams params):QThread()
|
2012-01-29 21:45:58 +00:00
|
|
|
{
|
2013-02-06 16:08:46 +00:00
|
|
|
_dialog = dialog;
|
2012-01-29 21:45:58 +00:00
|
|
|
_renderer = renderer;
|
2012-06-13 15:38:11 +00:00
|
|
|
_params = params;
|
2012-01-29 21:45:58 +00:00
|
|
|
}
|
|
|
|
void run()
|
|
|
|
{
|
2012-06-13 15:38:11 +00:00
|
|
|
rendererStart(_renderer, _params);
|
2013-02-06 16:08:46 +00:00
|
|
|
_dialog->tellRenderEnded();
|
2012-01-29 21:45:58 +00:00
|
|
|
}
|
|
|
|
private:
|
2013-02-06 16:08:46 +00:00
|
|
|
DialogRender* _dialog;
|
2012-01-29 21:45:58 +00:00
|
|
|
Renderer* _renderer;
|
2012-06-13 15:38:11 +00:00
|
|
|
RenderParams _params;
|
2012-01-29 21:45:58 +00:00
|
|
|
};
|
|
|
|
|
2013-08-21 21:22:13 +00:00
|
|
|
class _RenderArea:public QWidget
|
2012-01-06 16:09:03 +00:00
|
|
|
{
|
|
|
|
public:
|
2013-08-21 21:22:13 +00:00
|
|
|
_RenderArea(QWidget* parent):
|
2012-01-06 16:09:03 +00:00
|
|
|
QWidget(parent)
|
|
|
|
{
|
|
|
|
setMinimumSize(800, 600);
|
|
|
|
}
|
|
|
|
|
2012-11-24 14:19:43 +00:00
|
|
|
void paintEvent(QPaintEvent*)
|
2012-01-06 16:09:03 +00:00
|
|
|
{
|
|
|
|
QPainter painter(this);
|
2012-12-24 14:13:19 +00:00
|
|
|
_current_dialog->pixbuf_lock->lock();
|
2012-01-06 16:09:03 +00:00
|
|
|
painter.drawImage(0, 0, *_current_dialog->pixbuf);
|
2012-12-24 14:13:19 +00:00
|
|
|
_current_dialog->pixbuf_lock->unlock();
|
2012-01-06 16:09:03 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-04-02 19:38:59 +00:00
|
|
|
DialogRender::DialogRender(QWidget *parent, Renderer* renderer):
|
2012-01-26 18:20:19 +00:00
|
|
|
QDialog(parent, Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint)
|
2012-01-06 16:09:03 +00:00
|
|
|
{
|
2012-12-24 14:13:19 +00:00
|
|
|
pixbuf_lock = new QMutex();
|
2012-01-06 16:09:03 +00:00
|
|
|
pixbuf = new QImage(1, 1, QImage::Format_ARGB32);
|
|
|
|
_current_dialog = this;
|
2012-06-15 09:31:11 +00:00
|
|
|
_render_thread = NULL;
|
2012-04-02 19:38:59 +00:00
|
|
|
_renderer = renderer;
|
2012-12-24 14:13:19 +00:00
|
|
|
|
2012-01-06 16:09:03 +00:00
|
|
|
setModal(true);
|
2012-02-28 13:45:11 +00:00
|
|
|
setWindowTitle(tr("Paysages 3D - Render"));
|
2012-01-06 16:09:03 +00:00
|
|
|
setLayout(new QVBoxLayout());
|
|
|
|
|
2012-06-15 09:31:11 +00:00
|
|
|
_scroll = new QScrollArea(this);
|
|
|
|
_scroll->setAlignment(Qt::AlignCenter);
|
2013-08-21 21:22:13 +00:00
|
|
|
area = new _RenderArea(_scroll);
|
2012-06-15 09:31:11 +00:00
|
|
|
_scroll->setWidget(area);
|
|
|
|
layout()->addWidget(_scroll);
|
2012-12-24 14:13:19 +00:00
|
|
|
|
2013-02-05 21:25:30 +00:00
|
|
|
// Status bar
|
2012-06-15 09:31:11 +00:00
|
|
|
_info = new QWidget(this);
|
|
|
|
_info->setLayout(new QHBoxLayout());
|
|
|
|
layout()->addWidget(_info);
|
|
|
|
|
|
|
|
_timer = new QLabel(QString("0:00.00"), _info);
|
|
|
|
_info->layout()->addWidget(_timer);
|
2012-12-24 14:13:19 +00:00
|
|
|
|
2012-06-15 09:31:11 +00:00
|
|
|
_progress = new QProgressBar(_info);
|
|
|
|
_progress->setMaximumHeight(12);
|
|
|
|
_progress->setMinimum(0);
|
|
|
|
_progress->setMaximum(1000);
|
|
|
|
_progress->setValue(0);
|
|
|
|
_info->layout()->addWidget(_progress);
|
2012-12-24 14:13:19 +00:00
|
|
|
|
2013-02-05 21:25:30 +00:00
|
|
|
// Action bar
|
|
|
|
_actions = new QWidget(this);
|
|
|
|
_actions->setLayout(new QHBoxLayout());
|
|
|
|
layout()->addWidget(_actions);
|
|
|
|
|
|
|
|
_actions->layout()->addWidget(new QLabel(tr("Tone-mapping: "), _actions));
|
|
|
|
_tonemapping_control = new QComboBox(_actions);
|
|
|
|
_tonemapping_control->addItems(QStringList(tr("Uncharted")) << tr("Reinhard"));
|
|
|
|
_actions->layout()->addWidget(_tonemapping_control);
|
|
|
|
|
|
|
|
_actions->layout()->addWidget(new QLabel(tr("Exposure: "), _actions));
|
2013-02-06 16:08:46 +00:00
|
|
|
_actions->hide();
|
2013-02-05 21:25:30 +00:00
|
|
|
_exposure_control = new QSlider(Qt::Horizontal, _actions);
|
2013-02-06 16:08:46 +00:00
|
|
|
_exposure_control->setMinimumWidth(200);
|
2013-02-05 21:25:30 +00:00
|
|
|
_exposure_control->setRange(0, 1000);
|
|
|
|
_exposure_control->setValue(200);
|
|
|
|
_actions->layout()->addWidget(_exposure_control);
|
|
|
|
|
2013-04-17 12:29:51 +00:00
|
|
|
_save_button = new QPushButton(QIcon(getDataPath("images/save.png")), tr("Save picture"), _actions);
|
2013-02-05 21:25:30 +00:00
|
|
|
_actions->layout()->addWidget(_save_button);
|
|
|
|
|
|
|
|
// Connections
|
2013-06-01 15:10:00 +00:00
|
|
|
//connect(this, SIGNAL(renderSizeChanged(int, int)), this, SLOT(applyRenderSize(int, int)));
|
2012-06-17 09:40:40 +00:00
|
|
|
connect(this, SIGNAL(progressChanged(double)), this, SLOT(applyProgress(double)));
|
2013-02-06 16:08:46 +00:00
|
|
|
connect(this, SIGNAL(renderEnded()), this, SLOT(applyRenderEnded()));
|
2013-02-05 21:25:30 +00:00
|
|
|
connect(_save_button, SIGNAL(clicked()), this, SLOT(saveRender()));
|
|
|
|
connect(_tonemapping_control, SIGNAL(currentIndexChanged(int)), this, SLOT(toneMappingChanged()));
|
|
|
|
connect(_exposure_control, SIGNAL(valueChanged(int)), this, SLOT(toneMappingChanged()));
|
2012-01-18 16:20:14 +00:00
|
|
|
}
|
2012-01-06 16:09:03 +00:00
|
|
|
|
2012-01-25 17:31:36 +00:00
|
|
|
DialogRender::~DialogRender()
|
2012-01-18 16:20:14 +00:00
|
|
|
{
|
2012-06-15 09:31:11 +00:00
|
|
|
if (_render_thread)
|
2012-01-25 17:31:36 +00:00
|
|
|
{
|
2012-04-02 19:38:59 +00:00
|
|
|
rendererInterrupt(_renderer);
|
2012-06-15 09:31:11 +00:00
|
|
|
_render_thread->wait();
|
2012-01-25 17:31:36 +00:00
|
|
|
|
2012-06-15 09:31:11 +00:00
|
|
|
delete _render_thread;
|
2012-01-25 17:31:36 +00:00
|
|
|
}
|
|
|
|
delete pixbuf;
|
2012-12-24 14:13:19 +00:00
|
|
|
delete pixbuf_lock;
|
2012-01-25 17:31:36 +00:00
|
|
|
}
|
|
|
|
|
2012-06-13 20:38:01 +00:00
|
|
|
void DialogRender::tellRenderSize(int width, int height)
|
|
|
|
{
|
|
|
|
emit renderSizeChanged(width, height);
|
|
|
|
}
|
|
|
|
|
2012-06-17 09:40:40 +00:00
|
|
|
void DialogRender::tellProgressChange(double value)
|
2012-06-15 09:31:11 +00:00
|
|
|
{
|
|
|
|
emit progressChanged(value);
|
|
|
|
}
|
|
|
|
|
2013-02-06 16:08:46 +00:00
|
|
|
void DialogRender::tellRenderEnded()
|
|
|
|
{
|
|
|
|
emit renderEnded();
|
|
|
|
}
|
|
|
|
|
2012-06-13 15:38:11 +00:00
|
|
|
void DialogRender::startRender(RenderParams params)
|
2012-01-25 17:31:36 +00:00
|
|
|
{
|
2012-06-15 09:31:11 +00:00
|
|
|
_started = time(NULL);
|
2012-12-24 14:13:19 +00:00
|
|
|
|
2013-06-01 15:10:00 +00:00
|
|
|
applyRenderSize(params.width, params.height);
|
2012-04-02 19:38:59 +00:00
|
|
|
rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate);
|
2012-04-02 19:10:34 +00:00
|
|
|
|
2013-02-06 16:08:46 +00:00
|
|
|
_render_thread = new RenderThread(this, _renderer, params);
|
2012-06-15 09:31:11 +00:00
|
|
|
_render_thread->start();
|
2012-01-24 13:16:20 +00:00
|
|
|
|
2012-01-18 16:20:14 +00:00
|
|
|
exec();
|
2012-01-06 16:09:03 +00:00
|
|
|
}
|
2012-01-10 20:51:27 +00:00
|
|
|
|
2013-02-06 16:08:46 +00:00
|
|
|
void DialogRender::applyRenderEnded()
|
|
|
|
{
|
|
|
|
_info->hide();
|
|
|
|
_actions->show();
|
2013-06-11 16:09:14 +00:00
|
|
|
|
|
|
|
area->update();
|
2013-02-06 16:08:46 +00:00
|
|
|
}
|
|
|
|
|
2013-02-05 21:25:30 +00:00
|
|
|
void DialogRender::saveRender()
|
|
|
|
{
|
|
|
|
QString filepath;
|
|
|
|
|
|
|
|
filepath = QFileDialog::getSaveFileName(this, tr("Paysages 3D - Choose a filename to save the last render"), QString(), tr("Images (*.png *.jpg)"));
|
|
|
|
if (!filepath.isNull())
|
|
|
|
{
|
|
|
|
if (!filepath.toLower().endsWith(".jpg") && !filepath.toLower().endsWith(".jpeg") && !filepath.toLower().endsWith(".png"))
|
|
|
|
{
|
|
|
|
filepath = filepath.append(".png");
|
|
|
|
}
|
|
|
|
if (renderSaveToFile(_renderer->render_area, (char*)filepath.toStdString().c_str()))
|
|
|
|
{
|
|
|
|
QMessageBox::information(this, "Message", QString(tr("The picture %1 has been saved.")).arg(filepath));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
QMessageBox::critical(this, "Message", QString(tr("Can't write to file : %1")).arg(filepath));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DialogRender::toneMappingChanged()
|
|
|
|
{
|
|
|
|
renderSetToneMapping(_renderer->render_area, (ToneMappingOperator)_tonemapping_control->currentIndex(), ((double)_exposure_control->value()) * 0.01);
|
|
|
|
}
|
|
|
|
|
2012-01-18 16:20:14 +00:00
|
|
|
void DialogRender::loadLastRender()
|
2012-01-10 20:51:27 +00:00
|
|
|
{
|
2013-06-01 15:10:00 +00:00
|
|
|
applyRenderSize(_renderer->render_width, _renderer->render_height);
|
2012-04-02 19:38:59 +00:00
|
|
|
rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate);
|
2013-02-06 16:08:46 +00:00
|
|
|
renderEnded();
|
2013-06-01 15:10:00 +00:00
|
|
|
toneMappingChanged();
|
2012-01-24 13:16:20 +00:00
|
|
|
|
2012-01-18 16:20:14 +00:00
|
|
|
exec();
|
2012-01-10 20:51:27 +00:00
|
|
|
}
|
2012-04-02 19:38:59 +00:00
|
|
|
|
|
|
|
void DialogRender::applyRenderSize(int width, int height)
|
|
|
|
{
|
|
|
|
area->setMinimumSize(width, height);
|
|
|
|
area->setMaximumSize(width, height);
|
|
|
|
area->resize(width, height);
|
2012-06-15 09:31:11 +00:00
|
|
|
_scroll->setMinimumSize(width > 800 ? 820 : width + 20, height > 600 ? 620 : height + 20);
|
|
|
|
}
|
|
|
|
|
2012-06-17 09:40:40 +00:00
|
|
|
void DialogRender::applyProgress(double value)
|
2012-06-15 09:31:11 +00:00
|
|
|
{
|
|
|
|
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();
|
2012-04-02 19:38:59 +00:00
|
|
|
}
|
2012-06-15 09:31:11 +00:00
|
|
|
|