From 912166fdbafd7e8edec48bc86fb807bf9701cd58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Wed, 25 Jan 2012 22:32:06 +0000 Subject: [PATCH] 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 --- TODO | 5 +++-- gui_qt/baseform.cpp | 6 +++--- gui_qt/baseform.h | 2 +- gui_qt/dialognoise.cpp | 30 +++++++++++++++++--------- gui_qt/formsky.cpp | 20 ++++++++++++++---- gui_qt/formsky.h | 2 +- gui_qt/formterrain.cpp | 21 ++++++++++++++---- gui_qt/formterrain.h | 2 +- gui_qt/preview.cpp | 43 +++++++++++++++++++++++++++---------- gui_qt/preview.h | 48 ++++++++++++++++++++++++------------------ 10 files changed, 121 insertions(+), 58 deletions(-) diff --git a/TODO b/TODO index f0d4fba..edb3192 100644 --- a/TODO +++ b/TODO @@ -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. diff --git a/gui_qt/baseform.cpp b/gui_qt/baseform.cpp index 2666662..314d99d 100644 --- a/gui_qt/baseform.cpp +++ b/gui_qt/baseform.cpp @@ -52,7 +52,7 @@ BaseForm::BaseForm(QWidget* parent) : connect(button_revert, SIGNAL(clicked()), this, SLOT(revertConfig())); } -void BaseForm::applyConfigPreview() +void BaseForm::configChangeEvent() { QList list_previews = previews->findChildren("_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(); diff --git a/gui_qt/baseform.h b/gui_qt/baseform.h index 2cdbc52..6a9a632 100644 --- a/gui_qt/baseform.h +++ b/gui_qt/baseform.h @@ -20,7 +20,7 @@ public slots: virtual void applyConfig(); protected slots: - virtual void applyConfigPreview(); + virtual void configChangeEvent(); protected: void addPreview(Preview* preview, QString label); diff --git a/gui_qt/dialognoise.cpp b/gui_qt/dialognoise.cpp index c553270..3903f97 100644 --- a/gui_qt/dialognoise.cpp +++ b/gui_qt/dialognoise.cpp @@ -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 ****************/ diff --git a/gui_qt/formsky.cpp b/gui_qt/formsky.cpp index aa646cd..d36712d 100644 --- a/gui_qt/formsky.cpp +++ b/gui_qt/formsky.cpp @@ -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(); } diff --git a/gui_qt/formsky.h b/gui_qt/formsky.h index 4a0ebfe..2a792dc 100644 --- a/gui_qt/formsky.h +++ b/gui_qt/formsky.h @@ -17,7 +17,7 @@ public slots: virtual void applyConfig(); protected slots: - virtual void applyConfigPreview(); + virtual void configChangeEvent(); private: Preview* previewEast; diff --git a/gui_qt/formterrain.cpp b/gui_qt/formterrain.cpp index e7eb32a..ae6be33 100644 --- a/gui_qt/formterrain.cpp +++ b/gui_qt/formterrain.cpp @@ -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(); } diff --git a/gui_qt/formterrain.h b/gui_qt/formterrain.h index f0e4894..14877b0 100644 --- a/gui_qt/formterrain.h +++ b/gui_qt/formterrain.h @@ -17,7 +17,7 @@ public slots: virtual void applyConfig(); protected slots: - virtual void applyConfigPreview(); + virtual void configChangeEvent(); private: Preview* previewHeight; diff --git a/gui_qt/preview.cpp b/gui_qt/preview.cpp index d19b46d..e8d5672 100644 --- a/gui_qt/preview.cpp +++ b/gui_qt/preview.cpp @@ -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(); } } diff --git a/gui_qt/preview.h b/gui_qt/preview.h index 8aafc1d..2bb1385 100644 --- a/gui_qt/preview.h +++ b/gui_qt/preview.h @@ -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