paysages: Fixed previews causing segfaults when rendering definitions that where being updated by GUI.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@237 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-01-25 22:32:06 +00:00 committed by ThunderK
parent a2307c4746
commit 912166fdba
10 changed files with 121 additions and 58 deletions

5
TODO
View file

@ -1,4 +1,5 @@
- In GUI, revertConfig should lock the previews while reverting.
- All Save and Load methods should have same signature : void ...Save(FILE*, ...*)
- All noises should use the same entropy pool (saved separately), and avoid reallocs. - All noises should use the same entropy pool (saved separately), and avoid reallocs.
- Implement light multi-sampling (mainly for skydome).
- All Save and Load methods should have same signature : void ...Save(FILE*, ...*).
- Remove all global variables (render_quality, render_width...), it should all be set in Renderer. - Remove all global variables (render_quality, render_width...), it should all be set in Renderer.
- Implement scaling and scrolling on previews.

View file

@ -52,7 +52,7 @@ BaseForm::BaseForm(QWidget* parent) :
connect(button_revert, SIGNAL(clicked()), this, SLOT(revertConfig())); connect(button_revert, SIGNAL(clicked()), this, SLOT(revertConfig()));
} }
void BaseForm::applyConfigPreview() void BaseForm::configChangeEvent()
{ {
QList<Preview*> list_previews = previews->findChildren<Preview*>("_form_preview_"); QList<Preview*> list_previews = previews->findChildren<Preview*>("_form_preview_");
for (int i = 0; i < list_previews.size(); i++) for (int i = 0; i < list_previews.size(); i++)
@ -72,7 +72,7 @@ void BaseForm::revertConfig()
inputs[i]->revert(); inputs[i]->revert();
} }
BaseForm::applyConfigPreview(); BaseForm::configChangeEvent();
button_apply->setEnabled(false); button_apply->setEnabled(false);
button_revert->setEnabled(false); button_revert->setEnabled(false);
@ -111,7 +111,7 @@ void BaseForm::addInput(BaseInput* input)
input->preview()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); input->preview()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
input->control()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); input->control()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
connect(input, SIGNAL(valueChanged()), this, SLOT(applyConfigPreview())); connect(input, SIGNAL(valueChanged()), this, SLOT(configChangeEvent()));
input->setObjectName("_form_input_"); input->setObjectName("_form_input_");
input->revert(); input->revert();

View file

@ -20,7 +20,7 @@ public slots:
virtual void applyConfig(); virtual void applyConfig();
protected slots: protected slots:
virtual void applyConfigPreview(); virtual void configChangeEvent();
protected: protected:
void addPreview(Preview* preview, QString label); void addPreview(Preview* preview, QString label);

View file

@ -13,10 +13,10 @@
class PreviewLevel:public Preview class PreviewLevel:public Preview
{ {
public: public:
PreviewLevel(QWidget* parent, NoiseGenerator* noise): PreviewLevel(QWidget* parent, NoiseGenerator* noise): Preview(parent)
Preview(parent)
{ {
_noise = noise; _noise_original = noise;
_noise_preview = noiseCreateGenerator();
_level = -1; _level = -1;
} }
@ -26,9 +26,13 @@ public:
redraw(); redraw();
} }
protected: protected:
void updateData()
{
noiseCopy(_noise_original, _noise_preview);
}
QColor getColor(double x, double y) QColor getColor(double x, double y)
{ {
if ((_level >= 0) && (y > noiseGet1DLevel(_noise, _level, x))) if ((_level >= 0) && (y > noiseGet1DLevel(_noise_preview, _level, x)))
{ {
return QColor(255, 255, 255); return QColor(255, 255, 255);
} }
@ -38,22 +42,27 @@ protected:
} }
} }
private: private:
NoiseGenerator* _noise; NoiseGenerator* _noise_original;
NoiseGenerator* _noise_preview;
int _level; int _level;
}; };
class PreviewTotal:public Preview class PreviewTotal:public Preview
{ {
public: public:
PreviewTotal(QWidget* parent, NoiseGenerator* noise): PreviewTotal(QWidget* parent, NoiseGenerator* noise): Preview(parent)
Preview(parent),
_noise(noise)
{ {
_noise_original = noise;
_noise_preview = noiseCreateGenerator();
} }
protected: protected:
void updateData()
{
noiseCopy(_noise_original, _noise_preview);
}
QColor getColor(double x, double y) QColor getColor(double x, double y)
{ {
if (y > noiseGet1DTotal(_noise, x)) if (y > noiseGet1DTotal(_noise_preview, x))
{ {
return QColor(255, 255, 255); return QColor(255, 255, 255);
} }
@ -63,7 +72,8 @@ protected:
} }
} }
private: private:
NoiseGenerator* _noise; NoiseGenerator* _noise_original;
NoiseGenerator* _noise_preview;
}; };
/**************** Dialog form ****************/ /**************** Dialog form ****************/

