diff --git a/gui_gtk/global.c b/gui_gtk/global.c index 31d7e39..1db63c2 100644 --- a/gui_gtk/global.c +++ b/gui_gtk/global.c @@ -28,7 +28,7 @@ static void _cbLoad(GtkWidget* widget, gpointer data) { char *filename; filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - autoLoad(filename); + paysagesLoad(filename); g_free(filename); } @@ -52,7 +52,7 @@ static void _cbSaveAs(GtkWidget* widget, gpointer data) { char *filename; filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - autoSave(filename); + paysagesSave(filename); g_free(filename); } gtk_widget_destroy(dialog); diff --git a/gui_gtk/tab_clouds.c b/gui_gtk/tab_clouds.c index a7fe8de..84b078f 100644 --- a/gui_gtk/tab_clouds.c +++ b/gui_gtk/tab_clouds.c @@ -27,12 +27,10 @@ static void _revertCurrentLayer() guiPreviewRedraw(_preview); } -static void _applyCurrentLayer() +/*static void _applyCurrentLayer() { - /* TODO Apply layer config */ - guiUpdate(); -} +}*/ static void _revertAll() { diff --git a/gui_gtk/tab_water.c b/gui_gtk/tab_water.c index b0c8cdc..4341458 100644 --- a/gui_gtk/tab_water.c +++ b/gui_gtk/tab_water.c @@ -93,7 +93,6 @@ static Color _cbPreviewRender(SmallPreview* preview, double x, double y, double environment.reflection_function = _rayCastFromWater; environment.refraction_function = _rayCastFromWater; environment.toggle_fog = 0; - environment.toggle_shadows = 0; quality.force_detail = 0.0001; return waterGetColorCustom(location, look, &definition, &quality, &environment).final; diff --git a/gui_qt/formwater.cpp b/gui_qt/formwater.cpp index 5809cad..04f9b11 100644 --- a/gui_qt/formwater.cpp +++ b/gui_qt/formwater.cpp @@ -83,7 +83,8 @@ protected: environment.reflection_function = (RayCastingFunction)(&this->rayCastFromWater); environment.refraction_function = (RayCastingFunction)(&this->rayCastFromWater); environment.toggle_fog = 0; - environment.toggle_shadows = 0; + environment.lighting_definition = NULL; + environment.lighting_environment = NULL; quality.force_detail = 0.0001; quality.detail_boost = 1.0; diff --git a/gui_qt/mainwindow.cpp b/gui_qt/mainwindow.cpp index e007ff3..2c83ead 100644 --- a/gui_qt/mainwindow.cpp +++ b/gui_qt/mainwindow.cpp @@ -70,7 +70,7 @@ void MainWindow::fileSave() QString filepath = QFileDialog::getSaveFileName(this); if (!filepath.isNull()) { - autoSave((char*)filepath.toStdString().c_str()); + paysagesSave((char*)filepath.toStdString().c_str()); } } @@ -79,7 +79,7 @@ void MainWindow::fileLoad() QString filepath = QFileDialog::getOpenFileName(this); if (!filepath.isNull()) { - autoLoad((char*)filepath.toStdString().c_str()); + paysagesLoad((char*)filepath.toStdString().c_str()); refreshAll(); } } diff --git a/lib_paysages/auto.c b/lib_paysages/auto.c index 2e0de34..ad706d1 100644 --- a/lib_paysages/auto.c +++ b/lib_paysages/auto.c @@ -84,6 +84,8 @@ void autoSetDaytimeFraction(double daytime) sky.daytime = daytime; skySetDefinition(sky); + lightingValidateDefinition(NULL); + fogSetColor(colorGradationGet(&sky.haze_color, daytime)); } diff --git a/lib_paysages/clouds.c b/lib_paysages/clouds.c index b03aadd..6409f71 100644 --- a/lib_paysages/clouds.c +++ b/lib_paysages/clouds.c @@ -407,9 +407,9 @@ static Color _lightFilter(Color light, Vector3 location, Vector3 light_location, inside_depth = 1.0; } - result.r = data.base.r * sun_color_lum * (0.9 - 0.2 * inside_depth) + result.r * (0.1 + 0.1 * inside_depth) + (0.1 - inside_depth * 0.1) * sun_color_lum; - result.g = data.base.g * sun_color_lum * (0.9 - 0.2 * inside_depth) + result.g * (0.1 + 0.1 * inside_depth) + (0.1 - inside_depth * 0.1) * sun_color_lum; - result.b = data.base.b * sun_color_lum * (0.9 - 0.2 * inside_depth) + result.b * (0.1 + 0.1 * inside_depth) + (0.1 - inside_depth * 0.1) * sun_color_lum; + result.r = data.base.r * - 0.2 * inside_depth; + result.g = data.base.g * - 0.2 * inside_depth; + result.b = data.base.b * - 0.2 * inside_depth; return result; } diff --git a/lib_paysages/lighting.c b/lib_paysages/lighting.c index 6c525b7..3dadf9d 100644 --- a/lib_paysages/lighting.c +++ b/lib_paysages/lighting.c @@ -9,6 +9,9 @@ #include "shared/functions.h" #include "shared/constants.h" #include "shared/globals.h" +#include "sky.h" +#include "water.h" +#include "terrain.h" static LightingDefinition _definition; static LightingQuality _quality; @@ -18,8 +21,14 @@ static LightDefinition _LIGHT_NULL; static Color _standardFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data) { - // TODO Find shadows - return light; + Color result; + + result = waterLightFilter(light, location, light_location, direction_to_light, custom_data); + result = terrainLightFilter(result, location, light_location, direction_to_light, custom_data); + // TODO atmosphere filter + // TODO clouds filter + + return result; } void lightingInit() @@ -67,6 +76,7 @@ void lightingCopyDefinition(LightingDefinition source, LightingDefinition* desti void lightingSetDefinition(LightingDefinition definition) { + lightingValidateDefinition(&definition); lightingCopyDefinition(definition, &_definition); } @@ -80,11 +90,13 @@ void lightingValidateDefinition(LightingDefinition* definition) if (!definition) { lightingValidateDefinition(&_definition); + return; } if (definition->autosetfromsky) { // TODO Get lights from sky + definition->_nbautolights = skyGetLights(definition->_autolights, MAX_LIGHTS); } else { @@ -144,8 +156,53 @@ LightingQuality lightingGetQuality() return _quality; } +static Color _applyLightCustom(Vector3 location, Vector3 normal, ReceiverMaterial material, LightDefinition* definition, LightingQuality* quality, LightingEnvironment* environment) +{ + Color result, light; + double diffuse, specular; + Vector3 view, reflect, direction_inv; + + light = definition->color; + + direction_inv = v3Scale(definition->direction, -1.0); + light = environment->filter(light, location, v3Add(location, direction_inv), direction_inv, environment->custom_data); + + normal = v3Normalize(normal); + view = v3Normalize(v3Sub(location, camera_location)); // TODO Configurable + reflect = v3Sub(v3Scale(normal, 2.0 * v3Dot(direction_inv, normal)), direction_inv); + + diffuse = v3Dot(direction_inv, normal); + //diffuse = pow(diffuse * 0.5 + 0.5, 2.0); + if (diffuse > 0.0) + { + if (material.shininess > 0.0) + { + specular = pow(v3Dot(reflect, view) * material.reflection, material.shininess * 10.0 + 1.0); + } + else + { + specular = 0.0; + } + } + else + { + diffuse = 0.0; + specular = 0.0; + } + + result.r = material.base.r * diffuse * light.r + material.base.r * specular * light.r; + result.g = material.base.g * diffuse * light.g + material.base.g * specular * light.g; + result.b = material.base.b * diffuse * light.b + material.base.b * specular * light.b; + result.a = material.base.a; + + return result; +} + Color lightingApplyCustom(Vector3 location, Vector3 normal, ReceiverMaterial material, LightingDefinition* definition, LightingQuality* quality, LightingEnvironment* environment) { + Color result; + int i; + if (!definition) { definition = &_definition; @@ -159,72 +216,20 @@ Color lightingApplyCustom(Vector3 location, Vector3 normal, ReceiverMaterial mat environment = &_environment; } - return COLOR_RED; + /* TODO Merge lights */ + result = material.base; + for (i = 0; i < definition->nblights; i++) + { + result = _applyLightCustom(location, normal, material, definition->lights + i, quality, environment); + } + for (i = 0; i < definition->_nbautolights; i++) + { + result = _applyLightCustom(location, normal, material, definition->_autolights + i, quality, environment); + } + return result; } Color lightingApply(Vector3 location, Vector3 normal, ReceiverMaterial material) { return lightingApplyCustom(location, normal, material, &_definition, &_quality, &_environment); } - -/*void lightingSetSunDirection(double x, double y, double z) -{ - sun_direction.x = x; - sun_direction.y = y; - sun_direction.z = z; - sun_direction = v3Normalize(sun_direction); - sun_direction_inv = v3Scale(sun_direction, -1.0); -} - -void lightingSetSunAngle(double hor, double ver) -{ - lightingSetSunDirection(cos(hor) * cos(ver), sin(ver), -sin(hor) * cos(ver)); -} - -void lightingSetSunColor(Color col) -{ - sun_color = col; - sun_color_lum = colorGetValue(&col); -} - -Color lightingApply(Vector3 location, Vector3 normal, double shadowing, Color base, double reflection, double shininess) -{ - Color result, light; - double ambient, diffuse, specular; - Vector3 view, reflect; - - light.r = sun_color.r * (1.0 - 0.4 * shadowing); - light.g = sun_color.g * (1.0 - 0.4 * shadowing); - light.b = sun_color.b * (1.0 - 0.4 * shadowing); - - normal = v3Normalize(normal); - view = v3Normalize(v3Sub(location, camera_location)); - reflect = v3Sub(v3Scale(normal, 2.0 * v3Dot(sun_direction_inv, normal)), sun_direction_inv); - - ambient = 0.2; - diffuse = v3Dot(sun_direction_inv, normal); - diffuse = pow(diffuse * 0.5 + 0.5, 2.0) * (1.0 - shadowing) + (diffuse * 0.5 + 0.3) * shadowing; - if (diffuse > 0.0) - { - if (shininess > 0.0) - { - specular = pow(v3Dot(reflect, view) * reflection, shininess * 10.0 + 1.0); - } - else - { - specular = 0.0; - } - } - else - { - diffuse = 0.0; - specular = 0.0; - } - - result.r = base.r * ambient + base.r * diffuse * light.r + base.r * specular * light.r; - result.g = base.g * ambient + base.g * diffuse * light.g + base.g * specular * light.g; - result.b = base.b * ambient + base.b * diffuse * light.b + base.b * specular * light.b; - result.a = base.a; - - return result; -}*/ diff --git a/lib_paysages/shared/globals.h b/lib_paysages/shared/globals.h index 0241128..4e6438f 100644 --- a/lib_paysages/shared/globals.h +++ b/lib_paysages/shared/globals.h @@ -13,10 +13,6 @@ extern int render_width; extern int render_height; extern int render_quality; -extern double sun_color_lum; -extern Vector3 sun_direction; -extern Vector3 sun_direction_inv; - #ifdef __cplusplus } #endif diff --git a/lib_paysages/sky.c b/lib_paysages/sky.c index e8f95d8..d35325f 100644 --- a/lib_paysages/sky.c +++ b/lib_paysages/sky.c @@ -7,12 +7,13 @@ #include "shared/constants.h" #include "clouds.h" #include "sky.h" +#include "lighting.h" #define SPHERE_SIZE 1000.0 -SkyDefinition _definition; -SkyQuality _quality; -SkyEnvironment _environment; +static SkyDefinition _definition; +static SkyQuality _quality; +static SkyEnvironment _environment; void skyInit() { @@ -97,6 +98,28 @@ SkyDefinition skyGetDefinition() return _definition; } +int skyGetLights(LightDefinition* lights, int max_lights) +{ + double sun_angle; + Vector3 sun_direction; + int nblights = 0; + + sun_angle = (_definition.daytime + 0.75) * M_PI * 2.0; + sun_direction.x = cos(sun_angle); + sun_direction.y = sin(sun_angle); + sun_direction.z = 0.0; + + if (max_lights > 0) + { + lights[0].color = colorGradationGet(&_definition.sun_color, _definition.daytime); + lights[0].direction = v3Scale(sun_direction, -1.0); + lights[0].maxshadow = 1.0; + nblights = 1; + } + + return nblights; +} + Color skyGetColorCustom(Vector3 eye, Vector3 look, SkyDefinition* definition, SkyQuality* quality, SkyEnvironment* environment) { double sun_angle, dist; diff --git a/lib_paysages/sky.h b/lib_paysages/sky.h index 97e1b0e..6d069ad 100644 --- a/lib_paysages/sky.h +++ b/lib_paysages/sky.h @@ -2,6 +2,7 @@ #define _PAYSAGES_SKY_H_ #include "shared/types.h" +#include "lighting.h" #include #ifdef __cplusplus @@ -44,6 +45,8 @@ SkyDefinition skyGetDefinition(); void skySetQuality(SkyQuality quality); SkyQuality skyGetQuality(); +int skyGetLights(LightDefinition* lights, int max_lights); + Color skyGetColorCustom(Vector3 eye, Vector3 look, SkyDefinition* definition, SkyQuality* quality, SkyEnvironment* environment); Color skyGetColor(Vector3 eye, Vector3 look); diff --git a/lib_paysages/terrain.c b/lib_paysages/terrain.c index 362c6a2..6f8fdf7 100644 --- a/lib_paysages/terrain.c +++ b/lib_paysages/terrain.c @@ -22,6 +22,8 @@ void terrainInit() _max_height = noiseGetMaxValue(_definition.height_noise); _environment.toggle_fog = 1; + _environment.lighting_definition = NULL; + _environment.lighting_environment = NULL; } void terrainSave(FILE* f) @@ -164,31 +166,29 @@ static inline Vector3 _getPoint(TerrainDefinition* definition, double x, double return result; } -double terrainGetShadow(Vector3 start, Vector3 direction) +Color terrainLightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data) { Vector3 inc_vector; - double inc_value, inc_base, inc_factor, height, diff, light, smoothing, length, water; + double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length; - direction = v3Normalize(direction); - inc_factor = (double)render_quality; + direction_to_light = v3Normalize(direction_to_light); + inc_factor = (double)render_quality; // TODO Configurable inc_base = 1.0; inc_value = inc_base / inc_factor; smoothing = 0.03 * inc_factor;; - water = waterGetLightFactor(start); - - light = 1.0; + light_factor = 1.0; length = 0.0; do { - inc_vector = v3Scale(direction, inc_value); + inc_vector = v3Scale(direction_to_light, inc_value); length += v3Norm(inc_vector); - start = v3Add(start, inc_vector); - height = _getHeight(&_definition, start.x, start.z, inc_value); - diff = start.y - height; + location = v3Add(location, inc_vector); + height = _getHeight(&_definition, location.x, location.z, inc_value); + diff = location.y - height; if (diff < 0.0) { - light += diff / smoothing; + light_factor += diff / smoothing; } if (diff < inc_base / inc_factor) @@ -203,24 +203,31 @@ double terrainGetShadow(Vector3 start, Vector3 direction) { inc_value = diff; } - } while (light > 0.0 && length < 50.0 && start.y <= _max_height); + } while (light_factor > 0.0 && length < 50.0 && location.y <= _max_height); - light *= water; - if (light < 0.0) + if (light_factor <= 0.0) { - return 1.0; + return COLOR_BLACK; } else { - return 1.0 - light; + light.r *= light_factor; + light.g *= light_factor; + light.b *= light_factor; + + return light; } } static Color _getColor(TerrainDefinition* definition, TerrainEnvironment* environment, Vector3 point, double precision) { Color color; + TextureEnvironment texenv; - color = texturesGetColor(point); + texenv.lighting_definition = environment->lighting_definition; + texenv.lighting_environment = environment->lighting_environment; + + color = texturesGetColorCustom(point, precision, NULL, &texenv); if (environment->toggle_fog) { color = fogApplyToLocation(point, color); @@ -341,7 +348,8 @@ Color terrainGetColorCustom(double x, double z, double detail, TerrainDefinition environment = &_environment; } - return _getColor(definition, environment, _getPoint(definition, x, z, detail), detail); + Vector3 point = _getPoint(definition, x, z, detail); + return _getColor(definition, environment, point, detail); } Color terrainGetColor(double x, double z, double detail) diff --git a/lib_paysages/terrain.h b/lib_paysages/terrain.h index 006911e..373472c 100644 --- a/lib_paysages/terrain.h +++ b/lib_paysages/terrain.h @@ -3,6 +3,7 @@ #include "shared/types.h" #include "modifiers.h" +#include "lighting.h" #include #ifdef __cplusplus @@ -27,6 +28,8 @@ typedef struct typedef struct { int toggle_fog; + LightingDefinition* lighting_definition; + LightingEnvironment* lighting_environment; } TerrainEnvironment; void terrainInit(); @@ -45,7 +48,7 @@ void terrainDelModifier(TerrainDefinition* definition, int modifier_position); void terrainSetQuality(TerrainQuality quality); TerrainQuality terrainGetQuality(); -double terrainGetShadow(Vector3 start, Vector3 direction); +Color terrainLightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data); int terrainProjectRay(Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color); double terrainGetHeightCustom(double x, double z, TerrainDefinition* definition); double terrainGetHeight(double x, double z); diff --git a/lib_paysages/textures.c b/lib_paysages/textures.c index 6446df0..f0fef37 100644 --- a/lib_paysages/textures.c +++ b/lib_paysages/textures.c @@ -10,6 +10,7 @@ #include "textures.h" #include "terrain.h" +#include "lighting.h" #define TEXTURES_MAX 50 static TextureQuality _quality; @@ -20,6 +21,9 @@ static TextureDefinition _textures[TEXTURES_MAX]; void texturesInit() { _textures_count = 0; + + _environment.lighting_definition = NULL; + _environment.lighting_environment = NULL; } void texturesSave(FILE* f) @@ -179,34 +183,48 @@ static inline Vector3 _getNormal(TextureDefinition* definition, Vector3 point, d return v3Normalize(normal); } -Color texturesGetLayerColorCustom(Vector3 location, double shadowing, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment) +Color texturesGetLayerColorCustom(Vector3 location, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment) { Color result; Vector3 normal; double coverage; + ReceiverMaterial material; - result.a = 0.0; + result = COLOR_TRANSPARENT; normal = _getNormal(definition, location, detail * 0.3); coverage = zoneGetValue(definition->zone, location, normal); if (coverage > 0.0) { - result = lightingApply(location, normal, shadowing, definition->color, 0.1, 0.1); + material.base = definition->color; + material.reflection = 0.1; + material.shininess = 0.1; + + result = lightingApplyCustom(location, normal, material, environment->lighting_definition, NULL, environment->lighting_environment); result.a = coverage; } return result; } -Color texturesGetColorCustom(Vector3 location, double shadowing, double detail, TextureQuality* quality, TextureEnvironment* environment) +Color texturesGetColorCustom(Vector3 location, double detail, TextureQuality* quality, TextureEnvironment* environment) { Color result, tex_color; int i; + /*if (!quality) + { + quality = &_quality; + } + if (!environment) + { + environment = &_environment; + }*/ + result = COLOR_GREEN; for (i = 0; i < _textures_count; i++) { /* TODO Do not compute layers fully covered */ - tex_color = texturesGetLayerColorCustom(location, shadowing, detail, _textures + i, quality, environment); + tex_color = texturesGetLayerColorCustom(location, detail, _textures + i, quality, environment); if (tex_color.a > 0.0001) { colorMask(&result, &tex_color); @@ -218,10 +236,5 @@ Color texturesGetColorCustom(Vector3 location, double shadowing, double detail, Color texturesGetColor(Vector3 location) { - double shadowing; - - /* TODO Use environment to get lights to apply */ - shadowing = terrainGetShadow(location, sun_direction_inv); - - return texturesGetColorCustom(location, shadowing, renderGetPrecision(location), &_quality, &_environment); + return texturesGetColorCustom(location, renderGetPrecision(location), &_quality, &_environment); } diff --git a/lib_paysages/textures.h b/lib_paysages/textures.h index 345bc12..fc2af8f 100644 --- a/lib_paysages/textures.h +++ b/lib_paysages/textures.h @@ -2,6 +2,7 @@ #define _PAYSAGES_TEXTURES_H_ #include "shared/types.h" +#include "lighting.h" #include #ifdef __cplusplus @@ -22,7 +23,8 @@ typedef struct typedef struct { - int unused; + LightingDefinition* lighting_definition; + LightingEnvironment* lighting_environment; } TextureEnvironment; void texturesInit(); @@ -42,8 +44,8 @@ TextureDefinition texturesGetDefinition(int layer); void texturesSetQuality(TextureQuality quality); TextureQuality texturesGetQuality(); -Color texturesGetLayerColorCustom(Vector3 location, double shadowing, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment); -Color texturesGetColorCustom(Vector3 location, double shadowing, double detail, TextureQuality* quality, TextureEnvironment* environment); +Color texturesGetLayerColorCustom(Vector3 location, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment); +Color texturesGetColorCustom(Vector3 location, double detail, TextureQuality* quality, TextureEnvironment* environment); Color texturesGetColor(Vector3 location); #ifdef __cplusplus diff --git a/lib_paysages/water.c b/lib_paysages/water.c index 2373882..a86fb7c 100644 --- a/lib_paysages/water.c +++ b/lib_paysages/water.c @@ -45,7 +45,8 @@ void waterInit() _environment.reflection_function = _reflectionFunction; _environment.refraction_function = _refractionFunction; _environment.toggle_fog = 1; - _environment.toggle_shadows = 1; + _environment.lighting_definition = NULL; + _environment.lighting_environment = NULL; } void waterSave(FILE* f) @@ -292,29 +293,35 @@ static void _renderQuad(double x, double z, double size) renderPushQuad(&v1, &v2, &v3, &v4); } -double waterGetLightFactor(Vector3 location) +Color waterLightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data) { double factor; if (location.y < _definition.height) { - if (sun_direction_inv.y > 0.00001) + if (direction_to_light.y > 0.00001) { - factor = (_definition.height - location.y) / (sun_direction_inv.y * 3.0); + factor = (_definition.height - location.y) / (direction_to_light.y * 5.0); // TODO Configurable if (factor > 1.0) { factor = 1.0; } - return 1.0 - 0.8 * factor; + factor = 1.0 - 0.8 * factor; + + light.r *= factor; + light.g *= factor; + light.b *= factor; + + return light; } else { - return 0.0; + return COLOR_BLACK; } } else { - return 1.0; + return light; } } diff --git a/lib_paysages/water.h b/lib_paysages/water.h index ae3fdf3..74406f2 100644 --- a/lib_paysages/water.h +++ b/lib_paysages/water.h @@ -58,7 +58,7 @@ WaterDefinition waterGetDefinition(); void waterSetQuality(WaterQuality quality); WaterQuality waterGetQuality(); -double waterGetLightFactor(Vector3 location); +Color waterLightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data); WaterResult waterGetColorCustom(Vector3 location, Vector3 look, WaterDefinition* definition, WaterQuality* quality, WaterEnvironment* environment); Color waterGetColor(Vector3 location, Vector3 look); void waterRender(RenderProgressCallback callback);