paysages : Fixed several GUI segfaults + threaded previews + render show last and save + 64 bits compiling.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@225 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-01-18 16:20:14 +00:00 committed by ThunderK
parent d9ad396d12
commit 3e3244a036
14 changed files with 177 additions and 197 deletions

View file

@ -8,7 +8,7 @@ clean:
cd lib_paysages && make clean cd lib_paysages && make clean
cd cli && make clean cd cli && make clean
cd gui_gtk && make clean cd gui_gtk && make clean
cd gui_qt && make clean && rm -f Makefile paysages-qt cd gui_qt && make clean && rm -f paysages-qt
run_cli: run_cli:
LD_LIBRARY_PATH=lib_paysages ./cli/paysages-cli LD_LIBRARY_PATH=lib_paysages ./cli/paysages-cli

View file

@ -2,12 +2,63 @@
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QImage> #include <QImage>
#include <QLabel>
#include <QColor> #include <QColor>
#include <QPainter> #include <QPainter>
#include <QScrollArea> #include <QScrollArea>
#include "../lib_paysages/shared/functions.h" #include "../lib_paysages/shared/functions.h"
/**************** Previews ****************/
class PreviewLevel:public Preview
{
public:
PreviewLevel(QWidget* parent, NoiseGenerator* noise):
Preview(parent),
_noise(noise)
{
}
protected:
QColor getColor(double x, double y)
{
/*Vector3 eye = {0.0, 0.0, 0.0};
Vector3 look;
look.x = cos(M_PI * (x / 128.0 + 0.5)) * cos(M_PI * (y / 256.0));
look.y = -sin(M_PI * (y / 256.0));
look.z = sin(M_PI * (x / 128.0 + 0.5)) * cos(M_PI * (y / 256.0));
return colorToQColor(skyGetColorCustom(eye, look, &_definition, NULL, NULL));*/
}
private:
NoiseGenerator* _noise;
};
class PreviewTotal:public Preview
{
public:
PreviewTotal(QWidget* parent, NoiseGenerator* noise):
Preview(parent),
_noise(noise)
{
}
protected:
QColor getColor(double x, double y)
{
if (y > noiseGet1DTotal(_noise, x))
{
return QColor(255, 255, 255);
}
else
{
return QColor(0, 0, 0);
}
}
private:
NoiseGenerator* _noise;
};
/**************** Dialog form ****************/
DialogNoise::DialogNoise(QWidget *parent, NoiseGenerator* value): DialogNoise::DialogNoise(QWidget *parent, NoiseGenerator* value):
QDialog(parent) QDialog(parent)
{ {
@ -17,12 +68,25 @@ DialogNoise::DialogNoise(QWidget *parent, NoiseGenerator* value):
noiseCopy(_base, _current); noiseCopy(_base, _current);
setLayout(new QVBoxLayout()); setLayout(new QVBoxLayout());
_form = new FormNoise(this, _current);
layout()->addWidget(_form); previewLevel = new PreviewLevel(this, _current);
layout()->addWidget(new QLabel("Level preview"));
layout()->addWidget(previewLevel);
previewTotal = new PreviewTotal(this, _current);
layout()->addWidget(new QLabel("Total preview"));
layout()->addWidget(previewTotal);
setWindowTitle("Paysages 3D - Noise editor"); setWindowTitle("Paysages 3D - Noise editor");
} }
DialogNoise::~DialogNoise()
{
delete previewLevel;
delete previewTotal;
noiseDeleteGenerator(_current);
}
bool DialogNoise::getNoise(QWidget* parent, NoiseGenerator* noise) bool DialogNoise::getNoise(QWidget* parent, NoiseGenerator* noise)
{ {
int result; int result;
@ -43,10 +107,5 @@ void DialogNoise::closeEvent(QCloseEvent* e)
void DialogNoise::accept() void DialogNoise::accept()
{ {
noiseCopy(_current, _base); noiseCopy(_current, _base);
reject(); QDialog::accept();
}
void DialogNoise::reject()
{
noiseDeleteGenerator(_current);
} }

View file

@ -2,7 +2,7 @@
#define _PAYSAGES_QT_DIALOGNOISE_H_ #define _PAYSAGES_QT_DIALOGNOISE_H_
#include <QDialog> #include <QDialog>
#include "formnoise.h" #include "preview.h"
#include "../lib_paysages/shared/types.h" #include "../lib_paysages/shared/types.h"
@ -11,11 +11,12 @@ class DialogNoise : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit DialogNoise(QWidget* parent, NoiseGenerator* noise); explicit DialogNoise(QWidget* parent, NoiseGenerator* noise);
~DialogNoise();
static bool getNoise(QWidget* parent, NoiseGenerator* noise); static bool getNoise(QWidget* parent, NoiseGenerator* noise);
public slots: public slots:
virtual void accept(); virtual void accept();
virtual void reject();
protected: protected:
virtual void closeEvent(QCloseEvent* e); virtual void closeEvent(QCloseEvent* e);
@ -24,7 +25,8 @@ private:
NoiseGenerator* _base; NoiseGenerator* _base;
NoiseGenerator* _current; NoiseGenerator* _current;
NoiseLevel _current_level; NoiseLevel _current_level;
FormNoise* _form; Preview* previewLevel;
Preview* previewTotal;
}; };
#endif #endif

