paysages: Threaded previews (WIP).
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@310 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
79e687bd09
commit
5cd3c5b506
8 changed files with 363 additions and 196 deletions
2
TODO
2
TODO
|
@ -10,7 +10,7 @@ Technology Preview 2 :
|
|||
- Add a noise filler (and maybe noise intervals ?).
|
||||
- Improve curve editor.
|
||||
- Water and terrain LOD moves with the camera, fix it like in the wanderer.
|
||||
- More threading in previews and layered previews (with a less detailed layer in the background).
|
||||
- There should not have to be more preview threads than core.
|
||||
|
||||
Technology Preview 3 :
|
||||
- Restore render progress.
|
||||
|
|
|
@ -170,7 +170,6 @@ void BaseForm::addPreview(BasePreview* preview, QString label)
|
|||
previews->layout()->addWidget(label_widget);
|
||||
previews->layout()->addWidget(preview);
|
||||
|
||||
preview->start();
|
||||
preview->setObjectName("_form_preview_");
|
||||
}
|
||||
|
||||
|
|
|
@ -6,40 +6,208 @@
|
|||
#include <QTimer>
|
||||
#include <QWheelEvent>
|
||||
|
||||
class PreviewDrawer:public QThread
|
||||
class PreviewChunk
|
||||
{
|
||||
public:
|
||||
PreviewDrawer(BasePreview* preview):
|
||||
QThread(),
|
||||
_preview(preview)
|
||||
|
||||
PreviewChunk(BasePreview* preview, QImage* pixbuf, QMutex* lock, int xstart, int ystart, int xsize, int ysize)
|
||||
{
|
||||
_running = false;
|
||||
_preview = preview;
|
||||
_pixbuf = pixbuf;
|
||||
_lock = lock;
|
||||
_xstart = xstart;
|
||||
_ystart = ystart;
|
||||
_xsize = xsize;
|
||||
_ysize = ysize;
|
||||
|
||||
_need_render = true;
|
||||
}
|
||||
void askStop()
|
||||
|
||||
bool isFrom(BasePreview* preview)
|
||||
{
|
||||
_running = false;
|
||||
return _preview == preview;
|
||||
}
|
||||
static inline void usleep(int us)
|
||||
|
||||
void update()
|
||||
{
|
||||
QThread::usleep(us);
|
||||
_need_render = true;
|
||||
}
|
||||
protected:
|
||||
void run()
|
||||
|
||||
bool render()
|
||||
{
|
||||
_running = true;
|
||||
while (_running)
|
||||
bool changed = false;
|
||||
|
||||
if (_need_render)
|
||||
{
|
||||
_preview->doRender();
|
||||
QThread::usleep(50000);
|
||||
_need_render = false;
|
||||
|
||||
_lock->lock();
|
||||
QImage tempbuffer = _pixbuf->copy(_xstart, _ystart, _xsize, _ysize);
|
||||
_lock->unlock();
|
||||
|
||||
for (int x = 0; x < _xsize; x++)
|
||||
{
|
||||
for (int y = 0; y < _ysize; y++)
|
||||
{
|
||||
QRgb col = tempbuffer.pixel(x, y);
|
||||
if (qAlpha(col) < 255)
|
||||
{
|
||||
QColor newcol = _preview->getPixelColor(_xstart + x, _ystart + y);
|
||||
newcol.setAlpha(255);
|
||||
|
||||
tempbuffer.setPixel(x, y, newcol.rgb());
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
_lock->lock();
|
||||
for (int x = 0; x < _xsize; x++)
|
||||
{
|
||||
for (int y = 0; y < _ysize; y++)
|
||||
{
|
||||
_pixbuf->setPixel(_xstart + x, _ystart + y, tempbuffer.pixel(x, y));
|
||||
}
|
||||
}
|
||||
_lock->unlock();
|
||||
_preview->tellContentChange();
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
private:
|
||||
BasePreview* _preview;
|
||||
bool _running;
|
||||
QImage* _pixbuf;
|
||||
QMutex* _lock;
|
||||
bool _need_render;
|
||||
int _xstart;
|
||||
int _ystart;
|
||||
int _xsize;
|
||||
int _ysize;
|
||||
};
|
||||
|
||||
static PreviewDrawingManager* _drawing_manager = NULL;
|
||||
|
||||
/*************** PreviewDrawingThread ***************/
|
||||
PreviewDrawingThread::PreviewDrawingThread() :
|
||||
QThread()
|
||||
{
|
||||
_running = false;
|
||||
}
|
||||
|
||||
void PreviewDrawingThread::askStop()
|
||||
{
|
||||
_running = false;
|
||||
}
|
||||
|
||||
void PreviewDrawingThread::run()
|
||||
{
|
||||
_running = true;
|
||||
while (_running)
|
||||
{
|
||||
_drawing_manager->performOneThreadJob();
|
||||
QThread::usleep(50000);
|
||||
}
|
||||
}
|
||||
|
||||
/*************** PreviewDrawingManager ***************/
|
||||
PreviewDrawingManager::PreviewDrawingManager()
|
||||
{
|
||||
_thread_count = QThread::idealThreadCount();
|
||||
if (_thread_count < 1)
|
||||
{
|
||||
_thread_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewDrawingManager::startThreads()
|
||||
{
|
||||
for (int i = 0; i < _thread_count * 3; i++)
|
||||
{
|
||||
PreviewDrawingThread* thread = new PreviewDrawingThread();
|
||||
_threads.append(thread);
|
||||
thread->start();
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewDrawingManager::addChunk(PreviewChunk* chunk)
|
||||
{
|
||||
_lock.lock();
|
||||
_chunks.append(chunk);
|
||||
_updateQueue.append(chunk);
|
||||
_lock.unlock();
|
||||
}
|
||||
|
||||
void PreviewDrawingManager::removeChunks(BasePreview* preview)
|
||||
{
|
||||
for (int i = 0; i < _chunks.size(); i++)
|
||||
{
|
||||
PreviewChunk* chunk;
|
||||
chunk = _chunks.at(i);
|
||||
if (chunk->isFrom(preview))
|
||||
{
|
||||
_lock.lock();
|
||||
_chunks.remove(i);
|
||||
_updateQueue.removeAll(chunk);
|
||||
_lock.unlock();
|
||||
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewDrawingManager::updateChunks(BasePreview* preview)
|
||||
{
|
||||
for (int i = 0; i < _chunks.size(); i++)
|
||||
{
|
||||
PreviewChunk* chunk;
|
||||
chunk = _chunks.at(i);
|
||||
if (chunk->isFrom(preview))
|
||||
{
|
||||
chunk->update();
|
||||
_lock.lock();
|
||||
if (!_updateQueue.contains(chunk))
|
||||
{
|
||||
_updateQueue.prepend(chunk);
|
||||
}
|
||||
_lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewDrawingManager::performOneThreadJob()
|
||||
{
|
||||
PreviewChunk* chunk;
|
||||
do
|
||||
{
|
||||
chunk = NULL;
|
||||
_lock.lock();
|
||||
if (!_updateQueue.isEmpty())
|
||||
{
|
||||
chunk = _updateQueue.takeFirst();
|
||||
}
|
||||
_lock.unlock();
|
||||
|
||||
if (chunk)
|
||||
{
|
||||
chunk->render();
|
||||
PreviewDrawingThread::usleep(50000);
|
||||
}
|
||||
else
|
||||
{
|
||||
PreviewDrawingThread::usleep(50000);
|
||||
}
|
||||
|
||||
} while (true);
|
||||
}
|
||||
|
||||
/*************** BasePreview ***************/
|
||||
BasePreview::BasePreview(QWidget* parent) :
|
||||
QWidget(parent)
|
||||
QWidget(parent)
|
||||
{
|
||||
this->lock_drawing = new QMutex();
|
||||
|
||||
|
@ -60,10 +228,10 @@ BasePreview::BasePreview(QWidget* parent) :
|
|||
this->yoffset = 0.0;
|
||||
this->pixbuf = new QImage(this->size(), QImage::Format_ARGB32);
|
||||
this->pixbuf->fill(0x00000000);
|
||||
_width = width();
|
||||
_height = height();
|
||||
|
||||
this->alive = true;
|
||||
this->need_restart = false;
|
||||
this->need_render = true;
|
||||
|
||||
QObject::connect(this, SIGNAL(contentChange()), this, SLOT(update()));
|
||||
QObject::connect(this, SIGNAL(redrawRequested()), this, SLOT(handleRedraw()));
|
||||
|
@ -71,22 +239,29 @@ BasePreview::BasePreview(QWidget* parent) :
|
|||
this->setMinimumSize(256, 256);
|
||||
this->setMaximumSize(256, 256);
|
||||
this->resize(256, 256);
|
||||
|
||||
this->updater = new PreviewDrawer(this);
|
||||
}
|
||||
|
||||
BasePreview::~BasePreview()
|
||||
{
|
||||
alive = false;
|
||||
|
||||
((PreviewDrawer*)updater)->askStop();
|
||||
updater->wait();
|
||||
_drawing_manager->removeChunks(this);
|
||||
|
||||
delete updater;
|
||||
delete pixbuf;
|
||||
delete lock_drawing;
|
||||
}
|
||||
|
||||
void BasePreview::initDrawers()
|
||||
{
|
||||
_drawing_manager = new PreviewDrawingManager();
|
||||
_drawing_manager->startThreads();
|
||||
}
|
||||
|
||||
void BasePreview::stopDrawers()
|
||||
{
|
||||
//delete _drawing_manager;
|
||||
}
|
||||
|
||||
void BasePreview::updateData()
|
||||
{
|
||||
}
|
||||
|
@ -98,8 +273,8 @@ QColor BasePreview::getColor(double x, double y)
|
|||
|
||||
void BasePreview::configScaling(double min, double max, double step, double init, bool logarithmic)
|
||||
{
|
||||
double size = (double)width();
|
||||
|
||||
double size = (double) width();
|
||||
|
||||
if (size >= 1.0)
|
||||
{
|
||||
conf_scale_min = min / size;
|
||||
|
@ -131,44 +306,30 @@ void BasePreview::configScrolling(double xmin, double xmax, double xinit, double
|
|||
redraw();
|
||||
}
|
||||
|
||||
void BasePreview::start()
|
||||
{
|
||||
this->updater->start();
|
||||
}
|
||||
|
||||
void BasePreview::doRender()
|
||||
{
|
||||
if (this->alive)
|
||||
{
|
||||
if (this->need_render)
|
||||
{
|
||||
this->need_render = false;
|
||||
this->renderPixbuf();
|
||||
emit contentChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BasePreview::redraw()
|
||||
{
|
||||
emit(redrawRequested());
|
||||
}
|
||||
|
||||
QColor BasePreview::getPixelColor(int x, int y)
|
||||
{
|
||||
return getColor((double) (x - _width / 2) * scaling + xoffset, (double) (y - _height / 2) * scaling + yoffset);
|
||||
}
|
||||
|
||||
void BasePreview::handleRedraw()
|
||||
{
|
||||
lock_drawing->lock();
|
||||
|
||||
|
||||
updateData();
|
||||
|
||||
|
||||
QImage part = pixbuf->copy();
|
||||
pixbuf->fill(0x00000000);
|
||||
QPainter painter(pixbuf);
|
||||
painter.setOpacity(0.99);
|
||||
painter.drawImage(0, 0, part);
|
||||
|
||||
need_render = true;
|
||||
need_restart = true;
|
||||
|
||||
_drawing_manager->updateChunks(this);
|
||||
|
||||
lock_drawing->unlock();
|
||||
}
|
||||
|
||||
|
@ -180,11 +341,21 @@ void BasePreview::resizeEvent(QResizeEvent* event)
|
|||
|
||||
image = this->pixbuf;
|
||||
|
||||
_width = event->size().width();
|
||||
_height = event->size().height();
|
||||
|
||||
this->pixbuf = new QImage(this->size(), QImage::Format_ARGB32);
|
||||
|
||||
this->pixbuf->fill(0x00000000);
|
||||
this->need_render = true;
|
||||
this->need_restart = true;
|
||||
|
||||
_drawing_manager->removeChunks(this);
|
||||
for (int x = 0; x < _width; x += 32)
|
||||
{
|
||||
for (int y = 0; y < _height; y += 32)
|
||||
{
|
||||
_drawing_manager->addChunk(new PreviewChunk(this, pixbuf, lock_drawing, x, y, x + 32 > _width ? _width - x : 32, y + 32 > _height ? _height - y : 32));
|
||||
}
|
||||
}
|
||||
|
||||
delete image;
|
||||
|
||||
|
@ -197,53 +368,6 @@ void BasePreview::paintEvent(QPaintEvent* event)
|
|||
painter.drawImage(0, 0, *this->pixbuf);
|
||||
}
|
||||
|
||||
void BasePreview::renderPixbuf()
|
||||
{
|
||||
QColor col;
|
||||
bool done;
|
||||
int x, y, w, h;
|
||||
|
||||
w = this->pixbuf->width();
|
||||
h = this->pixbuf->height();
|
||||
|
||||
this->need_restart = false;
|
||||
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
this->lock_drawing->lock();
|
||||
|
||||
if (this->need_restart || !this->alive)
|
||||
{
|
||||
this->lock_drawing->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
done = false;
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
if (this->need_restart || !this->alive)
|
||||
{
|
||||
this->lock_drawing->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if (qAlpha(this->pixbuf->pixel(x, y)) < 255)
|
||||
{
|
||||
col = this->getColor((double)(x - w / 2) * this->scaling + this->xoffset, (double)(y - h / 2) * this->scaling + this->yoffset);
|
||||
col.setAlpha(255);
|
||||
this->pixbuf->setPixel(x, y, col.rgb());
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
if (done && (x == w - 1 || x % 10 == 0))
|
||||
{
|
||||
emit contentChange();
|
||||
}
|
||||
this->lock_drawing->unlock();
|
||||
PreviewDrawer::usleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
void BasePreview::updateScaling()
|
||||
{
|
||||
if (conf_scroll_logarithmic && conf_scale_max - conf_scale_min > 0.0000001)
|
||||
|
@ -270,7 +394,7 @@ void BasePreview::mouseMoveEvent(QMouseEvent* event)
|
|||
int dx, dy;
|
||||
int ndx, ndy;
|
||||
int width, height;
|
||||
|
||||
|
||||
if (event->buttons() & Qt::LeftButton)
|
||||
{
|
||||
dx = event->x() - mousex;
|
||||
|
@ -280,44 +404,44 @@ void BasePreview::mouseMoveEvent(QMouseEvent* event)
|
|||
ndy = dy;
|
||||
if (xoffset - dx * scaling > conf_scroll_xmax)
|
||||
{
|
||||
ndx = (int)floor((conf_scroll_xmax - xoffset) / scaling);
|
||||
ndx = (int) floor((conf_scroll_xmax - xoffset) / scaling);
|
||||
}
|
||||
if (xoffset - dx * scaling < conf_scroll_xmin)
|
||||
{
|
||||
ndx = (int)floor((conf_scroll_xmin - xoffset) / scaling);
|
||||
ndx = (int) floor((conf_scroll_xmin - xoffset) / scaling);
|
||||
}
|
||||
if (yoffset - dy * scaling > conf_scroll_ymax)
|
||||
{
|
||||
ndy = (int)floor((conf_scroll_ymax - yoffset) / scaling);
|
||||
ndy = (int) floor((conf_scroll_ymax - yoffset) / scaling);
|
||||
}
|
||||
if (yoffset - dy * scaling < conf_scroll_ymin)
|
||||
{
|
||||
ndy = (int)floor((conf_scroll_ymin - yoffset) / scaling);
|
||||
ndy = (int) floor((conf_scroll_ymin - yoffset) / scaling);
|
||||
}
|
||||
if (ndx != 0 || ndy != 0)
|
||||
{
|
||||
width = this->width();
|
||||
height = this->height();
|
||||
|
||||
|
||||
if (ndx <= -width || ndx >= width || ndy <= -height || ndy >= height)
|
||||
{
|
||||
xoffset -= (double)ndx * scaling;
|
||||
yoffset -= (double)ndy * scaling;
|
||||
|
||||
xoffset -= (double) ndx * scaling;
|
||||
yoffset -= (double) ndy * scaling;
|
||||
|
||||
lock_drawing->lock();
|
||||
pixbuf->fill(0x00000000);
|
||||
need_render = true;
|
||||
_drawing_manager->updateChunks(this);
|
||||
lock_drawing->unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
int xstart, xsize, ystart, ysize;
|
||||
|
||||
|
||||
lock_drawing->lock();
|
||||
|
||||
xoffset -= (double)ndx * scaling;
|
||||
yoffset -= (double)ndy * scaling;
|
||||
|
||||
xoffset -= (double) ndx * scaling;
|
||||
yoffset -= (double) ndy * scaling;
|
||||
|
||||
if (ndx < 0)
|
||||
{
|
||||
xstart = -ndx;
|
||||
|
@ -338,15 +462,15 @@ void BasePreview::mouseMoveEvent(QMouseEvent* event)
|
|||
ystart = 0;
|
||||
ysize = height - ndy;
|
||||
}
|
||||
|
||||
|
||||
QImage part = pixbuf->copy(xstart, ystart, xsize, ysize);
|
||||
QPainter painter(pixbuf);
|
||||
pixbuf->fill(0x00000000);
|
||||
painter.drawImage(xstart + ndx, ystart + ndy, part);
|
||||
|
||||
need_render = true;
|
||||
|
||||
_drawing_manager->updateChunks(this);
|
||||
lock_drawing->unlock();
|
||||
|
||||
|
||||
emit contentChange();
|
||||
}
|
||||
}
|
||||
|
@ -362,7 +486,7 @@ void BasePreview::wheelEvent(QWheelEvent* event)
|
|||
double old_scaling;
|
||||
int width, height;
|
||||
int new_width, new_height;
|
||||
|
||||
|
||||
if (event->modifiers() & Qt::ShiftModifier)
|
||||
{
|
||||
factor = 5.0;
|
||||
|
@ -375,10 +499,10 @@ void BasePreview::wheelEvent(QWheelEvent* event)
|
|||
{
|
||||
factor = 1.0;
|
||||
}
|
||||
|
||||
|
||||
if (event->orientation() == Qt::Vertical)
|
||||
{
|
||||
if (event->delta() > 0 && scalingbase > conf_scale_min)
|
||||
if (event->delta() > 0 && scalingbase > conf_scale_min)
|
||||
{
|
||||
scalingbase -= factor * conf_scale_step;
|
||||
if (scalingbase < conf_scale_min)
|
||||
|
@ -386,7 +510,7 @@ void BasePreview::wheelEvent(QWheelEvent* event)
|
|||
scalingbase = conf_scale_min;
|
||||
}
|
||||
}
|
||||
else if (event->delta() < 0 && scalingbase < conf_scale_max)
|
||||
else if (event->delta() < 0 && scalingbase < conf_scale_max)
|
||||
{
|
||||
scalingbase += factor * conf_scale_step;
|
||||
if (scalingbase > conf_scale_max)
|
||||
|
@ -408,21 +532,21 @@ void BasePreview::wheelEvent(QWheelEvent* event)
|
|||
|
||||
old_scaling = scaling;
|
||||
updateScaling();
|
||||
|
||||
|
||||
width = pixbuf->width();
|
||||
height = pixbuf->height();
|
||||
|
||||
|
||||
if (scaling < old_scaling)
|
||||
{
|
||||
lock_drawing->lock();
|
||||
new_width = (int)floor(((double)width) * scaling / old_scaling);
|
||||
new_height = (int)floor(((double)height) * scaling / old_scaling);
|
||||
new_width = (int) floor(((double) width) * scaling / old_scaling);
|
||||
new_height = (int) floor(((double) height) * scaling / old_scaling);
|
||||
QImage part = pixbuf->copy((width - new_width) / 2, (height - new_height) / 2, new_width, new_height).scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
QPainter painter(pixbuf);
|
||||
pixbuf->fill(0x00000000);
|
||||
painter.setOpacity(0.99);
|
||||
painter.drawImage(0, 0, part);
|
||||
need_render = true;
|
||||
_drawing_manager->updateChunks(this);
|
||||
lock_drawing->unlock();
|
||||
|
||||
emit contentChange();
|
||||
|
@ -430,16 +554,16 @@ void BasePreview::wheelEvent(QWheelEvent* event)
|
|||
else if (scaling > old_scaling)
|
||||
{
|
||||
lock_drawing->lock();
|
||||
QImage part = pixbuf->scaled((int)floor(((double)width) * old_scaling / scaling), (int)floor(((double)height) * old_scaling / scaling), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
QImage part = pixbuf->scaled((int) floor(((double) width) * old_scaling / scaling), (int) floor(((double) height) * old_scaling / scaling), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
QPainter painter(pixbuf);
|
||||
pixbuf->fill(0x00000000);
|
||||
painter.setOpacity(0.99);
|
||||
painter.drawImage((width - part.width()) / 2, (height - part.height()) / 2, part);
|
||||
need_render = true;
|
||||
_drawing_manager->updateChunks(this);
|
||||
lock_drawing->unlock();
|
||||
|
||||
emit contentChange();
|
||||
}
|
||||
|
||||
|
||||
event->accept();
|
||||
}
|
||||
|
|
|
@ -5,24 +5,30 @@
|
|||
#include <QImage>
|
||||
#include <QWidget>
|
||||
#include <QThread>
|
||||
#include <QVector>
|
||||
#include <QList>
|
||||
|
||||
class BasePreview:public QWidget
|
||||
{
|
||||
class BasePreview : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BasePreview(QWidget* parent);
|
||||
~BasePreview();
|
||||
|
||||
void start();
|
||||
void doRender();
|
||||
static void initDrawers();
|
||||
static void stopDrawers();
|
||||
|
||||
void redraw();
|
||||
|
||||
inline void tellContentChange() {emit contentChange();}
|
||||
|
||||
QColor getPixelColor(int x, int y);
|
||||
|
||||
protected:
|
||||
virtual void updateData();
|
||||
virtual QColor getColor(double x, double y);
|
||||
|
||||
void configScaling(double min, double max, double step, double init, bool logarithmic=true);
|
||||
|
||||
void configScaling(double min, double max, double step, double init, bool logarithmic = true);
|
||||
void configScrolling(double xmin, double xmax, double xinit, double ymin, double ymax, double yinit);
|
||||
|
||||
double xoffset;
|
||||
|
@ -30,29 +36,27 @@ protected:
|
|||
double scaling;
|
||||
|
||||
private:
|
||||
void renderPixbuf();
|
||||
void updateScaling();
|
||||
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
void paintEvent(QPaintEvent* event);
|
||||
|
||||
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
|
||||
QThread* updater;
|
||||
|
||||
QMutex* lock_drawing;
|
||||
QImage* pixbuf;
|
||||
|
||||
int _width;
|
||||
int _height;
|
||||
|
||||
int mousex;
|
||||
int mousey;
|
||||
|
||||
double scalingbase;
|
||||
|
||||
bool alive;
|
||||
bool need_restart;
|
||||
bool need_render;
|
||||
|
||||
double conf_scroll_xmin;
|
||||
double conf_scroll_xmax;
|
||||
|
@ -75,4 +79,43 @@ private slots:
|
|||
void handleRedraw();
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*** Private section ***/
|
||||
class PreviewChunk;
|
||||
|
||||
class PreviewDrawingThread : public QThread {
|
||||
public:
|
||||
PreviewDrawingThread();
|
||||
void askStop();
|
||||
|
||||
static inline void usleep(int us) {
|
||||
QThread::usleep(us);
|
||||
}
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
bool _running;
|
||||
};
|
||||
|
||||
class PreviewDrawingManager {
|
||||
public:
|
||||
PreviewDrawingManager();
|
||||
void startThreads();
|
||||
void addChunk(PreviewChunk* chunk);
|
||||
void removeChunks(BasePreview* preview);
|
||||
void updateChunks(BasePreview* preview);
|
||||
void performOneThreadJob();
|
||||
|
||||
private:
|
||||
int _thread_count;
|
||||
QVector<PreviewDrawingThread*> _threads;
|
||||
QVector<PreviewChunk*> _chunks;
|
||||
QList<PreviewChunk*> _updateQueue;
|
||||
QMutex _lock;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -105,14 +105,12 @@ DialogNoise::DialogNoise(QWidget *parent, NoiseGenerator* value):
|
|||
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
previews->layout()->addWidget(label);
|
||||
previews->layout()->addWidget(previewLevel);
|
||||
previewLevel->start();
|
||||
|
||||
previewTotal = new PreviewTotal(previews, _current);
|
||||
label = new QLabel(tr("Total preview"));
|
||||
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
previews->layout()->addWidget(label);
|
||||
previews->layout()->addWidget(previewTotal);
|
||||
previewTotal->start();
|
||||
|
||||
form = new QWidget(this);
|
||||
form->setLayout(new QVBoxLayout());
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <QLocale>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "basepreview.h"
|
||||
#include "formatmosphere.h"
|
||||
#include "formclouds.h"
|
||||
#include "formlighting.h"
|
||||
|
@ -52,6 +53,8 @@ int main(int argc, char** argv)
|
|||
app.installTranslator(&qtTranslator);
|
||||
}
|
||||
|
||||
BasePreview::initDrawers();
|
||||
|
||||
window = new MainWindow();
|
||||
window->show();
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<translation>Annuler les modifications</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/baseform.cpp" line="263"/>
|
||||
<location filename="../gui_qt/baseform.cpp" line="262"/>
|
||||
<source>Layer %1</source>
|
||||
<translation>Niveau %1</translation>
|
||||
</message>
|
||||
|
@ -98,57 +98,57 @@ Cliquez avec le bouton droit sur un point pour le supprimer.</translation>
|
|||
<translation>Aperçu du composant</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="111"/>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="110"/>
|
||||
<source>Total preview</source>
|
||||
<translation>Aperçu du total</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="121"/>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="119"/>
|
||||
<source>Noise components</source>
|
||||
<translation>Composants du bruit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="130"/>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="128"/>
|
||||
<source>Add component</source>
|
||||
<translation>Ajouter un composant</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="134"/>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="132"/>
|
||||
<source>Remove component</source>
|
||||
<translation>Supprimer un composant</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="138"/>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="136"/>
|
||||
<source>Component height</source>
|
||||
<translation>Hauteur du composant</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="150"/>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="148"/>
|
||||
<source>Component scaling</source>
|
||||
<translation>Echelle du composant</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="166"/>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="164"/>
|
||||
<source>Validate</source>
|
||||
<translation>Valider</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="170"/>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="168"/>
|
||||
<source>Reset</source>
|
||||
<translation>Recommencer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="174"/>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="172"/>
|
||||
<source>Cancel</source>
|
||||
<translation>Annuler</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="178"/>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="176"/>
|
||||
<source>Paysages 3D - Noise editor</source>
|
||||
<translation>Paysages 3D - Editeur de bruit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="232"/>
|
||||
<location filename="../gui_qt/dialognoise.cpp" line="230"/>
|
||||
<source>Component %1</source>
|
||||
<translation>Composant %1</translation>
|
||||
</message>
|
||||
|
@ -704,139 +704,139 @@ Maintenir Ctrl : Plus rapide</translation>
|
|||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="76"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="79"/>
|
||||
<source>Terrain</source>
|
||||
<translation>Terrain</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="80"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="83"/>
|
||||
<source>Textures</source>
|
||||
<translation>Textures</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="84"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="87"/>
|
||||
<source>Water</source>
|
||||
<translation>Eau</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="92"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="95"/>
|
||||
<source>Atmosphere</source>
|
||||
<translation>Atmosphère</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="118"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="121"/>
|
||||
<source>&Load</source>
|
||||
<translation>&Ouvrir</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="118"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="121"/>
|
||||
<source>Crtl+L</source>
|
||||
<translation>Ctrl+O</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="119"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="122"/>
|
||||
<source>&Explore (F2)</source>
|
||||
<translation>&Explorer (F2)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="119"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="122"/>
|
||||
<source>F2</source>
|
||||
<translation>F2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="120"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="123"/>
|
||||
<source>&Quick
|
||||
render (F5)</source>
|
||||
<translation>&Rendu
|
||||
rapide (F5)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="120"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="123"/>
|
||||
<source>F5</source>
|
||||
<translation>F5</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="140"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="143"/>
|
||||
<source>Do you want to start a new scenery ? Any unsaved changes will be lost.</source>
|
||||
<translation>Voulez-vous commencer un nouveau paysage ? Les modifications non sauvegardées seront perdues.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="140"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="143"/>
|
||||
<source>Paysages 3D - New scenery</source>
|
||||
<translation>Paysages 3D - Nouvelle scène</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="150"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="153"/>
|
||||
<source>Paysages 3D - Choose a file to save the scenery</source>
|
||||
<translation>Paysages 3D - Choisissez un fichier pour enregistrer la scène</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="150"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="176"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="153"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="179"/>
|
||||
<source>Paysages 3D Scenery (*.p3d)</source>
|
||||
<translation>Scène Paysages 3D (*.p3d)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="164"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="167"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="170"/>
|
||||
<source>Paysages 3D - File saving error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="164"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="167"/>
|
||||
<source>Can't write specified file : %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="167"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="170"/>
|
||||
<source>Unexpected error while saving file : %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="174"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="177"/>
|
||||
<source>Do you want to load a scenery from file ? Any unsaved changes will be lost.</source>
|
||||
<translation>Voulez-vous charger une scène ? Les modifications nons sauvegardées seront perdues.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="174"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="177"/>
|
||||
<source>Paysages 3D - Load scenery</source>
|
||||
<translation>Paysages 3D - Charger une scène</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="176"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="179"/>
|
||||
<source>Paysages 3D - Choose a scenery file to load</source>
|
||||
<translation>Paysages 3D - Choisissez un fichier de scène à charger</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="186"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="189"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="192"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="195"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="198"/>
|
||||
<source>Paysages 3D - File loading error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="186"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="189"/>
|
||||
<source>Can't read specified file : %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="189"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="192"/>
|
||||
<source>This file doesn't look like a Paysages 3D file : %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="192"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="195"/>
|
||||
<source>This file was created with an incompatible Paysages 3D version : %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="195"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="198"/>
|
||||
<source>Unexpected error while loading file : %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="203"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="206"/>
|
||||
<source>A 3D landscape editing and rendering software.
|
||||
|
||||
Authors :
|
||||
|
@ -849,12 +849,12 @@ GLib - http://www.gtk.org/
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="88"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="91"/>
|
||||
<source>Sky</source>
|
||||
<translation>Ciel</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="96"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="99"/>
|
||||
<source>Clouds</source>
|
||||
<translation>Nuages</translation>
|
||||
</message>
|
||||
|
@ -863,7 +863,7 @@ GLib - http://www.gtk.org/
|
|||
<translation type="obsolete">Eclairage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="104"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="107"/>
|
||||
<source>Render</source>
|
||||
<translation>Rendu</translation>
|
||||
</message>
|
||||
|
@ -872,22 +872,22 @@ GLib - http://www.gtk.org/
|
|||
<translation type="obsolete">&Scène</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="116"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="119"/>
|
||||
<source>&New</source>
|
||||
<translation>&Nouveau</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="116"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="119"/>
|
||||
<source>Crtl+N</source>
|
||||
<translation>Ctrl+N</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="117"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="120"/>
|
||||
<source>&Save</source>
|
||||
<translation>&Sauvegarder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="117"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="120"/>
|
||||
<source>Crtl+S</source>
|
||||
<translation>Ctrl+S</translation>
|
||||
</message>
|
||||
|
@ -924,7 +924,7 @@ GLib - http://www.gtk.org/
|
|||
<translation type="obsolete">Ai&de</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="121"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="124"/>
|
||||
<source>&About</source>
|
||||
<translation>&A propos</translation>
|
||||
</message>
|
||||
|
@ -945,7 +945,7 @@ GLib - http://www.gtk.org/
|
|||
<translation type="obsolete">Voulez-vous charger un paysage ? Les modifications nons sauvegardées seront perdues.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="203"/>
|
||||
<location filename="../gui_qt/mainwindow.cpp" line="206"/>
|
||||
<source>Paysages 3D</source>
|
||||
<translation>Paysages 3D</translation>
|
||||
</message>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
void arrayCreate(Array* array, int item_size)
|
||||
{
|
||||
array->length = 0;
|
||||
array->alloc_length = 3;
|
||||
array->alloc_length = 1;
|
||||
array->item_size = item_size;
|
||||
array->dirty = 1;
|
||||
array->data = malloc((size_t)item_size * array->alloc_length);
|
||||
|
@ -25,7 +25,7 @@ void* arrayAppend(Array* array, void* item)
|
|||
|
||||
if (array->length >= array->alloc_length)
|
||||
{
|
||||
array->alloc_length += 10;
|
||||
array->alloc_length += 1;
|
||||
array->data = realloc(array->data, item_size * array->alloc_length);
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ void arrayClear(Array* array)
|
|||
{
|
||||
free(array->data);
|
||||
array->length = 0;
|
||||
array->alloc_length = 3;
|
||||
array->data = malloc((size_t)array->item_size * 3);
|
||||
array->alloc_length = 1;
|
||||
array->data = malloc((size_t)array->item_size * array->alloc_length);
|
||||
array->dirty = 1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue