diff --git a/gui_qt/baseform.cpp b/gui_qt/baseform.cpp index 11e420a..b281e49 100644 --- a/gui_qt/baseform.cpp +++ b/gui_qt/baseform.cpp @@ -8,7 +8,6 @@ #include "inputnoise.h" #include "inputcurve.h" #include "inputmaterial.h" -#include "inputheightmap.h" #include "inputenum.h" #include "inputlayers.h" @@ -28,14 +27,14 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget this->_with_layers = with_layers; setLayout(new QHBoxLayout()); - + control = new QWidget(this); control->setLayout(new QVBoxLayout()); control->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); layout()->addWidget(control); - + _layer_count = 0; - + if (with_layers) { layers = new QWidget(this); @@ -45,7 +44,7 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget label = new QLabel(tr("Layers : "), layers); label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); layers->layout()->addWidget(label); - + _layer_list = new QComboBox(layers); layers->layout()->addWidget(_layer_list); QObject::connect(_layer_list, SIGNAL(currentIndexChanged(int)), this, SLOT(layerListChanged())); @@ -55,7 +54,7 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget _layer_new->setMaximumSize(30, 30); layers->layout()->addWidget(_layer_new); QObject::connect(_layer_new, SIGNAL(clicked()), this, SLOT(layerAddClicked())); - + _layer_del = new QPushButton(QIcon("images/layer_del.png"), "", layers); _layer_del->setToolTip(tr("Delete layer")); _layer_del->setMaximumSize(30, 30); @@ -67,7 +66,7 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget _layer_rename->setMaximumSize(30, 30); layers->layout()->addWidget(_layer_rename); QObject::connect(_layer_rename, SIGNAL(clicked()), this, SLOT(layerRenameClicked())); - + _layer_up = new QPushButton(QIcon("images/layer_up.png"), "", layers); _layer_up->setToolTip(tr("Move layer upward")); _layer_up->setMaximumSize(30, 30); @@ -79,7 +78,7 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget _layer_down->setMaximumSize(30, 30); layers->layout()->addWidget(_layer_down); QObject::connect(_layer_down, SIGNAL(clicked()), this, SLOT(layerDownClicked())); - + control->layout()->addWidget(layers); control->layout()->setAlignment(_buttons, Qt::AlignTop); } @@ -89,12 +88,12 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget _previews->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); layout()->addWidget(_previews); layout()->setAlignment(_previews, Qt::AlignTop); - + _form = new QWidget(this); _form->setLayout(new QHBoxLayout()); control->layout()->addWidget(_form); control->layout()->setAlignment(_form, Qt::AlignTop); - + _form_labels = new QWidget(_form); _form_labels->setLayout(new QVBoxLayout()); _form->layout()->addWidget(_form_labels); @@ -106,7 +105,7 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget _form_controls = new QWidget(_form); _form_controls->setLayout(new QVBoxLayout()); _form->layout()->addWidget(_form_controls); - + _buttons = new QWidget(this); _buttons->setLayout(new QHBoxLayout()); control->layout()->addWidget(_buttons); @@ -124,7 +123,7 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget _button_preset->setIcon(QIcon("images/auto.png")); _button_preset->hide(); connect(_button_preset, SIGNAL(clicked()), this, SLOT(presetChoiceClicked())); - + _auto_update_previews = true; if (auto_apply) @@ -180,7 +179,7 @@ void BaseForm::configChangeEvent() _inputs_list[i]->checkVisibility(true); } } - + if (_auto_update_previews) { updatePreviews(); @@ -203,7 +202,7 @@ void BaseForm::revertConfig() { _inputs_list[i]->revert(); } - + if (_with_layers) { rebuildLayerList(); @@ -234,7 +233,7 @@ void BaseForm::rebuildLayerList() { int selected = _layer_list->currentIndex(); _layer_list->clear(); - + _layer_names = getLayers(); _layer_count = _layer_names.count(); @@ -259,10 +258,10 @@ void BaseForm::rebuildLayerList() void BaseForm::layerAddClicked() { layerAddedEvent(); - + rebuildLayerList(); _layer_list->setCurrentIndex(_layer_list->count() - 1); - + _button_apply->setEnabled(true); _button_revert->setEnabled(true); } @@ -279,7 +278,7 @@ void BaseForm::layerDelClicked() _button_revert->setEnabled(true); } } - + void BaseForm::layerUpClicked() { if (_layer_list->currentIndex() < _layer_count - 1) @@ -287,9 +286,9 @@ void BaseForm::layerUpClicked() layerMovedEvent(_layer_list->currentIndex(), _layer_list->currentIndex() + 1); rebuildLayerList(); - + _layer_list->setCurrentIndex(_layer_list->currentIndex() + 1); - + _button_apply->setEnabled(true); _button_revert->setEnabled(true); } @@ -329,9 +328,9 @@ void BaseForm::layerRenameClicked() void BaseForm::layerListChanged() { bool changed = _button_apply->isEnabled(); - + layerSelectedEvent(_layer_list->currentIndex()); - + _button_apply->setEnabled(changed); _button_revert->setEnabled(changed); } @@ -340,7 +339,7 @@ void BaseForm::presetChoiceClicked() { bool ok; QString item = QInputDialog::getItem(this, tr("Choose a preset"), tr("Preset settings : "), _preset_list, 0, false, &ok); - + if (ok && !item.isEmpty()) { int preset = _preset_list.indexOf(item); @@ -354,13 +353,13 @@ void BaseForm::presetChoiceClicked() void BaseForm::addPreview(BasePreview* preview, QString label) { QLabel* label_widget; - + label_widget = new QLabel(label, _previews); label_widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - + _previews->layout()->addWidget(label_widget); _previews->layout()->addWidget(preview); - + _previews_list.append(preview); } @@ -380,19 +379,19 @@ void BaseForm::addAutoPreset(QString label) BaseInput* BaseForm::addInput(BaseInput* input) { int row_height = 30; - + _form_labels->layout()->addWidget(input->label()); _form_previews->layout()->addWidget(input->preview()); _form_controls->layout()->addWidget(input->control()); - + input->label()->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); input->label()->setMinimumSize(150, row_height); input->label()->setMaximumSize(250, row_height); - + input->preview()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); input->preview()->setMinimumSize(100, row_height); input->preview()->setMaximumSize(250, row_height); - + input->control()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); input->control()->setMinimumSize(280, row_height); input->control()->setMaximumSize(700, row_height); @@ -401,7 +400,7 @@ BaseInput* BaseForm::addInput(BaseInput* input) _inputs_list.append(input); input->revert(); - + return input; } @@ -445,11 +444,6 @@ BaseInput* BaseForm::addInputMaterial(QString label, SurfaceMaterial* material) return addInput(new InputMaterial(_form, label, material)); } -BaseInput* BaseForm::addInputHeightMap(QString label, HeightMap* heightmap, TerrainCanvas* canvas) -{ - return addInput(new InputHeightMap(_form, label, heightmap, canvas)); -} - BaseInput* BaseForm::addInputEnum(QString label, int* value, const QStringList& values) { return addInput(new InputEnum(_form, label, value, values)); @@ -489,7 +483,7 @@ QStringList BaseForm::getLayers() { return QStringList(); } - + void BaseForm::layerAddedEvent() { rebuildLayerList(); @@ -522,7 +516,7 @@ void BaseForm::layerSelectedEvent(int layer) { _previews_list[i]->redraw(); } - + _layer_del->setEnabled(layer >= 0); _layer_rename->setEnabled(layer >= 0); _layer_down->setEnabled(layer > 0); diff --git a/gui_qt/baseform.h b/gui_qt/baseform.h index 154b16f..311e13e 100644 --- a/gui_qt/baseform.h +++ b/gui_qt/baseform.h @@ -15,7 +15,6 @@ #include "../lib_paysages/layers.h" #include "../lib_paysages/heightmap.h" #include "../lib_paysages/pack.h" -#include "../lib_paysages/terraincanvas.h" class BaseForm:public QWidget { @@ -37,7 +36,7 @@ public slots: protected slots: virtual void configChangeEvent(); virtual void autoPresetSelected(int preset); - + private slots: void rebuildLayerList(); void layerAddClicked(); @@ -61,16 +60,15 @@ protected: BaseInput* addInputNoise(QString label, NoiseGenerator* value); BaseInput* addInputCurve(QString label, Curve* value, double xmin, double xmax, double ymin, double ymax, QString xlabel, QString ylabel); BaseInput* addInputMaterial(QString label, SurfaceMaterial* material); - BaseInput* addInputHeightMap(QString label, HeightMap* heightmap, TerrainCanvas* canvas); BaseInput* addInputEnum(QString label, int* value, const QStringList& values); BaseInput* addInputLayers(QString label, Layers* value, FormLayerBuilder form_builder); - + void updatePreviews(); void disablePreviewsUpdate(); - + int currentLayer(); virtual QStringList getLayers(); - + virtual void layerAddedEvent(); virtual void layerDeletedEvent(int layer); virtual void layerMovedEvent(int layer, int new_position); @@ -91,11 +89,11 @@ private: QWidget* _previews; QVector _previews_list; bool _auto_update_previews; - + QVector _inputs_list; - + QStringList _preset_list; - + bool _with_layers; QComboBox* _layer_list; int _layer_count; diff --git a/gui_qt/dialogheightmap.cpp b/gui_qt/dialogheightmap.cpp index 313e303..d0e2efd 100644 --- a/gui_qt/dialogheightmap.cpp +++ b/gui_qt/dialogheightmap.cpp @@ -9,51 +9,49 @@ #include #include #include -#include "../lib_paysages/terrain.h" #include "../lib_paysages/scenery.h" #include "widgetheightmap.h" /**************** Dialog form ****************/ -DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap, TerrainCanvas* canvas) : DialogWithPreview(parent) +DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap, void* canvas) : DialogWithPreview(parent) { QWidget* mainarea; QWidget* buttons; QWidget* panel; QWidget* viewer; QGridLayout* viewer_layout; - + QLabel* label; QSlider* slider; QPushButton* button; QComboBox* combobox; - - _canvas = canvas; + _value_original = heightmap; _value_modified = heightmapCreate(); heightmapCopy(_value_original, &_value_modified); setLayout(new QVBoxLayout()); - + // Dialog layout (main area + buttons) mainarea = new QWidget(this); mainarea->setLayout(new QHBoxLayout()); this->layout()->addWidget(mainarea); - + buttons = new QWidget(this); buttons->setLayout(new QHBoxLayout()); buttons->layout()->setAlignment(buttons, Qt::AlignBottom); this->layout()->addWidget(buttons); - + // Main area layout (viewer + panel) viewer = new QWidget(mainarea); viewer_layout = new QGridLayout(); viewer->setLayout(viewer_layout); mainarea->layout()->addWidget(viewer); - + panel = new QWidget(mainarea); panel->setLayout(new QVBoxLayout()); mainarea->layout()->addWidget(panel); mainarea->layout()->setAlignment(panel, Qt::AlignTop); - + // Viewer layout (3d display + sliders) _3dview = new WidgetHeightMap(viewer, &_value_modified); viewer_layout->addWidget(_3dview, 0, 0); @@ -65,7 +63,7 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap, TerrainC slider->setRange(-300, 700); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(angleVChanged(int))); viewer_layout->addWidget(slider, 0, 1); - + // Panel layout if (canvas) { @@ -81,20 +79,20 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap, TerrainC button = new QPushButton(tr("Change resolution"), panel); connect(button, SIGNAL(clicked()), this, SLOT(changeResolution())); panel->layout()->addWidget(button); - + _resolution_label = new QLabel("", panel); panel->layout()->addWidget(_resolution_label); updateResolutionLabel(); - + combobox = new QComboBox(panel); combobox->addItem(tr("Raise / lower")); combobox->addItem(tr("Add noise / smooth")); connect(combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(brushModeChanged(int))); panel->layout()->addWidget(combobox); - + label = new QLabel(tr("Brush size"), panel); panel->layout()->addWidget(label); - + slider = new QSlider(Qt::Horizontal, panel); slider->setRange(6, 300); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(brushSizeChanged(int))); @@ -103,22 +101,22 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap, TerrainC label = new QLabel(tr("Brush smoothing"), panel); panel->layout()->addWidget(label); - + slider = new QSlider(Qt::Horizontal, panel); slider->setRange(0, 1000); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(brushSmoothingChanged(int))); panel->layout()->addWidget(slider); slider->setValue(600); - + label = new QLabel(tr("Brush strength"), panel); panel->layout()->addWidget(label); - + slider = new QSlider(Qt::Horizontal, panel); slider->setRange(0, 1000); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(brushStrengthChanged(int))); panel->layout()->addWidget(slider); slider->setValue(200); - + // Buttons layout button = new QPushButton(tr("Cancel"), buttons); button->setIcon(QIcon("images/cancel.png")); @@ -138,7 +136,7 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap, TerrainC setWindowTitle(tr("Paysages 3D - Height map painting")); } -bool DialogHeightMap::editHeightMap(QWidget* parent, HeightMap* heightmap, TerrainCanvas* canvas) +bool DialogHeightMap::editHeightMap(QWidget* parent, HeightMap* heightmap, void* canvas) { int result; @@ -206,7 +204,7 @@ void DialogHeightMap::loadFromFile() void DialogHeightMap::resetToTerrain() { - if (_canvas) + /*if (_canvas) { TerrainDefinition terrain; @@ -216,9 +214,9 @@ void DialogHeightMap::resetToTerrain() heightmapRevertToTerrain(&_value_modified, &terrain, &_canvas->area); terrainDeleteDefinition(&terrain); - + _3dview->revert(); - } + }*/ } void DialogHeightMap::changeResolution() @@ -226,7 +224,7 @@ void DialogHeightMap::changeResolution() QString result; QStringList items; int current; - + items << QString("64 x 64") << QString("128 x 128") << QString("256 x 256") << QString("512 x 512"); current = 1; if (_value_modified.resolution_x == 64 && _value_modified.resolution_z == 64) @@ -261,7 +259,7 @@ void DialogHeightMap::changeResolution() { new_res_x = new_res_z = 128; } - + if (new_res_x != _value_modified.resolution_x or new_res_z != _value_modified.resolution_z) { heightmapChangeResolution(&_value_modified, new_res_x, new_res_z); diff --git a/gui_qt/dialogheightmap.h b/gui_qt/dialogheightmap.h index 757e624..dd6f84d 100644 --- a/gui_qt/dialogheightmap.h +++ b/gui_qt/dialogheightmap.h @@ -5,19 +5,18 @@ #include "tools.h" #include "widgetheightmap.h" #include "../lib_paysages/heightmap.h" -#include "../lib_paysages/terraincanvas.h" class DialogHeightMap : public DialogWithPreview { Q_OBJECT public: - explicit DialogHeightMap(QWidget* parent, HeightMap* heightmap, TerrainCanvas* canvas); - static bool editHeightMap(QWidget* parent, HeightMap* heightmap, TerrainCanvas* canvas); + explicit DialogHeightMap(QWidget* parent, HeightMap* heightmap, void* canvas); + static bool editHeightMap(QWidget* parent, HeightMap* heightmap, void* canvas); public slots: virtual void accept(); void revert(); - + private slots: void angleHChanged(int value); void angleVChanged(int value); @@ -35,7 +34,6 @@ private: HeightMap _value_modified; WidgetHeightMap* _3dview; QLabel* _resolution_label; - TerrainCanvas* _canvas; }; #endif diff --git a/gui_qt/explorerchunkterrain.cpp b/gui_qt/explorerchunkterrain.cpp index 6b4425c..354b2cb 100644 --- a/gui_qt/explorerchunkterrain.cpp +++ b/gui_qt/explorerchunkterrain.cpp @@ -10,14 +10,14 @@ ExplorerChunkTerrain::ExplorerChunkTerrain(Renderer* renderer, double x, double _startz = z; _size = size; _overall_step = size * (double)nbchunks; - + _tessellation_max_size = 32; _tessellation = new double[(_tessellation_max_size + 1) * (_tessellation_max_size + 1)]; _tessellation_current_size = 0; _tessellation_step = _size / (double)_tessellation_max_size; - + setMaxTextureSize(128); - + maintain(); } @@ -36,7 +36,7 @@ void ExplorerChunkTerrain::onResetEvent() bool ExplorerChunkTerrain::onMaintainEvent() { Renderer* renderer = this->renderer(); - + // Improve heightmap resolution if (_tessellation_current_size < _tessellation_max_size) { @@ -49,7 +49,7 @@ bool ExplorerChunkTerrain::onMaintainEvent() { if (_tessellation_current_size == 0 || i % old_tessellation_inc != 0 || j % old_tessellation_inc != 0) { - double height = renderer->getTerrainHeight(renderer, _startx + _tessellation_step * (double)i, _startz + _tessellation_step * (double)j); + double height = renderer->terrain->getHeight(renderer, _startx + _tessellation_step * (double)i, _startz + _tessellation_step * (double)j); _tessellation[j * (_tessellation_max_size + 1) + i] = height; } } @@ -100,7 +100,7 @@ void ExplorerChunkTerrain::onRenderEvent(QGLWidget* widget) int tessellation_size = _tessellation_current_size; double tsize = 1.0 / (double)_tessellation_max_size; _lock_data.unlock(); - + if (tessellation_size <= 1) { return; @@ -149,10 +149,10 @@ Color ExplorerChunkTerrain::getTextureColor(double x, double y) Vector3 ExplorerChunkTerrain::getCenter() { Vector3 result; - + result.x = _startx + _size / 2.0; result.y = 0.0; result.z = _startz + _size / 2.0; - + return result; } diff --git a/gui_qt/formrender.cpp b/gui_qt/formrender.cpp index 27196bc..3f3746d 100644 --- a/gui_qt/formrender.cpp +++ b/gui_qt/formrender.cpp @@ -16,18 +16,17 @@ public: { _renderer = rendererCreate(); _renderer.applyTextures = _applyTextures; - _renderer.getTerrainHeight = _getTerrainHeight; - _renderer.alterLight = _alterLight; _renderer.getLightStatus = _getLightStatus; _renderer.camera_location.x = 0.0; _renderer.camera_location.y = 50.0; _renderer.camera_location.z = 0.0; - _terrain = terrainCreateDefinition(); _textures = texturesCreateDefinition(); _lighting = lightingCreateDefinition(); _water = waterCreateDefinition(); + _atmosphere = (AtmosphereDefinition*)AtmosphereDefinitionClass.create(); + _terrain = (TerrainDefinition*)TerrainDefinitionClass.create(); _renderer.customData[0] = &_terrain; _renderer.customData[1] = &_textures; @@ -44,7 +43,7 @@ protected: { Vector3 down = {0.0, -1.0, 0.0}; Vector3 location; - double height = terrainGetHeight(&_terrain, x, y); + double height = _renderer.terrain->getHeight(&_renderer, x, y); if (height < _water.height) { @@ -55,12 +54,14 @@ protected: } else { - return colorToQColor(terrainGetColor(&_terrain, &_renderer, x, y, scaling)); + location.x = x; + location.y = height; + location.z = y; + return colorToQColor(_renderer.terrain->getFinalColor(&_renderer, location, scaling)); } } void updateData() { - sceneryGetTerrain(&_terrain); sceneryGetLighting(&_lighting); sceneryGetTextures(&_textures); sceneryGetWater(&_water); @@ -68,30 +69,23 @@ protected: sceneryGetAtmosphere(_atmosphere); AtmosphereRendererClass.bind(_renderer.atmosphere, _atmosphere); _renderer.atmosphere->applyAerialPerspective = _applyAerialPerspective; + + sceneryGetTerrain(_terrain); + TerrainRendererClass.bind(_renderer.terrain, _terrain); } private: Renderer _renderer; - TerrainDefinition _terrain; + TerrainDefinition* _terrain; WaterDefinition _water; TexturesDefinition _textures; LightingDefinition _lighting; AtmosphereDefinition* _atmosphere; - static double _getTerrainHeight(Renderer* renderer, double x, double z) - { - return terrainGetHeight((TerrainDefinition*)(renderer->customData[0]), x, z); - } - static Color _applyTextures(Renderer* renderer, Vector3 location, double precision) { return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision); } - static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location) - { - light->color = terrainLightFilter((TerrainDefinition*)(renderer->customData[0]), renderer, light->color, location, v3Scale(light->direction, -1000.0), v3Scale(light->direction, -1.0)); - } - static void _getLightStatus(Renderer* renderer, LightStatus* status, Vector3 location) { lightingGetStatus((LightingDefinition*)renderer->customData[2], renderer, location, status); diff --git a/gui_qt/formterrain.cpp b/gui_qt/formterrain.cpp index ba8b99c..e9c4d6f 100644 --- a/gui_qt/formterrain.cpp +++ b/gui_qt/formterrain.cpp @@ -3,14 +3,12 @@ #include #include #include -#include "formterraincanvas.h" #include "tools.h" -#include "../lib_paysages/terrain.h" #include "../lib_paysages/scenery.h" #include "../lib_paysages/euclid.h" -static TerrainDefinition _definition; +static TerrainDefinition* _definition; /**************** Previews ****************/ class PreviewTerrainHeight:public BasePreview @@ -18,27 +16,28 @@ class PreviewTerrainHeight:public BasePreview public: PreviewTerrainHeight(QWidget* parent):BasePreview(parent) { - _preview_definition = terrainCreateDefinition(); - + _renderer = rendererCreate(); + addOsd(QString("geolocation")); - + configScaling(0.5, 200.0, 3.0, 50.0); configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0); } protected: QColor getColor(double x, double y) { - double height; + double height = 0.0; - height = terrainGetHeightNormalized(&_preview_definition, x, y); + // TODO + //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); + TerrainRendererClass.bind(_renderer.terrain, _definition); } private: - TerrainDefinition _preview_definition; + Renderer _renderer; }; class PreviewTerrainColor:public BasePreview @@ -52,8 +51,6 @@ public: _renderer = rendererCreate(); _renderer.render_quality = 3; _renderer.applyTextures = _applyTextures; - _renderer.getTerrainHeight = _getTerrainHeight; - _renderer.alterLight = _alterLight; _renderer.getLightStatus = _getLightStatus; _renderer.camera_location.x = 0.0; _renderer.camera_location.y = 50.0; @@ -83,7 +80,6 @@ public: lightingAddLight(&_lighting, light); lightingValidateDefinition(&_lighting); - _terrain = terrainCreateDefinition(); _textures = texturesCreateDefinition(); texture = (TextureLayerDefinition*)layersGetLayer(_textures.layers, layersAddLayer(_textures.layers, NULL)); texture->material.base = COLOR_WHITE; @@ -92,92 +88,80 @@ public: texture->bump_height = 0.0; texturesLayerValidateDefinition(texture); - _renderer.customData[0] = &_terrain; _renderer.customData[1] = &_textures; _renderer.customData[2] = &_lighting; addOsd(QString("geolocation")); - + configScaling(0.5, 200.0, 3.0, 50.0); configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0); } protected: QColor getColor(double x, double y) { - return colorToQColor(terrainGetColor(&_terrain, &_renderer, x, y, scaling)); + Vector3 point; + + point.x = x; + point.y = _renderer.terrain->getHeight(&_renderer, x, y); + point.z = y; + + return colorToQColor(_renderer.terrain->getFinalColor(&_renderer, point, scaling)); } void updateData() { - terrainCopyDefinition(&_definition, &_terrain); + TerrainRendererClass.bind(_renderer.terrain, _definition); //sceneryGetTextures(&_textures); } private: Renderer _renderer; - TerrainDefinition _terrain; TexturesDefinition _textures; LightingDefinition _lighting; - static double _getTerrainHeight(Renderer* renderer, double x, double z) - { - return terrainGetHeight((TerrainDefinition*)(renderer->customData[0]), x, z); - } - static Color _applyTextures(Renderer* renderer, Vector3 location, double precision) { return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision); } - static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location) - { - light->color = terrainLightFilter((TerrainDefinition*)(renderer->customData[0]), renderer, light->color, location, v3Scale(light->direction, -1000.0), v3Scale(light->direction, -1.0)); - } - static void _getLightStatus(Renderer* renderer, LightStatus* status, Vector3 location) { lightingGetStatus((LightingDefinition*)renderer->customData[2], renderer, location, status); } - + }; /**************** Form ****************/ -static BaseFormLayer* _formBuilderCanvas(DialogLayers* parent, Layers* layers) -{ - return new FormTerrainCanvas(parent, layers); -} - FormTerrain::FormTerrain(QWidget *parent): BaseForm(parent) { - _definition = terrainCreateDefinition(); + _definition = (TerrainDefinition*)TerrainDefinitionClass.create(); previewHeight = new PreviewTerrainHeight(this); previewColor = new PreviewTerrainColor(this); addPreview(previewHeight, tr("Height preview (normalized)")); addPreview(previewColor, tr("Lighted preview (no texture)")); - addInputNoise(tr("Noise"), _definition.height_noise); - addInputDouble(tr("Height"), &_definition.height_factor, 0.0, 20.0, 0.1, 1.0); - addInputDouble(tr("Scaling"), &_definition.scaling, 20.0, 200.0, 1.0, 10.0); - addInputDouble(tr("Shadow smoothing"), &_definition.shadow_smoothing, 0.0, 0.3, 0.003, 0.03); - addInputLayers(tr("Canvases"), _definition.canvases, _formBuilderCanvas); + //addInputNoise(tr("Noise"), _definition.height_noise); + addInputDouble(tr("Height"), &_definition->height, 0.0, 20.0, 0.1, 1.0); + addInputDouble(tr("Scaling"), &_definition->scaling, 20.0, 200.0, 1.0, 10.0); + addInputDouble(tr("Shadow smoothing"), &_definition->shadow_smoothing, 0.0, 0.3, 0.003, 0.03); revertConfig(); } void FormTerrain::revertConfig() { - sceneryGetTerrain(&_definition); + sceneryGetTerrain(_definition); BaseForm::revertConfig(); } void FormTerrain::applyConfig() { - scenerySetTerrain(&_definition); + scenerySetTerrain(_definition); BaseForm::applyConfig(); } void FormTerrain::configChangeEvent() { - terrainValidateDefinition(&_definition); + TerrainDefinitionClass.validate(_definition); BaseForm::configChangeEvent(); } diff --git a/gui_qt/formterraincanvas.cpp b/gui_qt/formterraincanvas.cpp deleted file mode 100644 index 69ca1a0..0000000 --- a/gui_qt/formterraincanvas.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "formterraincanvas.h" - -/**************** Form ****************/ -class PreviewTerrainCanvasHeight:public BasePreview -{ -public: - PreviewTerrainCanvasHeight(QWidget* parent, TerrainCanvas* canvas):BasePreview(parent) - { - _base_canvas = canvas; - _preview_canvas = terrainCanvasCreate(); - - //addOsd(QString("geolocation")); - - configScaling(1.0, 1.0, 1.0, 1.0); - //configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0); - } - - ~PreviewTerrainCanvasHeight() - { - terrainCanvasDelete(_preview_canvas); - } -protected: - QColor getColor(double x, double y) - { - Color col, mask; - double height; - - if (_max - _min < 0.000001) - { - return Qt::black; - } - else - { - height = heightmapGetValue(&_preview_canvas->height_map, x + 0.5, y + 0.5); - col.r = col.g = col.b = (height - _min) / (_max - _min); - col.a = 1.0; - - mask.r = 0.3; - mask.g = 0.0; - mask.b = 0.0; - mask.a = 1.0 - terrainCanvasGetMaskValue(_preview_canvas, x + 0.5, y + 0.5); - colorMask(&col, &mask); - - return colorToQColor(col); - } - } - void updateData() - { - terrainCanvasCopy(_base_canvas, _preview_canvas); - heightmapGetLimits(&_preview_canvas->height_map, &_min, &_max); - } -private: - TerrainCanvas* _base_canvas; - TerrainCanvas* _preview_canvas; - double _max, _min; -}; - -/**************** Form ****************/ -FormTerrainCanvas::FormTerrainCanvas(QWidget *parent, Layers* layers): - BaseFormLayer(parent, layers) -{ - _definition = terrainCanvasCreate(); - - // TODO Area - //addInputDouble(tr("Apply at height"), &_definition->offset_y, -20.0, 20.0, 0.1, 1.0); - addInputHeightMap(tr("Height map"), &_definition->height_map, _definition); - //addInputDouble(tr("Canvas height"), &_definition->height_factor, 0.0, 20.0, 0.1, 1.0); - addInputNoise(tr("Detail noise"), _definition->detail_noise); - addInputDouble(tr("Detail noise height"), &_definition->detail_height_factor, 0.0, 20.0, 0.1, 1.0); - addInputDouble(tr("Detail noise scaling"), &_definition->detail_scaling, 0.0, 20.0, 0.1, 1.0); - addInputEnum(tr("Mask shape"), &_definition->mask.mode, QStringList(tr("Square")) << tr("Circle")); - addInputDouble(tr("Mask smoothing"), &_definition->mask.smoothing, 0.0, 1.0, 0.01, 0.1); - - _previewHeight = new PreviewTerrainCanvasHeight(this, _definition); - addPreview(_previewHeight, tr("Height preview (normalized)")); - - revertConfig(); -} - -FormTerrainCanvas::~FormTerrainCanvas() -{ - terrainCanvasDelete(_definition); -} - -void FormTerrainCanvas::layerReadCurrentFrom(void* layer_definition) -{ - terrainCanvasCopy((TerrainCanvas*)layer_definition, _definition); -} - -void FormTerrainCanvas::layerWriteCurrentTo(void* layer_definition) -{ - terrainCanvasCopy(_definition, (TerrainCanvas*)layer_definition); -} - -void FormTerrainCanvas::afterLayerAdded(void* layer_definition) -{ - terrainCanvasRevertToTerrain((TerrainCanvas*)layer_definition); -} diff --git a/gui_qt/formterraincanvas.h b/gui_qt/formterraincanvas.h deleted file mode 100644 index 2b19db0..0000000 --- a/gui_qt/formterraincanvas.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _PAYSAGES_QT_FORMTERRAINCANVAS_H_ -#define _PAYSAGES_QT_FORMTERRAINCANVAS_H_ - -#include -#include "basepreview.h" -#include "baseformlayer.h" -#include "../lib_paysages/terraincanvas.h" - -class FormTerrainCanvas : public BaseFormLayer -{ - Q_OBJECT - -public: - FormTerrainCanvas(QWidget* parent, Layers* layers); - ~FormTerrainCanvas(); - -protected: - virtual void layerReadCurrentFrom(void* layer_definition); - virtual void layerWriteCurrentTo(void* layer_definition); - virtual void afterLayerAdded(void* layer_definition); - -private: - TerrainCanvas* _definition; - BasePreview* _previewHeight; - BasePreview* _previewColor; -}; - -#endif diff --git a/gui_qt/formtextures.cpp b/gui_qt/formtextures.cpp index 0ca382f..4f4e207 100644 --- a/gui_qt/formtextures.cpp +++ b/gui_qt/formtextures.cpp @@ -17,12 +17,10 @@ class PreviewTexturesCoverage:public BasePreview public: PreviewTexturesCoverage(QWidget* parent, TextureLayerDefinition* layer):BasePreview(parent) { - _terrain = terrainCreateDefinition(); + _terrain = (TerrainDefinition*)TerrainDefinitionClass.create(); _renderer = rendererCreate(); _renderer.render_quality = 3; - _renderer.getTerrainHeight = _getTerrainHeight; - _renderer.customData[0] = &_terrain; _original_layer = layer; _preview_layer = texturesLayerCreateDefinition(); @@ -42,27 +40,24 @@ protected: Vector3 location; double coverage; location.x = x; - location.y = terrainGetHeight(&_terrain, x, y); + location.y = _renderer.terrain->getHeight(&_renderer, x, y); location.z = y; coverage = texturesGetLayerCoverage(_preview_layer, &_renderer, location, this->scaling); return QColor::fromRgbF(coverage, coverage, coverage, 1.0); } void updateData() { - sceneryGetTerrain(&_terrain); + sceneryGetTerrain(_terrain); + TerrainRendererClass.bind(_renderer.terrain, _terrain); + texturesLayerCopyDefinition(_original_layer, _preview_layer); } private: - static double _getTerrainHeight(Renderer* renderer, double x, double z) - { - return terrainGetHeight((TerrainDefinition*)(renderer->customData[0]), x, z); - } - Renderer _renderer; TextureLayerDefinition* _original_layer; TextureLayerDefinition* _preview_layer; - TerrainDefinition _terrain; + TerrainDefinition* _terrain; }; class PreviewTexturesColor:public BasePreview diff --git a/gui_qt/formwater.cpp b/gui_qt/formwater.cpp index 2e10a37..4f2bc7c 100644 --- a/gui_qt/formwater.cpp +++ b/gui_qt/formwater.cpp @@ -9,7 +9,6 @@ #include "../lib_paysages/lighting.h" #include "../lib_paysages/renderer.h" #include "../lib_paysages/scenery.h" -#include "../lib_paysages/terrain.h" #include "../lib_paysages/water.h" #include "tools.h" @@ -21,15 +20,15 @@ class PreviewWaterCoverage:public BasePreview public: PreviewWaterCoverage(QWidget* parent):BasePreview(parent) { - _water = waterCreateDefinition(); - _terrain = terrainCreateDefinition(); - + /*_water = waterCreateDefinition(); + _terrain = terrainCreateDefinition();*/ + addOsd(QString("geolocation")); - + configScaling(0.5, 200.0, 3.0, 50.0); configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0); } -protected: +/*protected: QColor getColor(double x, double y) { double height; @@ -49,7 +48,7 @@ protected: { waterCopyDefinition(&_definition, &_water); sceneryGetTerrain(&_terrain); - } + }*/ private: WaterDefinition _water; TerrainDefinition _terrain; @@ -61,12 +60,12 @@ public: PreviewWaterColor(QWidget* parent):BasePreview(parent) { LightDefinition light; - + _background = 0; _lighting_enabled = false; - + _water = waterCreateDefinition(); - + _lighting = lightingCreateDefinition(); light.color = COLOR_WHITE; light.direction.x = 0.0; @@ -85,7 +84,7 @@ public: _renderer.customData[0] = &_water; _renderer.customData[1] = &_lighting; _renderer.customData[2] = this; - + configScaling(10.0, 1000.0, 10.0, 250.0); //configScrolling(-30.0, 30.0, 0.0, -20.0, 20.0, 0.0); @@ -149,7 +148,7 @@ private: WaterDefinition _water; LightingDefinition _lighting; bool _lighting_enabled; - + static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds) { RayCastingResult result; @@ -208,7 +207,7 @@ FormWater::FormWater(QWidget *parent): { addAutoPreset(tr("Lake surface")); addAutoPreset(tr("Standard sea")); - + _definition = waterCreateDefinition(); previewCoverage = new PreviewWaterCoverage(this); diff --git a/gui_qt/inputheightmap.cpp b/gui_qt/inputheightmap.cpp deleted file mode 100644 index d3c599d..0000000 --- a/gui_qt/inputheightmap.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "inputheightmap.h" - -#include -#include -#include "dialogheightmap.h" - -class SmallPreviewHeightMap:public QWidget -{ -public: - SmallPreviewHeightMap(QWidget* parent, HeightMap* value) : QWidget(parent) - { - _value = value; - } - - void paintEvent(QPaintEvent* event) - { - double min, max, value, fx, fy; - int ivalue; - QPainter painter(this); - - heightmapGetLimits(_value, &min, &max); - if (max - min < 0.000001) - { - painter.fillRect(rect(), Qt::black); - return; - } - - fx = 1.0 / (double)(width() - 1); - fy = 1.0 / (double)(height() - 1); - for (int x = 0; x < width(); x++) - { - for (int y = 0; y < height(); y++) - { - value = heightmapGetRawValue(_value, fx * x, fy * y); - ivalue = (int)(255.0 * (value - min) / (max - min)); - if (ivalue > 255 || ivalue < 0) - { - ivalue = 128; - } - painter.setPen(QColor(ivalue, ivalue, ivalue)); - painter.drawPoint(x, y); - } - } - } - HeightMap* _value; -}; - -InputHeightMap::InputHeightMap(QWidget* form, QString label, HeightMap* value, TerrainCanvas* canvas) : BaseInput(form, label) -{ - _value = value; - _canvas = canvas; - - _preview = new SmallPreviewHeightMap(form, value); - _preview->setMinimumSize(100, 100); - - _control = new QPushButton(tr("Paint"), form); - _control->setMaximumWidth(150); - - connect((QPushButton*)_control, SIGNAL(clicked()), this, SLOT(editHeightMap())); -} - -void InputHeightMap::updatePreview() -{ - _preview->update(); - - BaseInput::updatePreview(); -} - -void InputHeightMap::applyValue() -{ - BaseInput::applyValue(); -} - -void InputHeightMap::revert() -{ - BaseInput::revert(); -} - -void InputHeightMap::editHeightMap() -{ - if (DialogHeightMap::editHeightMap(_control, _value, _canvas)) - { - applyValue(); - } -} diff --git a/gui_qt/inputheightmap.h b/gui_qt/inputheightmap.h deleted file mode 100644 index f25189d..0000000 --- a/gui_qt/inputheightmap.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _PAYSAGES_QT_INPUTHEIGHTMAP_H_ -#define _PAYSAGES_QT_INPUTHEIGHTMAP_H_ - -#include -#include "baseinput.h" - -#include "../lib_paysages/heightmap.h" -#include "../lib_paysages/terraincanvas.h" - -class InputHeightMap:public BaseInput -{ - Q_OBJECT - -public: - InputHeightMap(QWidget* form, QString label, HeightMap* value, TerrainCanvas* canvas); - -public slots: - virtual void updatePreview(); - virtual void applyValue(); - virtual void revert(); - -private slots: - void editHeightMap(); - -private: - HeightMap* _value; - TerrainCanvas* _canvas; -}; - -#endif diff --git a/gui_qt/mainwindow.cpp b/gui_qt/mainwindow.cpp index 4aab54b..600ec0a 100644 --- a/gui_qt/mainwindow.cpp +++ b/gui_qt/mainwindow.cpp @@ -54,7 +54,7 @@ int main(int argc, char** argv) } BasePreview::initDrawers(); - + window = new MainWindow(); window->show(); @@ -127,14 +127,14 @@ QMainWindow(parent) toolbar->addAction(QIcon("images/explore.png"), tr("&Explore (F2)"), this, SLOT(explore3D()))->setShortcut(QKeySequence(tr("F2"))); toolbar->addAction(QIcon("images/render.png"), tr("&Quick\nrender (F5)"), this, SLOT(quickPreview()))->setShortcut(QKeySequence(tr("F5"))); toolbar->addAction(QIcon("images/about.png"), tr("&About"), this, SLOT(showAboutDialog())); - + setCentralWidget(tabs); setWindowTitle("Paysages 3D"); setWindowIcon(QIcon("images/logo_32.png")); - + scenerySetCustomDataCallback(MainWindow::guiSaveCallback, MainWindow::guiLoadCallback, this); - + refreshAll(); } @@ -144,20 +144,20 @@ bool MainWindow::event(QEvent* event) { BasePreview::reviveAll(); } - + return QMainWindow::event(event); } void MainWindow::refreshAll() { logDebug("[MainWindow] Refreshing whole UI"); - + // Refresh all tabs for (int i = 0; i < _forms.size(); i++) { _forms[i]->revertConfig(); } - + // Refresh preview OSD CameraDefinition camera = cameraCreateDefinition(); PreviewOsd* osd = PreviewOsd::getInstance(QString("geolocation")); diff --git a/gui_qt/widgetexplorer.cpp b/gui_qt/widgetexplorer.cpp index 0e60c5d..ecbb7f9 100644 --- a/gui_qt/widgetexplorer.cpp +++ b/gui_qt/widgetexplorer.cpp @@ -25,12 +25,12 @@ public: { _running = false; } - + static inline void usleep(unsigned long us) { QThread::usleep(us); } - + protected: void run() { @@ -40,7 +40,7 @@ protected: QThread::usleep(10000); } } - + private: bool _running; WidgetExplorer* _wanderer; @@ -48,21 +48,11 @@ private: static QVector _threads; -static double _getTerrainHeight(Renderer* renderer, double x, double z) -{ - return terrainGetHeight((TerrainDefinition*)(renderer->customData[0]), x, z); -} - static Color _applyTextures(Renderer* renderer, Vector3 location, double precision) { return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision); } -static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location) -{ - light->color = terrainLightFilter((TerrainDefinition*)(renderer->customData[0]), renderer, light->color, location, v3Scale(light->direction, -1000.0), v3Scale(light->direction, -1.0)); -} - static void _getLightStatus(Renderer* renderer, LightStatus* status, Vector3 location) { lightingGetStatus((LightingDefinition*)renderer->customData[2], renderer, location, status); @@ -79,24 +69,19 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera): _water = waterCreateDefinition(); sceneryGetWater(&_water); - _terrain = terrainCreateDefinition(); - sceneryGetTerrain(&_terrain); _textures = texturesCreateDefinition(); sceneryGetTextures(&_textures); _lighting = lightingCreateDefinition(); sceneryGetLighting(&_lighting); - + _renderer = sceneryCreateStandardRenderer(); _renderer.render_quality = 3; - _renderer.customData[0] = &_terrain; _renderer.customData[1] = &_textures; _renderer.customData[2] = &_lighting; _renderer.customData[3] = &_water; _renderer.applyTextures = _applyTextures; - _renderer.getTerrainHeight = _getTerrainHeight; - _renderer.alterLight = _alterLight; _renderer.getLightStatus = _getLightStatus; - + _updated = false; // Add terrain @@ -113,7 +98,7 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera): _updateQueue.append(chunk); } } - + // Add skybox for (int orientation = 0; orientation < 6; orientation++) { @@ -124,7 +109,7 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera): startThreads(); startTimer(500); - + _average_frame_time = 0.05; _quality = 3; _last_mouse_x = 0; @@ -134,7 +119,7 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera): WidgetExplorer::~WidgetExplorer() { stopThreads(); - + for (int i = 0; i < _chunks.count(); i++) { delete _chunks[i]; @@ -145,15 +130,15 @@ WidgetExplorer::~WidgetExplorer() void WidgetExplorer::startThreads() { int nbcore; - + _alive = true; - + nbcore = QThread::idealThreadCount(); if (nbcore < 1) { nbcore = 1; } - + for (int i = 0; i < nbcore; i++) { _threads.append(new ChunkMaintenanceThread(this)); @@ -185,7 +170,7 @@ bool _cmpChunks(const BaseExplorerChunk* c1, const BaseExplorerChunk* c2) void WidgetExplorer::performChunksMaintenance() { BaseExplorerChunk* chunk; - + _lock_chunks.lock(); if (_updateQueue.count() > 0) { @@ -197,7 +182,7 @@ void WidgetExplorer::performChunksMaintenance() _lock_chunks.unlock(); return; } - + if (chunk->maintain()) { if (!_alive) @@ -207,7 +192,7 @@ void WidgetExplorer::performChunksMaintenance() _updated = true; } - + _lock_chunks.lock(); _updateQueue.append(chunk); _lock_chunks.unlock(); @@ -361,7 +346,7 @@ void WidgetExplorer::timerEvent(QTimerEvent *event) _updated = false; updateGL(); } - + for (int i = 0; i < _chunks.count(); i++) { _chunks[i]->updatePriority(&_current_camera); @@ -397,13 +382,13 @@ void WidgetExplorer::initializeGL() void WidgetExplorer::resizeGL(int w, int h) { cameraSetRenderSize(&_current_camera, w, h); - + glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(_current_camera.yfov * 180.0 / M_PI, _current_camera.xratio, _current_camera.znear, _current_camera.zfar); - + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -412,17 +397,17 @@ void WidgetExplorer::paintGL() GLenum error_code; QTime start_time; double frame_time; - + if (_current_camera.location.y > 30.0) { _current_camera.location.y = 30.0; } - + cameraValidateDefinition(&_current_camera, 1); _renderer.camera_location = _current_camera.location; - + start_time = QTime::currentTime(); - + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(_current_camera.location.x, _current_camera.location.y, _current_camera.location.z, _current_camera.target.x, _current_camera.target.y, _current_camera.target.z, _current_camera.up.x, _current_camera.up.y, _current_camera.up.z); @@ -448,12 +433,12 @@ void WidgetExplorer::paintGL() glColor3f(1.0, 1.0, 1.0); _chunks[i]->render(this); } - + frame_time = 0.001 * (double)start_time.msecsTo(QTime::currentTime()); - + _average_frame_time = _average_frame_time * 0.8 + frame_time * 0.2; //printf("%d %f\n", quality, average_frame_time); - + if (_average_frame_time > 0.1 && _quality > 1) { _quality--; @@ -462,7 +447,7 @@ void WidgetExplorer::paintGL() { _quality++; } - + while ((error_code = glGetError()) != GL_NO_ERROR) { logDebug(QString("[OpenGL] ERROR : ") + (const char*)gluErrorString(error_code)); diff --git a/gui_qt/widgetexplorer.h b/gui_qt/widgetexplorer.h index 28d314b..619dda0 100644 --- a/gui_qt/widgetexplorer.h +++ b/gui_qt/widgetexplorer.h @@ -6,7 +6,6 @@ #include "../lib_paysages/camera.h" #include "../lib_paysages/water.h" #include "../lib_paysages/renderer.h" -#include "../lib_paysages/terrain.h" #include "../lib_paysages/textures.h" #include "../lib_paysages/lighting.h" @@ -16,7 +15,7 @@ class WidgetExplorer : public QGLWidget public: WidgetExplorer(QWidget* parent, CameraDefinition* camera); ~WidgetExplorer(); - + void performChunksMaintenance(); public slots: @@ -33,27 +32,26 @@ protected: void initializeGL(); void resizeGL(int w, int h); void paintGL(); - + private: void startThreads(); void stopThreads(); - + CameraDefinition _current_camera; CameraDefinition* _base_camera; - + Renderer _renderer; bool _updated; - + QVector _chunks; QList _updateQueue; bool _alive; QMutex _lock_chunks; WaterDefinition _water; - TerrainDefinition _terrain; TexturesDefinition _textures; LightingDefinition _lighting; - + double _average_frame_time; int _quality; diff --git a/lib_paysages/Makefile b/lib_paysages/Makefile index c6cde54..fb4f116 100644 --- a/lib_paysages/Makefile +++ b/lib_paysages/Makefile @@ -1,9 +1,9 @@ BUILDMODE = debug BUILDPATH = ../build/${BUILDMODE} OBJPATH = ./obj/${BUILDMODE} -SOURCES = $(wildcard *.c atmosphere/*.c) +SOURCES = $(wildcard *.c atmosphere/*.c terrain/*.c) OBJECTS = ${SOURCES:%.c=${OBJPATH}/%.o} -HEADERS = $(wildcard shared/*.h atmosphere/*.h *.h) +HEADERS = $(wildcard *.h atmosphere/*.h terrain/*.h shared/*.h) RESULT = ${BUILDPATH}/libpaysages.so LIBS = glib-2.0 gthread-2.0 IL ILU CC_FLAGS = -Wall -fPIC -DHAVE_GLIB=1 diff --git a/lib_paysages/atmosphere/atmosphere.c b/lib_paysages/atmosphere/main.c similarity index 79% rename from lib_paysages/atmosphere/atmosphere.c rename to lib_paysages/atmosphere/main.c index 1dff706..02c656e 100644 --- a/lib_paysages/atmosphere/atmosphere.c +++ b/lib_paysages/atmosphere/main.c @@ -9,7 +9,6 @@ #include "../lighting.h" #include "../system.h" -#define SPHERE_SIZE 1000.0 #define MAX_SKYDOME_LIGHTS 100 typedef struct @@ -342,73 +341,3 @@ StandardRenderer AtmosphereRendererClass = { (FuncObjectDelete)_deleteRenderer, (FuncObjectBind)_bindRenderer }; - -/******************** Utilities ********************/ -static Color _postProcessFragment(Renderer* renderer, Vector3 location, void* data) -{ - Vector3 direction; - Color result; - - UNUSED(data); - - direction = v3Sub(location, renderer->camera_location); - - /* TODO Don't compute result->color if it's fully covered by clouds */ - result = renderer->atmosphere->getSkyColor(renderer, v3Normalize(direction)); - result = renderer->applyClouds(renderer, result, renderer->camera_location, v3Add(renderer->camera_location, v3Scale(direction, 10.0))); - - return result; -} - -void atmosphereRenderSkydome(Renderer* renderer) -{ - int res_i, res_j; - int i, j; - double step_i, step_j; - double current_i, current_j; - Vector3 vertex1, vertex2, vertex3, vertex4; - Vector3 direction; - - res_i = renderer->render_quality * 40; - res_j = renderer->render_quality * 20; - step_i = M_PI * 2.0 / (double)res_i; - step_j = M_PI / (double)res_j; - - for (j = 0; j < res_j; j++) - { - if (!renderer->addRenderProgress(renderer, 0.0)) - { - return; - } - - current_j = (double)(j - res_j / 2) * step_j; - - for (i = 0; i < res_i; i++) - { - current_i = (double)i * step_i; - - direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j); - direction.y = SPHERE_SIZE * sin(current_j); - direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j); - vertex1 = v3Add(renderer->camera_location, direction); - - direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j); - direction.y = SPHERE_SIZE * sin(current_j); - direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j); - vertex2 = v3Add(renderer->camera_location, direction); - - direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j + step_j); - direction.y = SPHERE_SIZE * sin(current_j + step_j); - direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j + step_j); - vertex3 = v3Add(renderer->camera_location, direction); - - direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j + step_j); - direction.y = SPHERE_SIZE * sin(current_j + step_j); - direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j + step_j); - vertex4 = v3Add(renderer->camera_location, direction); - - /* TODO Triangles at poles */ - renderer->pushQuad(renderer, vertex1, vertex4, vertex3, vertex2, _postProcessFragment, NULL); - } - } -} diff --git a/lib_paysages/atmosphere/preview.c b/lib_paysages/atmosphere/preview.c index 9eeef88..89f9502 100644 --- a/lib_paysages/atmosphere/preview.c +++ b/lib_paysages/atmosphere/preview.c @@ -2,7 +2,6 @@ #include "../renderer.h" #include "../lighting.h" -#include "../terrain.h" /* * Atmosphere previews. diff --git a/lib_paysages/atmosphere/private.h b/lib_paysages/atmosphere/private.h index fb6faee..603f319 100644 --- a/lib_paysages/atmosphere/private.h +++ b/lib_paysages/atmosphere/private.h @@ -1,6 +1,8 @@ #ifndef _PAYSAGES_ATMOSPHERE_PRIVATE_H_ #define _PAYSAGES_ATMOSPHERE_PRIVATE_H_ +#define SPHERE_SIZE 1000.0 + Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position); Color preethamGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position); diff --git a/lib_paysages/atmosphere/public.h b/lib_paysages/atmosphere/public.h index b9f90f8..06d5db6 100644 --- a/lib_paysages/atmosphere/public.h +++ b/lib_paysages/atmosphere/public.h @@ -11,31 +11,6 @@ extern "C" { #endif - /*** TO EXTRACT ***/ -typedef void* (*FuncObjectCreate)(); -typedef void (*FuncObjectDelete)(void* object); -typedef void (*FuncObjectCopy)(void* source, void* destination); -typedef void (*FuncObjectValidate)(void* object); -typedef void (*FuncObjectSave)(PackStream* stream, void* object); -typedef void (*FuncObjectLoad)(PackStream* stream, void* object); -typedef void (*FuncObjectBind)(void* base, void* sub); - -typedef struct { - FuncObjectCreate create; - FuncObjectDelete destroy; - FuncObjectCopy copy; - FuncObjectValidate validate; - FuncObjectSave save; - FuncObjectLoad load; -} StandardDefinition; - -typedef struct { - FuncObjectCreate create; - FuncObjectDelete destroy; - FuncObjectBind bind; -} StandardRenderer; - /*** TO EXTRACT ***/ - typedef enum { ATMOSPHERE_MODEL_PREETHAM = 0, diff --git a/lib_paysages/atmosphere/raster.c b/lib_paysages/atmosphere/raster.c new file mode 100644 index 0000000..f9f26ad --- /dev/null +++ b/lib_paysages/atmosphere/raster.c @@ -0,0 +1,76 @@ +#include "public.h" +#include "private.h" + +#include +#include +#include "../tools.h" +#include "../renderer.h" + +static Color _postProcessFragment(Renderer* renderer, Vector3 location, void* data) +{ + Vector3 direction; + Color result; + + UNUSED(data); + + direction = v3Sub(location, renderer->camera_location); + + /* TODO Don't compute result->color if it's fully covered by clouds */ + result = renderer->atmosphere->getSkyColor(renderer, v3Normalize(direction)); + result = renderer->applyClouds(renderer, result, renderer->camera_location, v3Add(renderer->camera_location, v3Scale(direction, 10.0))); + + return result; +} + +void atmosphereRenderSkydome(Renderer* renderer) +{ + int res_i, res_j; + int i, j; + double step_i, step_j; + double current_i, current_j; + Vector3 vertex1, vertex2, vertex3, vertex4; + Vector3 direction; + + res_i = renderer->render_quality * 40; + res_j = renderer->render_quality * 20; + step_i = M_PI * 2.0 / (double)res_i; + step_j = M_PI / (double)res_j; + + for (j = 0; j < res_j; j++) + { + if (!renderer->addRenderProgress(renderer, 0.0)) + { + return; + } + + current_j = (double)(j - res_j / 2) * step_j; + + for (i = 0; i < res_i; i++) + { + current_i = (double)i * step_i; + + direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j); + direction.y = SPHERE_SIZE * sin(current_j); + direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j); + vertex1 = v3Add(renderer->camera_location, direction); + + direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j); + direction.y = SPHERE_SIZE * sin(current_j); + direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j); + vertex2 = v3Add(renderer->camera_location, direction); + + direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j + step_j); + direction.y = SPHERE_SIZE * sin(current_j + step_j); + direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j + step_j); + vertex3 = v3Add(renderer->camera_location, direction); + + direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j + step_j); + direction.y = SPHERE_SIZE * sin(current_j + step_j); + direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j + step_j); + vertex4 = v3Add(renderer->camera_location, direction); + + /* TODO Triangles at poles */ + renderer->pushQuad(renderer, vertex1, vertex4, vertex3, vertex2, _postProcessFragment, NULL); + } + } +} diff --git a/lib_paysages/auto.c b/lib_paysages/auto.c index 08a2cab..af18a2d 100644 --- a/lib_paysages/auto.c +++ b/lib_paysages/auto.c @@ -10,7 +10,6 @@ #include "lighting.h" #include "modifiers.h" #include "render.h" -#include "terrain.h" #include "textures.h" #include "scenery.h" #include "system.h" @@ -66,17 +65,6 @@ void autoGenRealisticLandscape(int seed) scenerySetWater(&water); waterDeleteDefinition(&water); - /* Terrain */ - terrain = terrainCreateDefinition(); - noiseClearLevels(terrain.height_noise); - noiseAddLevelsSimple(terrain.height_noise, 10, 1.0, 1.0); - noiseSetFunctionParams(terrain.height_noise, NOISE_FUNCTION_SIMPLEX, -0.2); - terrain.height_factor = 12.0 / noiseGetMaxValue(terrain.height_noise); - terrain.scaling = 80.0; - terrain.shadow_smoothing = 0.03; - scenerySetTerrain(&terrain); - terrainDeleteDefinition(&terrain); - /* Textures */ textures = texturesCreateDefinition(); layer = layersAddLayer(textures.layers, NULL); diff --git a/lib_paysages/camera.c b/lib_paysages/camera.c index 84221a0..826e95b 100644 --- a/lib_paysages/camera.c +++ b/lib_paysages/camera.c @@ -36,14 +36,14 @@ CameraDefinition cameraCreateDefinition() definition.yaw = 0.0; definition.pitch = 0.0; definition.roll = 0.0; - + definition.width = 1.0; definition.height = 1.0; definition.yfov = 1.57; definition.xratio = 1.0; definition.znear = 1.0; definition.zfar = 1000.0; - + cameraValidateDefinition(&definition, 0); return definition; @@ -56,18 +56,18 @@ void cameraDeleteDefinition(CameraDefinition* definition) void cameraCopyDefinition(CameraDefinition* source, CameraDefinition* destination) { *destination = *source; - + cameraValidateDefinition(destination, 0); } void cameraValidateDefinition(CameraDefinition* definition, int check_above) { WaterDefinition water; - TerrainDefinition terrain; + Renderer renderer; double water_height, terrain_height, diff; Vector3 move; Matrix4 rotation; - + if (check_above) { water = waterCreateDefinition(); @@ -75,11 +75,10 @@ void cameraValidateDefinition(CameraDefinition* definition, int check_above) water_height = water.height + 0.5; waterDeleteDefinition(&water); - terrain = terrainCreateDefinition(); - sceneryGetTerrain(&terrain); - terrain_height = terrainGetHeight(&terrain, definition->location.x, definition->location.z) + 0.5; - terrainDeleteDefinition(&terrain); - + renderer = sceneryCreateStandardRenderer(); + terrain_height = renderer.terrain->getHeight(&renderer, definition->location.x, definition->location.z) + 0.5; + rendererDelete(&renderer); + if (definition->location.y < water_height || definition->location.y < terrain_height) { if (water_height > terrain_height) @@ -96,7 +95,7 @@ void cameraValidateDefinition(CameraDefinition* definition, int check_above) definition->location = v3Add(definition->location, move); } } - + definition->forward.x = 1.0; definition->forward.y = 0.0; definition->forward.z = 0.0; @@ -106,13 +105,13 @@ void cameraValidateDefinition(CameraDefinition* definition, int check_above) definition->up.x = 0.0; definition->up.y = 1.0; definition->up.z = 0.0; - + rotation = m4NewRotateEuler(definition->yaw, definition->pitch, definition->roll); - + definition->forward = m4MultPoint(rotation, definition->forward); definition->right = m4MultPoint(rotation, definition->right); definition->up = m4MultPoint(rotation, definition->up); - + definition->target = v3Add(definition->location, definition->forward); definition->project = m4Mult(m4NewPerspective(definition->yfov, definition->xratio, definition->znear, definition->zfar), m4NewLookAt(definition->location, definition->target, definition->up)); @@ -131,18 +130,18 @@ void cameraSetLocation(CameraDefinition* camera, double x, double y, double z) void cameraSetTarget(CameraDefinition* camera, double x, double y, double z) { Vector3 forward, target; - + target.x = x; target.y = y; target.z = z; - + forward = v3Sub(target, camera->location); if (v3Norm(forward) < 0.0000001) { return; } forward = v3Normalize(forward); - + if (fabs(forward.x) < 0.0000001 && fabs(forward.z) < 0.0000001) { /* Forward vector is vertical */ @@ -217,7 +216,7 @@ void cameraSetRenderSize(CameraDefinition* camera, int width, int height) camera->width = (double)width; camera->height = (double)height; camera->xratio = camera->width / camera->height; - + cameraValidateDefinition(camera, 0); } @@ -288,7 +287,7 @@ static inline void _updateBox(Vector3* point, double* xmin, double* xmax, double { *xmin = (*xmin < point->x) ? *xmin : point->x; *ymin = (*ymin < point->y) ? *ymin : point->y; - + *xmax = (*xmax > point->x) ? *xmax : point->x; *ymax = (*ymax > point->y) ? *ymax : point->y; *zmax = (*zmax > point->z) ? *zmax : point->z; @@ -298,7 +297,7 @@ int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, do { Vector3 projected; double xmin, xmax, ymin, ymax, zmax; - + center.x -= xsize / 2.0; center.y -= ysize / 2.0; center.z -= zsize / 2.0; @@ -306,7 +305,7 @@ int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, do xmin = xmax = projected.x; ymin = ymax = projected.y; zmax = projected.z; - + center.x += xsize; projected = cameraProject(camera, NULL, center); _updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax); @@ -322,7 +321,7 @@ int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, do center.y += ysize; projected = cameraProject(camera, NULL, center); _updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax); - + center.x += xsize; projected = cameraProject(camera, NULL, center); _updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax); @@ -334,6 +333,6 @@ int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, do center.x -= xsize; projected = cameraProject(camera, NULL, center); _updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax); - + return xmin <= camera->width && xmax >= 0.0 && ymin <= camera->height && ymax >= 0.0 && zmax >= camera->znear; } diff --git a/lib_paysages/heightmap.c b/lib_paysages/heightmap.c index 0957fb2..98125ce 100644 --- a/lib_paysages/heightmap.c +++ b/lib_paysages/heightmap.c @@ -11,11 +11,11 @@ HeightMap heightmapCreate() { HeightMap result; - + result.data = malloc(sizeof(double)); result.resolution_x = 1; result.resolution_z = 1; - + return result; } @@ -40,7 +40,7 @@ void heightmapValidate(HeightMap* heightmap) void heightmapSave(PackStream* stream, HeightMap* heightmap) { int i; - + packWriteInt(stream, &heightmap->resolution_x); packWriteInt(stream, &heightmap->resolution_z); for (i = 0; i < heightmap->resolution_x * heightmap->resolution_z; i++) @@ -52,7 +52,7 @@ void heightmapSave(PackStream* stream, HeightMap* heightmap) void heightmapLoad(PackStream* stream, HeightMap* heightmap) { int i; - + packReadInt(stream, &heightmap->resolution_x); packReadInt(stream, &heightmap->resolution_z); heightmap->data = realloc(heightmap->data, sizeof(double) * heightmap->resolution_x * heightmap->resolution_z); @@ -66,7 +66,7 @@ static void _loadFromFilePixel(HeightMap* heightmap, int x, int y, Color col) { assert(x >= 0 && x < heightmap->resolution_x); assert(y >= 0 && y < heightmap->resolution_z); - + heightmap->data[y * heightmap->resolution_x + x] = (col.r + col.g + col.b) / 3.0; } @@ -95,7 +95,7 @@ double heightmapGetRawValue(HeightMap* heightmap, double x, double z) { assert(x >= 0.0 && x <= 1.0); assert(z >= 0.0 && z <= 1.0); - + return heightmap->data[((int)(z * (double)(heightmap->resolution_z - 1))) * heightmap->resolution_x + ((int)(x * (double)(heightmap->resolution_x - 1)))]; } @@ -107,7 +107,7 @@ double heightmapGetValue(HeightMap* heightmap, double x, double z) int zlow; double stencil[16]; int ix, iz, cx, cz; - + if (x < 0.0) { x = 0.0; @@ -139,7 +139,7 @@ double heightmapGetValue(HeightMap* heightmap, double x, double z) stencil[(iz - (zlow - 1)) * 4 + ix - (xlow - 1)] = heightmap->data[cz * heightmap->resolution_x + cx]; } } - + return toolsBicubicInterpolate(stencil, x * xmax - (double)xlow, z * zmax - (double)zlow); } @@ -152,11 +152,11 @@ void heightmapImportFromPicture(HeightMap* heightmap, const char* picturepath) void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z) { int i; - + heightmap->resolution_x = resolution_x; heightmap->resolution_z = resolution_z; heightmap->data = realloc(heightmap->data, sizeof(double) * heightmap->resolution_x * heightmap->resolution_z); - + for (i = 0; i < heightmap->resolution_x * heightmap->resolution_z; i++) { heightmap->data[i] = 0.0; @@ -168,7 +168,7 @@ void heightmapRevertToTerrain(HeightMap* heightmap, TerrainDefinition* terrain, int rx, rz; int x, z; double dx, dz; - + rx = heightmap->resolution_x; rz = heightmap->resolution_z; for (x = 0; x < rx; x++) @@ -178,7 +178,7 @@ void heightmapRevertToTerrain(HeightMap* heightmap, TerrainDefinition* terrain, dx = (double)x / (double)(rx - 1); dz = (double)z / (double)(rz - 1); geoareaFromLocal(area, dx, dz, &dx, &dz); - heightmap->data[z * rx + x] = terrainGetHeight(terrain, dx, dz); +// heightmap->data[z * rx + x] = terrainGetHeight(terrain, dx, dz); } } } @@ -235,9 +235,9 @@ static inline void _applyBrush(HeightMap* heightmap, HeightMapBrush* brush, doub { int x, x1, x2, z, z1, z2; double dx, dz, distance, influence; - + _getBrushBoundaries(brush, heightmap->resolution_x - 1, heightmap->resolution_z - 1, &x1, &x2, &z1, &z2); - + for (x = x1; x <= x2; x++) { dx = (double)x / (double)heightmap->resolution_x; @@ -245,7 +245,7 @@ static inline void _applyBrush(HeightMap* heightmap, HeightMapBrush* brush, doub { dz = (double)z / (double)heightmap->resolution_z; distance = sqrt((brush->relative_x - dx) * (brush->relative_x - dx) + (brush->relative_z - dz) * (brush->relative_z - dz)); - + if (distance > brush->hard_radius) { if (distance <= brush->hard_radius + brush->smoothed_size) @@ -261,7 +261,7 @@ static inline void _applyBrush(HeightMap* heightmap, HeightMapBrush* brush, doub { influence = 1.0; } - + heightmap->data[z * heightmap->resolution_x + x] = callback(heightmap, brush, dx, dz, heightmap->data[z * heightmap->resolution_x + x], influence, force, data); } } diff --git a/lib_paysages/heightmap.h b/lib_paysages/heightmap.h index 2b06c83..cdbedb4 100644 --- a/lib_paysages/heightmap.h +++ b/lib_paysages/heightmap.h @@ -6,7 +6,7 @@ #include "pack.h" #include "noise.h" #include "geoarea.h" -#include "terrain.h" +#include "terrain/public.h" #ifdef __cplusplus extern "C" { @@ -47,7 +47,7 @@ void heightmapRevertToTerrain(HeightMap* heightmap, TerrainDefinition* terrain, void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double value); void heightmapBrushSmooth(HeightMap* heightmap, HeightMapBrush* brush, double value); void heightmapBrushAddNoise(HeightMap* heightmap, HeightMapBrush* brush, NoiseGenerator* generator, double value); - + #ifdef __cplusplus } #endif diff --git a/lib_paysages/lighting.c b/lib_paysages/lighting.c index 1515d64..8cdbea0 100644 --- a/lib_paysages/lighting.c +++ b/lib_paysages/lighting.c @@ -10,7 +10,6 @@ #include "euclid.h" #include "renderer.h" #include "scenery.h" -#include "terrain.h" #include "tools.h" #include "water.h" @@ -130,12 +129,12 @@ void lightingDeleteLight(LightingDefinition* definition, int light) static int _getLightStatus(LightDefinition* definition, Renderer* renderer, Vector3 location, LightDefinition* result) { *result = *definition; - + if (definition->masked || definition->filtered) { renderer->alterLight(renderer, result, location); } - + if (result->color.r > 0.0 || result->color.g > 0.0 || result->color.b > 0.0) { return 1; @@ -209,9 +208,9 @@ void lightingGetStatus(LightingDefinition* definition, Renderer* renderer, Vecto { int i, skydome_lights_count; LightDefinition skydome_lights[LIGHTING_MAX_LIGHTS]; - + result->nblights = 0; - + /* Apply static lights */ for (i = 0; i < definition->nblights; i++) { @@ -220,7 +219,7 @@ void lightingGetStatus(LightingDefinition* definition, Renderer* renderer, Vecto result->nblights++; } } - + /* Apply skydome lights */ /* TODO Cache skydome lights for same render */ skydome_lights_count = renderer->atmosphere->getSkydomeLights(renderer, skydome_lights, LIGHTING_MAX_LIGHTS); @@ -240,7 +239,7 @@ Color lightingApplyStatusToSurface(Renderer* renderer, LightStatus* status, Vect result = COLOR_BLACK; result.a = material.base.a; - + for (i = 0; i < status->nblights; i++) { lighted = _applyDirectLight(status->lights + i, renderer, location, normal, material); @@ -248,14 +247,14 @@ Color lightingApplyStatusToSurface(Renderer* renderer, LightStatus* status, Vect result.g += lighted.g; result.b += lighted.b; } - + return result; } Color lightingApplyToSurface(LightingDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material) { LightStatus status; - + lightingGetStatus(definition, renderer, location, &status); return lightingApplyStatusToSurface(renderer, &status, location, normal, material); } diff --git a/lib_paysages/lighting.h b/lib_paysages/lighting.h index c753301..b883baf 100644 --- a/lib_paysages/lighting.h +++ b/lib_paysages/lighting.h @@ -2,7 +2,6 @@ #define _PAYSAGES_LIGHTING_H_ #include "shared/types.h" -#include "renderer.h" #include "pack.h" #ifdef __cplusplus @@ -32,6 +31,8 @@ struct LightStatus LightDefinition lights[LIGHTING_MAX_LIGHTS * 2]; }; +typedef LightDefinition (*FuncLightingAlterLight)(Renderer* renderer, LightDefinition* light, Vector3 at); + void lightingInit(); void lightingQuit(); void lightingSave(PackStream* stream, LightingDefinition* definition); diff --git a/lib_paysages/renderer.c b/lib_paysages/renderer.c index baf0f93..40a2e42 100644 --- a/lib_paysages/renderer.c +++ b/lib_paysages/renderer.c @@ -11,7 +11,7 @@ HeightInfo _WATER_HEIGHT_INFO = {-1000000.0, -1000000.0, -1000000.0}; static void* _renderFirstPass(void* data) { Renderer* renderer = (Renderer*)data; - + sceneryRenderFirstPass(renderer); renderer->is_rendering = 0; return NULL; @@ -40,11 +40,11 @@ static Vector3 _unprojectPoint(Renderer* renderer, Vector3 point) static void _pushTriangle(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, f_RenderFragmentCallback callback, void* callback_data) { Vector3 p1, p2, p3; - + p1 = renderer->projectPoint(renderer, v1); p2 = renderer->projectPoint(renderer, v2); p3 = renderer->projectPoint(renderer, v3); - + renderPushTriangle(renderer->render_area, p1, p2, p3, v1, v2, v3, callback, callback_data); } @@ -73,11 +73,6 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector return _RAYCASTING_NULL; } -static double _getTerrainHeight(Renderer* renderer, double x, double z) -{ - return 0.0; -} - static HeightInfo _getWaterHeightInfo(Renderer* renderer) { return _WATER_HEIGHT_INFO; @@ -107,7 +102,7 @@ Renderer rendererCreate() result.render_camera = cameraCreateDefinition(); result.camera_location = result.render_camera.location; result.render_area = renderCreateArea(); - + renderSetParams(result.render_area, params); result.addRenderProgress = _addRenderProgress; @@ -118,7 +113,6 @@ Renderer rendererCreate() result.pushQuad = _pushQuad; result.rayWalking = _rayWalking; - result.getTerrainHeight = _getTerrainHeight; result.getWaterHeightInfo = _getWaterHeightInfo; result.applyTextures = _applyTextures; result.applyClouds = _applyClouds; @@ -126,8 +120,9 @@ Renderer rendererCreate() result.alterLight = _alterLight; result.getLightStatus = _getLightStatus; result.applyLightStatus = _applyLightStatus; - + result.atmosphere = AtmosphereRendererClass.create(); + result.terrain = TerrainRendererClass.create(); return result; } @@ -135,6 +130,8 @@ Renderer rendererCreate() void rendererDelete(Renderer* renderer) { AtmosphereRendererClass.destroy(renderer->atmosphere); + TerrainRendererClass.destroy(renderer->terrain); + renderDeleteArea(renderer->render_area); } @@ -151,13 +148,13 @@ void rendererStart(Renderer* renderer, RenderParams params) params.antialias = (params.antialias < 1) ? 1 : params.antialias; params.antialias = (params.antialias > 4) ? 4 : params.antialias; - + renderer->render_quality = params.quality; renderer->render_width = params.width * params.antialias; renderer->render_height = params.height * params.antialias; renderer->render_interrupt = 0; renderer->render_progress = 0.0; - + cameraSetRenderSize(&renderer->render_camera, renderer->render_width, renderer->render_height); renderer->camera_location = renderer->render_camera.location; @@ -180,7 +177,7 @@ void rendererStart(Renderer* renderer, RenderParams params) } } threadJoin(thread); - + renderer->is_rendering = 1; renderPostProcess(renderer->render_area, renderer, core_count); renderer->is_rendering = 0; diff --git a/lib_paysages/renderer.h b/lib_paysages/renderer.h index 092662b..3a3b26e 100644 --- a/lib_paysages/renderer.h +++ b/lib_paysages/renderer.h @@ -3,6 +3,7 @@ #include "shared/types.h" #include "atmosphere/public.h" +#include "terrain/public.h" #ifdef __cplusplus extern "C" { @@ -31,7 +32,6 @@ struct Renderer /* Scenery related */ RayCastingResult (*rayWalking)(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds); - double (*getTerrainHeight)(Renderer* renderer, double x, double z); HeightInfo (*getWaterHeightInfo)(Renderer* renderer); Color (*applyTextures)(Renderer* renderer, Vector3 location, double precision); Color (*applyClouds)(Renderer* renderer, Color base, Vector3 start, Vector3 end); @@ -43,6 +43,7 @@ struct Renderer /* Autonomous sub-renderers */ AtmosphereRenderer* atmosphere; + TerrainRenderer* terrain; /* Custom data */ void* customData[10]; diff --git a/lib_paysages/scenery.c b/lib_paysages/scenery.c index c56bce7..f8dcae6 100644 --- a/lib_paysages/scenery.c +++ b/lib_paysages/scenery.c @@ -10,7 +10,7 @@ static AtmosphereDefinition* _atmosphere; static CameraDefinition _camera; static CloudsDefinition _clouds; static LightingDefinition _lighting; -static TerrainDefinition _terrain; +static TerrainDefinition* _terrain; static TexturesDefinition _textures; static WaterDefinition _water; @@ -27,10 +27,10 @@ void sceneryInit() _camera = cameraCreateDefinition(); _clouds = cloudsCreateDefinition(); _lighting = lightingCreateDefinition(); - _terrain = terrainCreateDefinition(); + _terrain = TerrainDefinitionClass.create(); _textures = texturesCreateDefinition(); _water = waterCreateDefinition(); - + _custom_save = NULL; _custom_load = NULL; } @@ -41,7 +41,7 @@ void sceneryQuit() cameraDeleteDefinition(&_camera); cloudsDeleteDefinition(&_clouds); lightingDeleteDefinition(&_lighting); - terrainDeleteDefinition(&_terrain); + TerrainDefinitionClass.destroy(_terrain); texturesDeleteDefinition(&_textures); waterDeleteDefinition(&_water); @@ -63,10 +63,10 @@ void scenerySave(PackStream* stream) cameraSave(stream, &_camera); cloudsSave(stream, &_clouds); lightingSave(stream, &_lighting); - terrainSave(stream, &_terrain); + TerrainDefinitionClass.save(stream, _terrain); texturesSave(stream, &_textures); waterSave(stream, &_water); - + if (_custom_save) { _custom_save(stream, _custom_data); @@ -82,17 +82,16 @@ void sceneryLoad(PackStream* stream) cameraLoad(stream, &_camera); cloudsLoad(stream, &_clouds); lightingLoad(stream, &_lighting); - terrainLoad(stream, &_terrain); + TerrainDefinitionClass.load(stream, _terrain); texturesLoad(stream, &_textures); waterLoad(stream, &_water); - + cameraValidateDefinition(&_camera, 0); cloudsValidateDefinition(&_clouds); lightingValidateDefinition(&_lighting); - terrainValidateDefinition(&_terrain); texturesValidateDefinition(&_textures); waterValidateDefinition(&_water); - + if (_custom_load) { _custom_load(stream, _custom_data); @@ -102,7 +101,6 @@ void sceneryLoad(PackStream* stream) void scenerySetAtmosphere(AtmosphereDefinition* atmosphere) { AtmosphereDefinitionClass.copy(atmosphere, _atmosphere); - AtmosphereDefinitionClass.validate(_atmosphere); } void sceneryGetAtmosphere(AtmosphereDefinition* atmosphere) @@ -145,15 +143,14 @@ void sceneryGetLighting(LightingDefinition* lighting) void scenerySetTerrain(TerrainDefinition* terrain) { - terrainCopyDefinition(terrain, &_terrain); - terrainValidateDefinition(&_terrain); - + TerrainDefinitionClass.copy(terrain, _terrain); + cameraValidateDefinition(&_camera, 1); } void sceneryGetTerrain(TerrainDefinition* terrain) { - terrainCopyDefinition(&_terrain, terrain); + TerrainDefinitionClass.copy(_terrain, terrain); } void scenerySetTextures(TexturesDefinition* textures) @@ -182,7 +179,7 @@ void sceneryGetWater(WaterDefinition* water) void sceneryRenderFirstPass(Renderer* renderer) { - terrainRender(&_terrain, renderer); + terrainRenderSurface(renderer); waterRender(&_water, renderer); atmosphereRenderSkydome(renderer); } @@ -197,10 +194,10 @@ static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 loca { Vector3 light_location; Vector3 direction_to_light; - + direction_to_light = v3Normalize(v3Scale(light->direction, -1.0)); light_location = v3Add(location, v3Scale(direction_to_light, 1000.0)); - + if (light->filtered) { // TODO atmosphere filter @@ -208,7 +205,7 @@ static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 loca } if (light->masked) { - light->color = terrainLightFilter(&_terrain, renderer, light->color, location, light_location, direction_to_light); + *light = renderer->terrain->alterLight(renderer, light, location); light->color = cloudsFilterLight(&_clouds, renderer, light->color, location, light_location, direction_to_light); } } @@ -228,22 +225,19 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector RayCastingResult result; Color sky_color; - if (!terrainProjectRay(&_terrain, renderer, location, direction, &result.hit_location, &result.hit_color)) + result = renderer->terrain->castRay(renderer, location, direction); + if (!result.hit) { sky_color = renderer->atmosphere->getSkyColor(renderer, direction); + + result.hit = 1; result.hit_location = v3Add(location, v3Scale(direction, 1000.0)); result.hit_color = renderer->applyClouds(renderer, sky_color, location, result.hit_location); } - result.hit = 1; return result; } -static double _getTerrainHeight(Renderer* renderer, double x, double z) -{ - return terrainGetHeight(&_terrain, x, z); -} - static HeightInfo _getWaterHeightInfo(Renderer* renderer) { return waterGetHeightInfo(&_water); @@ -283,7 +277,7 @@ static double _getPrecision(Renderer* renderer, Vector3 location) Renderer sceneryCreateStandardRenderer() { Renderer result; - + result = rendererCreate(); cameraCopyDefinition(&_camera, &result.render_camera); @@ -293,15 +287,15 @@ Renderer sceneryCreateStandardRenderer() result.getLightStatus = _getLightStatus; result.applyLightStatus = _applyLightStatus; result.rayWalking = _rayWalking; - result.getTerrainHeight = _getTerrainHeight; result.getWaterHeightInfo = _getWaterHeightInfo; result.applyTextures = _applyTextures; result.applyClouds = _applyClouds; result.projectPoint = _projectPoint; result.unprojectPoint = _unprojectPoint; result.getPrecision = _getPrecision; - + AtmosphereRendererClass.bind(result.atmosphere, _atmosphere); + TerrainRendererClass.bind(result.terrain, _terrain); return result; } diff --git a/lib_paysages/scenery.h b/lib_paysages/scenery.h index 9406c6f..cd0fe56 100644 --- a/lib_paysages/scenery.h +++ b/lib_paysages/scenery.h @@ -9,10 +9,10 @@ */ #include "atmosphere/public.h" +#include "terrain/public.h" #include "camera.h" #include "clouds.h" #include "lighting.h" -#include "terrain.h" #include "textures.h" #include "water.h" #include "pack.h" diff --git a/lib_paysages/shared/types.h b/lib_paysages/shared/types.h index c75ef0c..65bc42b 100644 --- a/lib_paysages/shared/types.h +++ b/lib_paysages/shared/types.h @@ -51,7 +51,7 @@ typedef struct Color hit_color; Vector3 hit_location; } RayCastingResult; -typedef RayCastingResult (*RayCastingFunction)(Vector3 start, Vector3 direction); +typedef RayCastingResult (*FuncGeneralCastRay)(Renderer* renderer, Vector3 start, Vector3 direction); typedef struct { @@ -66,23 +66,46 @@ typedef struct double yaw; double pitch; double roll; - + Vector3 target; Vector3 forward; Vector3 right; Vector3 up; - + double width; double height; double yfov; double xratio; double znear; double zfar; - + Matrix4 project; Matrix4 unproject; } CameraDefinition; +typedef void* (*FuncObjectCreate)(); +typedef void (*FuncObjectDelete)(void* object); +typedef void (*FuncObjectCopy)(void* source, void* destination); +typedef void (*FuncObjectValidate)(void* object); +typedef void (*FuncObjectSave)(PackStream* stream, void* object); +typedef void (*FuncObjectLoad)(PackStream* stream, void* object); +typedef void (*FuncObjectBind)(void* base, void* sub); + +typedef struct { + FuncObjectCreate create; + FuncObjectDelete destroy; + FuncObjectCopy copy; + FuncObjectValidate validate; + FuncObjectSave save; + FuncObjectLoad load; +} StandardDefinition; + +typedef struct { + FuncObjectCreate create; + FuncObjectDelete destroy; + FuncObjectBind bind; +} StandardRenderer; + #ifdef __cplusplus } #endif diff --git a/lib_paysages/terrain.c b/lib_paysages/terrain.c deleted file mode 100644 index 39f716c..0000000 --- a/lib_paysages/terrain.c +++ /dev/null @@ -1,390 +0,0 @@ -#include "terrain.h" - -#include -#include -#include -#include - -#include "shared/types.h" -#include "euclid.h" -#include "render.h" -#include "textures.h" -#include "water.h" -#include "tools.h" -#include "layers.h" -#include "terraincanvas.h" - -void terrainSave(PackStream* stream, TerrainDefinition* definition) -{ - noiseSaveGenerator(stream, definition->height_noise); - packWriteDouble(stream, &definition->height_factor); - packWriteDouble(stream, &definition->scaling); - layersSave(stream, definition->canvases); - packWriteDouble(stream, &definition->shadow_smoothing); -} - -void terrainLoad(PackStream* stream, TerrainDefinition* definition) -{ - noiseLoadGenerator(stream, definition->height_noise); - packReadDouble(stream, &definition->height_factor); - packReadDouble(stream, &definition->scaling); - layersLoad(stream, definition->canvases); - packReadDouble(stream, &definition->shadow_smoothing); - - terrainValidateDefinition(definition); -} - -TerrainDefinition terrainCreateDefinition() -{ - TerrainDefinition definition; - - definition.height_noise = noiseCreateGenerator(); - definition.height_factor = 0.0; - definition.scaling = 1.0; - definition.canvases = layersCreate(terrainCanvasGetLayerType(), 50); - definition.shadow_smoothing = 0.0; - - terrainValidateDefinition(&definition); - - return definition; -} - -void terrainDeleteDefinition(TerrainDefinition* definition) -{ - noiseDeleteGenerator(definition->height_noise); - layersDelete(definition->canvases); -} - -void terrainCopyDefinition(TerrainDefinition* source, TerrainDefinition* destination) -{ - noiseCopy(source->height_noise, destination->height_noise); - destination->height_factor = source->height_factor; - destination->scaling = source->scaling; - layersCopy(source->canvases, destination->canvases); - destination->shadow_smoothing = source->shadow_smoothing; - - terrainValidateDefinition(destination); -} - -void terrainValidateDefinition(TerrainDefinition* definition) -{ - int i, n; - TerrainCanvas* canvas; - double min, max; - - noiseValidate(definition->height_noise); - layersValidate(definition->canvases); - - /* Get minimal and maximal height */ - definition->_min_height = -noiseGetMaxValue(definition->height_noise) * definition->height_factor; - definition->_max_height = noiseGetMaxValue(definition->height_noise) * definition->height_factor; - - n = layersCount(definition->canvases); - for (i = 0; i < n; i++) - { - canvas = layersGetLayer(definition->canvases, i); - terrainCanvasGetLimits(canvas, &min, &max); - if (min < definition->_min_height) - { - definition->_min_height = min; - } - if (max > definition->_max_height) - { - definition->_max_height = max; - } - } -} - -static inline double _getHeight(TerrainDefinition* definition, double x, double z) -{ - TerrainCanvas* canvas; - Vector3 location; - int i, n; - - location.x = x; - location.y = noiseGet2DTotal(definition->height_noise, x / definition->scaling, z / definition->scaling) * definition->height_factor; - location.z = z; - - n = layersCount(definition->canvases); - for (i = 0; i < n; i++) - { - canvas = layersGetLayer(definition->canvases, i); - location = terrainCanvasApply(canvas, location); - } - - /* TODO Apply modifiers */ - - return location.y; -} - -static inline double _getHeightDetail(TerrainDefinition* definition, double x, double z, double detail) -{ - TerrainCanvas* canvas; - Vector3 location; - int i, n; - - location.x = x; - location.y = noiseGet2DDetail(definition->height_noise, x / definition->scaling, z / definition->scaling, detail / definition->height_factor) * definition->height_factor; - location.z = z; - - n = layersCount(definition->canvases); - for (i = 0; i < n; i++) - { - canvas = layersGetLayer(definition->canvases, i); - location = terrainCanvasApply(canvas, location); - } - - /* TODO Apply modifiers */ - - return location.y; -} - -static inline Vector3 _getPoint(TerrainDefinition* definition, double x, double z) -{ - Vector3 result; - - result.x = x; - result.y = _getHeight(definition, x, z); - result.z = z; - - return result; -} - -Color terrainLightFilter(TerrainDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light) -{ - Vector3 inc_vector; - double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length; - - direction_to_light = v3Normalize(direction_to_light); - if ((fabs(direction_to_light.x) < 0.0001 && fabs(direction_to_light.z) < 0.0001) || definition->height_factor < 0.001) - { - return light; - } - else if (direction_to_light.y < 0.05) - { - return COLOR_BLACK; - } - else if (direction_to_light.y < 0.0000) - { - light.r *= (0.05 + direction_to_light.y) / 0.05; - light.g *= (0.05 + direction_to_light.y) / 0.05; - light.b *= (0.05 + direction_to_light.y) / 0.05; - } - - inc_factor = (double)renderer->render_quality; - inc_base = definition->height_factor / definition->scaling; - inc_value = inc_base / inc_factor; - smoothing = definition->shadow_smoothing; - - light_factor = 1.0; - length = 0.0; - diff = 0.0; - do - { - inc_vector = v3Scale(direction_to_light, inc_value); - length += v3Norm(inc_vector); - location = v3Add(location, inc_vector); - height = _getHeightDetail(definition, location.x, location.z, diff / inc_factor); - diff = location.y - height; - if (diff < 0.0) - { - if (length * smoothing > 0.000001) - { - light_factor += diff * v3Norm(inc_vector) / (length * smoothing); - } - else - { - light_factor = 0.0; - } - } - - if (diff < inc_base / inc_factor) - { - inc_value = inc_base / inc_factor; - } - else if (diff > inc_base) - { - inc_value = inc_base; - } - else - { - inc_value = diff; - } - } while (light_factor > 0.0 && length < (10.0 * inc_factor) && location.y <= definition->_max_height); - - if (light_factor <= 0.0) - { - return COLOR_BLACK; - } - else - { - light.r *= light_factor; - light.g *= light_factor; - light.b *= light_factor; - - return light; - } -} - -static Color _getColor(TerrainDefinition* definition, Renderer* renderer, Vector3 point, double precision) -{ - Color color; - - color = renderer->applyTextures(renderer, point, precision); - color = renderer->atmosphere->applyAerialPerspective(renderer, point, color); - color = renderer->applyClouds(renderer, color, renderer->camera_location, point); - - return color; -} - -int terrainProjectRay(TerrainDefinition* definition, Renderer* renderer, Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color) -{ - Vector3 inc_vector; - double inc_value, inc_base, inc_factor, height, diff, lastdiff, length; - - direction = v3Normalize(direction); - inc_factor = (double)renderer->render_quality; - inc_base = 1.0; - inc_value = inc_base / inc_factor; - lastdiff = start.y - _getHeight(definition, start.x, start.z); - - length = 0.0; - do - { - inc_vector = v3Scale(direction, inc_value); - length += v3Norm(inc_vector); - start = v3Add(start, inc_vector); - height = _getHeight(definition, start.x, start.z); - diff = start.y - height; - if (diff < 0.0) - { - if (fabs(diff - lastdiff) > 0.00001) - { - start = v3Add(start, v3Scale(inc_vector, -diff / (diff - lastdiff))); - start.y = _getHeight(definition, start.x, start.z); - } - else - { - start.y = height; - } - *hit_point = start; - *hit_color = _getColor(definition, renderer, start, renderer->getPrecision(renderer, start)); - return 1; - } - - if (diff < inc_base / inc_factor) - { - inc_value = inc_base / inc_factor; - } - else if (diff > inc_base) - { - inc_value = inc_base; - } - else - { - inc_value = diff; - } - lastdiff = diff; - } while (length < 50.0 && start.y <= definition->_max_height); - - return 0; -} - -static Color _postProcessFragment(Renderer* renderer, Vector3 point, void* data) -{ - double precision; - TerrainDefinition* definition; - - definition = (TerrainDefinition*)data; - - point = _getPoint(definition, point.x, point.z); - - precision = renderer->getPrecision(renderer, point); - return _getColor(definition, renderer, point, precision); -} - -static void _renderQuad(TerrainDefinition* definition, Renderer* renderer, double x, double z, double size, double water_height) -{ - Vector3 v1, v2, v3, v4; - - v1 = _getPoint(definition, x, z); - v2 = _getPoint(definition, x, z + size); - v3 = _getPoint(definition, x + size, z + size); - v4 = _getPoint(definition, x + size, z); - - if (v1.y > water_height || v2.y > water_height || v3.y > water_height || v4.y > water_height) - { - renderer->pushQuad(renderer, v1, v2, v3, v4, _postProcessFragment, definition); - } -} - -double terrainGetHeight(TerrainDefinition* definition, double x, double z) -{ - return _getHeight(definition, x, z); -} - -double terrainGetHeightNormalized(TerrainDefinition* definition, double x, double z) -{ - if (definition->_max_height - definition->_min_height <= 0.0000001) - { - return 0.5; - } - else - { - return (_getHeight(definition, x, z) - definition->_min_height) / (definition->_max_height - definition->_min_height); - } -} - -Color terrainGetColor(TerrainDefinition* definition, Renderer* renderer, double x, double z, double detail) -{ - Vector3 point = _getPoint(definition, x, z); - return _getColor(definition, renderer, point, detail); -} - -void terrainRender(TerrainDefinition* definition, Renderer* renderer) -{ - int chunk_factor, chunk_count, i; - double cx = renderer->camera_location.x; - double cz = renderer->camera_location.z; - double min_chunk_size, visible_chunk_size; - double radius_int, radius_ext, chunk_size; - double water_height; - - min_chunk_size = 0.1 / (double)renderer->render_quality; - visible_chunk_size = 0.05 / (double)renderer->render_quality; - - chunk_factor = 1; - chunk_count = 2; - radius_int = 0.0; - radius_ext = min_chunk_size; - chunk_size = min_chunk_size; - - water_height = renderer->getWaterHeightInfo(renderer).max_height; - - while (radius_ext < 1000.0) - { - if (!renderer->addRenderProgress(renderer, 0.0)) - { - return; - } - - for (i = 0; i < chunk_count - 1; i++) - { - _renderQuad(definition, renderer, cx - radius_ext + chunk_size * i, cz - radius_ext, chunk_size, water_height); - _renderQuad(definition, renderer, cx + radius_int, cz - radius_ext + chunk_size * i, chunk_size, water_height); - _renderQuad(definition, renderer, cx + radius_int - chunk_size * i, cz + radius_int, chunk_size, water_height); - _renderQuad(definition, renderer, cx - radius_ext, cz + radius_int - chunk_size * i, chunk_size, water_height); - } - - if (chunk_count % 64 == 0 && chunk_size / radius_int < visible_chunk_size) - { - chunk_count /= 2; - chunk_factor *= 2; - /* TODO Fill in gaps with triangles */ - } - chunk_count += 2; - chunk_size = min_chunk_size * chunk_factor; - radius_int = radius_ext; - radius_ext += chunk_size; - } -} diff --git a/lib_paysages/terrain.h b/lib_paysages/terrain.h deleted file mode 100644 index e962c7f..0000000 --- a/lib_paysages/terrain.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _PAYSAGES_TERRAIN_H_ -#define _PAYSAGES_TERRAIN_H_ - -#include "shared/types.h" -#include "modifiers.h" -#include "noise.h" -#include "lighting.h" -#include "pack.h" -#include "layers.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define TERRAIN_MAX_MODIFIERS 50 - -typedef struct -{ - NoiseGenerator* height_noise; - double height_factor; - double scaling; - Layers* canvases; - double shadow_smoothing; - - double _min_height; - double _max_height; -} TerrainDefinition; - -void terrainSave(PackStream* stream, TerrainDefinition* definition); -void terrainLoad(PackStream* stream, TerrainDefinition* definition); - -TerrainDefinition terrainCreateDefinition(); -void terrainDeleteDefinition(TerrainDefinition* definition); -void terrainCopyDefinition(TerrainDefinition* source, TerrainDefinition* destination); -void terrainValidateDefinition(TerrainDefinition* definition); - -Color terrainLightFilter(TerrainDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light); -int terrainProjectRay(TerrainDefinition* definition, Renderer* renderer, Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color); -double terrainGetHeight(TerrainDefinition* definition, double x, double z); -double terrainGetHeightNormalized(TerrainDefinition* definition, double x, double z); -Color terrainGetColor(TerrainDefinition* definition, Renderer* renderer, double x, double z, double detail); -void terrainRender(TerrainDefinition* definition, Renderer* renderer); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib_paysages/terrain/main.c b/lib_paysages/terrain/main.c new file mode 100644 index 0000000..4514a60 --- /dev/null +++ b/lib_paysages/terrain/main.c @@ -0,0 +1,300 @@ +#include "public.h" +#include "private.h" + +#include +#include +#include "../tools.h" +#include "../lighting.h" +#include "../renderer.h" + +/******************** Definition ********************/ +static void _validateDefinition(TerrainDefinition* definition) +{ + noiseValidate(definition->_height_noise); + + /* Get minimal and maximal height */ + definition->_min_height = -noiseGetMaxValue(definition->_height_noise) * definition->height; + definition->_max_height = noiseGetMaxValue(definition->_height_noise) * definition->height; +} + +static TerrainDefinition* _createDefinition() +{ + TerrainDefinition* definition = malloc(sizeof(TerrainDefinition)); + + definition->height = 0.0; + definition->scaling = 1.0; + definition->shadow_smoothing = 0.0; + definition->_height_noise = noiseCreateGenerator(); + + terrainAutoPreset(definition, TERRAIN_PRESET_STANDARD); + + return definition; +} + +static void _deleteDefinition(TerrainDefinition* definition) +{ + noiseDeleteGenerator(definition->_height_noise); + free(definition); +} + +static void _copyDefinition(TerrainDefinition* source, TerrainDefinition* destination) +{ + destination->height = source->height; + destination->scaling = source->scaling; + destination->shadow_smoothing = source->shadow_smoothing; + + _validateDefinition(destination); +} + +static void _saveDefinition(PackStream* stream, TerrainDefinition* definition) +{ + packWriteDouble(stream, &definition->height); + packWriteDouble(stream, &definition->scaling); + packWriteDouble(stream, &definition->shadow_smoothing); +} + +static void _loadDefinition(PackStream* stream, TerrainDefinition* definition) +{ + packReadDouble(stream, &definition->height); + packReadDouble(stream, &definition->scaling); + packReadDouble(stream, &definition->shadow_smoothing); + + _validateDefinition(definition); +} + +StandardDefinition TerrainDefinitionClass = { + (FuncObjectCreate)_createDefinition, + (FuncObjectDelete)_deleteDefinition, + (FuncObjectCopy)_copyDefinition, + (FuncObjectValidate)_validateDefinition, + (FuncObjectSave)_saveDefinition, + (FuncObjectLoad)_loadDefinition +}; + +/******************** Binding ********************/ +static double _fakeGetHeight(Renderer* renderer, double x, double z) +{ + UNUSED(renderer); + UNUSED(x); + UNUSED(z); + + return 0.0; +} + +static double _getHeight(Renderer* renderer, double x, double z) +{ + TerrainDefinition* definition = renderer->terrain->definition; + return noiseGet2DTotal(definition->_height_noise, x / definition->scaling, z / definition->scaling) * definition->height; +} + +static Color _fakeGetFinalColor(Renderer* renderer, Vector3 location, double precision) +{ + return COLOR_GREEN; +} + +static Color _getFinalColor(Renderer* renderer, Vector3 location, double precision) +{ + Color color; + + color = renderer->applyTextures(renderer, location, precision); + + /* TODO Factorize this in scenery renderer */ + color = renderer->atmosphere->applyAerialPerspective(renderer, location, color); + color = renderer->applyClouds(renderer, color, renderer->camera_location, location); + + return color; +} + +RayCastingResult _fakeCastRay(Renderer* renderer, Vector3 start, Vector3 direction) +{ + UNUSED(renderer); + UNUSED(start); + UNUSED(direction); + + RayCastingResult result; + result.hit = 0; + return result; +} + +RayCastingResult _castRay(Renderer* renderer, Vector3 start, Vector3 direction) +{ + RayCastingResult result; + TerrainDefinition* definition = renderer->terrain->definition; + Vector3 inc_vector; + double inc_value, inc_base, inc_factor, height, diff, lastdiff, length; + + direction = v3Normalize(direction); + inc_factor = (double)renderer->render_quality; + inc_base = 1.0; + inc_value = inc_base / inc_factor; + lastdiff = start.y - _getHeight(renderer, start.x, start.z); + + length = 0.0; + do + { + inc_vector = v3Scale(direction, inc_value); + length += v3Norm(inc_vector); + start = v3Add(start, inc_vector); + height = _getHeight(renderer, start.x, start.z); + diff = start.y - height; + if (diff < 0.0) + { + if (fabs(diff - lastdiff) > 0.00001) + { + start = v3Add(start, v3Scale(inc_vector, -diff / (diff - lastdiff))); + start.y = _getHeight(renderer, start.x, start.z); + } + else + { + start.y = height; + } + result.hit = 1; + result.hit_location = start; + result.hit_color = _getFinalColor(renderer, start, renderer->getPrecision(renderer, result.hit_location)); + return result; + } + + if (diff < inc_base / inc_factor) + { + inc_value = inc_base / inc_factor; + } + else if (diff > inc_base) + { + inc_value = inc_base; + } + else + { + inc_value = diff; + } + lastdiff = diff; + } while (length < 50.0 && start.y <= definition->_max_height); + + result.hit = 0; + return result; +} + +static LightDefinition _fakeAlterLight(Renderer* renderer, LightDefinition* light, Vector3 at) +{ + UNUSED(renderer); + UNUSED(at); + + return *light; +} + +static LightDefinition _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location) +{ + TerrainDefinition* definition = renderer->terrain->definition; + LightDefinition result = *light; + Vector3 inc_vector, direction_to_light; + double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length; + + direction_to_light = v3Scale(light->direction, -1.0); + if ((fabs(direction_to_light.x) < 0.0001 && fabs(direction_to_light.z) < 0.0001) || definition->height < 0.001) + { + return result; + } + else if (direction_to_light.y < 0.05) + { + result.color = COLOR_BLACK; + return result; + } + else if (direction_to_light.y < 0.0000) + { + result.color.r *= (0.05 + direction_to_light.y) / 0.05; + result.color.g *= (0.05 + direction_to_light.y) / 0.05; + result.color.b *= (0.05 + direction_to_light.y) / 0.05; + } + + inc_factor = (double)renderer->render_quality; + inc_base = definition->height / definition->scaling; + inc_value = inc_base / inc_factor; + smoothing = definition->shadow_smoothing; + + light_factor = 1.0; + length = 0.0; + diff = 0.0; + do + { + inc_vector = v3Scale(direction_to_light, inc_value); + length += v3Norm(inc_vector); + location = v3Add(location, inc_vector); + height = _getHeight(renderer, location.x, location.z); + diff = location.y - height; + if (diff < 0.0) + { + if (length * smoothing > 0.000001) + { + light_factor += diff * v3Norm(inc_vector) / (length * smoothing); + } + else + { + light_factor = 0.0; + } + } + + if (diff < inc_base / inc_factor) + { + inc_value = inc_base / inc_factor; + } + else if (diff > inc_base) + { + inc_value = inc_base; + } + else + { + inc_value = diff; + } + } while (light_factor > 0.0 && length < (10.0 * inc_factor) && location.y <= definition->_max_height); + + if (light_factor <= 0.0) + { + result.color = COLOR_BLACK; + return result; + } + else + { + result.color.r *= light_factor; + result.color.g *= light_factor; + result.color.b *= light_factor; + + return result; + } +} + +/******************** Renderer ********************/ +static TerrainRenderer* _createRenderer() +{ + TerrainRenderer* result; + + result = malloc(sizeof(TerrainRenderer)); + result->definition = TerrainDefinitionClass.create(); + + result->castRay = _fakeCastRay; + result->alterLight = _fakeAlterLight; + result->getHeight = _fakeGetHeight; + result->getFinalColor = _fakeGetFinalColor; + + return result; +} + +static void _deleteRenderer(TerrainRenderer* renderer) +{ + TerrainDefinitionClass.destroy(renderer->definition); + free(renderer); +} + +static void _bindRenderer(TerrainRenderer* renderer, TerrainDefinition* definition) +{ + TerrainDefinitionClass.copy(definition, renderer->definition); + + renderer->castRay = _castRay; + renderer->alterLight = _alterLight; + renderer->getHeight = _getHeight; + renderer->getFinalColor = _getFinalColor; +} + +StandardRenderer TerrainRendererClass = { + (FuncObjectCreate)_createRenderer, + (FuncObjectDelete)_deleteRenderer, + (FuncObjectBind)_bindRenderer +}; diff --git a/lib_paysages/terrain/presets.c b/lib_paysages/terrain/presets.c new file mode 100644 index 0000000..3104494 --- /dev/null +++ b/lib_paysages/terrain/presets.c @@ -0,0 +1,25 @@ +#include "public.h" +#include "private.h" + +/* + * Terrain presets. + */ + +void terrainAutoPreset(TerrainDefinition* definition, TerrainPreset preset) +{ + switch (preset) + { + case TERRAIN_PRESET_STANDARD: + noiseClearLevels(definition->_height_noise); + noiseAddLevelsSimple(definition->_height_noise, 10, 1.0, 1.0); + noiseSetFunctionParams(definition->_height_noise, NOISE_FUNCTION_SIMPLEX, -0.2); + definition->height = 12.0 / noiseGetMaxValue(definition->_height_noise); + definition->scaling = 80.0; + definition->shadow_smoothing = 0.03; + break; + default: + ; + } + + TerrainDefinitionClass.validate(definition); +} diff --git a/lib_paysages/terrain/private.h b/lib_paysages/terrain/private.h new file mode 100644 index 0000000..546e40f --- /dev/null +++ b/lib_paysages/terrain/private.h @@ -0,0 +1,4 @@ +#ifndef _PAYSAGES_TERRAIN_PRIVATE_H_ +#define _PAYSAGES_TERRAIN_PRIVATE_H_ + +#endif diff --git a/lib_paysages/terrain/public.h b/lib_paysages/terrain/public.h new file mode 100644 index 0000000..09b6f2a --- /dev/null +++ b/lib_paysages/terrain/public.h @@ -0,0 +1,56 @@ +#ifndef _PAYSAGES_TERRAIN_PUBLIC_H_ +#define _PAYSAGES_TERRAIN_PUBLIC_H_ + +#include "../shared/types.h" +#include "../noise.h" +#include "../lighting.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + TERRAIN_PRESET_STANDARD +} TerrainPreset; + +typedef struct +{ + double height; + double scaling; + double shadow_smoothing; + + double _detail; + NoiseGenerator* _height_noise; + double _min_height; + double _max_height; +} TerrainDefinition; + +typedef double (*FuncTerrainGetHeight)(Renderer* renderer, double x, double z); +typedef Color (*FuncTerrainGetFinalColor)(Renderer* renderer, Vector3 location, double precision); + +typedef struct +{ + TerrainDefinition* definition; + + FuncGeneralCastRay castRay; + FuncLightingAlterLight alterLight; + FuncTerrainGetHeight getHeight; + FuncTerrainGetFinalColor getFinalColor; + + void* _internal_data; +} TerrainRenderer; + +extern StandardDefinition TerrainDefinitionClass; +extern StandardRenderer TerrainRendererClass; + +void terrainAutoPreset(TerrainDefinition* definition, TerrainPreset preset); +void terrainRenderSurface(Renderer* renderer); +/*Renderer terrainCreatePreviewRenderer(); +Color terrainGetPreview(Renderer* renderer, double x, double y);*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib_paysages/terrain/raster.c b/lib_paysages/terrain/raster.c new file mode 100644 index 0000000..d4f8616 --- /dev/null +++ b/lib_paysages/terrain/raster.c @@ -0,0 +1,94 @@ +#include "public.h" +#include "private.h" + +#include +#include "../renderer.h" + +/* + * Terrain rasterization. + */ + +static inline Vector3 _getPoint(TerrainDefinition* definition, Renderer* renderer, double x, double z) +{ + Vector3 result; + + result.x = x; + result.y = renderer->terrain->getHeight(renderer, x, z); + result.z = z; + + return result; +} + +static Color _postProcessFragment(Renderer* renderer, Vector3 point, void* data) +{ + double precision; + + point = _getPoint(renderer->terrain->definition, renderer, point.x, point.z); + + precision = renderer->getPrecision(renderer, point); + return renderer->terrain->getFinalColor(renderer, point, precision); +} + +static void _renderQuad(TerrainDefinition* definition, Renderer* renderer, double x, double z, double size, double water_height) +{ + Vector3 v1, v2, v3, v4; + + v1 = _getPoint(definition, renderer, x, z); + v2 = _getPoint(definition, renderer, x, z + size); + v3 = _getPoint(definition, renderer, x + size, z + size); + v4 = _getPoint(definition, renderer, x + size, z); + + if (v1.y > water_height || v2.y > water_height || v3.y > water_height || v4.y > water_height) + { + renderer->pushQuad(renderer, v1, v2, v3, v4, _postProcessFragment, NULL); + } +} + +void terrainRenderSurface(Renderer* renderer) +{ + int chunk_factor, chunk_count, i; + double cx = renderer->camera_location.x; + double cz = renderer->camera_location.z; + double min_chunk_size, visible_chunk_size; + double radius_int, radius_ext, chunk_size; + double water_height; + TerrainDefinition* definition = renderer->terrain->definition; + + min_chunk_size = 0.1 / (double)renderer->render_quality; + visible_chunk_size = 0.05 / (double)renderer->render_quality; + + chunk_factor = 1; + chunk_count = 2; + radius_int = 0.0; + radius_ext = min_chunk_size; + chunk_size = min_chunk_size; + + water_height = renderer->getWaterHeightInfo(renderer).max_height; + + while (radius_ext < 1000.0) + { + if (!renderer->addRenderProgress(renderer, 0.0)) + { + return; + } + + for (i = 0; i < chunk_count - 1; i++) + { + _renderQuad(definition, renderer, cx - radius_ext + chunk_size * i, cz - radius_ext, chunk_size, water_height); + _renderQuad(definition, renderer, cx + radius_int, cz - radius_ext + chunk_size * i, chunk_size, water_height); + _renderQuad(definition, renderer, cx + radius_int - chunk_size * i, cz + radius_int, chunk_size, water_height); + _renderQuad(definition, renderer, cx - radius_ext, cz + radius_int - chunk_size * i, chunk_size, water_height); + } + + if (chunk_count % 64 == 0 && chunk_size / radius_int < visible_chunk_size) + { + chunk_count /= 2; + chunk_factor *= 2; + /* TODO Fill in gaps with triangles */ + } + chunk_count += 2; + chunk_size = min_chunk_size * chunk_factor; + radius_int = radius_ext; + radius_ext += chunk_size; + } +} diff --git a/lib_paysages/terraincanvas.c b/lib_paysages/terraincanvas.c deleted file mode 100644 index 2eefaa6..0000000 --- a/lib_paysages/terraincanvas.c +++ /dev/null @@ -1,175 +0,0 @@ -#include "terraincanvas.h" -#include "scenery.h" - -#include -#include -#include - -TerrainCanvas* terrainCanvasCreate() -{ - TerrainCanvas* result = malloc(sizeof(TerrainCanvas)); - - result->area = geoareaCreate(); - result->offset_y = 0.0; - result->height_map = heightmapCreate(); - heightmapChangeResolution(&result->height_map, 256, 256); - result->height_factor = 1.0; - result->detail_noise = noiseCreateGenerator(); - noiseAddLevelsSimple(result->detail_noise, 5, 1.0, 1.0); - result->detail_height_factor = 0.2; - result->detail_scaling = 0.4; - result->mask.mode = INTEGRATIONMASK_MODE_CIRCLE; - result->mask.smoothing = 0.1; - - return result; -} - -void terrainCanvasDelete(TerrainCanvas* canvas) -{ - heightmapDelete(&canvas->height_map); - noiseDeleteGenerator(canvas->detail_noise); - free(canvas); -} - -void terrainCanvasCopy(TerrainCanvas* source, TerrainCanvas* destination) -{ - geoareaCopy(&source->area, &destination->area); - destination->offset_y = source->offset_y; - destination->height_factor = source->height_factor; - heightmapCopy(&source->height_map, &destination->height_map); - noiseCopy(source->detail_noise, destination->detail_noise); - destination->detail_height_factor = source->detail_height_factor; - destination->detail_scaling = source->detail_scaling; - destination->mask = source->mask; -} - -void terrainCanvasValidate(TerrainCanvas* canvas) -{ - if (canvas->detail_scaling < 0.00001) - { - canvas->detail_scaling = 0.00001; - } - geoareaValidate(&canvas->area); - heightmapValidate(&canvas->height_map); - noiseValidate(canvas->detail_noise); -} - -LayerType terrainCanvasGetLayerType() -{ - LayerType result; - - result.callback_create = (LayerCallbackCreate)terrainCanvasCreate; - result.callback_delete = (LayerCallbackDelete)terrainCanvasDelete; - result.callback_copy = (LayerCallbackCopy)terrainCanvasCopy; - result.callback_validate = (LayerCallbackValidate)terrainCanvasValidate; - result.callback_save = (LayerCallbackSave)terrainCanvasSave; - result.callback_load = (LayerCallbackLoad)terrainCanvasLoad; - - return result; -} - -void terrainCanvasSave(PackStream* stream, TerrainCanvas* canvas) -{ - geoareaSave(stream, &canvas->area); - packWriteDouble(stream, &canvas->offset_y); - heightmapSave(stream, &canvas->height_map); - packWriteDouble(stream, &canvas->height_factor); - noiseSaveGenerator(stream, canvas->detail_noise); - packWriteDouble(stream, &canvas->detail_height_factor); - packWriteDouble(stream, &canvas->detail_scaling); - packWriteInt(stream, &canvas->mask.mode); - packWriteDouble(stream, &canvas->mask.smoothing); -} - -void terrainCanvasLoad(PackStream* stream, TerrainCanvas* canvas) -{ - geoareaLoad(stream, &canvas->area); - packReadDouble(stream, &canvas->offset_y); - heightmapLoad(stream, &canvas->height_map); - packReadDouble(stream, &canvas->height_factor); - noiseLoadGenerator(stream, canvas->detail_noise); - packReadDouble(stream, &canvas->detail_height_factor); - packReadDouble(stream, &canvas->detail_scaling); - packReadInt(stream, &canvas->mask.mode); - packReadDouble(stream, &canvas->mask.smoothing); -} - -void terrainCanvasGetLimits(TerrainCanvas* canvas, double* ymin, double* ymax) -{ - double noise_max = noiseGetMaxValue(canvas->detail_noise) * canvas->detail_height_factor; - heightmapGetLimits(&canvas->height_map, ymin, ymax); - *ymin -= noise_max; - *ymax += noise_max; -} - -void terrainCanvasRevertToTerrain(TerrainCanvas* canvas) -{ - TerrainDefinition terrain; - - terrain = terrainCreateDefinition(); - sceneryGetTerrain(&terrain); - - heightmapRevertToTerrain(&canvas->height_map, &terrain, &canvas->area); - - terrainDeleteDefinition(&terrain); -} - -Vector3 terrainCanvasApply(TerrainCanvas* canvas, Vector3 location) -{ - if (location.x >= canvas->area.location_x && - location.z >= canvas->area.location_z && - location.x <= canvas->area.location_x + canvas->area.size_x && - location.z <= canvas->area.location_z + canvas->area.size_z) - { - double inside_x, inside_z; - double height; - - /* Get height map displacement */ - geoareaToLocal(&canvas->area, location.x, location.z, &inside_x, &inside_z); - height = heightmapGetValue(&canvas->height_map, inside_x, inside_z); - - /* Apply factor */ - height = height * canvas->height_factor + canvas->offset_y; - - /* Apply detail noise */ - height += noiseGet2DTotal(canvas->detail_noise, location.x / canvas->detail_scaling, location.z / canvas->detail_scaling) * canvas->detail_height_factor; - - /* Apply integration mask */ - double influence = terrainCanvasGetMaskValue(canvas, inside_x, inside_z); - location.y = influence * height + (1.0 - influence) * location.y; - - } - return location; -} - -double terrainCanvasGetMaskValue(TerrainCanvas* canvas, double local_x, double local_z) -{ - double distance; - - local_x = (local_x - 0.5) * 2.0; - local_z = (local_z - 0.5) * 2.0; - - if (canvas->mask.mode == INTEGRATIONMASK_MODE_SQUARE) - { - local_x = fabs(local_x); - local_z = fabs(local_z); - distance = local_x > local_z ? local_x : local_z; - } - else - { - distance = sqrt(local_x * local_x + local_z * local_z); - } - - if (distance <= 1.0 - canvas->mask.smoothing) - { - return 1.0; - } - else if (distance <= 1.0) - { - return (1.0 - distance) / canvas->mask.smoothing; - } - else - { - return 0.0; - } -} diff --git a/lib_paysages/terraincanvas.h b/lib_paysages/terraincanvas.h deleted file mode 100644 index 45488ac..0000000 --- a/lib_paysages/terraincanvas.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef _PAYSAGES_TERRAINCANVAS_H_ -#define _PAYSAGES_TERRAINCANVAS_H_ - -/* Terrain edition by painting over an area */ - -#include "pack.h" -#include "noise.h" -#include "terrain.h" -#include "layers.h" -#include "heightmap.h" -#include "geoarea.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct -{ - int mode; - double smoothing; -} IntegrationMask; - -#define INTEGRATIONMASK_MODE_SQUARE 0 -#define INTEGRATIONMASK_MODE_CIRCLE 1 - -typedef struct -{ - GeoArea area; - double offset_y; - HeightMap height_map; - double height_factor; - NoiseGenerator* detail_noise; - double detail_height_factor; - double detail_scaling; - IntegrationMask mask; -} TerrainCanvas; - -TerrainCanvas* terrainCanvasCreate(); -void terrainCanvasDelete(TerrainCanvas* canvas); -void terrainCanvasCopy(TerrainCanvas* source, TerrainCanvas* destination); -void terrainCanvasValidate(TerrainCanvas* canvas); -LayerType terrainCanvasGetLayerType(); - -void terrainCanvasSave(PackStream* stream, TerrainCanvas* canvas); -void terrainCanvasLoad(PackStream* stream, TerrainCanvas* canvas); - -void terrainCanvasGetLimits(TerrainCanvas* canvas, double* ymin, double* ymax); -void terrainCanvasRevertToTerrain(TerrainCanvas* canvas); -Vector3 terrainCanvasApply(TerrainCanvas* canvas, Vector3 location); -double terrainCanvasGetMaskValue(TerrainCanvas* canvas, double local_x, double local_z); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib_paysages/textures.c b/lib_paysages/textures.c index dc9514a..8378ef8 100644 --- a/lib_paysages/textures.c +++ b/lib_paysages/textures.c @@ -6,10 +6,11 @@ #include #include "shared/types.h" +#include "terrain/public.h" #include "color.h" #include "euclid.h" #include "lighting.h" -#include "terrain.h" +#include "renderer.h" #include "tools.h" #define TEXTURES_MAX_LAYERS 50 @@ -61,7 +62,7 @@ TextureLayerDefinition* texturesLayerCreateDefinition() TextureLayerDefinition* result; result = malloc(sizeof(TextureLayerDefinition)); - + result->zone = zoneCreate(); result->bump_noise = noiseCreateGenerator(); noiseAddLevelsSimple(result->bump_noise, 8, 1.0, 1.0); @@ -135,31 +136,31 @@ static void _texturesLayerLoad(PackStream* stream, TextureLayerDefinition* layer LayerType texturesGetLayerType() { LayerType result; - + result.callback_create = (LayerCallbackCreate)texturesLayerCreateDefinition; result.callback_delete = (LayerCallbackDelete)texturesLayerDeleteDefinition; result.callback_copy = (LayerCallbackCopy)texturesLayerCopyDefinition; result.callback_validate = (LayerCallbackValidate)texturesLayerValidateDefinition; result.callback_save = (LayerCallbackSave)_texturesLayerSave; result.callback_load = (LayerCallbackLoad)_texturesLayerLoad; - + return result; } static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west) { Vector3 dnorth, deast, dsouth, dwest, normal; - + dnorth = v3Sub(north, center); deast = v3Sub(east, center); dsouth = v3Sub(south, center); dwest = v3Sub(west, center); - + normal = v3Cross(deast, dnorth); normal = v3Add(normal, v3Cross(dsouth, deast)); normal = v3Add(normal, v3Cross(dwest, dsouth)); normal = v3Add(normal, v3Cross(dnorth, dwest)); - + return v3Normalize(normal); } @@ -172,30 +173,30 @@ static inline TextureResult _getTerrainResult(Renderer* renderer, double x, doub { TextureResult result; Vector3 center, north, east, south, west; - + /* TODO This method is better suited in terrain.c */ center.x = x; center.z = z; - center.y = renderer->getTerrainHeight(renderer, center.x, center.z); + center.y = renderer->terrain->getHeight(renderer, center.x, center.z); east.x = x + detail; east.z = z; - east.y = renderer->getTerrainHeight(renderer, east.x, east.z); + east.y = renderer->terrain->getHeight(renderer, east.x, east.z); south.x = x; south.z = z + detail; - south.y = renderer->getTerrainHeight(renderer, south.x, south.z); + south.y = renderer->terrain->getHeight(renderer, south.x, south.z); if (renderer->render_quality > 5) { west.x = x - detail; west.z = z; - west.y = renderer->getTerrainHeight(renderer, west.x, west.z); + west.y = renderer->terrain->getHeight(renderer, west.x, west.z); north.x = x; north.z = z - detail; - north.y = renderer->getTerrainHeight(renderer, north.x, north.z); + north.y = renderer->terrain->getHeight(renderer, north.x, north.z); result.normal = _getNormal4(center, north, east, south, west); } @@ -207,7 +208,7 @@ static inline TextureResult _getTerrainResult(Renderer* renderer, double x, doub result.location = center; result.thickness = -100.0; result.definition = NULL; - + return result; } @@ -235,25 +236,25 @@ static inline void _getLayerThickness(TextureLayerDefinition* definition, Render static inline TextureResult _getLayerResult(TextureLayerDefinition* definition, Renderer* renderer, double x, double z, double detail) { TextureResult result_center, result_north, result_east, result_south, result_west; - + _getLayerThickness(definition, renderer, x, z, &result_center); _getLayerThickness(definition, renderer, x + detail, z, &result_east); _getLayerThickness(definition, renderer, x, z + detail, &result_south); - + if (renderer->render_quality > 5) { _getLayerThickness(definition, renderer, x - detail, z, &result_west); _getLayerThickness(definition, renderer, x, z - detail, &result_north); - + result_center.normal = _getNormal4(result_center.location, result_north.location, result_east.location, result_south.location, result_west.location); } else { result_center.normal = _getNormal2(result_center.location, result_east.location, result_south.location); } - + result_center.definition = definition; - + return result_center; } @@ -289,7 +290,7 @@ Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, doubl int i, start, nblayers; detail *= 0.1; - + results[0] = _getTerrainResult(renderer, x, z, detail); nblayers = layersCount(definition->layers); @@ -297,7 +298,7 @@ Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, doubl { results[i + 1] = _getLayerResult(layersGetLayer(definition->layers, i), renderer, x, z, detail); } - + qsort(results, nblayers + 1, sizeof(TextureResult), _cmpResults); /* Pre compute alpha channel */ @@ -308,7 +309,7 @@ Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, doubl { thickness = results[i].thickness - last_height; last_height = results[i].thickness; - + if (results[i].definition) { if (thickness < results[i].definition->thickness_transparency) @@ -324,7 +325,7 @@ Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, doubl { results[i].thickness = 1.0; } - + if (results[i].thickness >= 0.999999) { start = i; @@ -359,6 +360,6 @@ Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, doubl colorMask(&result, &color); } } - + return result; } diff --git a/lib_paysages/water.c b/lib_paysages/water.c index 48f6277..ce35524 100644 --- a/lib_paysages/water.c +++ b/lib_paysages/water.c @@ -4,7 +4,6 @@ #include "color.h" #include "euclid.h" #include "render.h" -#include "terrain.h" #include "lighting.h" #include "tools.h" @@ -19,7 +18,7 @@ void waterSave(PackStream* stream, WaterDefinition* definition) packWriteDouble(stream, &definition->transparency); packWriteDouble(stream, &definition->reflection); packWriteDouble(stream, &definition->lighting_depth); - + packWriteDouble(stream, &definition->scaling); packWriteDouble(stream, &definition->waves_height); packWriteDouble(stream, &definition->detail_height); @@ -27,7 +26,7 @@ void waterSave(PackStream* stream, WaterDefinition* definition) packWriteDouble(stream, &definition->foam_coverage); materialSave(stream, &definition->foam_material); - + noiseSaveGenerator(stream, definition->_waves_noise); } @@ -60,9 +59,9 @@ WaterDefinition waterCreateDefinition() result.height = -4.0; result._waves_noise = noiseCreateGenerator(); - + waterAutoPreset(&result, WATER_PRESET_LAKE); - + return result; } @@ -120,7 +119,7 @@ void waterAutoPreset(WaterDefinition* definition, WaterPreset preset) definition->foam_material.base.a = 1.0; definition->foam_material.reflection = 0.4; definition->foam_material.shininess = 1.5; - + waterValidateDefinition(definition); } @@ -159,7 +158,7 @@ static inline Vector3 _getNormal(WaterDefinition* definition, Vector3 base, doub { Vector3 back, right; double x, z; - + x = base.x; z = base.z; @@ -204,18 +203,18 @@ static inline Vector3 _refractRay(Vector3 incoming, Vector3 normal) HeightInfo waterGetHeightInfo(WaterDefinition* definition) { HeightInfo info; - + info.base_height = definition->height; info.min_height = definition->height - noiseGetMaxValue(definition->_waves_noise); info.max_height = definition->height + noiseGetMaxValue(definition->_waves_noise); - + return info; } Color waterLightFilter(WaterDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light) { double factor; - + UNUSED(renderer); UNUSED(light_location); @@ -251,9 +250,9 @@ static inline void _applyFoam(WaterDefinition* definition, Vector3 location, Vec { Color result = definition->foam_material.base; double foam_factor, normal_diff, location_offset; - + location_offset = 2.0 * detail; - + foam_factor = 0.0; location.x += location_offset; normal_diff = 1.0 - v3Dot(normal, _getNormal(definition, location, detail)); @@ -280,22 +279,22 @@ static inline void _applyFoam(WaterDefinition* definition, Vector3 location, Vec { foam_factor = normal_diff; } - + foam_factor *= 10.0; if (foam_factor > 1.0) { foam_factor = 1.0; } - + if (foam_factor <= 1.0 - definition->foam_coverage) { return; } foam_factor = (foam_factor - (1.0 - definition->foam_coverage)) * definition->foam_coverage; - + material->reflection = foam_factor * definition->foam_material.reflection + (1.0 - foam_factor) * material->reflection; material->shininess = foam_factor * definition->foam_material.shininess + (1.0 - foam_factor) * material->shininess; - + /* TODO This should be configurable */ if (foam_factor > 0.2) { @@ -349,17 +348,17 @@ WaterResult waterGetColorDetail(WaterDefinition* definition, Renderer* renderer, color.g = definition->material.base.g * (1.0 - definition->transparency) + result.reflected.g * definition->reflection + result.refracted.g * definition->transparency; color.b = definition->material.base.b * (1.0 - definition->transparency) + result.reflected.b * definition->reflection + result.refracted.b * definition->transparency; color.a = 1.0; - + material = definition->material; material.base = color; - + _applyFoam(definition, location, normal, detail, &material); renderer->getLightStatus(renderer, &light, location); color = renderer->applyLightStatus(renderer, &light, location, normal, material); color = renderer->atmosphere->applyAerialPerspective(renderer, location, color); color = renderer->applyClouds(renderer, color, renderer->camera_location, location); - + result.base = definition->material.base; result.final = color; @@ -395,7 +394,7 @@ static void _renderQuad(WaterDefinition* definition, Renderer* renderer, double v2 = _getFirstPassVertex(definition, x, z + size, size); v3 = _getFirstPassVertex(definition, x + size, z + size, size); v4 = _getFirstPassVertex(definition, x + size, z, size); - + renderer->pushQuad(renderer, v1, v2, v3, v4, _postProcessFragment, definition); }