View file

@ -4,7 +4,6 @@
#include <QImage> #include <QImage>
#include <QColor> #include <QColor>
#include <QPainter> #include <QPainter>
#include <QScrollArea>
#include "../lib_paysages/shared/functions.h" #include "../lib_paysages/shared/functions.h"
@ -26,6 +25,7 @@ static void _renderResize(int width, int height)
_current_dialog->area->setMinimumSize(width, height); _current_dialog->area->setMinimumSize(width, height);
_current_dialog->area->setMaximumSize(width, height); _current_dialog->area->setMaximumSize(width, height);
_current_dialog->area->resize(width, height); _current_dialog->area->resize(width, height);
_current_dialog->scroll->setMinimumSize(width > 800 ? 850 : width + 50, height > 600 ? 650 : height + 50);
} }
static void _renderClear(Color col) static void _renderClear(Color col)
@ -62,20 +62,18 @@ public:
} }
}; };
DialogRender::DialogRender(QWidget *parent, int quality, int width, int height): DialogRender::DialogRender(QWidget *parent):
QDialog(parent) QDialog(parent)
{ {
QScrollArea* scroll;
pixbuf = new QImage(1, 1, QImage::Format_ARGB32); pixbuf = new QImage(1, 1, QImage::Format_ARGB32);
_current_dialog = this; _current_dialog = this;
render_thread = NULL;
setModal(true); setModal(true);
setWindowTitle("Paysages 3D - Render"); setWindowTitle("Paysages 3D - Render");
setLayout(new QVBoxLayout()); setLayout(new QVBoxLayout());
scroll = new QScrollArea(this); scroll = new QScrollArea(this);
scroll->setMinimumSize(width > 800 ? 850 : width + 50, height > 600 ? 650 : height + 50);
scroll->setAlignment(Qt::AlignCenter); scroll->setAlignment(Qt::AlignCenter);
area = new RenderArea(scroll); area = new RenderArea(scroll);
scroll->setWidget(area); scroll->setWidget(area);
@ -87,7 +85,10 @@ DialogRender::DialogRender(QWidget *parent, int quality, int width, int height):
progress->setValue(0); progress->setValue(0);
layout()->addWidget(progress); layout()->addWidget(progress);
progress_value = 0; progress_value = 0;
}
void DialogRender::startRender(int quality, int width, int height)
{
renderSetSize(width, height); renderSetSize(width, height);
autoSetRenderQuality(quality); autoSetRenderQuality(quality);
@ -95,28 +96,28 @@ DialogRender::DialogRender(QWidget *parent, int quality, int width, int height):
render_thread = new RenderThread(); render_thread = new RenderThread();
render_thread->start(); render_thread->start();
exec();
} }
void DialogRender::closeEvent(QCloseEvent* e) void DialogRender::loadLastRender()
{ {
progress->hide();
renderSetPreviewCallbacks(_renderResize, _renderClear, _renderDraw, _renderUpdate);
exec();
}
DialogRender::~DialogRender()
{
if (render_thread)
{
renderInterrupt(); renderInterrupt();
render_thread->wait(); render_thread->wait();
renderSetPreviewCallbacks(NULL, NULL, NULL, NULL); renderSetPreviewCallbacks(NULL, NULL, NULL, NULL);
delete render_thread; delete render_thread;
}
delete pixbuf; delete pixbuf;
} }
void DialogRender::reject()
{
renderInterrupt();
render_thread->wait();
renderSetPreviewCallbacks(NULL, NULL, NULL, NULL);
delete render_thread;
delete pixbuf;
QDialog::reject();
}

