diff --git a/gui_qt/formwater.cpp b/gui_qt/formwater.cpp index 97c5801..4935a4d 100644 --- a/gui_qt/formwater.cpp +++ b/gui_qt/formwater.cpp @@ -2,11 +2,16 @@ #include "formwater.h" #include "ui_formwater.h" #include +#include #include "../lib_paysages/water.h" #include "../lib_paysages/shared/functions.h" +#include "../lib_paysages/shared/constants.h" -class PreviewCoverage:private Preview +static WaterDefinition _definition; + +/**************** Previews ****************/ +class PreviewCoverage:public Preview { public: PreviewCoverage(QWidget* parent): @@ -19,32 +24,159 @@ protected: double height; height = terrainGetHeight(x, y); - if (height > 0.0) + if (height > _definition.height) { height = terrainGetHeightNormalized(x, y); return QColor((int)(255.0 * height), (int)(255.0 * height), (int)(255.0 * height)); } else { - return QColor(0, 0, 255); + return QColor(_definition.main_color.r * 255.0, _definition.main_color.g * 255.0, _definition.main_color.b * 255.0); } } }; +class PreviewColor:public Preview +{ +public: + PreviewColor(QWidget* parent): + Preview(parent) + { + } +protected: + QColor getColor(double x, double y) + { + Vector3 eye, look, location; + WaterDefinition definition; + WaterEnvironment environment; + WaterQuality quality; + Color 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); + + if (look.y > -0.0001) + { + result = this->rayCastFromWater(eye, look).hit_color; + return QColor(result.r * 255.0, result.g * 255.0, result.b * 255.0); + } + + location.x = eye.x - look.x * eye.y / look.y; + location.y = 0.0; + location.z = eye.z - look.z * eye.y / look.y; + + if (location.z > 0.0) + { + result = this->rayCastFromWater(eye, look).hit_color; + return QColor(result.r * 255.0, result.g * 255.0, result.b * 255.0); + } + + definition = _definition; + definition.height = 0.0; + environment.reflection_function = (RayCastingFunction)(&this->rayCastFromWater); + environment.refraction_function = (RayCastingFunction)(&this->rayCastFromWater); + environment.toggle_fog = 0; + environment.toggle_shadows = 0; + quality.force_detail = 0.0001; + + result = waterGetColorCustom(location, look, &definition, &quality, &environment).final; + return QColor(result.r * 255.0, result.g * 255.0, result.b * 255.0); + } + +private: + static RayCastingResult rayCastFromWater(Vector3 start, Vector3 direction) + { + RayCastingResult result; + double x, y; + + result.hit = 1; + if (direction.z < 0.0001) + { + result.hit_color = COLOR_WHITE; + } + else + { + x = start.x + direction.x * (0.0 - start.z) / direction.z; + y = start.y + direction.y * (0.0 - start.z) / direction.z; + + if (((int)ceil(x * 0.2) % 2 == 0) ^ ((int)ceil(y * 0.2 - 0.5) % 2 == 0)) + { + result.hit_color = COLOR_WHITE; + } + else + { + result.hit_color = COLOR_GREY; + } + } + /* TODO hit_location */ + + return result; + } +}; + +/**************** Form ****************/ FormWater::FormWater(QWidget *parent) : QWidget(parent), ui(new Ui::FormWater) { - PreviewCoverage* previewCoverage; - ui->setupUi(this); - this->findChild("water_configs")->setCurrentIndex(0); + findChild("water_configs")->setCurrentIndex(0); - previewCoverage = new PreviewCoverage(this->findChild("water_preview_coverage")); + _definition = waterCreateDefinition(); + + previewCoverage = new PreviewCoverage(findChild("water_preview_coverage")); + previewColor = new PreviewColor(findChild("water_preview_color")); + + QObject::connect(findChild("water_height"), SIGNAL(valueChanged(int)), this, SLOT(configChange())); + QObject::connect(findChild("water_transparency"), SIGNAL(valueChanged(int)), this, SLOT(configChange())); + QObject::connect(findChild("water_reflection"), SIGNAL(valueChanged(int)), this, SLOT(configChange())); + QObject::connect(findChild("water_depth_limit"), SIGNAL(valueChanged(int)), this, SLOT(configChange())); + + revertConfig(); } FormWater::~FormWater() { delete ui; } + +void FormWater::dataUpdated() +{ + revertConfig(); +} + +void FormWater::configChange() +{ + _definition.height = (double)findChild("water_height")->value() / 10.0; + _definition.transparency = (double)findChild("water_transparency")->value() / 1000.0; + _definition.reflection = (double)findChild("water_reflection")->value() / 1000.0; + _definition.transparency_depth = (double)findChild("water_depth_limit")->value() / 10.0; + + previewCoverage->redraw(); + previewColor->redraw(); +} + +void FormWater::applyConfig() +{ + waterSetDefinition(_definition); + //guiUpdate(); +} + +void FormWater::revertConfig() +{ + waterCopyDefinition(waterGetDefinition(), &_definition); + + findChild("water_height")->setValue(_definition.height * 10.0); + findChild("water_transparency")->setValue(_definition.transparency * 1000.0); + findChild("water_reflection")->setValue(_definition.reflection * 1000.0); + findChild("water_depth_limit")->setValue(_definition.transparency_depth * 10.0); + + previewCoverage->redraw(); + previewColor->redraw(); +} diff --git a/gui_qt/formwater.h b/gui_qt/formwater.h index ef499c6..1948b33 100644 --- a/gui_qt/formwater.h +++ b/gui_qt/formwater.h @@ -2,6 +2,7 @@ #define FORMWATER_H #include +#include "preview.h" namespace Ui { class FormWater; @@ -15,8 +16,17 @@ public: explicit FormWater(QWidget *parent = 0); ~FormWater(); + void dataUpdated(); + +public slots: + void configChange(); + void applyConfig(); + void revertConfig(); + private: Ui::FormWater *ui; + Preview* previewCoverage; + Preview* previewColor; }; #endif // FORMWATER_H diff --git a/gui_qt/formwater.ui b/gui_qt/formwater.ui index d3ade26..6557ab9 100644 --- a/gui_qt/formwater.ui +++ b/gui_qt/formwater.ui @@ -156,8 +156,8 @@ 0 0 - 98 - 28 + 451 + 438 @@ -185,6 +185,12 @@ + + -300 + + + 300 + Qt::Horizontal @@ -198,8 +204,8 @@ 0 0 - 98 - 28 + 451 + 438 @@ -315,7 +321,7 @@ - 50 + 500 Qt::Horizontal @@ -324,7 +330,7 @@ QSlider::TicksBelow - 1 + 10 diff --git a/gui_qt/main.cc b/gui_qt/main.cc index 1f9bbf6..279d6fa 100644 --- a/gui_qt/main.cc +++ b/gui_qt/main.cc @@ -6,11 +6,11 @@ int main(int argc, char** argv) { + paysagesInit(); + QApplication app(argc, argv); MainWindow window; - paysagesInit(); - window.show(); Preview::startUpdater(); diff --git a/gui_qt/preview.cpp b/gui_qt/preview.cpp index ef0c802..140747e 100644 --- a/gui_qt/preview.cpp +++ b/gui_qt/preview.cpp @@ -15,9 +15,9 @@ public: protected: void run() { - QVectorIterator iter(_previews); while (true) { + QVectorIterator iter(_previews); while (iter.hasNext()) { iter.next()->doRender(); @@ -68,6 +68,13 @@ void Preview::doRender() } } +void Preview::redraw() +{ + lock->lock(); + need_rerender = 1; + lock->unlock(); +} + void Preview::resizeEvent(QResizeEvent* event) { QImage* image; @@ -307,13 +314,6 @@ void Preview::renderPixbuf() // return 1; //} -//void guiPreviewRedraw(SmallPreview* preview) -//{ -// mutexAcquire(preview->lock); -// preview->need_rerender = 1; -// mutexRelease(preview->lock); -//} - //void guiPreviewRedrawAll() //{ // int i; diff --git a/gui_qt/preview.h b/gui_qt/preview.h index b1a6d02..080882a 100644 --- a/gui_qt/preview.h +++ b/gui_qt/preview.h @@ -11,13 +11,13 @@ public: Preview(QWidget* parent); static void startUpdater(); void doRender(); + void redraw(); protected: void resizeEvent(QResizeEvent* event); void paintEvent(QPaintEvent* event); virtual QColor getColor(double x, double y) = 0; -private: void renderPixbuf(); void forceRender();