View file

@ -22,6 +22,7 @@ public:
Preview(parent) Preview(parent)
{ {
_renderer = rendererGetFake(); _renderer = rendererGetFake();
_preview_definition = skyCreateDefinition();
} }
protected: protected:
QColor getColor(double x, double y) QColor getColor(double x, double y)
@ -33,10 +34,15 @@ protected:
look.y = -y; look.y = -y;
look.z = x; look.z = x;
return colorToQColor(skyGetColor(&_definition, &_renderer, eye, look)); return colorToQColor(skyGetColor(&_preview_definition, &_renderer, eye, look));
}
void updateData()
{
skyCopyDefinition(&_definition, &_preview_definition);
} }
private: private:
Renderer _renderer; Renderer _renderer;
SkyDefinition _preview_definition;
}; };
class PreviewWest:public Preview class PreviewWest:public Preview
@ -46,6 +52,7 @@ public:
Preview(parent) Preview(parent)
{ {
_renderer = rendererGetFake(); _renderer = rendererGetFake();
_preview_definition = skyCreateDefinition();
} }
protected: protected:
QColor getColor(double x, double y) QColor getColor(double x, double y)
@ -57,10 +64,15 @@ protected:
look.y = -y; look.y = -y;
look.z = -x; look.z = -x;
return colorToQColor(skyGetColor(&_definition, &_renderer, eye, look)); return colorToQColor(skyGetColor(&_preview_definition, &_renderer, eye, look));
}
void updateData()
{
skyCopyDefinition(&_definition, &_preview_definition);
} }
private: private:
Renderer _renderer; Renderer _renderer;
SkyDefinition _preview_definition;
}; };
/**************** Form ****************/ /**************** Form ****************/
@ -97,8 +109,8 @@ void FormSky::applyConfig()
BaseForm::applyConfig(); BaseForm::applyConfig();
} }
void FormSky::applyConfigPreview() void FormSky::configChangeEvent()
{ {
skyValidateDefinition(&_definition); skyValidateDefinition(&_definition);
BaseForm::applyConfigPreview(); BaseForm::configChangeEvent();
} }

View file

@ -17,7 +17,7 @@ public slots:
virtual void applyConfig(); virtual void applyConfig();
protected slots: protected slots:
virtual void applyConfigPreview(); virtual void configChangeEvent();
private: private:
Preview* previewEast; Preview* previewEast;

View file

