diff --git a/ChangeLog b/ChangeLog index 1f53f7d..e79cc1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,12 +15,12 @@ Textures : * Textures ranges are now using curves. Water : + * Revamped light-based coloring. * Added foam. Atmosphere : * Merged with sky module. - * New sky model (based on Preetham's work). - * Added sun halo control. + * New sky model and aerial perspective (based on Preetham's work). * Better previews. Clouds : diff --git a/TODO b/TODO index 1b7ce29..b6ae2a8 100644 --- a/TODO +++ b/TODO @@ -1,23 +1,26 @@ Technology Preview 2 : -- Better time selection widget for atmosphere. -- Replace terrain canvas editor by full sculpting editor. - => Add a generation dialog, with fixed resolution. - => Store local terrain modifications in fully dynamic canvas. - => Add map preview with editor area. - => Allow camera move and zoom. +- Finalize terrain editor. + => Add a generation dialog for base noise (overwriting changes). + => Implement chunks merging (with max size control). - Get rid of noise dialogs, for simpler settings. -- Finalize lighting refactoring +- Finalize lighting/clouds refactoring => Restore cloud lighting + => Improve cloud rendering precision (and beware of precision discontinuity when rendering clouds in front of ground (shorter distance)). - Improve textures (current model is greatly incorrect). + => Convert to new architecture model. + => Use triplanar projection. => Separate models (basic texture and covering texture). => Covering texture height should inpact terrain height. => Add texture shadowing. -- Clouds should keep distance to ground. - Fix rendering when inside a cloud layer, with other upper or lower layers. -- Improve cloud rendering precision (and beware of precision discontinuity when rendering clouds in front of ground (shorter distance)). - Translations. Technlogy Preview 3 : +- Improve terrain 3D editor: + => Add a map preview with edit area highlighted. + => Allow zooming and simplified camera control. +- Better time selection widget for atmosphere. +- Clouds should keep distance to ground. - Find a proper model for night sky (maybe Shirley). - Create a StandardPreviewClass in C-lib (with renderer, updateData, changeView, getColor, choices and toggles). - Fully move layer management from BaseForm to BaseFormLayer. @@ -27,7 +30,7 @@ Technlogy Preview 3 : - Add fresnel effect to specular lighting. - Add "hardness to light" and shadow control ("minimum lighting") to material. - Start using OpenCL to optimize rendering. -- Restore render progress. +- Fully restore render progress (with first pass). - Rethink the quality settings and detail smoothing in the distance. => When quality setting is set to 10, add boost options => Add detail boost (adds granularity) diff --git a/gui_qt/explorerchunkterrain.cpp b/gui_qt/explorerchunkterrain.cpp index f6af5c9..84018e4 100644 --- a/gui_qt/explorerchunkterrain.cpp +++ b/gui_qt/explorerchunkterrain.cpp @@ -108,7 +108,7 @@ void ExplorerChunkTerrain::onCameraEvent(CameraDefinition* camera) } _distance_to_camera = v3Norm(v3Sub(getCenter(), camera->location)); - + _lock_data.unlock(); } @@ -166,7 +166,7 @@ double ExplorerChunkTerrain::getDisplayedSizeHint(CameraDefinition* camera) Color ExplorerChunkTerrain::getTextureColor(double x, double y) { Vector3 location = {_startx + x * _size, 0.0, _startz + y * _size}; - return renderer()->applyTextures(renderer(), location, 0.01); + return renderer()->terrain->getFinalColor(renderer(), location, 0.01); } Vector3 ExplorerChunkTerrain::getCenter() diff --git a/gui_qt/formclouds.cpp b/gui_qt/formclouds.cpp index fe132d9..2572fb3 100644 --- a/gui_qt/formclouds.cpp +++ b/gui_qt/formclouds.cpp @@ -115,6 +115,15 @@ FormClouds::FormClouds(QWidget *parent): setLayers(_definition->layers); } +FormClouds::~FormClouds() +{ + CloudsDefinitionClass.destroy(_definition); + cloudsGetLayerType().callback_delete(_layer); + + delete _previewCoverage; + delete _previewColor; +} + void FormClouds::revertConfig() { sceneryGetClouds(_definition); @@ -142,4 +151,3 @@ void FormClouds::autoPresetSelected(int preset) cloudsLayerAutoPreset(_layer, (CloudsLayerPreset)preset); BaseForm::autoPresetSelected(preset); } - diff --git a/gui_qt/formclouds.h b/gui_qt/formclouds.h index 73e100c..e5cdd09 100644 --- a/gui_qt/formclouds.h +++ b/gui_qt/formclouds.h @@ -12,6 +12,7 @@ class FormClouds : public BaseFormLayer public: explicit FormClouds(QWidget *parent = 0); + ~FormClouds(); public slots: virtual void revertConfig(); diff --git a/gui_qt/formrender.cpp b/gui_qt/formrender.cpp index 99c34d6..9244493 100644 --- a/gui_qt/formrender.cpp +++ b/gui_qt/formrender.cpp @@ -13,19 +13,10 @@ public: PreviewRenderLandscape(QWidget* parent):BasePreview(parent) { _renderer = sceneryCreateStandardRenderer(); - _renderer->applyTextures = _applyTextures; _renderer->getCameraLocation = _getCameraLocation; lightingManagerDisableSpecularity(_renderer->lighting); - _textures = texturesCreateDefinition(); - - _atmosphere = (AtmosphereDefinition*)AtmosphereDefinitionClass.create(); - _terrain = (TerrainDefinition*)TerrainDefinitionClass.create(); - _water = (WaterDefinition*)WaterDefinitionClass.create(); - _clouds = (CloudsDefinition*)CloudsDefinitionClass.create(); - - _renderer->customData[0] = &_textures; - + _no_clouds = (CloudsDefinition*)CloudsDefinitionClass.create(); _clouds_enabled = true; addOsd(QString("geolocation")); @@ -41,7 +32,7 @@ protected: Vector3 location; double height = _renderer->terrain->getHeight(_renderer, x, y, 1); - if (height < _water->height) + if (height < _renderer->water->getHeightInfo(_renderer).max_height) { return _renderer->water->getResult(_renderer, x, y).final; } @@ -55,14 +46,12 @@ protected: } void updateData() { - sceneryGetTextures(&_textures); - sceneryBindRenderer(_renderer); _renderer->atmosphere->applyAerialPerspective = _applyAerialPerspective; if (!_clouds_enabled) { - CloudsRendererClass.bind(_renderer, _clouds); + CloudsRendererClass.bind(_renderer, _no_clouds); } } void toggleChangeEvent(QString key, bool value) @@ -76,16 +65,7 @@ protected: private: Renderer* _renderer; bool _clouds_enabled; - CloudsDefinition* _clouds; - TerrainDefinition* _terrain; - WaterDefinition *_water; - TexturesDefinition _textures; - AtmosphereDefinition* _atmosphere; - - static Color _applyTextures(Renderer* renderer, Vector3 location, double precision) - { - return texturesGetColor((TexturesDefinition*)(renderer->customData[0]), renderer, location.x, location.z, precision); - } + CloudsDefinition* _no_clouds; static Vector3 _getCameraLocation(Renderer*, Vector3 location) { diff --git a/gui_qt/formtextures.cpp b/gui_qt/formtextures.cpp index b2664b6..3d38b18 100644 --- a/gui_qt/formtextures.cpp +++ b/gui_qt/formtextures.cpp @@ -1,21 +1,13 @@ #include "formtextures.h" -#include "../lib_paysages/textures.h" #include "../lib_paysages/scenery.h" #include "tools.h" -typedef struct -{ - Curve* height_curve; - Curve* slope_curve; -} TextureSupp; -static TextureSupp _supp; - /**************** Previews ****************/ class PreviewTexturesCoverage:public BasePreview { public: - PreviewTexturesCoverage(QWidget* parent, TextureLayerDefinition* layer):BasePreview(parent) + PreviewTexturesCoverage(QWidget* parent, TexturesLayerDefinition* layer):BasePreview(parent) { _terrain = (TerrainDefinition*)TerrainDefinitionClass.create(); @@ -23,7 +15,7 @@ public: _renderer->render_quality = 3; _original_layer = layer; - _preview_layer = texturesLayerCreateDefinition(); + //_preview_definition = (TexturesDefinition*)TexturesDefinitionClass.create(); addOsd(QString("geolocation")); @@ -32,7 +24,7 @@ public: } ~PreviewTexturesCoverage() { - texturesLayerDeleteDefinition(_preview_layer); + //TexturesDefinitionClass.destroy(_preview_layer); } protected: Color getColor(double x, double y) @@ -42,7 +34,7 @@ protected: location.x = x; location.y = _renderer->terrain->getHeight(_renderer, x, y, 1); location.z = y; - result.r = result.g = result.b = texturesGetLayerCoverage(_preview_layer, _renderer, location, this->scaling); + //result.r = result.g = result.b = texturesGetLayerCoverage(_preview_layer, _renderer, location, this->scaling); return result; } void updateData() @@ -50,23 +42,23 @@ protected: sceneryGetTerrain(_terrain); TerrainRendererClass.bind(_renderer, _terrain); - texturesLayerCopyDefinition(_original_layer, _preview_layer); + //TexturesDefinitionClass.copy(_original_layer, _preview_layer); } private: Renderer* _renderer; - TextureLayerDefinition* _original_layer; - TextureLayerDefinition* _preview_layer; + TexturesLayerDefinition* _original_layer; + TexturesDefinition* _preview_definition; TerrainDefinition* _terrain; }; class PreviewTexturesColor:public BasePreview { public: - PreviewTexturesColor(QWidget* parent, TextureLayerDefinition* layer):BasePreview(parent) + PreviewTexturesColor(QWidget* parent, TexturesLayerDefinition* layer):BasePreview(parent) { _original_layer = layer; - _preview_layer = texturesLayerCreateDefinition(); + //_preview_layer = (TexturesLayerDefinition*)TexturesDefinitionClass.create(); _renderer = rendererCreate(); _renderer->render_quality = 3; @@ -74,14 +66,12 @@ public: _renderer->render_camera.location.y = 20.0; _renderer->render_camera.location.z = 0.0; - _zone = zoneCreate(); - configScaling(0.01, 1.0, 0.01, 0.1); configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0); } ~PreviewTexturesColor() { - texturesLayerDeleteDefinition(_preview_layer); + //TexturesDefinitionClass.destroy(_preview_layer); } protected: Color getColor(double x, double y) @@ -90,35 +80,32 @@ protected: location.x = x; location.y = 0.0; location.z = y; - return texturesGetLayerColor(_preview_layer, _renderer, location, this->scaling); + //return texturesGetLayerColor(_preview_layer, _renderer, location, this->scaling); + return COLOR_BLACK; } void updateData() { - texturesLayerCopyDefinition(_original_layer, _preview_layer); - zoneCopy(_zone, _preview_layer->zone); + //TexturesDefinitionClass.copy(_original_layer, _preview_layer); } private: - Zone* _zone; Renderer* _renderer; - TextureLayerDefinition* _original_layer; - TextureLayerDefinition* _preview_layer; + TexturesLayerDefinition* _original_layer; + TexturesLayerDefinition* _preview_layer; }; /**************** Form ****************/ FormTextures::FormTextures(QWidget *parent): BaseFormLayer(parent) { - _definition = texturesCreateDefinition(); - _layer = texturesLayerCreateDefinition(); - _supp.height_curve = curveCreate(); - _supp.slope_curve = curveCreate(); + _definition = (TexturesDefinition*)TexturesDefinitionClass.create(); + _layer = (TexturesLayerDefinition*)texturesGetLayerType().callback_create(); _previewCoverage = new PreviewTexturesCoverage(this, _layer); _previewColor = new PreviewTexturesColor(this, _layer); addPreview(_previewCoverage, tr("Coverage preview")); addPreview(_previewColor, tr("Lighted sample")); - addInputNoise(tr("Surface noise"), _layer->bump_noise); + /*addInputNoise(tr("Surface noise"), _layer->bump_noise); addInputDouble(tr("Surface noise height"), &_layer->bump_height, 0.0, 0.1, 0.001, 0.01); addInputDouble(tr("Surface noise scaling"), &_layer->bump_scaling, 0.003, 0.3, 0.003, 0.03); addInputMaterial(tr("Material"), &_layer->material); @@ -126,45 +113,41 @@ FormTextures::FormTextures(QWidget *parent): addInputCurve(tr("Coverage by slope"), _supp.slope_curve, 0.0, 5.0, 0.0, 1.0, tr("Terrain slope"), tr("Texture coverage")); addInputDouble(tr("Amplitude for slope coverage"), &_layer->slope_range, 0.001, 0.1, 0.001, 0.01); addInputDouble(tr("Layer thickness"), &_layer->thickness, 0.0, 0.1, 0.001, 0.01); - addInputDouble(tr("Transparency thickness"), &_layer->thickness_transparency, 0.0, 0.1, 0.001, 0.01); + addInputDouble(tr("Transparency thickness"), &_layer->thickness_transparency, 0.0, 0.1, 0.001, 0.01);*/ - setLayers(_definition.layers); + setLayers(_definition->layers); } FormTextures::~FormTextures() { - texturesDeleteDefinition(&_definition); - texturesLayerDeleteDefinition(_layer); - curveDelete(_supp.height_curve); - curveDelete(_supp.slope_curve); + TexturesDefinitionClass.destroy(_definition); + texturesGetLayerType().callback_delete(_layer); } void FormTextures::revertConfig() { - sceneryGetTextures(&_definition); + sceneryGetTextures(_definition); BaseFormLayer::revertConfig(); } void FormTextures::applyConfig() { BaseFormLayer::applyConfig(); - scenerySetTextures(&_definition); + scenerySetTextures(_definition); } void FormTextures::layerReadCurrentFrom(void* layer_definition) { - TextureLayerDefinition* source = (TextureLayerDefinition*)layer_definition; - texturesLayerCopyDefinition(source, _layer); - - zoneGetHeightCurve(source->zone, _supp.height_curve); - zoneGetSlopeCurve(source->zone, _supp.slope_curve); + texturesGetLayerType().callback_copy((TexturesLayerDefinition*)layer_definition, _layer); } void FormTextures::layerWriteCurrentTo(void* layer_definition) { - TextureLayerDefinition* destination = (TextureLayerDefinition*)layer_definition; - texturesLayerCopyDefinition(_layer, destination); - - zoneSetHeightCurve(destination->zone, _supp.height_curve); - zoneSetSlopeCurve(destination->zone, _supp.slope_curve); + texturesGetLayerType().callback_copy(_layer, (TexturesLayerDefinition*)layer_definition); +} + +void FormTextures::autoPresetSelected(int preset) +{ + texturesLayerAutoPreset(_layer, (TexturesLayerPreset)preset); + BaseForm::autoPresetSelected(preset); } diff --git a/gui_qt/formtextures.h b/gui_qt/formtextures.h index 1bd9a5b..914a9c2 100644 --- a/gui_qt/formtextures.h +++ b/gui_qt/formtextures.h @@ -4,7 +4,7 @@ #include #include "basepreview.h" #include "baseformlayer.h" -#include "../lib_paysages/textures.h" +#include "../lib_paysages/textures/public.h" class FormTextures : public BaseFormLayer { @@ -21,10 +21,11 @@ public slots: protected: virtual void layerReadCurrentFrom(void* layer_definition); virtual void layerWriteCurrentTo(void* layer_definition); + virtual void autoPresetSelected(int preset); private: - TexturesDefinition _definition; - TextureLayerDefinition* _layer; + TexturesDefinition* _definition; + TexturesLayerDefinition* _layer; BasePreview* _previewCoverage; BasePreview* _previewColor; }; diff --git a/gui_qt/widgetexplorer.cpp b/gui_qt/widgetexplorer.cpp index 4d48b9c..9833729 100644 --- a/gui_qt/widgetexplorer.cpp +++ b/gui_qt/widgetexplorer.cpp @@ -48,11 +48,6 @@ private: static QVector _threads; -static Color _applyTextures(Renderer* renderer, Vector3 location, double precision) -{ - return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision); -} - static Vector3 _getCameraLocation(Renderer* renderer, Vector3) { return ((CameraDefinition*)renderer->customData[2])->location; @@ -67,14 +62,9 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera): _base_camera = camera; cameraCopyDefinition(camera, &_current_camera); - _textures = texturesCreateDefinition(); - sceneryGetTextures(&_textures); - _renderer = sceneryCreateStandardRenderer(); _renderer->render_quality = 3; - _renderer->customData[1] = &_textures; _renderer->customData[2] = _base_camera; - _renderer->applyTextures = _applyTextures; _renderer->getCameraLocation = _getCameraLocation; lightingManagerDisableSpecularity(_renderer->lighting); diff --git a/gui_qt/widgetexplorer.h b/gui_qt/widgetexplorer.h index 4d63c07..3a7b815 100644 --- a/gui_qt/widgetexplorer.h +++ b/gui_qt/widgetexplorer.h @@ -5,7 +5,6 @@ #include "baseexplorerchunk.h" #include "../lib_paysages/camera.h" #include "../lib_paysages/renderer.h" -#include "../lib_paysages/textures.h" class WidgetExplorer : public QGLWidget { @@ -47,8 +46,6 @@ private: bool _alive; QMutex _lock_chunks; - TexturesDefinition _textures; - double _average_frame_time; int _quality; diff --git a/lib_paysages/Makefile b/lib_paysages/Makefile index a04a88a..3c8bef1 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 clouds/*.c terrain/*.c water/*.c tools/*.c shared/*.c) +SOURCES = $(wildcard *.c atmosphere/*.c clouds/*.c terrain/*.c textures/*.c water/*.c tools/*.c shared/*.c) OBJECTS = ${SOURCES:%.c=${OBJPATH}/%.o} -HEADERS = $(wildcard *.h atmosphere/*.h clouds/*.h terrain/*.h water/*.h tools/*.h shared/*.h) +HEADERS = $(wildcard *.h atmosphere/*.h clouds/*.h terrain/*.h textures/*.h water/*.h tools/*.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/auto.c b/lib_paysages/auto.c index 94e6ee9..8b0690a 100644 --- a/lib_paysages/auto.c +++ b/lib_paysages/auto.c @@ -5,17 +5,12 @@ #include #include "render.h" -#include "textures.h" #include "scenery.h" #include "system.h" #include "zone.h" void autoGenRealisticLandscape(int seed) { - TexturesDefinition textures; - TextureLayerDefinition* texture; - int layer; - if (!seed) { seed = time(NULL); @@ -23,60 +18,4 @@ void autoGenRealisticLandscape(int seed) srand(seed); sceneryAutoPreset(); - - /* Textures */ - textures = texturesCreateDefinition(); - layer = layersAddLayer(textures.layers, NULL); - layersSetName(textures.layers, layer, "Ground"); - texture = layersGetLayer(textures.layers, layer); - noiseClearLevels(texture->bump_noise); - noiseRandomizeOffsets(texture->bump_noise); - noiseAddLevelsSimple(texture->bump_noise, 8, 1.0, -0.5, 0.5, 0.5); - texture->bump_height = 0.01; - texture->bump_scaling = 0.045; - texture->material.base.r = 0.6; - texture->material.base.g = 0.55; - texture->material.base.b = 0.57; - texture->material.reflection = 0.02; - texture->material.shininess = 3.0; - texture->thickness = 0.001; - texture->slope_range = 0.001; - texture->thickness_transparency = 0.0; - layer = layersAddLayer(textures.layers, NULL); - layersSetName(textures.layers, layer, "Grass"); - texture = layersGetLayer(textures.layers, layer); - zoneAddHeightRangeQuick(texture->zone, 1.0, -6.0, -5.0, 3.0, 15.0); - zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.05, 0.4); - noiseClearLevels(texture->bump_noise); - noiseRandomizeOffsets(texture->bump_noise); - noiseAddLevelsSimple(texture->bump_noise, 5, 1.0, -0.2, 0.2, 0.5); - noiseAddLevelsSimple(texture->bump_noise, 2, 0.03, -0.04, 0.04, 0.5); - texture->bump_height = 0.002; - texture->bump_scaling = 0.03; - texture->material.base.r = 0.12; - texture->material.base.g = 0.19; - texture->material.base.b = 0.035; - texture->material.reflection = 0.003; - texture->material.shininess = 2.0; - texture->thickness = 0.02; - texture->slope_range = 0.03; - texture->thickness_transparency = 0.005; - /*texture = texturesGetLayer(&textures, texturesAddLayer(&textures)); - zoneAddHeightRangeQuick(texture->zone, 1.0, 4.0, 5.0, 100.0, 100.0); - zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.2, 1.0); - noiseGenerateBaseNoise(texture->bump_noise, 102400); - noiseClearLevels(texture->bump_noise); - noiseAddLevelsSimple(texture->bump_noise, 6, 1.0, 1.0); - texture->bump_height = 0.002; - texture->bump_scaling = 0.03; - texture->material.base.r = 1.0; - texture->material.base.g = 1.0; - texture->material.base.b = 1.0; - texture->material.reflection = 0.25; - texture->material.shininess = 0.6; - texture->thickness = 0.05; - texture->slope_range = 0.3; - texture->thickness_transparency = 0.015;*/ - scenerySetTextures(&textures); - texturesDeleteDefinition(&textures); } diff --git a/lib_paysages/renderer.c b/lib_paysages/renderer.c index 39ea329..25d5f67 100644 --- a/lib_paysages/renderer.c +++ b/lib_paysages/renderer.c @@ -78,11 +78,6 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector return _RAYCASTING_NULL; } -static Color _applyTextures(Renderer* renderer, Vector3 location, double precision) -{ - return COLOR_TRANSPARENT; -} - static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial* material) { LightStatus* light = lightingCreateStatus(renderer->lighting, location, renderer->getCameraLocation(renderer, location)); @@ -125,7 +120,6 @@ Renderer* rendererCreate() result->pushQuad = _pushQuad; result->rayWalking = _rayWalking; - result->applyTextures = _applyTextures; result->applyLightingToSurface = _applyLightingToSurface; result->applyMediumTraversal = _applyMediumTraversal; @@ -135,6 +129,7 @@ Renderer* rendererCreate() result->atmosphere = AtmosphereRendererClass.create(); result->clouds = CloudsRendererClass.create(); result->terrain = TerrainRendererClass.create(); + result->textures = TexturesRendererClass.create(); result->water = WaterRendererClass.create(); return result; @@ -147,6 +142,7 @@ void rendererDelete(Renderer* renderer) AtmosphereRendererClass.destroy(renderer->atmosphere); CloudsRendererClass.destroy(renderer->clouds); TerrainRendererClass.destroy(renderer->terrain); + TexturesRendererClass.destroy(renderer->textures); WaterRendererClass.destroy(renderer->water); renderDeleteArea(renderer->render_area); diff --git a/lib_paysages/renderer.h b/lib_paysages/renderer.h index 1b05343..56b0e02 100644 --- a/lib_paysages/renderer.h +++ b/lib_paysages/renderer.h @@ -5,6 +5,7 @@ #include "atmosphere/public.h" #include "clouds/public.h" #include "terrain/public.h" +#include "textures/public.h" #include "water/public.h" #include "render.h" @@ -40,7 +41,6 @@ struct Renderer /* Scenery related */ RayCastingResult (*rayWalking)(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds); - Color (*applyTextures)(Renderer* renderer, Vector3 location, double precision); /* Autonomous tools */ LightingManager* lighting; @@ -48,6 +48,7 @@ struct Renderer /* Autonomous sub-renderers */ AtmosphereRenderer* atmosphere; TerrainRenderer* terrain; + TexturesRenderer* textures; CloudsRenderer* clouds; WaterRenderer* water; diff --git a/lib_paysages/scenery.c b/lib_paysages/scenery.c index d7ccfd8..e3f2ac2 100644 --- a/lib_paysages/scenery.c +++ b/lib_paysages/scenery.c @@ -9,7 +9,7 @@ static AtmosphereDefinition* _atmosphere; static CameraDefinition _camera; static CloudsDefinition* _clouds; static TerrainDefinition* _terrain; -static TexturesDefinition _textures; +static TexturesDefinition* _textures; static WaterDefinition* _water; static SceneryCustomDataCallback _custom_save = NULL; @@ -24,7 +24,7 @@ void sceneryInit() _camera = cameraCreateDefinition(); _clouds = CloudsDefinitionClass.create(); _terrain = TerrainDefinitionClass.create(); - _textures = texturesCreateDefinition(); + _textures = TexturesDefinitionClass.create(); _water = WaterDefinitionClass.create(); _custom_save = NULL; @@ -37,7 +37,7 @@ void sceneryQuit() cameraDeleteDefinition(&_camera); CloudsDefinitionClass.destroy(_clouds); TerrainDefinitionClass.destroy(_terrain); - texturesDeleteDefinition(&_textures); + TexturesDefinitionClass.destroy(_textures); AtmosphereDefinitionClass.destroy(_water); noiseQuit(); @@ -46,6 +46,7 @@ void sceneryQuit() void sceneryAutoPreset() { terrainAutoPreset(_terrain, TERRAIN_PRESET_STANDARD); + texturesAutoPreset(_textures, TEXTURES_PRESET_IRELAND); atmosphereAutoPreset(_atmosphere, ATMOSPHERE_PRESET_CLEAR_DAY); waterAutoPreset(_water, WATER_PRESET_LAKE); cloudsAutoPreset(_clouds, CLOUDS_PRESET_PARTLY_CLOUDY); @@ -65,7 +66,7 @@ void scenerySave(PackStream* stream) cameraSave(stream, &_camera); CloudsDefinitionClass.save(stream, _clouds); TerrainDefinitionClass.save(stream, _terrain); - texturesSave(stream, &_textures); + TexturesDefinitionClass.save(stream, _textures); WaterDefinitionClass.save(stream, _water); if (_custom_save) @@ -83,12 +84,9 @@ void sceneryLoad(PackStream* stream) cameraLoad(stream, &_camera); CloudsDefinitionClass.load(stream, _clouds); TerrainDefinitionClass.load(stream, _terrain); - texturesLoad(stream, &_textures); + TexturesDefinitionClass.load(stream, _textures); WaterDefinitionClass.load(stream, _water); - cameraValidateDefinition(&_camera, 0); - texturesValidateDefinition(&_textures); - if (_custom_load) { _custom_load(stream, _custom_data); @@ -140,13 +138,14 @@ void sceneryGetTerrain(TerrainDefinition* terrain) void scenerySetTextures(TexturesDefinition* textures) { - texturesCopyDefinition(textures, &_textures); - texturesValidateDefinition(&_textures); + TexturesDefinitionClass.copy(textures, _textures); + + cameraValidateDefinition(&_camera, 1); } void sceneryGetTextures(TexturesDefinition* textures) { - texturesCopyDefinition(&_textures, textures); + TexturesDefinitionClass.copy(_textures, textures); } void scenerySetWater(WaterDefinition* water) @@ -192,11 +191,6 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector return result; } -static Color _applyTextures(Renderer* renderer, Vector3 location, double precision) -{ - return texturesGetColor(&_textures, renderer, location.x, location.z, precision); -} - static Vector3 _projectPoint(Renderer* renderer, Vector3 point) { return cameraProject(&renderer->render_camera, renderer, point); @@ -227,7 +221,6 @@ Renderer* sceneryCreateStandardRenderer() cameraCopyDefinition(&_camera, &result->render_camera); result->rayWalking = _rayWalking; - result->applyTextures = _applyTextures; result->projectPoint = _projectPoint; result->unprojectPoint = _unprojectPoint; result->getPrecision = _getPrecision; @@ -241,6 +234,7 @@ void sceneryBindRenderer(Renderer* renderer) { AtmosphereRendererClass.bind(renderer, _atmosphere); TerrainRendererClass.bind(renderer, _terrain); + TexturesRendererClass.bind(renderer, _textures); CloudsRendererClass.bind(renderer, _clouds); WaterRendererClass.bind(renderer, _water); } diff --git a/lib_paysages/scenery.h b/lib_paysages/scenery.h index 3b09155..17174d4 100644 --- a/lib_paysages/scenery.h +++ b/lib_paysages/scenery.h @@ -12,9 +12,9 @@ #include "atmosphere/public.h" #include "clouds/public.h" #include "terrain/public.h" +#include "textures/public.h" #include "water/public.h" #include "camera.h" -#include "textures.h" #include "renderer.h" #ifdef __cplusplus diff --git a/lib_paysages/terrain/main.c b/lib_paysages/terrain/main.c index c4d171d..2bf3c7d 100644 --- a/lib_paysages/terrain/main.c +++ b/lib_paysages/terrain/main.c @@ -93,11 +93,45 @@ static double _fakeGetHeight(Renderer* renderer, double x, double z, int with_pa return 0.0; } -static double _getHeight(Renderer* renderer, double x, double z, int with_painting) +static double _realGetHeight(Renderer* renderer, double x, double z, int with_painting) { return terrainGetInterpolatedHeight(renderer->terrain->definition, x, z, with_painting); } +static TerrainResult _fakeGetResult(Renderer* renderer, double x, double z, int with_painting, int with_textures) +{ + TerrainResult result; + + UNUSED(renderer); + UNUSED(x); + UNUSED(z); + UNUSED(with_painting); + UNUSED(with_textures); + + result.location.x = x; + result.location.y = 0.0; + result.location.z = z; + result.normal = VECTOR_UP; + + return result; +} + +static TerrainResult _realGetResult(Renderer* renderer, double x, double z, int with_painting, int with_textures) +{ + TerrainResult result; + + result.location.x = x; + result.location.y = renderer->terrain->getHeight(renderer, x, z, with_painting); + result.location.z = z; + + if (with_textures) + { + result = renderer->textures->displaceTerrain(renderer, result); + } + + return result; +} + static Color _fakeGetFinalColor(Renderer* renderer, Vector3 location, double precision) { UNUSED(renderer); @@ -106,14 +140,11 @@ static Color _fakeGetFinalColor(Renderer* renderer, Vector3 location, double pre return COLOR_GREEN; } -static Color _getFinalColor(Renderer* renderer, Vector3 location, double precision) +static Color _realgetFinalColor(Renderer* renderer, Vector3 location, double precision) { - Color color; - - color = renderer->applyTextures(renderer, location, precision); - color = renderer->applyMediumTraversal(renderer, location, color); - - return color; + TerrainResult terrain = renderer->terrain->getResult(renderer, location.x, location.z, 1, 1); + TexturesResult textures = renderer->textures->applyToTerrain(renderer, terrain); + return renderer->applyMediumTraversal(renderer, textures.final_location, textures.final_color); } static RayCastingResult _fakeCastRay(Renderer* renderer, Vector3 start, Vector3 direction) @@ -127,7 +158,7 @@ static RayCastingResult _fakeCastRay(Renderer* renderer, Vector3 start, Vector3 return result; } -static RayCastingResult _castRay(Renderer* renderer, Vector3 start, Vector3 direction) +static RayCastingResult _realCastRay(Renderer* renderer, Vector3 start, Vector3 direction) { RayCastingResult result; TerrainDefinition* definition = renderer->terrain->definition; @@ -138,7 +169,7 @@ static RayCastingResult _castRay(Renderer* renderer, Vector3 start, Vector3 dire 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, 1); + lastdiff = start.y - _realGetHeight(renderer, start.x, start.z, 1); length = 0.0; do @@ -146,14 +177,14 @@ static RayCastingResult _castRay(Renderer* renderer, Vector3 start, Vector3 dire inc_vector = v3Scale(direction, inc_value); length += v3Norm(inc_vector); start = v3Add(start, inc_vector); - height = _getHeight(renderer, start.x, start.z, 1); + height = _realGetHeight(renderer, start.x, start.z, 1); 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, 1); + start.y = _realGetHeight(renderer, start.x, start.z, 1); } else { @@ -161,7 +192,7 @@ static RayCastingResult _castRay(Renderer* renderer, Vector3 start, Vector3 dire } result.hit = 1; result.hit_location = start; - result.hit_color = _getFinalColor(renderer, start, renderer->getPrecision(renderer, result.hit_location)); + result.hit_color = _realgetFinalColor(renderer, start, renderer->getPrecision(renderer, result.hit_location)); return result; } @@ -220,7 +251,7 @@ static int _alterLight(Renderer* renderer, LightDefinition* light, Vector3 locat inc_vector = v3Scale(direction_to_light, inc_value); length += v3Norm(inc_vector); location = v3Add(location, inc_vector); - height = _getHeight(renderer, location.x, location.z, 1); + height = _realGetHeight(renderer, location.x, location.z, 1); diff = location.y - height; if (diff < 0.0) { @@ -300,6 +331,7 @@ static TerrainRenderer* _createRenderer() result->castRay = _fakeCastRay; result->getHeight = _fakeGetHeight; + result->getResult = _fakeGetResult; result->getFinalColor = _fakeGetFinalColor; return result; @@ -315,9 +347,10 @@ static void _bindRenderer(Renderer* renderer, TerrainDefinition* definition) { TerrainDefinitionClass.copy(definition, renderer->terrain->definition); - renderer->terrain->castRay = _castRay; - renderer->terrain->getHeight = _getHeight; - renderer->terrain->getFinalColor = _getFinalColor; + renderer->terrain->castRay = _realCastRay; + renderer->terrain->getHeight = _realGetHeight; + renderer->terrain->getResult = _realGetResult; + renderer->terrain->getFinalColor = _realgetFinalColor; lightingManagerRegisterFilter(renderer->lighting, (FuncLightingAlterLight)_alterLight, renderer); } diff --git a/lib_paysages/terrain/preview.c b/lib_paysages/terrain/preview.c index da3484c..3074958 100644 --- a/lib_paysages/terrain/preview.c +++ b/lib_paysages/terrain/preview.c @@ -4,20 +4,11 @@ #include "../tools.h" #include "../tools/lighting.h" #include "../renderer.h" -#include "../textures.h" /* * Terrain previews. */ -static TexturesDefinition _textures; -static int _inited = 0; - -static Color _applyTextures(Renderer* renderer, Vector3 location, double precision) -{ - return texturesGetColor(&_textures, renderer, location.x, location.z, precision); -} - static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque) { LightDefinition light; @@ -63,26 +54,9 @@ Renderer* terrainCreatePreviewRenderer() Renderer* result = rendererCreate(); result->render_quality = 3; - result->applyTextures = _applyTextures; result->getCameraLocation = _getCameraLocation; result->atmosphere->getLightingStatus = _getLightingStatus; - if (!_inited) - { - /*LightDefinition light;*/ - TextureLayerDefinition* texture; - - _inited = 1; - - _textures = texturesCreateDefinition(); - texture = (TextureLayerDefinition*)layersGetLayer(_textures.layers, layersAddLayer(_textures.layers, NULL)); - texture->material.base = COLOR_WHITE; - texture->material.reflection = 0.3; - texture->material.shininess = 2.0; - texture->bump_height = 0.0; - texturesLayerValidateDefinition(texture); - } - return result; } diff --git a/lib_paysages/terrain/public.h b/lib_paysages/terrain/public.h index 1696dc1..1fcd994 100644 --- a/lib_paysages/terrain/public.h +++ b/lib_paysages/terrain/public.h @@ -32,7 +32,14 @@ typedef struct double _max_height; } TerrainDefinition; +typedef struct +{ + Vector3 location; + Vector3 normal; +} TerrainResult; + typedef double (*FuncTerrainGetHeight)(Renderer* renderer, double x, double z, int with_painting); +typedef TerrainResult (*FuncTerrainGetResult)(Renderer* renderer, double x, double z, int with_painting, int with_textures); typedef Color (*FuncTerrainGetFinalColor)(Renderer* renderer, Vector3 location, double precision); typedef struct @@ -41,6 +48,7 @@ typedef struct FuncGeneralCastRay castRay; FuncTerrainGetHeight getHeight; + FuncTerrainGetResult getResult; FuncTerrainGetFinalColor getFinalColor; void* _internal_data; diff --git a/lib_paysages/textures.c b/lib_paysages/textures.c deleted file mode 100644 index 1e50914..0000000 --- a/lib_paysages/textures.c +++ /dev/null @@ -1,358 +0,0 @@ -#include "textures.h" - -#include -#include -#include -#include - -#include "terrain/public.h" -#include "tools/lighting.h" -#include "renderer.h" -#include "tools.h" - -#define TEXTURES_MAX_LAYERS 50 - -typedef struct -{ - double thickness; - Vector3 location; - Vector3 normal; - TextureLayerDefinition* definition; -} TextureResult; - -TexturesDefinition texturesCreateDefinition() -{ - TexturesDefinition result; - - result.layers = layersCreate(texturesGetLayerType(), TEXTURES_MAX_LAYERS); - - return result; -} - -void texturesDeleteDefinition(TexturesDefinition* definition) -{ - layersDelete(definition->layers); -} - -void texturesCopyDefinition(TexturesDefinition* source, TexturesDefinition* destination) -{ - layersCopy(source->layers, destination->layers); -} - -void texturesValidateDefinition(TexturesDefinition* definition) -{ - layersValidate(definition->layers); -} - -void texturesSave(PackStream* stream, TexturesDefinition* definition) -{ - layersSave(stream, definition->layers); -} - -void texturesLoad(PackStream* stream, TexturesDefinition* definition) -{ - layersLoad(stream, definition->layers); -} - -TextureLayerDefinition* texturesLayerCreateDefinition() -{ - TextureLayerDefinition* result; - - result = malloc(sizeof(TextureLayerDefinition)); - - result->zone = zoneCreate(); - result->bump_noise = noiseCreateGenerator(); - noiseAddLevelsSimple(result->bump_noise, 8, 1.0, -0.5, 0.5, 0.5); - result->bump_height = 0.1; - result->bump_scaling = 0.1; - result->material.base = COLOR_WHITE; - result->material.reflection = 0.0; - result->material.shininess = 0.0; - result->thickness = 0.0; - result->slope_range = 0.001; - result->thickness_transparency = 0.0; - - return result; -} - -void texturesLayerDeleteDefinition(TextureLayerDefinition* definition) -{ - zoneDelete(definition->zone); - noiseDeleteGenerator(definition->bump_noise); - free(definition); -} - -void texturesLayerCopyDefinition(TextureLayerDefinition* source, TextureLayerDefinition* destination) -{ - destination->material = source->material; - destination->bump_height = source->bump_height; - destination->bump_scaling = source->bump_scaling; - destination->thickness = source->thickness; - destination->slope_range = source->slope_range; - destination->thickness_transparency = source->thickness_transparency; - noiseCopy(source->bump_noise, destination->bump_noise); - zoneCopy(source->zone, destination->zone); -} - -void texturesLayerValidateDefinition(TextureLayerDefinition* definition) -{ - if (definition->bump_scaling < 0.000001) - { - definition->bump_scaling = 0.000001; - } - if (definition->slope_range < 0.001) - { - definition->slope_range = 0.001; - } -} - -static void _texturesLayerSave(PackStream* stream, TextureLayerDefinition* layer) -{ - zoneSave(stream, layer->zone); - noiseSaveGenerator(stream, layer->bump_noise); - packWriteDouble(stream, &layer->bump_height); - packWriteDouble(stream, &layer->bump_scaling); - materialSave(stream, &layer->material); - packWriteDouble(stream, &layer->thickness); - packWriteDouble(stream, &layer->slope_range); - packWriteDouble(stream, &layer->thickness_transparency); -} - -static void _texturesLayerLoad(PackStream* stream, TextureLayerDefinition* layer) -{ - zoneLoad(stream, layer->zone); - noiseLoadGenerator(stream, layer->bump_noise); - packReadDouble(stream, &layer->bump_height); - packReadDouble(stream, &layer->bump_scaling); - materialLoad(stream, &layer->material); - packReadDouble(stream, &layer->thickness); - packReadDouble(stream, &layer->slope_range); - packReadDouble(stream, &layer->thickness_transparency); -} - -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); -} - -static inline Vector3 _getNormal2(Vector3 center, Vector3 east, Vector3 south) -{ - return v3Normalize(v3Cross(v3Sub(south, center), v3Sub(east, center))); -} - -static inline TextureResult _getTerrainResult(Renderer* renderer, double x, double z, double detail) -{ - 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->terrain->getHeight(renderer, center.x, center.z, 1); - - east.x = x + detail; - east.z = z; - east.y = renderer->terrain->getHeight(renderer, east.x, east.z, 1); - - south.x = x; - south.z = z + detail; - south.y = renderer->terrain->getHeight(renderer, south.x, south.z, 1); - - if (renderer->render_quality > 5) - { - west.x = x - detail; - west.z = z; - west.y = renderer->terrain->getHeight(renderer, west.x, west.z, 1); - - north.x = x; - north.z = z - detail; - north.y = renderer->terrain->getHeight(renderer, north.x, north.z, 1); - - result.normal = _getNormal4(center, north, east, south, west); - } - else - { - result.normal = _getNormal2(center, east, south); - } - - result.location = center; - result.thickness = -100.0; - result.definition = NULL; - - return result; -} - -static inline void _getLayerThickness(TextureLayerDefinition* definition, Renderer* renderer, double x, double z, TextureResult* result) -{ - TextureResult base; - double coverage; - - base = _getTerrainResult(renderer, x, z, definition->slope_range); - coverage = zoneGetValue(definition->zone, base.location, base.normal); - if (coverage > 0.0) - { - result->thickness = coverage * definition->thickness; - result->thickness += noiseGet2DTotal(definition->bump_noise, base.location.x / definition->bump_scaling, base.location.z / definition->bump_scaling) * definition->bump_height; - - result->location = v3Add(base.location, v3Scale(base.normal, result->thickness)); - } - else - { - result->thickness = -1000.0; - result->location = base.location; - } -} - -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; -} - -static int _cmpResults(const void* result1, const void* result2) -{ - return ((TextureResult*)result1)->thickness > ((TextureResult*)result2)->thickness; -} - -double texturesGetLayerCoverage(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail) -{ - TextureResult base = _getTerrainResult(renderer, location.x, location.z, definition->slope_range); - return zoneGetValue(definition->zone, base.location, base.normal); -} - -static inline Color _getLayerColor(Renderer* renderer, TextureResult texture) -{ - return renderer->applyLightingToSurface(renderer, texture.location, texture.normal, &texture.definition->material); -} - -Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail) -{ - TextureResult result = _getLayerResult(definition, renderer, location.x, location.z, detail); - return _getLayerColor(renderer, result); -} - -Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, double x, double z, double detail) -{ - TextureResult results[TEXTURES_MAX_LAYERS + 1]; - Color result, color; - double thickness, last_height; - int i, start, nblayers; - - detail *= 0.1; - - results[0] = _getTerrainResult(renderer, x, z, detail); - - nblayers = layersCount(definition->layers); - for (i = 0; i < nblayers; i++) - { - results[i + 1] = _getLayerResult(layersGetLayer(definition->layers, i), renderer, x, z, detail); - } - - qsort(results, nblayers + 1, sizeof(TextureResult), _cmpResults); - - /* Pre compute alpha channel */ - start = 0; - last_height = results[0].thickness; - results[0].thickness = 1.0; - for (i = 1; i <= nblayers; i++) - { - thickness = results[i].thickness - last_height; - last_height = results[i].thickness; - - if (results[i].definition) - { - if (thickness < results[i].definition->thickness_transparency) - { - results[i].thickness = thickness / results[i].definition->thickness_transparency; - } - else - { - results[i].thickness = (thickness > 0.0) ? 1.0 : 0.0; - } - } - else - { - results[i].thickness = 1.0; - } - - if (results[i].thickness >= 0.999999) - { - start = i; - } - } - - /* Apply colors and alphas */ - if (results[start].definition) - { - result = _getLayerColor(renderer, results[start]); - } - else - { - result = COLOR_GREEN; - } - for (i = start + 1; i <= nblayers; i++) - { - if (results[i].thickness) - { - if (results[i].definition) - { - color = _getLayerColor(renderer, results[i]); - color.a = results[i].thickness; - } - else - { - color = COLOR_GREEN; - } - - colorMask(&result, &color); - } - } - - return result; -} diff --git a/lib_paysages/textures.h b/lib_paysages/textures.h deleted file mode 100644 index 843f4d6..0000000 --- a/lib_paysages/textures.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef _PAYSAGES_TEXTURES_H_ -#define _PAYSAGES_TEXTURES_H_ - -#include "tools/lighting.h" -#include "tools/color.h" -#include "tools/euclid.h" -#include "tools/pack.h" -#include "shared/types.h" -#include "layers.h" -#include "noise.h" -#include "zone.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct -{ - Zone* zone; - NoiseGenerator* bump_noise; - double bump_scaling; - double bump_height; - SurfaceMaterial material; - double thickness; - double slope_range; - double thickness_transparency; -} TextureLayerDefinition; - -typedef struct -{ - Layers* layers; -} TexturesDefinition; - -TexturesDefinition texturesCreateDefinition(); -void texturesDeleteDefinition(TexturesDefinition* definition); -void texturesCopyDefinition(TexturesDefinition* source, TexturesDefinition* destination); -void texturesValidateDefinition(TexturesDefinition* definition); - -void texturesSave(PackStream* stream, TexturesDefinition* definition); -void texturesLoad(PackStream* stream, TexturesDefinition* definition); - -TextureLayerDefinition* texturesLayerCreateDefinition(); -void texturesLayerDeleteDefinition(TextureLayerDefinition* definition); -void texturesLayerCopyDefinition(TextureLayerDefinition* source, TextureLayerDefinition* destination); -void texturesLayerValidateDefinition(TextureLayerDefinition* definition); -LayerType texturesGetLayerType(); - -double texturesGetLayerCoverage(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail); -Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail); -Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, double x, double z, double detail); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib_paysages/textures/definition.c b/lib_paysages/textures/definition.c new file mode 100644 index 0000000..812dab6 --- /dev/null +++ b/lib_paysages/textures/definition.c @@ -0,0 +1,135 @@ +#include "private.h" + +#include + +/******************** Global definition ********************/ +static void _validateDefinition(TexturesDefinition* definition) +{ + layersValidate(definition->layers); +} + +static TexturesDefinition* _createDefinition() +{ + TexturesDefinition* definition = malloc(sizeof(TexturesDefinition)); + + definition->layers = layersCreate(texturesGetLayerType(), TEXTURES_MAX_LAYERS); + + return definition; +} + +static void _deleteDefinition(TexturesDefinition* definition) +{ + layersDelete(definition->layers); + free(definition); +} + +static void _copyDefinition(TexturesDefinition* source, TexturesDefinition* destination) +{ + layersCopy(source->layers, destination->layers); +} + +static void _saveDefinition(PackStream* stream, TexturesDefinition* definition) +{ + layersSave(stream, definition->layers); +} + +static void _loadDefinition(PackStream* stream, TexturesDefinition* definition) +{ + layersLoad(stream, definition->layers); +} + +StandardDefinition TexturesDefinitionClass = { + (FuncObjectCreate)_createDefinition, + (FuncObjectDelete)_deleteDefinition, + (FuncObjectCopy)_copyDefinition, + (FuncObjectValidate)_validateDefinition, + (FuncObjectSave)_saveDefinition, + (FuncObjectLoad)_loadDefinition +}; + +/*** Layer definition ***/ + +static void _layerValidateDefinition(TexturesLayerDefinition* definition) +{ + if (definition->displacement_scaling < 0.000001) + { + definition->displacement_scaling = 0.000001; + } + + noiseClearLevels(definition->_displacement_noise); + noiseAddLevelsSimple(definition->_displacement_noise, 3, 1.0, -1.0, 1.0, 0.0); + noiseValidate(definition->_displacement_noise); +} + +static TexturesLayerDefinition* _layerCreateDefinition() +{ + TexturesLayerDefinition* result; + + result = malloc(sizeof(TexturesLayerDefinition)); + + result->terrain_zone = zoneCreate(); + result->displacement_scaling = 0.1; + result->displacement_height = 0.1; + result->displacement_offset = 0.0; + result->material.base = COLOR_WHITE; + result->material.reflection = 0.0; + result->material.shininess = 0.0; + + result->_displacement_noise = noiseCreateGenerator(); + + return result; +} + +static void _layerDeleteDefinition(TexturesLayerDefinition* definition) +{ + zoneDelete(definition->terrain_zone); + noiseDeleteGenerator(definition->_displacement_noise); + free(definition); +} + +static void _layerCopyDefinition(TexturesLayerDefinition* source, TexturesLayerDefinition* destination) +{ + zoneCopy(source->terrain_zone, destination->terrain_zone); + destination->displacement_scaling = source->displacement_scaling; + destination->displacement_height = source->displacement_height; + destination->displacement_offset = source->displacement_offset; + destination->material = source->material; + + noiseCopy(source->_displacement_noise, destination->_displacement_noise); +} + +static void _layerSave(PackStream* stream, TexturesLayerDefinition* layer) +{ + zoneSave(stream, layer->terrain_zone); + packWriteDouble(stream, &layer->displacement_scaling); + packWriteDouble(stream, &layer->displacement_height); + packWriteDouble(stream, &layer->displacement_offset); + materialSave(stream, &layer->material); + + noiseSaveGenerator(stream, layer->_displacement_noise); +} + +static void _layerLoad(PackStream* stream, TexturesLayerDefinition* layer) +{ + zoneLoad(stream, layer->terrain_zone); + packReadDouble(stream, &layer->displacement_scaling); + packReadDouble(stream, &layer->displacement_height); + packReadDouble(stream, &layer->displacement_offset); + materialLoad(stream, &layer->material); + + noiseLoadGenerator(stream, layer->_displacement_noise); +} + +LayerType texturesGetLayerType() +{ + LayerType result; + + result.callback_create = (LayerCallbackCreate)_layerCreateDefinition; + result.callback_delete = (LayerCallbackDelete)_layerDeleteDefinition; + result.callback_copy = (LayerCallbackCopy)_layerCopyDefinition; + result.callback_validate = (LayerCallbackValidate)_layerValidateDefinition; + result.callback_save = (LayerCallbackSave)_layerSave; + result.callback_load = (LayerCallbackLoad)_layerLoad; + + return result; +} diff --git a/lib_paysages/textures/presets.c b/lib_paysages/textures/presets.c new file mode 100644 index 0000000..11261a2 --- /dev/null +++ b/lib_paysages/textures/presets.c @@ -0,0 +1,94 @@ +#include "private.h" + +void texturesAutoPreset(TexturesDefinition* definition, TexturesPreset preset) +{ + layersClear(definition->layers); + + if (preset == TEXTURES_PRESET_IRELAND) + { + } + else if (preset == TEXTURES_PRESET_IRELAND) + { + } + else if (preset == TEXTURES_PRESET_IRELAND) + { + } +} + +void texturesLayerAutoPreset(TexturesLayerDefinition* definition, TexturesLayerPreset preset) +{ + noiseRandomizeOffsets(definition->_displacement_noise); + + switch (preset) + { + case TEXTURES_LAYER_PRESET_ROCK: + break; + case TEXTURES_LAYER_PRESET_GRASS: + break; + case TEXTURES_LAYER_PRESET_SAND: + break; + case TEXTURES_LAYER_PRESET_SNOW: + break; + default: + break; + } + + cloudsLayerValidateDefinition(definition); +} + +#if 0 + textures = texturesCreateDefinition(); + layer = layersAddLayer(textures.layers, NULL); + layersSetName(textures.layers, layer, "Ground"); + texture = layersGetLayer(textures.layers, layer); + noiseClearLevels(texture->bump_noise); + noiseRandomizeOffsets(texture->bump_noise); + noiseAddLevelsSimple(texture->bump_noise, 8, 1.0, -0.5, 0.5, 0.5); + texture->bump_height = 0.01; + texture->bump_scaling = 0.045; + texture->material.base.r = 0.6; + texture->material.base.g = 0.55; + texture->material.base.b = 0.57; + texture->material.reflection = 0.02; + texture->material.shininess = 3.0; + texture->thickness = 0.001; + texture->slope_range = 0.001; + texture->thickness_transparency = 0.0; + layer = layersAddLayer(textures.layers, NULL); + layersSetName(textures.layers, layer, "Grass"); + texture = layersGetLayer(textures.layers, layer); + zoneAddHeightRangeQuick(texture->zone, 1.0, -6.0, -5.0, 3.0, 15.0); + zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.05, 0.4); + noiseClearLevels(texture->bump_noise); + noiseRandomizeOffsets(texture->bump_noise); + noiseAddLevelsSimple(texture->bump_noise, 5, 1.0, -0.2, 0.2, 0.5); + noiseAddLevelsSimple(texture->bump_noise, 2, 0.03, -0.04, 0.04, 0.5); + texture->bump_height = 0.002; + texture->bump_scaling = 0.03; + texture->material.base.r = 0.12; + texture->material.base.g = 0.19; + texture->material.base.b = 0.035; + texture->material.reflection = 0.003; + texture->material.shininess = 2.0; + texture->thickness = 0.02; + texture->slope_range = 0.03; + texture->thickness_transparency = 0.005; + /*texture = texturesGetLayer(&textures, texturesAddLayer(&textures)); + zoneAddHeightRangeQuick(texture->zone, 1.0, 4.0, 5.0, 100.0, 100.0); + zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.2, 1.0); + noiseGenerateBaseNoise(texture->bump_noise, 102400); + noiseClearLevels(texture->bump_noise); + noiseAddLevelsSimple(texture->bump_noise, 6, 1.0, 1.0); + texture->bump_height = 0.002; + texture->bump_scaling = 0.03; + texture->material.base.r = 1.0; + texture->material.base.g = 1.0; + texture->material.base.b = 1.0; + texture->material.reflection = 0.25; + texture->material.shininess = 0.6; + texture->thickness = 0.05; + texture->slope_range = 0.3; + texture->thickness_transparency = 0.015;*/ + scenerySetTextures(&textures); + texturesDeleteDefinition(&textures); +#endif \ No newline at end of file diff --git a/lib_paysages/textures/preview.c b/lib_paysages/textures/preview.c new file mode 100644 index 0000000..bd0db8d --- /dev/null +++ b/lib_paysages/textures/preview.c @@ -0,0 +1,2 @@ +#include "private.h" + diff --git a/lib_paysages/textures/private.h b/lib_paysages/textures/private.h new file mode 100644 index 0000000..35323af --- /dev/null +++ b/lib_paysages/textures/private.h @@ -0,0 +1,21 @@ +#ifndef _PAYSAGES_TEXTURES_PRIVATE_H_ +#define _PAYSAGES_TEXTURES_PRIVATE_H_ + +#include "public.h" + +/* + * Get the base presence factor of a layer, not accounting for other layers. + */ +double texturesGetLayerBasePresence(Renderer* renderer, TexturesLayerDefinition* layer, TerrainResult result); + +/* + * Get triplanar noise value, depending on the normal direction. + */ +double texturesGetTriplanarNoise(NoiseGenerator* noise, Vector3 location, Vector3 normal); + +/* + * Apply texture displacement on a terrain result. + */ +TerrainResult texturesApplyLayerDisplacement(Renderer* renderer, TexturesLayerDefinition* layer, TerrainResult initial, TerrainResult support, double presence, double cancel_factor); + +#endif diff --git a/lib_paysages/textures/public.h b/lib_paysages/textures/public.h new file mode 100644 index 0000000..57c3ca1 --- /dev/null +++ b/lib_paysages/textures/public.h @@ -0,0 +1,109 @@ +#ifndef _PAYSAGES_TEXTURES_PUBLIC_H_ +#define _PAYSAGES_TEXTURES_PUBLIC_H_ + +#include "../layers.h" +#include "../zone.h" +#include "../tools/lighting.h" +#include "../terrain/public.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TEXTURES_MAX_LAYERS 50 + +typedef enum +{ + TEXTURES_PRESET_IRELAND, + TEXTURES_PRESET_ALPS, + TEXTURES_PRESET_CANYON +} TexturesPreset; + +typedef enum +{ + TEXTURES_LAYER_PRESET_ROCK, + TEXTURES_LAYER_PRESET_GRASS, + TEXTURES_LAYER_PRESET_SAND, + TEXTURES_LAYER_PRESET_SNOW +} TexturesLayerPreset; + +typedef enum +{ + TEXTURES_MERGE_FADE, + TEXTURES_MERGE_DISSOLVE, + TEXTURES_MERGE_DISPLACEMENT_VALUE +} TexturesMergeMode; + +typedef struct +{ + Zone* terrain_zone; + double displacement_scaling; + double displacement_height; + double displacement_offset; + /*double detail_scaling; + double detail_height;*/ + SurfaceMaterial material; + /*double cancel_displacement_factor; + TexturesMergeMode merge_mode;*/ + + NoiseGenerator* _displacement_noise; + /*NoiseGenerator* _detail_noise;*/ + /*Curve* _local_slope_condition;*/ +} TexturesLayerDefinition; + +typedef struct +{ + Layers* layers; +} TexturesDefinition; + +typedef struct +{ + double global_presence; + double local_presence; + Vector3 displaced_location; + Vector3 displaced_normal; + Color color; + Color cancelled_color; +} TexturesLayerResult; + +typedef struct +{ + Vector3 base_location; + Vector3 base_normal; + int layer_count; + TexturesLayerResult layers[TEXTURES_MAX_LAYERS]; + Vector3 final_location; + Color final_color; +} TexturesResult; + +typedef TerrainResult (*FuncTexturesDisplaceTerrain)(Renderer* renderer, TerrainResult terrain); +typedef TexturesResult (*FuncTexturesApplyToTerrain)(Renderer* renderer, TerrainResult terrain); + +typedef struct +{ + TexturesDefinition* definition; + + FuncTexturesDisplaceTerrain displaceTerrain; + FuncTexturesApplyToTerrain applyToTerrain; +} TexturesRenderer; + + +extern StandardDefinition TexturesDefinitionClass; +extern StandardRenderer TexturesRendererClass; + + +LayerType texturesGetLayerType(); +void texturesAutoPreset(TexturesDefinition* definition, TexturesPreset preset); +void texturesLayerAutoPreset(TexturesLayerDefinition* definition, TexturesLayerPreset preset); + +/*Renderer* cloudsCreatePreviewCoverageRenderer(); +Color cloudsGetPreviewCoverage(Renderer* renderer, double x, double y, double scaling, int perspective); + +Renderer* cloudsCreatePreviewColorRenderer(); +Color cloudsGetPreviewColor(Renderer* renderer, double x, double y);*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib_paysages/textures/rendering.c b/lib_paysages/textures/rendering.c new file mode 100644 index 0000000..ee4c04a --- /dev/null +++ b/lib_paysages/textures/rendering.c @@ -0,0 +1,73 @@ +#include "private.h" + +#include +#include "../tools.h" +#include "../renderer.h" + +/******************** Fake ********************/ +static TerrainResult _fakeDisplaceTerrain(Renderer* renderer, TerrainResult terrain) +{ + UNUSED(renderer); + + return terrain; +} + +static TexturesResult _fakeApplyToTerrain(Renderer* renderer, TerrainResult terrain) +{ + TexturesResult result; + + result.base_location = terrain.location; + result.base_normal = terrain.normal; + result.layer_count = 0; + result.final_location = terrain.location; + result.final_color = COLOR_WHITE; + + return result; +} + +/******************** Real ********************/ +static TerrainResult _realDisplaceTerrain(Renderer* renderer, TerrainResult terrain) +{ + /* TODO */ + return _fakeDisplaceTerrain(renderer, terrain); +} + +static TexturesResult _realApplyToTerrain(Renderer* renderer, TerrainResult terrain) +{ + /* TODO */ + return _fakeApplyToTerrain(renderer, terrain); +} + +/******************** Renderer ********************/ +static TexturesRenderer* _createRenderer() +{ + TexturesRenderer* result; + + result = malloc(sizeof(TexturesRenderer)); + result->definition = TexturesDefinitionClass.create(); + + result->displaceTerrain = _fakeDisplaceTerrain; + result->applyToTerrain = _fakeApplyToTerrain; + + return result; +} + +static void _deleteRenderer(TexturesRenderer* renderer) +{ + TexturesDefinitionClass.destroy(renderer->definition); + free(renderer); +} + +static void _bindRenderer(Renderer* renderer, TexturesDefinition* definition) +{ + TexturesDefinitionClass.copy(definition, renderer->textures->definition); + + renderer->textures->displaceTerrain = _realDisplaceTerrain; + renderer->textures->applyToTerrain = _realApplyToTerrain; +} + +StandardRenderer TexturesRendererClass = { + (FuncObjectCreate)_createRenderer, + (FuncObjectDelete)_deleteRenderer, + (FuncObjectBind)_bindRenderer +};