diff --git a/gui_qt/baseform.cpp b/gui_qt/baseform.cpp index c804eab..9dc8e57 100644 --- a/gui_qt/baseform.cpp +++ b/gui_qt/baseform.cpp @@ -10,17 +10,41 @@ #include #include #include +#include -BaseForm::BaseForm(QWidget* parent, bool auto_apply) : QWidget(parent) +BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget(parent) { QWidget* hwidget; QVBoxLayout* vlayout; QHBoxLayout* hlayout; this->auto_apply = auto_apply; + this->with_layers = with_layers; vlayout = new QVBoxLayout(); hlayout = new QHBoxLayout(); + + if (with_layers) + { + hwidget = new QWidget(this); + hwidget->setLayout(new QHBoxLayout()); + + hwidget->layout()->addWidget(new QLabel("Layers : ", hwidget)); + + layer_list = new QComboBox(hwidget); + hwidget->layout()->addWidget(layer_list); + QObject::connect(layer_list, SIGNAL(currentIndexChanged(int)), this, SLOT(layerListChanged())); + + layer_new = new QPushButton("Add layer", hwidget); + hwidget->layout()->addWidget(layer_new); + QObject::connect(layer_new, SIGNAL(clicked()), this, SLOT(layerAddClicked())); + + layer_del = new QPushButton("Delete layer", hwidget); + hwidget->layout()->addWidget(layer_del); + QObject::connect(layer_del, SIGNAL(clicked()), this, SLOT(layerDelClicked())); + + vlayout->addWidget(hwidget); + } hwidget = new QWidget(this); @@ -85,6 +109,14 @@ void BaseForm::revertConfig() { inputs[i]->revert(); } + + if (with_layers) + { + if (layer_list->currentIndex() < 0 && layer_list->count() > 0) + { + layer_list->setCurrentIndex(0); + } + } BaseForm::configChangeEvent(); @@ -100,6 +132,21 @@ void BaseForm::applyConfig() emit(configApplied()); } +void BaseForm::layerAddClicked() +{ + layerAddedEvent(); +} + +void BaseForm::layerDelClicked() +{ + layerDeletedEvent(layer_list->currentIndex()); +} + +void BaseForm::layerListChanged() +{ + layerSelectedEvent(layer_list->currentIndex()); +} + void BaseForm::addPreview(Preview* preview, QString label) { previews->layout()->addWidget(new QLabel(label, previews)); @@ -158,3 +205,58 @@ void BaseForm::addInputNoise(QString label, NoiseGenerator* value) { addInput(new InputNoise(form, label, value)); } + +int BaseForm::currentLayer() +{ + if (with_layers) + { + return layer_list->currentIndex(); + } + else + { + return -1; + } +} + +void BaseForm::setLayerCount(int layer_count) +{ + int i, selected; + + if (with_layers) + { + selected = layer_list->currentIndex(); + layer_list->clear(); + + for (i = 0; i < layer_count; i++) + { + layer_list->addItem(QString("Layer %1").arg(i + 1)); + } + layer_list->setCurrentIndex(selected); + } +} + +void BaseForm::layerAddedEvent() +{ + setLayerCount(layer_list->count() + 1); + layer_list->setCurrentIndex(layer_list->count() - 1); +} + +void BaseForm::layerDeletedEvent(int layer) +{ + layer_list->removeItem(layer); +} + +void BaseForm::layerSelectedEvent(int layer) +{ + QList inputs = form->findChildren("_form_input_"); + for (int i = 0; i < inputs.size(); i++) + { + inputs[i]->revert(); + } + + QList list_previews = previews->findChildren("_form_preview_"); + for (int i = 0; i < list_previews.size(); i++) + { + list_previews[i]->redraw(); + } +} diff --git a/gui_qt/baseform.h b/gui_qt/baseform.h index a098447..5f75b87 100644 --- a/gui_qt/baseform.h +++ b/gui_qt/baseform.h @@ -3,6 +3,7 @@ #include #include +#include #include "preview.h" #include "baseinput.h" #include "../lib_paysages/shared/types.h" @@ -13,7 +14,7 @@ class BaseForm:public QWidget Q_OBJECT public: - BaseForm(QWidget* parent, bool auto_apply=false); + BaseForm(QWidget* parent, bool auto_apply=false, bool with_layers=false); signals: void configApplied(); @@ -24,6 +25,11 @@ public slots: protected slots: virtual void configChangeEvent(); + +private slots: + void layerAddClicked(); + void layerDelClicked(); + void layerListChanged(); protected: void addPreview(Preview* preview, QString label); @@ -35,8 +41,19 @@ protected: void addInputColorGradation(QString label, ColorGradation* value); void addInputNoise(QString label, NoiseGenerator* value); + int currentLayer(); + void setLayerCount(int layer_count); + + virtual void layerAddedEvent(); + virtual void layerDeletedEvent(int layer); + virtual void layerSelectedEvent(int layer); + private: bool auto_apply; + bool with_layers; + QComboBox* layer_list; + QPushButton* layer_new; + QPushButton* layer_del; QWidget* previews; QWidget* form; QWidget* buttons; diff --git a/gui_qt/formclouds.cpp b/gui_qt/formclouds.cpp index b88558c..1fcda83 100644 --- a/gui_qt/formclouds.cpp +++ b/gui_qt/formclouds.cpp @@ -1,26 +1,73 @@ #include "formclouds.h" #include "../lib_paysages/clouds.h" +#include "../lib_paysages/color.h" +#include "../lib_paysages/euclid.h" #include "../lib_paysages/scenery.h" +#include "../lib_paysages/shared/constants.h" + +#include "tools.h" static CloudsDefinition _definition; +static CloudsLayerDefinition _layer; /**************** Previews ****************/ +class PreviewCloudsCoverage:public Preview +{ +public: + PreviewCloudsCoverage(QWidget* parent):Preview(parent) + { + _renderer = rendererCreate(); + _renderer.render_quality = 3; + + _preview_layer = cloudsLayerCreateDefinition(); + } +protected: + QColor getColor(double x, double y) + { + Vector3 eye, look; + Color color_layer, result; + + eye.x = 0.0; + eye.y = scaling; + eye.z = -10.0 * scaling; + look.x = x * 0.01 / scaling; + look.y = -y * 0.01 / scaling - 0.3; + look.z = 1.0; + look = v3Normalize(look); + + result = COLOR_BLUE; + color_layer = cloudsGetLayerColor(&_preview_layer, &_renderer, eye, v3Add(eye, v3Scale(look, 1000.0))); + colorMask(&result, &color_layer); + return colorToQColor(result); + } + void updateData() + { + cloudsLayerCopyDefinition(&_layer, &_preview_layer); + } + +private: + Renderer _renderer; + CloudsLayerDefinition _preview_layer; +}; /**************** Form ****************/ FormClouds::FormClouds(QWidget *parent): - BaseForm(parent) + BaseForm(parent, false, true) { _definition = cloudsCreateDefinition(); + _layer = cloudsLayerCreateDefinition(); + + addPreview(new PreviewCloudsCoverage(parent), "Layer coverage (no lighting)"); - /*previewHeight = new PreviewTerrainHeight(this); - previewColor = new PreviewTerrainColor(this); - addPreview(previewHeight, QString("Height preview (normalized)")); - addPreview(previewColor, QString("Textured preview (no shadow)"));*/ - - /*addInputNoise("Noise", _definition.height_noise); - addInputDouble("Height", &_definition.height_factor, 0.0, 20.0, 0.1, 1.0); - addInputDouble("Scaling", &_definition.scaling, 1.0, 20.0, 0.1, 1.0);*/ + addInputDouble("Start altitude", &_layer.ymin, -10.0, 250.0, 0.5, 5.0); + addInputDouble("Max density altitude", &_layer.ycenter, -10.0, 250.0, 0.5, 5.0); + addInputDouble("End altitude", &_layer.ymax, -10.0, 250.0, 0.5, 5.0); + addInputNoise("Noise", _layer.noise); + addInputDouble("Coverage", &_layer.coverage, 0.0, 1.0, 0.01, 0.1); + addInputDouble("Scaling", &_layer.scaling, 1.0, 100.0, 0.5, 5.0); + addInputColor("Base color", &_layer.color); + addInputDouble("Opacity", &_layer.color.a, 0.0, 1.0, 0.01, 0.1); revertConfig(); } @@ -28,6 +75,7 @@ FormClouds::FormClouds(QWidget *parent): void FormClouds::revertConfig() { sceneryGetClouds(&_definition); + setLayerCount(cloudsGetLayerCount(&_definition)); BaseForm::revertConfig(); } @@ -39,6 +87,29 @@ void FormClouds::applyConfig() void FormClouds::configChangeEvent() { + cloudsLayerCopyDefinition(&_layer, cloudsGetLayer(&_definition, currentLayer())); cloudsValidateDefinition(&_definition); BaseForm::configChangeEvent(); } + +void FormClouds::layerAddedEvent() +{ + if (cloudsAddLayer(&_definition) > 0) + { + BaseForm::layerAddedEvent(); + } +} + +void FormClouds::layerDeletedEvent(int layer) +{ + cloudsDeleteLayer(&_definition, layer); + + BaseForm::layerDeletedEvent(layer); +} + +void FormClouds::layerSelectedEvent(int layer) +{ + cloudsLayerCopyDefinition(cloudsGetLayer(&_definition, layer), &_layer); + + BaseForm::layerSelectedEvent(layer); +} diff --git a/gui_qt/formclouds.h b/gui_qt/formclouds.h index e4879e4..84a900e 100644 --- a/gui_qt/formclouds.h +++ b/gui_qt/formclouds.h @@ -18,6 +18,11 @@ public slots: protected slots: virtual void configChangeEvent(); + +protected: + virtual void layerAddedEvent(); + virtual void layerDeletedEvent(int layer); + virtual void layerSelectedEvent(int layer); private: Preview* previewCoverage; diff --git a/gui_qt/widgetwanderer.cpp b/gui_qt/widgetwanderer.cpp index b5760e6..337ad54 100644 --- a/gui_qt/widgetwanderer.cpp +++ b/gui_qt/widgetwanderer.cpp @@ -285,10 +285,10 @@ void WidgetWanderer::paintGL() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glColor3f(0.0, 0.0, 1.0); glBegin(GL_QUADS); - glVertex3f(-500.0, water.height, -500.0); - glVertex3f(-500.0, water.height, 500.0); - glVertex3f(500.0, water.height, 500.0); - glVertex3f(500.0, water.height, -500.0); + glVertex3f(_current_camera.location.x - 500.0, water.height, _current_camera.location.z - 500.0); + glVertex3f(_current_camera.location.x - 500.0, water.height, _current_camera.location.z + 500.0); + glVertex3f(_current_camera.location.x + 500.0, water.height, _current_camera.location.z + 500.0); + glVertex3f(_current_camera.location.x + 500.0, water.height, _current_camera.location.z - 500.0); glEnd(); _renderTerrain(&terrain, &_current_camera, quality); diff --git a/lib_paysages/clouds.c b/lib_paysages/clouds.c index d5a4f02..954d373 100644 --- a/lib_paysages/clouds.c +++ b/lib_paysages/clouds.c @@ -466,17 +466,13 @@ Color cloudsGetColor(CloudsDefinition* definition, Renderer* renderer, Vector3 s int i; Color layer_color, result; - if (end.y < start.y) - { - return cloudsGetColor(definition, renderer, end, start); - } - - if (definition->nblayers < 1 || end.y - start.y < 0.001) + if (definition->nblayers < 1) { return COLOR_TRANSPARENT; } result = COLOR_TRANSPARENT; + /* TODO Order layers */ for (i = 0; i < definition->nblayers; i++) { layer_color = cloudsGetLayerColor(definition->layers + i, renderer, start, end); diff --git a/lib_paysages/render.c b/lib_paysages/render.c index 65dab01..9e0fc20 100644 --- a/lib_paysages/render.c +++ b/lib_paysages/render.c @@ -588,7 +588,7 @@ void* _renderPostProcessChunk(void* data) RenderChunk* chunk = (RenderChunk*)data; #ifdef RENDER_INVERSE - for (y = render_height - 1 - chunk->starty; y >= render_height - 1 - chunk->endy; y--) + for (y = chunk->area->height - 1 - chunk->starty; y >= chunk->area->height - 1 - chunk->endy; y--) #else for (y = chunk->starty; y <= chunk->endy; y++) #endif