@ -18,15 +18,22 @@ class PreviewTerrainHeight:public Preview
public: public:
PreviewTerrainHeight(QWidget* parent):Preview(parent) PreviewTerrainHeight(QWidget* parent):Preview(parent)
{ {
_preview_definition = terrainCreateDefinition();
} }
protected: protected:
QColor getColor(double x, double y) QColor getColor(double x, double y)
{ {
double height; double height;
height = terrainGetHeightNormalized(&_definition, x, y); height = terrainGetHeightNormalized(&_preview_definition, x, y);
return QColor((int)(255.0 * height), (int)(255.0 * height), (int)(255.0 * height)); return QColor((int)(255.0 * height), (int)(255.0 * height), (int)(255.0 * height));
} }
void updateData()
{
terrainCopyDefinition(&_definition, &_preview_definition);
}
private:
TerrainDefinition _preview_definition;
}; };
class PreviewTerrainColor:public Preview class PreviewTerrainColor:public Preview
@ -36,14 +43,20 @@ public:
{ {
// TODO Use custom renderer // TODO Use custom renderer
_renderer = sceneryGetStandardRenderer(3); _renderer = sceneryGetStandardRenderer(3);
_preview_definition = terrainCreateDefinition();
} }
protected: protected:
QColor getColor(double x, double y) QColor getColor(double x, double y)
{ {
return colorToQColor(terrainGetColor(&_definition, &_renderer, x, y, scaling)); return colorToQColor(terrainGetColor(&_preview_definition, &_renderer, x, y, scaling));
}
void updateData()
{
terrainCopyDefinition(&_definition, &_preview_definition);
} }
private: private:
Renderer _renderer; Renderer _renderer;
TerrainDefinition _preview_definition;
}; };
/**************** Form ****************/ /**************** Form ****************/
@ -76,8 +89,8 @@ void FormTerrain::applyConfig()
BaseForm::applyConfig(); BaseForm::applyConfig();
} }
void FormTerrain::applyConfigPreview() void FormTerrain::configChangeEvent()
{ {
terrainValidateDefinition(&_definition); terrainValidateDefinition(&_definition);
BaseForm::applyConfigPreview(); BaseForm::configChangeEvent();
} }

View file

@ -17,7 +17,7 @@ public slots:
virtual void applyConfig(); virtual void applyConfig();
protected slots: protected slots:
virtual void applyConfigPreview(); virtual void configChangeEvent();
private: private:
Preview* previewHeight; Preview* previewHeight;

View file

