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.
- 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.
- Implement scaling and scrolling on previews.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -14,19 +14,38 @@ public:
Preview(QWidget* parent);
~Preview();
static void startUpdater();
void doRender();
void redraw();
void setScaling(double scaling);
protected:
void resizeEvent(QResizeEvent* event);
void paintEvent(QPaintEvent* event);
virtual void updateData();
virtual QColor getColor(double x, double y);
void renderPixbuf();
double xoffset;
double yoffset;
double scaling;
private:
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_xmax;
@ -37,25 +56,12 @@ protected:
double conf_scale_max;
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:
void contentChange();
void redrawRequested();
private slots:
void handleRedraw();
};
#endif