View file

@ -4,23 +4,24 @@
#include <QDialog> #include <QDialog>
#include <QThread> #include <QThread>
#include <QProgressBar> #include <QProgressBar>
#include <QScrollArea>
class DialogRender : public QDialog class DialogRender : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit DialogRender(QWidget *parent, int quality, int width, int height); explicit DialogRender(QWidget *parent);
~DialogRender();
void startRender(int quality, int width, int height);
void loadLastRender();
QImage* pixbuf; QImage* pixbuf;
QWidget* area; QWidget* area;
QScrollArea* scroll;
QProgressBar* progress; QProgressBar* progress;
int progress_value; int progress_value;
public slots:
virtual void reject();
protected:
virtual void closeEvent(QCloseEvent* e);
private: private:
QThread* render_thread; QThread* render_thread;
}; };

View file

@ -1,94 +0,0 @@
#include "formnoise.h"
#include "tools.h"
#include <QColor>
#include <QSlider>
#include <math.h>
#include "../lib_paysages/sky.h"
#include "../lib_paysages/shared/functions.h"
#include "../lib_paysages/shared/constants.h"
/**************** Previews ****************/
class PreviewLevel:public Preview
{
public:
PreviewLevel(QWidget* parent, NoiseGenerator* noise):
Preview(parent),
_noise(noise)
{
}
protected:
QColor getColor(double x, double y)
{
/*Vector3 eye = {0.0, 0.0, 0.0};
Vector3 look;
look.x = cos(M_PI * (x / 128.0 + 0.5)) * cos(M_PI * (y / 256.0));
look.y = -sin(M_PI * (y / 256.0));
look.z = sin(M_PI * (x / 128.0 + 0.5)) * cos(M_PI * (y / 256.0));
return colorToQColor(skyGetColorCustom(eye, look, &_definition, NULL, NULL));*/
}
private:
NoiseGenerator* _noise;
};
class PreviewTotal:public Preview
{
public:
PreviewTotal(QWidget* parent, NoiseGenerator* noise):
Preview(parent),
_noise(noise)
{
}
protected:
QColor getColor(double x, double y)
{
if (y > noiseGet1DTotal(_noise, x))
{
return QColor(255, 255, 255);
}
else
{
return QColor(0, 0, 0);
}
}
private:
NoiseGenerator* _noise;
};
/**************** Form ****************/
FormNoise::FormNoise(QWidget *parent, NoiseGenerator* noise):
BaseForm(parent)
{
/*_definition = skyCreateDefinition();*/
previewLevel = new PreviewLevel(this, noise);
addPreview(previewLevel, QString("Level preview"));
previewTotal = new PreviewTotal(this, noise);
addPreview(previewTotal, QString("Total preview"));
/*addInputDouble("Day time", &_definition.daytime, 0.0, 1.0, 0.01, 0.1);*/
revertConfig();
}
void FormNoise::revertConfig()
{
/*skyCopyDefinition(skyGetDefinition(), &_definition);
BaseForm::revertConfig();*/
}
void FormNoise::applyConfig()
{
/*skySetDefinition(_definition);
BaseForm::applyConfig();*/
}
void FormNoise::applyConfigPreview()
{
/*skyValidateDefinition(&_definition);
BaseForm::applyConfigPreview();*/
}