@ -34,7 +34,8 @@ private:
Preview::Preview(QWidget* parent) : Preview::Preview(QWidget* parent) :
QWidget(parent) QWidget(parent)
{ {
this->lock = new QMutex(); this->lock_drawing = new QMutex();
this->conf_scroll_xmin = 0.0; this->conf_scroll_xmin = 0.0;
this->conf_scroll_xmax = 0.0; this->conf_scroll_xmax = 0.0;
this->conf_scroll_ymin = 0.0; this->conf_scroll_ymin = 0.0;
@ -57,6 +58,7 @@ Preview::Preview(QWidget* parent) :
this->resize(256, 256); this->resize(256, 256);
QObject::connect(this, SIGNAL(contentChange()), this, SLOT(update())); QObject::connect(this, SIGNAL(contentChange()), this, SLOT(update()));
QObject::connect(this, SIGNAL(redrawRequested()), this, SLOT(handleRedraw()));
this->updater = new PreviewDrawer(this); this->updater = new PreviewDrawer(this);
this->updater->start(); this->updater->start();
@ -65,10 +67,16 @@ Preview::Preview(QWidget* parent) :
Preview::~Preview() Preview::~Preview()
{ {
alive = false; alive = false;
((PreviewDrawer*)updater)->askStop(); ((PreviewDrawer*)updater)->askStop();
updater->wait(); updater->wait();
delete updater; delete updater;
delete pixbuf; delete pixbuf;
delete lock_drawing;;}
void Preview::updateData()
{
} }
QColor Preview::getColor(double x, double y) QColor Preview::getColor(double x, double y)
@ -94,9 +102,16 @@ void Preview::doRender()
void Preview::redraw() void Preview::redraw()
{ {
//lock->lock(); emit(redrawRequested());
}
void Preview::handleRedraw()
{
need_rerender = true; need_rerender = true;
//lock->unlock(); lock_drawing->lock();
updateData();
need_rerender = true;
lock_drawing->unlock();
} }
void Preview::setScaling(double scaling) void Preview::setScaling(double scaling)
@ -110,7 +125,7 @@ void Preview::resizeEvent(QResizeEvent* event)
{ {
QImage* image; QImage* image;
this->lock->lock(); this->lock_drawing->lock();
image = this->pixbuf; image = this->pixbuf;
@ -122,7 +137,7 @@ void Preview::resizeEvent(QResizeEvent* event)
delete image; delete image;
this->lock->unlock(); this->lock_drawing->unlock();
} }
void Preview::paintEvent(QPaintEvent* event) void Preview::paintEvent(QPaintEvent* event)
@ -133,11 +148,11 @@ void Preview::paintEvent(QPaintEvent* event)
void Preview::forceRender() void Preview::forceRender()
{ {
this->lock->lock(); this->lock_drawing->lock();
this->pixbuf->fill(0x00000000); this->pixbuf->fill(0x00000000);
this->need_rerender = false; this->need_rerender = false;
this->need_render = true; this->need_render = true;
this->lock->unlock(); this->lock_drawing->unlock();
} }
void Preview::renderPixbuf() void Preview::renderPixbuf()
@ -151,17 +166,23 @@ void Preview::renderPixbuf()
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
this->lock->lock(); this->lock_drawing->lock();
if (this->need_rerender || !this->alive) if (this->need_rerender || !this->alive)
{ {
this->lock->unlock(); this->lock_drawing->unlock();
break; return;
} }
done = false; done = false;
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
{ {
if (this->need_rerender || !this->alive)
{
this->lock_drawing->unlock();
return;
}
if (qAlpha(this->pixbuf->pixel(x, y)) == 0) if (qAlpha(this->pixbuf->pixel(x, y)) == 0)
{ {
col = this->getColor((double)(x - w / 2) * this->scaling + this->xoffset, (double)(y - h / 2) * this->scaling + this->yoffset); col = this->getColor((double)(x - w / 2) * this->scaling + this->xoffset, (double)(y - h / 2) * this->scaling + this->yoffset);
@ -173,7 +194,7 @@ void Preview::renderPixbuf()
{ {
emit contentChange(); emit contentChange();
} }
this->lock->unlock(); this->lock_drawing->unlock();
} }
} }

View file

@ -14,19 +14,38 @@ public:
Preview(QWidget* parent); Preview(QWidget* parent);
~Preview(); ~Preview();
static void startUpdater();
void doRender(); void doRender();
void redraw(); void redraw();
void setScaling(double scaling); void setScaling(double scaling);
protected: protected:
void resizeEvent(QResizeEvent* event); virtual void updateData();
void paintEvent(QPaintEvent* event);
virtual QColor getColor(double x, double y); virtual QColor getColor(double x, double y);
void renderPixbuf(); double xoffset;
double yoffset;
double scaling;
private:
void forceRender(); void forceRender();
void renderPixbuf();
static void startUpdater();
void resizeEvent(QResizeEvent* event);
void paintEvent(QPaintEvent* event);
QThread* updater;
QMutex* lock_drawing;
QImage* pixbuf;
int mousex;
int mousey;
bool alive;
bool need_rerender;
bool need_render;
double conf_scroll_xmin; double conf_scroll_xmin;
double conf_scroll_xmax; double conf_scroll_xmax;
@ -37,25 +56,12 @@ protected:
double conf_scale_max; double conf_scale_max;
double conf_scale_step; double conf_scale_step;
double xoffset;
double yoffset;
double scaling;
QMutex* lock;
QImage* pixbuf;
int mousex;
int mousey;
bool alive;
bool need_rerender;
bool need_render;
private:
QThread* updater;
signals: signals:
void contentChange(); void contentChange();
void redrawRequested();
private slots:
void handleRedraw();
}; };
#endif #endif