diff --git a/TODO b/TODO index 8205520..df6b752 100644 --- a/TODO +++ b/TODO @@ -7,8 +7,6 @@ Technology Preview 2 : - Get rid of noise dialogs, for simpler settings. - Finalize lighting refactoring => Restore cloud lighting -- Hide Preetham's model. - => Implement weather effect in Bruneton's model. - Improve textures (current model is greatly incorrect). => Separate models (basic texture and covering texture). => Covering texture height should inpact terrain height. diff --git a/gui_qt/formatmosphere.cpp b/gui_qt/formatmosphere.cpp index 58add2f..3d44004 100644 --- a/gui_qt/formatmosphere.cpp +++ b/gui_qt/formatmosphere.cpp @@ -78,13 +78,13 @@ FormAtmosphere::FormAtmosphere(QWidget *parent): previewEast = new PreviewSkyEast(this); addPreview(previewEast, QString(tr("East preview"))); - addInputEnum(tr("Color model"), (int*)&_definition->model, QStringList(tr("Simplified model (with weather)")) << tr("Complex model")); + //addInputEnum(tr("Color model"), (int*)&_definition->model, QStringList(tr("Simplified model (with weather)")) << tr("Complex model")); addInputInt(tr("Day time (hour)"), &_definition->hour, 0, 23, 1, 10); addInputInt(tr("Day time (minute)"), &_definition->minute, 0, 59, 1, 10); //addInputColor(tr("Sun color"), &_definition->sun_color); addInputDouble(tr("Sun radius"), &_definition->sun_radius, 0.0, 5.0, 0.05, 0.5); - addInputDouble(tr("Influence of skydome on lighting"), &_definition->dome_lighting, 0.0, 2.0, 0.01, 0.1); - addInputDouble(tr("Humidity"), &_definition->humidity, 0.0, 1.0, 0.01, 0.1)->setVisibilityCondition((int*)&_definition->model, 0); + //addInputDouble(tr("Influence of skydome on lighting"), &_definition->dome_lighting, 0.0, 2.0, 0.01, 0.1); + addInputDouble(tr("Humidity"), &_definition->humidity, 0.0, 1.0, 0.01, 0.1); revertConfig(); } diff --git a/lib_paysages/atmosphere/definition.c b/lib_paysages/atmosphere/definition.c new file mode 100644 index 0000000..fcc4b96 --- /dev/null +++ b/lib_paysages/atmosphere/definition.c @@ -0,0 +1,102 @@ +#include "private.h" + +#include +#include +#include +#include "../tools.h" +#include "../renderer.h" +#include "../system.h" + +static int _inited = 0; + +/******************** Definition ********************/ +static void _validateDefinition(AtmosphereDefinition* definition) +{ + if (definition->hour < 0) + { + definition->hour = 0; + } + if (definition->hour > 23) + { + definition->hour = 23; + } + if (definition->minute < 0) + { + definition->minute = 0; + } + if (definition->minute > 59) + { + definition->minute = 59; + } + + definition->_daytime = (double)definition->hour / 24.0 + (double)definition->minute / 1440.0; +} + +static AtmosphereDefinition* _createDefinition() +{ + AtmosphereDefinition* result; + + /* TODO Find a better place for this */ + if (!_inited) + { + _inited = 1; + brunetonInit(); + } + + result = malloc(sizeof(AtmosphereDefinition)); + + atmosphereAutoPreset(result, ATMOSPHERE_PRESET_CLEAR_DAY); + + return result; +} + +static void _deleteDefinition(AtmosphereDefinition* definition) +{ + free(definition); +} + +static void _copyDefinition(AtmosphereDefinition* source, AtmosphereDefinition* destination) +{ + destination->model = source->model; + destination->hour = source->hour; + destination->minute = source->minute; + destination->sun_color = source->sun_color; + destination->sun_radius = source->sun_radius; + destination->dome_lighting = source->dome_lighting; + destination->humidity = source->humidity; + + _validateDefinition(destination); +} + +static void _saveDefinition(PackStream* stream, AtmosphereDefinition* definition) +{ + packWriteInt(stream, (int*)&definition->model); + packWriteInt(stream, &definition->hour); + packWriteInt(stream, &definition->minute); + colorSave(stream, &definition->sun_color); + packWriteDouble(stream, &definition->sun_radius); + packWriteDouble(stream, &definition->dome_lighting); + packWriteDouble(stream, &definition->humidity); +} + +static void _loadDefinition(PackStream* stream, AtmosphereDefinition* definition) +{ + packReadInt(stream, (int*)&definition->model); + packReadInt(stream, &definition->hour); + packReadInt(stream, &definition->minute); + colorLoad(stream, &definition->sun_color); + packReadDouble(stream, &definition->sun_radius); + packReadDouble(stream, &definition->dome_lighting); + packReadDouble(stream, &definition->humidity); + + _validateDefinition(definition); +} + +StandardDefinition AtmosphereDefinitionClass = { + (FuncObjectCreate)_createDefinition, + (FuncObjectDelete)_deleteDefinition, + (FuncObjectCopy)_copyDefinition, + (FuncObjectValidate)_validateDefinition, + (FuncObjectSave)_saveDefinition, + (FuncObjectLoad)_loadDefinition +}; diff --git a/lib_paysages/atmosphere/presets.c b/lib_paysages/atmosphere/presets.c index 941343d..fb70c32 100644 --- a/lib_paysages/atmosphere/presets.c +++ b/lib_paysages/atmosphere/presets.c @@ -13,41 +13,38 @@ void atmosphereAutoPreset(AtmosphereDefinition* definition, AtmospherePreset pre definition->sun_radius = 1.0; definition->humidity = 0.1; + definition->model = ATMOSPHERE_MODEL_BRUNETON; + switch (preset) { case ATMOSPHERE_PRESET_CLEAR_DAY: - definition->model = ATMOSPHERE_MODEL_BRUNETON; definition->hour = 15; definition->minute = 0; definition->dome_lighting = 0.2; break; case ATMOSPHERE_PRESET_CLEAR_SUNSET: - definition->model = ATMOSPHERE_MODEL_BRUNETON; definition->hour = 17; definition->minute = 45; definition->dome_lighting = 0.3; definition->sun_radius = 0.03; break; case ATMOSPHERE_PRESET_HAZY_MORNING: - definition->model = ATMOSPHERE_MODEL_PREETHAM; definition->hour = 8; definition->minute = 30; definition->dome_lighting = 0.25; definition->humidity = 0.3; break; case ATMOSPHERE_PRESET_FOGGY: - definition->model = ATMOSPHERE_MODEL_PREETHAM; definition->hour = 15; definition->minute = 0; definition->dome_lighting = 0.1; - definition->humidity = 0.6; + definition->humidity = 0.5; break; case ATMOSPHERE_PRESET_STORMY: - definition->model = ATMOSPHERE_MODEL_PREETHAM; definition->hour = 15; definition->minute = 0; definition->dome_lighting = 0.05; - definition->humidity = 0.9; + definition->humidity = 0.8; break; default: ; diff --git a/lib_paysages/atmosphere/main.c b/lib_paysages/atmosphere/render.c similarity index 58% rename from lib_paysages/atmosphere/main.c rename to lib_paysages/atmosphere/render.c index f36d6c7..417df85 100644 --- a/lib_paysages/atmosphere/main.c +++ b/lib_paysages/atmosphere/render.c @@ -7,109 +7,14 @@ #include "../renderer.h" #include "../system.h" -#define MAX_SKYDOME_LIGHTS 100 - -static int _inited = 0; - -/******************** Definition ********************/ -static void _validateDefinition(AtmosphereDefinition* definition) -{ - if (definition->hour < 0) - { - definition->hour = 0; - } - if (definition->hour > 23) - { - definition->hour = 23; - } - if (definition->minute < 0) - { - definition->minute = 0; - } - if (definition->minute > 59) - { - definition->minute = 59; - } - - definition->_daytime = (double)definition->hour / 24.0 + (double)definition->minute / 1440.0; -} - -static AtmosphereDefinition* _createDefinition() -{ - AtmosphereDefinition* result; - - /* TODO Find a better place for this */ - if (!_inited) - { - _inited = 1; - brunetonInit(); - } - - result = malloc(sizeof(AtmosphereDefinition)); - - atmosphereAutoPreset(result, ATMOSPHERE_PRESET_CLEAR_DAY); - - return result; -} - -static void _deleteDefinition(AtmosphereDefinition* definition) -{ - free(definition); -} - -static void _copyDefinition(AtmosphereDefinition* source, AtmosphereDefinition* destination) -{ - destination->model = source->model; - destination->hour = source->hour; - destination->minute = source->minute; - destination->sun_color = source->sun_color; - destination->sun_radius = source->sun_radius; - destination->dome_lighting = source->dome_lighting; - destination->humidity = source->humidity; - - _validateDefinition(destination); -} - -static void _saveDefinition(PackStream* stream, AtmosphereDefinition* definition) -{ - packWriteInt(stream, (int*)&definition->model); - packWriteInt(stream, &definition->hour); - packWriteInt(stream, &definition->minute); - colorSave(stream, &definition->sun_color); - packWriteDouble(stream, &definition->sun_radius); - packWriteDouble(stream, &definition->dome_lighting); - packWriteDouble(stream, &definition->humidity); -} - -static void _loadDefinition(PackStream* stream, AtmosphereDefinition* definition) -{ - packReadInt(stream, (int*)&definition->model); - packReadInt(stream, &definition->hour); - packReadInt(stream, &definition->minute); - colorLoad(stream, &definition->sun_color); - packReadDouble(stream, &definition->sun_radius); - packReadDouble(stream, &definition->dome_lighting); - packReadDouble(stream, &definition->humidity); - - _validateDefinition(definition); -} - -StandardDefinition AtmosphereDefinitionClass = { - (FuncObjectCreate)_createDefinition, - (FuncObjectDelete)_deleteDefinition, - (FuncObjectCopy)_copyDefinition, - (FuncObjectValidate)_validateDefinition, - (FuncObjectSave)_saveDefinition, - (FuncObjectLoad)_loadDefinition -}; - -/******************** Binding ********************/ +/******************** Fake ********************/ static Color _fakeApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base) { UNUSED(renderer); UNUSED(location); return base; } + static Color _fakeGetSkyColor(Renderer* renderer, Vector3 direction) { UNUSED(renderer); @@ -117,7 +22,93 @@ static Color _fakeGetSkyColor(Renderer* renderer, Vector3 direction) return COLOR_WHITE; } -static Color _getSkyColor(Renderer* renderer, Vector3 direction) +static void _fakeGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque) +{ + LightDefinition light; + + UNUSED(renderer); + UNUSED(normal); + UNUSED(opaque); + + light.color.r = 0.8; + light.color.g = 0.8; + light.color.b = 0.8; + light.direction.x = -0.7; + light.direction.y = -0.7; + light.direction.z = 0.7; + light.altered = 0; + light.reflection = 0.0; + lightingPushLight(status, &light); + light.color.r = 0.3; + light.color.g = 0.31; + light.color.b = 0.34; + light.direction.x = 0.7; + light.direction.y = -0.7; + light.direction.z = -0.7; + light.altered = 0; + light.reflection = 0.0; + lightingPushLight(status, &light); +} + +/******************** Real ********************/ +static inline Color _applyWeatherEffects(AtmosphereDefinition* definition, Color base, Color scattered, double distance) +{ + double max_power = colorGetPower(&scattered); + + UNUSED(base); + + if (distance > 100.0) + { + distance = 100.0; + } + + scattered.r += distance * 0.02 * definition->humidity; + scattered.g += distance * 0.02 * definition->humidity; + scattered.b += distance * 0.02 * definition->humidity; + + colorLimitPower(&scattered, max_power - max_power * 0.4 * definition->humidity); + + if (definition->humidity > 0.3) + { + double humidity = (definition->humidity - 0.3) / 0.7; + scattered.r += distance * 0.1 * humidity * humidity; + scattered.g += distance * 0.1 * humidity * humidity; + scattered.b += distance * 0.1 * humidity * humidity; + + colorLimitPower(&scattered, 10.0 - humidity * 4.0); + /*scattered.r *= 1.0 - humidity * 0.8; + scattered.g *= 1.0 - humidity * 0.8; + scattered.b *= 1.0 - humidity * 0.8;*/ + } + + return scattered; +} + +static Color _realApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base) +{ + AtmosphereDefinition* definition = renderer->atmosphere->definition; + Color changed; + + /* Get base perspective */ + switch (definition->model) + { + case ATMOSPHERE_MODEL_BRUNETON: + changed = brunetonApplyAerialPerspective(renderer, location, base); + break; + case ATMOSPHERE_MODEL_PREETHAM: + changed = basicApplyAerialPerspective(renderer, location, base); + break; + default: + ; + } + + /* Apply weather effects */ + changed = _applyWeatherEffects(definition, base, changed, v3Norm(v3Sub(location, renderer->getCameraLocation(renderer, location)))); + + return changed; +} + +static Color _realGetSkyColor(Renderer* renderer, Vector3 direction) { AtmosphereDefinition* definition; Vector3 sun_direction, sun_position, camera_location; @@ -169,10 +160,14 @@ static Color _getSkyColor(Renderer* renderer, Vector3 direction) } } } + + /* TODO Apply weather effects */ + sky_color = _applyWeatherEffects(definition, COLOR_BLACK, sky_color, SPHERE_SIZE); + return sky_color; } -static Vector3 _getSunDirection(Renderer* renderer) +static Vector3 _realGetSunDirection(Renderer* renderer) { Vector3 result; double sun_angle = (renderer->atmosphere->definition->_daytime + 0.75) * M_PI * 2.0; @@ -182,34 +177,6 @@ static Vector3 _getSunDirection(Renderer* renderer) return result; } -static void _fakeGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque) -{ - LightDefinition light; - - UNUSED(renderer); - UNUSED(normal); - UNUSED(opaque); - - light.color.r = 0.8; - light.color.g = 0.8; - light.color.b = 0.8; - light.direction.x = -0.7; - light.direction.y = -0.7; - light.direction.z = 0.7; - light.altered = 0; - light.reflection = 0.0; - lightingPushLight(status, &light); - light.color.r = 0.3; - light.color.g = 0.31; - light.color.b = 0.34; - light.direction.x = 0.7; - light.direction.y = -0.7; - light.direction.z = -0.7; - light.altered = 0; - light.reflection = 0.0; - lightingPushLight(status, &light); -} - /******************** Renderer ********************/ static AtmosphereRenderer* _createRenderer() { @@ -219,7 +186,7 @@ static AtmosphereRenderer* _createRenderer() result->definition = AtmosphereDefinitionClass.create(); result->getLightingStatus = _fakeGetLightingStatus; - result->getSunDirection = _getSunDirection; + result->getSunDirection = _realGetSunDirection; result->applyAerialPerspective = _fakeApplyAerialPerspective; result->getSkyColor = _fakeGetSkyColor; @@ -236,16 +203,15 @@ static void _bindRenderer(Renderer* renderer, AtmosphereDefinition* definition) { AtmosphereDefinitionClass.copy(definition, renderer->atmosphere->definition); - renderer->atmosphere->getSkyColor = _getSkyColor; + renderer->atmosphere->getSkyColor = _realGetSkyColor; + renderer->atmosphere->applyAerialPerspective = _realApplyAerialPerspective; switch (definition->model) { case ATMOSPHERE_MODEL_BRUNETON: - renderer->atmosphere->applyAerialPerspective = brunetonApplyAerialPerspective; renderer->atmosphere->getLightingStatus = brunetonGetLightingStatus; break; default: - renderer->atmosphere->applyAerialPerspective = basicApplyAerialPerspective; renderer->atmosphere->getLightingStatus = basicGetLightingStatus; } }