View file

@ -1,30 +0,0 @@
#ifndef _PAYSAGES_QT_FORMNOISE_H_
#define _PAYSAGES_QT_FORMNOISE_H_
#include <QWidget>
#include "preview.h"
#include "baseform.h"
#include "../lib_paysages/shared/types.h"
class FormNoise : public BaseForm
{
Q_OBJECT
public:
FormNoise(QWidget* parent, NoiseGenerator* noise);
public slots:
virtual void revertConfig();
virtual void applyConfig();
protected slots:
virtual void applyConfigPreview();
private:
Preview* previewLevel;
Preview* previewTotal;
NoiseGenerator* generator;
};
#endif

View file

@ -1,6 +1,10 @@
#include "formrender.h" #include "formrender.h"
#include <QFileDialog>
#include <QMessageBox>
#include "dialogrender.h" #include "dialogrender.h"
#include "../lib_paysages/shared/functions.h"
/**************** Form ****************/ /**************** Form ****************/
FormRender::FormRender(QWidget *parent) : FormRender::FormRender(QWidget *parent) :
@ -27,18 +31,28 @@ FormRender::FormRender(QWidget *parent) :
void FormRender::startRender() void FormRender::startRender()
{ {
DialogRender* dialog = new DialogRender(this, _quality, _width, _height); DialogRender* dialog = new DialogRender(this);
dialog->exec(); dialog->startRender(_quality, _width, _height);
delete dialog; delete dialog;
} }
void FormRender::showRender() void FormRender::showRender()
{ {
DialogRender* dialog = new DialogRender(this);
dialog->loadLastRender();
delete dialog;
} }
void FormRender::saveRender() void FormRender::saveRender()
{ {
QString filepath;
filepath = QFileDialog::getSaveFileName(this, "Choose a filename to save the last render");
if (!filepath.isNull())
{
renderSaveToFile((char*)filepath.toStdString().c_str());
QMessageBox::information(this, "Message", "The picture " + filepath + " has been saved.");
}
} }

View file

@ -20,8 +20,6 @@ int main(int argc, char** argv)
window.show(); window.show();
Preview::startUpdater();
return app.exec(); return app.exec();
} }
@ -87,5 +85,8 @@ void MainWindow::fileLoad()
void MainWindow::quickPreview() void MainWindow::quickPreview()
{ {
DialogRender(this, 3, 400, 300).exec(); DialogRender* dialog = new DialogRender(this);
dialog->startRender(3, 400, 300);
delete dialog;
} }

View file

@ -27,7 +27,6 @@ HEADERS += ../lib_paysages/shared/functions.h ../lib_paysages/shared/types.h \
dialognoise.h \ dialognoise.h \
inputcolorgradation.h \ inputcolorgradation.h \
formsky.h \ formsky.h \
formnoise.h \
inputnoise.h \ inputnoise.h \
tools.h tools.h
FORMS += FORMS +=
@ -45,5 +44,4 @@ SOURCES += \
dialognoise.cpp \ dialognoise.cpp \
inputcolorgradation.cpp \ inputcolorgradation.cpp \
formsky.cpp \ formsky.cpp \
formnoise.cpp \
inputnoise.cpp inputnoise.cpp

View file

