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:
Michaël Lemaire 2012-04-29 15:14:37 +00:00 committed by ThunderK
parent 79e687bd09
commit 5cd3c5b506
8 changed files with 363 additions and 196 deletions

2
TODO
View file

@ -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.

View file

@ -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_");
}

View file

@ -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();
}

View file

@ -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

View file

@ -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());

View file

@ -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();

View file

@ -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>&amp;Load</source>
<translation>&amp;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>&amp;Explore (F2)</source>
<translation>&amp;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>&amp;Quick
render (F5)</source>
<translation>&amp;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&apos;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&apos;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&apos;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">&amp;Scène</translation>
</message>
<message>
<location filename="../gui_qt/mainwindow.cpp" line="116"/>
<location filename="../gui_qt/mainwindow.cpp" line="119"/>
<source>&amp;New</source>
<translation>&amp;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>&amp;Save</source>
<translation>&amp;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&amp;de</translation>
</message>
<message>
<location filename="../gui_qt/mainwindow.cpp" line="121"/>
<location filename="../gui_qt/mainwindow.cpp" line="124"/>
<source>&amp;About</source>
<translation>&amp;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>

View file

@ -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;
}