Restored (partially) render progress
This commit is contained in:
parent
18a669675f
commit
14e0320848
4 changed files with 38 additions and 34 deletions
|
@ -116,11 +116,6 @@ DialogRender::~DialogRender()
|
||||||
delete pixbuf_lock;
|
delete pixbuf_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogRender::tellProgressChange(double value)
|
|
||||||
{
|
|
||||||
emit progressChanged(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogRender::tellRenderEnded()
|
void DialogRender::tellRenderEnded()
|
||||||
{
|
{
|
||||||
emit renderEnded();
|
emit renderEnded();
|
||||||
|
@ -133,6 +128,8 @@ void DialogRender::startRender()
|
||||||
_render_thread = new RenderThread(this, canvas_renderer);
|
_render_thread = new RenderThread(this, canvas_renderer);
|
||||||
_render_thread->start();
|
_render_thread->start();
|
||||||
|
|
||||||
|
startTimer(100);
|
||||||
|
|
||||||
exec();
|
exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,14 +176,15 @@ void DialogRender::loadLastRender()
|
||||||
exec();
|
exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogRender::applyProgress(double value)
|
void DialogRender::timerEvent(QTimerEvent *)
|
||||||
{
|
{
|
||||||
double diff = difftime(time(NULL), _started);
|
double diff = difftime(time(NULL), _started);
|
||||||
int hours = (int)floor(diff / 3600.0);
|
int hours = (int)floor(diff / 3600.0);
|
||||||
int minutes = (int)floor((diff - 3600.0 * hours) / 60.0);
|
int minutes = (int)floor((diff - 3600.0 * hours) / 60.0);
|
||||||
int seconds = (int)floor(diff - 3600.0 * hours - 60.0 * minutes);
|
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')));
|
_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->setValue((int)(canvas_renderer->getProgress() * 1000.0));
|
||||||
_progress->update();
|
_progress->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,25 +18,24 @@ class DialogRender : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit DialogRender(QWidget *parent, SoftwareCanvasRenderer* renderer);
|
explicit DialogRender(QWidget *parent, SoftwareCanvasRenderer *renderer);
|
||||||
~DialogRender();
|
~DialogRender();
|
||||||
|
|
||||||
void tellProgressChange(double value);
|
|
||||||
void tellRenderEnded();
|
void tellRenderEnded();
|
||||||
void startRender();
|
void startRender();
|
||||||
void loadLastRender();
|
void loadLastRender();
|
||||||
|
|
||||||
|
virtual void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
QImage* pixbuf;
|
QImage* pixbuf;
|
||||||
QMutex* pixbuf_lock;
|
QMutex* pixbuf_lock;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void applyProgress(double value);
|
|
||||||
void saveRender();
|
void saveRender();
|
||||||
void applyRenderEnded();
|
void applyRenderEnded();
|
||||||
void toneMappingChanged();
|
void toneMappingChanged();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void progressChanged(double value);
|
|
||||||
void renderEnded();
|
void renderEnded();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -17,6 +17,7 @@ SoftwareCanvasRenderer::SoftwareCanvasRenderer()
|
||||||
started = false;
|
started = false;
|
||||||
interrupted = false;
|
interrupted = false;
|
||||||
canvas = new Canvas();
|
canvas = new Canvas();
|
||||||
|
progress = 0.0;
|
||||||
|
|
||||||
rasterizers.push_back(new SkyRasterizer(this, 0));
|
rasterizers.push_back(new SkyRasterizer(this, 0));
|
||||||
rasterizers.push_back(new WaterRasterizer(this, 1));
|
rasterizers.push_back(new WaterRasterizer(this, 1));
|
||||||
|
@ -55,6 +56,7 @@ void SoftwareCanvasRenderer::setSize(int width, int height, int samples)
|
||||||
void SoftwareCanvasRenderer::render()
|
void SoftwareCanvasRenderer::render()
|
||||||
{
|
{
|
||||||
started = true;
|
started = true;
|
||||||
|
progress = 0.0;
|
||||||
|
|
||||||
render_camera->setRenderSize(canvas->getWidth(), canvas->getHeight());
|
render_camera->setRenderSize(canvas->getWidth(), canvas->getHeight());
|
||||||
|
|
||||||
|
@ -63,6 +65,8 @@ void SoftwareCanvasRenderer::render()
|
||||||
// Iterate portions
|
// Iterate portions
|
||||||
int nx = canvas->getHorizontalPortionCount();
|
int nx = canvas->getHorizontalPortionCount();
|
||||||
int ny = canvas->getVerticalPortionCount();
|
int ny = canvas->getVerticalPortionCount();
|
||||||
|
int i = 0;
|
||||||
|
int n = nx * ny;
|
||||||
for (int y = 0; y < ny; y++)
|
for (int y = 0; y < ny; y++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < nx; x++)
|
for (int x = 0; x < nx; x++)
|
||||||
|
@ -71,16 +75,20 @@ void SoftwareCanvasRenderer::render()
|
||||||
|
|
||||||
if (not interrupted)
|
if (not interrupted)
|
||||||
{
|
{
|
||||||
|
progress_segment = 0.2 / (double)n;
|
||||||
portion->preparePixels();
|
portion->preparePixels();
|
||||||
rasterize(portion, true);
|
rasterize(portion);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not interrupted)
|
if (not interrupted)
|
||||||
{
|
{
|
||||||
applyPixelShader(portion, true);
|
progress_segment = 0.8 / (double)n;
|
||||||
|
applyPixelShader(portion);
|
||||||
}
|
}
|
||||||
|
|
||||||
portion->discardPixels();
|
portion->discardPixels();
|
||||||
|
i++;
|
||||||
|
progress = (double)i / (double)n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,31 +101,27 @@ void SoftwareCanvasRenderer::interrupt()
|
||||||
{
|
{
|
||||||
current_work->interrupt();
|
current_work->interrupt();
|
||||||
}
|
}
|
||||||
for (auto &rasterizer:getRasterizers())
|
for (auto &rasterizer:rasterizers)
|
||||||
{
|
{
|
||||||
rasterizer->interrupt();
|
rasterizer->interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Rasterizer *> &SoftwareCanvasRenderer::getRasterizers() const
|
|
||||||
{
|
|
||||||
return rasterizers;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Rasterizer &SoftwareCanvasRenderer::getRasterizer(int client_id) const
|
const Rasterizer &SoftwareCanvasRenderer::getRasterizer(int client_id) const
|
||||||
{
|
{
|
||||||
return *(getRasterizers()[client_id]);
|
return *(rasterizers[client_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareCanvasRenderer::rasterize(CanvasPortion *portion, bool threaded)
|
void SoftwareCanvasRenderer::rasterize(CanvasPortion *portion)
|
||||||
{
|
{
|
||||||
for (auto &rasterizer:getRasterizers())
|
for (auto &rasterizer:rasterizers)
|
||||||
{
|
{
|
||||||
rasterizer->rasterizeToCanvas(portion);
|
rasterizer->rasterizeToCanvas(portion);
|
||||||
|
progress += progress_segment / (double)rasterizers.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareCanvasRenderer::applyPixelShader(CanvasPortion *portion, bool threaded)
|
void SoftwareCanvasRenderer::applyPixelShader(CanvasPortion *portion)
|
||||||
{
|
{
|
||||||
// Subdivide in chunks
|
// Subdivide in chunks
|
||||||
int chunk_size = 64;
|
int chunk_size = 64;
|
||||||
|
@ -125,6 +129,13 @@ void SoftwareCanvasRenderer::applyPixelShader(CanvasPortion *portion, bool threa
|
||||||
int chunks_y = (portion->getHeight() - 1) / chunk_size + 1;
|
int chunks_y = (portion->getHeight() - 1) / chunk_size + 1;
|
||||||
int units = chunks_x * chunks_y;
|
int units = chunks_x * chunks_y;
|
||||||
|
|
||||||
|
// Estimate chunks
|
||||||
|
int n = 0;
|
||||||
|
for (int sub_chunk_size = chunk_size; sub_chunk_size >= 1; sub_chunk_size /= 2)
|
||||||
|
{
|
||||||
|
n += chunk_size / sub_chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
// Render chunks in parallel
|
// Render chunks in parallel
|
||||||
for (int sub_chunk_size = chunk_size; sub_chunk_size >= 1; sub_chunk_size /= 2)
|
for (int sub_chunk_size = chunk_size; sub_chunk_size >= 1; sub_chunk_size /= 2)
|
||||||
{
|
{
|
||||||
|
@ -139,5 +150,6 @@ void SoftwareCanvasRenderer::applyPixelShader(CanvasPortion *portion, bool threa
|
||||||
current_work = &work;
|
current_work = &work;
|
||||||
work.perform();
|
work.perform();
|
||||||
current_work = NULL;
|
current_work = NULL;
|
||||||
|
progress += progress_segment * (double)(chunk_size / sub_chunk_size) / (double)n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ public:
|
||||||
virtual ~SoftwareCanvasRenderer();
|
virtual ~SoftwareCanvasRenderer();
|
||||||
|
|
||||||
inline const Canvas *getCanvas() const {return canvas;}
|
inline const Canvas *getCanvas() const {return canvas;}
|
||||||
|
inline double getProgress() const {return progress;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the renderer configuration.
|
* Set the renderer configuration.
|
||||||
|
@ -46,11 +47,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void interrupt();
|
void interrupt();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the list of objects that can be rasterized to polygons on a canvas.
|
|
||||||
*/
|
|
||||||
virtual const std::vector<Rasterizer*> &getRasterizers() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a rasterizer by its client id.
|
* Get a rasterizer by its client id.
|
||||||
*/
|
*/
|
||||||
|
@ -59,19 +55,18 @@ public:
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief Rasterize the scenery into a canvas portion.
|
* @brief Rasterize the scenery into a canvas portion.
|
||||||
*
|
|
||||||
* If 'threaded' is true, the rasterization will take advantage of multiple CPU cores.
|
|
||||||
*/
|
*/
|
||||||
void rasterize(CanvasPortion *portion, bool threaded=false);
|
void rasterize(CanvasPortion *portion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Apply pixel shader to fragments stored in the CanvasPortion.
|
* @brief Apply pixel shader to fragments stored in the CanvasPortion.
|
||||||
*
|
|
||||||
* If 'threaded' is true, the shader will take advantage of multiple CPU cores.
|
|
||||||
*/
|
*/
|
||||||
void applyPixelShader(CanvasPortion *portion, bool threaded=true);
|
void applyPixelShader(CanvasPortion *portion);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
double progress;
|
||||||
|
double progress_segment;
|
||||||
|
|
||||||
Canvas *canvas;
|
Canvas *canvas;
|
||||||
std::vector<Rasterizer*> rasterizers;
|
std::vector<Rasterizer*> rasterizers;
|
||||||
bool started;
|
bool started;
|
||||||
|
|
Loading…
Reference in a new issue