@ -1,7 +1,6 @@
#include "preview.h" #include "preview.h"
#include <QVector> #include <QVector>
#include <QPainter> #include <QPainter>
#include <QThread>
#include <QTimer> #include <QTimer>
static QVector<Preview*> _previews; static QVector<Preview*> _previews;
@ -9,22 +8,29 @@ static QVector<Preview*> _previews;
class PreviewDrawer:public QThread class PreviewDrawer:public QThread
{ {
public: public:
PreviewDrawer() PreviewDrawer(Preview* preview):
QThread(),
_preview(preview)
{ {
_running = false;
}
void askStop()
{
_running = false;
} }
protected: protected:
void run() void run()
{ {
while (true) _running = true;
while (_running)
{ {
QVectorIterator<Preview*> iter(_previews); _preview->doRender();
while (iter.hasNext())
{
iter.next()->doRender();
}
QThread::usleep(50000); QThread::usleep(50000);
} }
} }
private:
Preview* _preview;
bool _running;
}; };
Preview::Preview(QWidget* parent) : Preview::Preview(QWidget* parent) :
@ -51,22 +57,17 @@ Preview::Preview(QWidget* parent) :
this->setMaximumSize(256, 256); this->setMaximumSize(256, 256);
this->resize(256, 256); this->resize(256, 256);
_previews.append(this); this->updater = new PreviewDrawer(this);
this->updater->start();
} }
Preview::~Preview() Preview::~Preview()
{ {
_previews.remove(_previews.indexOf(this)); alive = false;
((PreviewDrawer*)updater)->askStop();
lock->lock(); updater->wait();
alive = true; delete updater;
delete pixbuf; delete pixbuf;
lock->unlock();
}
void Preview::startUpdater()
{
(new PreviewDrawer())->start();
} }
void Preview::doRender() void Preview::doRender()

View file

@ -4,6 +4,7 @@
#include <QMutex> #include <QMutex>
#include <QImage> #include <QImage>
#include <QWidget> #include <QWidget>
#include <QThread>
class Preview:public QWidget class Preview:public QWidget
{ {
@ -47,6 +48,8 @@ protected:
bool alive; bool alive;
bool need_rerender; bool need_rerender;
bool need_render; bool need_render;
private:
QThread* updater;
}; };
#endif #endif

View file

@ -2,7 +2,7 @@ SOURCES=$(wildcard *.c)
OBJECTS=${SOURCES:.c=.o} OBJECTS=${SOURCES:.c=.o}
HEADERS=$(wildcard shared/*.h *.h) HEADERS=$(wildcard shared/*.h *.h)
RESULT=libpaysages.so RESULT=libpaysages.so
CC_FLAGS=-g -pg -Wall $(shell pkg-config --cflags glib-2.0 gthread-2.0) CC_FLAGS=-g -pg -Wall -fPIC $(shell pkg-config --cflags glib-2.0 gthread-2.0)
CC_LDFLAGS=$(shell pkg-config --libs glib-2.0 gthread-2.0) -lIL -lILU CC_LDFLAGS=$(shell pkg-config --libs glib-2.0 gthread-2.0) -lIL -lILU
all:${RESULT} all:${RESULT}

View file

@ -260,6 +260,24 @@ static void _processDirtyPixels()
_dirty_count = 0; _dirty_count = 0;
} }
static void _setAllDirty()
{
int x, y;
_dirty_left = 0;
_dirty_right = render_width - 1;
_dirty_down = 0;
_dirty_up = render_height - 1;
for (y = _dirty_down; y <= _dirty_up; y++)
{
for (x = _dirty_left; x <= _dirty_right; x++)
{
(render_zone + y * render_width + x)->dirty = 1;
}
}
}
void renderAddFragment(RenderFragment* fragment) void renderAddFragment(RenderFragment* fragment)
{ {
Array* pixel_data; Array* pixel_data;
@ -781,8 +799,14 @@ void renderSetPreviewCallbacks(PreviewCallbackResize resize, PreviewCallbackClea
_cb_preview_clear = clear ? clear : _previewClear; _cb_preview_clear = clear ? clear : _previewClear;
_cb_preview_draw = draw ? draw : _previewDraw; _cb_preview_draw = draw ? draw : _previewDraw;
_cb_preview_update = update ? update : _previewUpdate; _cb_preview_update = update ? update : _previewUpdate;
_cb_preview_resize(render_width, render_height); _cb_preview_resize(render_width, render_height);
/* TODO Send all pixels ? */ _cb_preview_clear(background_color);
_setAllDirty();
_processDirtyPixels();
_cb_preview_update(1.0);
} }
int renderSetNextProgressStep(double start, double end) int renderSetNextProgressStep(double start, double end)