diff --git a/data/textures/grass1.jpg b/data/textures/grass1.jpg deleted file mode 100644 index b6711b0..0000000 Binary files a/data/textures/grass1.jpg and /dev/null differ diff --git a/data/textures/rock1.jpg b/data/textures/rock1.jpg deleted file mode 100644 index b7ab8fd..0000000 Binary files a/data/textures/rock1.jpg and /dev/null differ diff --git a/data/textures/rock2.jpg b/data/textures/rock2.jpg deleted file mode 100644 index 803a064..0000000 Binary files a/data/textures/rock2.jpg and /dev/null differ diff --git a/data/textures/rock3.jpg b/data/textures/rock3.jpg deleted file mode 100644 index 1e3a350..0000000 Binary files a/data/textures/rock3.jpg and /dev/null differ diff --git a/data/textures/rock4.jpg b/data/textures/rock4.jpg deleted file mode 100644 index d55fedd..0000000 Binary files a/data/textures/rock4.jpg and /dev/null differ diff --git a/data/textures/rock5.jpg b/data/textures/rock5.jpg deleted file mode 100644 index e120674..0000000 Binary files a/data/textures/rock5.jpg and /dev/null differ diff --git a/data/textures/rock6.jpg b/data/textures/rock6.jpg deleted file mode 100644 index d6bc54b..0000000 Binary files a/data/textures/rock6.jpg and /dev/null differ diff --git a/data/textures/rock7.jpg b/data/textures/rock7.jpg deleted file mode 100644 index 0cadf5f..0000000 Binary files a/data/textures/rock7.jpg and /dev/null differ diff --git a/data/textures/snow1.jpg b/data/textures/snow1.jpg deleted file mode 100644 index dc85f4e..0000000 Binary files a/data/textures/snow1.jpg and /dev/null differ diff --git a/data/textures/white.jpg b/data/textures/white.jpg deleted file mode 100644 index 21fcb5a..0000000 Binary files a/data/textures/white.jpg and /dev/null differ diff --git a/gui_gtk/tab_terrain.c b/gui_gtk/tab_terrain.c index 33765ce..d464b12 100644 --- a/gui_gtk/tab_terrain.c +++ b/gui_gtk/tab_terrain.c @@ -2,8 +2,11 @@ #include "common.h" #include "lib_paysages/shared/functions.h" +#include "lib_paysages/terrain.h" +#include "lib_paysages/textures.h" static SmallPreview* _preview; +static TerrainDefinition _definition; static Color _cbPreviewRenderPixel(SmallPreview* preview, double x, double y, double xoffset, double yoffset, double scaling) { @@ -11,20 +14,25 @@ static Color _cbPreviewRenderPixel(SmallPreview* preview, double x, double y, do result.r = result.g = result.b = terrainGetHeightNormalized(x, y); result.a = 1.0; - + + /* TEMP */ + //result = terrainGetColor(x, y, 0.01); + return result; } static void _cbEditNoiseDone(NoiseGenerator* generator) { - terrainSetNoiseGenerator(generator); + noiseCopy(generator, _definition.height_noise); + terrainSetDefinition(_definition); + /* TODO Redraw only affected by terrain */ guiPreviewRedrawAll(); } static void _cbEditNoise(GtkWidget* widget, gpointer data) { - guiNoiseEdit(terrainGetNoiseGenerator(), _cbEditNoiseDone); + guiNoiseEdit(texturesGetDefinition(0).bump_noise, _cbEditNoiseDone); } void guiTerrainInit() diff --git a/gui_qt/formwater.cpp b/gui_qt/formwater.cpp index 4935a4d..effd540 100644 --- a/gui_qt/formwater.cpp +++ b/gui_qt/formwater.cpp @@ -4,6 +4,7 @@ #include #include +#include "../lib_paysages/terrain.h" #include "../lib_paysages/water.h" #include "../lib_paysages/shared/functions.h" #include "../lib_paysages/shared/constants.h" diff --git a/gui_qt/paysages-qt.pro.user b/gui_qt/paysages-qt.pro.user index 8348f08..cfdefc0 100644 --- a/gui_qt/paysages-qt.pro.user +++ b/gui_qt/paysages-qt.pro.user @@ -82,7 +82,7 @@ Qt4ProjectManager.Qt4BuildConfiguration 0 - /home/michael/coding/paysages/gui_qt + /home/michael/workspace/paysages/gui_qt 3 ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-32bit. false @@ -133,9 +133,7 @@ paysages-qt.pro false false - - LD_LIBRARY_PATH=../lib_paysages - + 3768 true @@ -150,7 +148,7 @@ ProjectExplorer.Project.Updater.EnvironmentId - {8abe6662-5ded-4243-9d4d-dbf8a3c19b83} + {d5145163-5b06-43da-aefd-e689d7a52ef8} ProjectExplorer.Project.Updater.FileVersion diff --git a/lib_paysages/auto.c b/lib_paysages/auto.c index 0313b95..6d80e5a 100644 --- a/lib_paysages/auto.c +++ b/lib_paysages/auto.c @@ -12,6 +12,8 @@ #include "water.h" #include "clouds.h" #include "sky.h" +#include "terrain.h" +#include "textures.h" static int _cpu_count = 1; static int _is_rendering = 0; @@ -100,6 +102,7 @@ void autoSetDaytimeFraction(double daytime) void autoSetRenderQuality(int quality) { + TerrainQuality terrain; WaterQuality water; CloudsQuality clouds; @@ -114,7 +117,9 @@ void autoSetRenderQuality(int quality) renderSetQuality(quality); - terrainSetChunkSize(0.1 / (double)render_quality, 0.05 / (double)render_quality); + terrain.min_chunk_size = 0.1 / (double)render_quality; + terrain.visible_chunk_size = 0.05 / (double)render_quality; + terrainSetQuality(terrain); water.detail_boost = 5.0; water.force_detail = 0.0; @@ -126,14 +131,14 @@ void autoSetRenderQuality(int quality) void autoGenRealisticLandscape(int seed) { - Texture* tex; + TerrainDefinition terrain; WaterDefinition water; CloudsDefinition cloud; SkyDefinition sky; + TextureDefinition texture; int layer; HeightModifier* mod; Zone* zone; - NoiseGenerator* noise; if (!seed) { @@ -166,7 +171,7 @@ void autoGenRealisticLandscape(int seed) noiseAddLevelSimple(cloud.noise, 50.0 / 800.0, 0.001); noiseAddLevelSimple(cloud.noise, 50.0 / 1000.0, 0.0005); layer = cloudsAddLayer(); - cloudsSetDefinition(layer, cloud); + //cloudsSetDefinition(layer, cloud); /* Water */ water.height = 0.0; @@ -215,14 +220,22 @@ void autoGenRealisticLandscape(int seed) sky.sun_radius = 0.02; skySetDefinition(sky); - noise = noiseCreateGenerator(); - noiseGenerateBaseNoise(noise, 1048576); - noiseAddLevelsSimple(noise, 10, 10.0, 1.0); - noiseNormalizeHeight(noise, -12.0, 12.0, 0); - terrainSetNoiseGenerator(noise); - noiseDeleteGenerator(noise); - - tex = textureCreateFromFile("./data/textures/rock3.jpg"); + terrain = terrainCreateDefinition(); + noiseGenerateBaseNoise(terrain.height_noise, 1048576); + noiseAddLevelsSimple(terrain.height_noise, 8, 10.0, 1.0); + noiseNormalizeHeight(terrain.height_noise, -12.0, 12.0, 0); + terrainSetDefinition(terrain); + terrainDeleteDefinition(terrain); + + layer = texturesAddLayer(); + texture = texturesCreateDefinition(); + noiseGenerateBaseNoise(texture.bump_noise, 102400); + noiseAddLevelsSimple(texture.bump_noise, 6, 0.01, 0.01); + texture.color = COLOR_WHITE; + texturesSetDefinition(layer, texture); + texturesDeleteDefinition(texture); + + /*tex = textureCreateFromFile("./data/textures/rock3.jpg"); tex->scaling_x = 0.003; tex->scaling_y = 0.003; tex->scaling_z = 0.003; @@ -236,7 +249,7 @@ void autoGenRealisticLandscape(int seed) zone = zoneCreate(0.0); zoneAddHeightRange(zone, 1.0, -1.0, 0.0, 3.0, 15.0); zoneAddSteepnessRange(zone, 1.0, 0.0, 0.0, 0.3, 0.4); - terrainAddTexture(tex, 0.15, zone, 0.05); + terrainAddTexture(tex, 0.15, zone, 0.05);*/ /*tex = textureCreateFromFile("./data/textures/snow1.jpg"); tex->scaling_x = 0.001; @@ -247,7 +260,7 @@ void autoGenRealisticLandscape(int seed) terrainAddTexture(tex, 0.5, zone, 0.1);*/ /* DEBUG */ - mod = modifierCreate(); + /*mod = modifierCreate(); zone = modifierGetZone(mod); zoneIncludeCircleArea(zone, 0.4, 0.0, 0.0, 8.0, 20.0); modifierActionFixValue(mod, -2.0); @@ -261,7 +274,7 @@ void autoGenRealisticLandscape(int seed) zone = modifierGetZone(mod); zoneIncludeCircleArea(zone, 0.8, 0.0, 0.0, 0.3, 4.0); modifierActionFixValue(mod, -8.0); - terrainAddModifier(mod); + terrainAddModifier(mod);*/ fogSetDistance(20.0, 100.0); } diff --git a/lib_paysages/clouds.c b/lib_paysages/clouds.c index cf5be32..9fe28ca 100644 --- a/lib_paysages/clouds.c +++ b/lib_paysages/clouds.c @@ -50,6 +50,8 @@ void cloudsLoad(FILE* f) { int i; CloudsDefinition* layer; + + /* FIXME Delete unused noise generators and add missing ones */ _layers_count = toolsLoadInt(f); for (i = 0; i < _layers_count; i++) diff --git a/lib_paysages/main.c b/lib_paysages/main.c index 572d589..01ee225 100644 --- a/lib_paysages/main.c +++ b/lib_paysages/main.c @@ -11,6 +11,7 @@ #include "shared/constants.h" #include "shared/functions.h" #include "shared/globals.h" +#include "terrain.h" void paysagesInit() { @@ -25,4 +26,17 @@ void paysagesInit() autoSetRenderQuality(5); autoGenRealisticLandscape(0); autoSetDaytime(8, 30); + + // DEBUG + double last_height, height, x; + last_height = height = 0.0; + x = 0.0; + while (height <= 1.0 || height >= last_height || last_height < 0.1) + { + last_height = height; + height = terrainGetHeight(x, 0.0); + x += 0.1; + } + cameraSetLocation(x - 2.0, height, 0.0); + cameraSetTarget(x - 1.0, height, 0.0); } diff --git a/lib_paysages/shared/functions.h b/lib_paysages/shared/functions.h index 5d8cd2a..567d96c 100644 --- a/lib_paysages/shared/functions.h +++ b/lib_paysages/shared/functions.h @@ -172,28 +172,6 @@ Color skyProjectRay(Vector3 start, Vector3 direction); void skySetGradation(ColorGradation grad); void skyRender(RenderProgressCallback callback); -/* terrain.c */ -void terrainSave(FILE* f); -void terrainLoad(FILE* f); -void terrainInit(); -NoiseGenerator* terrainGetNoiseGenerator(); -void terrainSetNoiseGenerator(NoiseGenerator* generator); -void terrainAddTexture(Texture* tex, double subsurf_scale, Zone* zone, double border_scaling); -void terrainAddModifier(HeightModifier* modifier); -double terrainGetHeight(double x, double z); -double terrainGetHeightNormalized(double x, double z); -Color terrainGetColor(double x, double z, double precision); -double terrainGetShadow(Vector3 start, Vector3 direction); -int terrainProjectRay(Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color); -void terrainSetChunkSize(double min_size, double visible_size); -void terrainRender(RenderProgressCallback callback); - -/* textures.c */ -void texturesSave(FILE* f); -void texturesLoad(FILE* f); -Texture* textureCreateFromFile(const char* filename); -Color textureApply(Texture* tex, Vector3 location, Vector3 normal); - /* tools.c */ double toolsRandom(); double toolsBicubicInterpolate(double stencil[16], double x, double y); @@ -209,6 +187,7 @@ Zone* zoneCreate(); void zoneDelete(Zone* zone); void zoneSave(Zone* zone, FILE* f); void zoneLoad(Zone* zone, FILE* f); +void zoneCopy(Zone* source, Zone* destination); void zoneIncludeCircleArea(Zone* zone, double value, double centerx, double centerz, double softradius, double hardradius); void zoneExcludeCircleArea(Zone* zone, double centerx, double centerz, double softradius, double hardradius); void zoneAddHeightRange(Zone* zone, double value, double hardmin, double softmin, double softmax, double hardmax); diff --git a/lib_paysages/shared/types.h b/lib_paysages/shared/types.h index bf47080..637f2e7 100644 --- a/lib_paysages/shared/types.h +++ b/lib_paysages/shared/types.h @@ -87,16 +87,6 @@ typedef struct void* data; } Array; -typedef struct { - void* pixels; - int bytes_per_pixel; - int picture_width; - int picture_height; - double scaling_x; - double scaling_y; - double scaling_z; -} Texture; - struct NoiseLevel { double scaling; diff --git a/lib_paysages/terrain.c b/lib_paysages/terrain.c index c4283a2..a752146 100644 --- a/lib_paysages/terrain.c +++ b/lib_paysages/terrain.c @@ -6,118 +6,103 @@ #include "shared/globals.h" #include "shared/constants.h" +#include "textures.h" #include "water.h" +#include "terrain.h" -#define MAX_TEXTURES 10 #define MAX_MODIFIERS 50 -typedef struct { - Texture* tex; - double subsurf_scale; - Zone* zone; - double border_scaling; -} TerrainTexture; - -static NoiseGenerator* _noise_height; -static NoiseGenerator* _noise_texture_borders; +static TerrainDefinition _definition; +static TerrainQuality _quality; +static TerrainEnvironment _environment; static double _max_height = 1.0; -static double _base_chunk_size = 1.0, _visible_chunk_size = 1.0; -static int _texture_count = 0; -static TerrainTexture _textures[MAX_TEXTURES]; + static int _modifiers_count = 0; static HeightModifier* _modifiers[MAX_MODIFIERS]; +void terrainInit() +{ + _definition = terrainCreateDefinition(); + _max_height = noiseGetMaxValue(_definition.height_noise); +} + void terrainSave(FILE* f) { - noiseSave(_noise_height, f); - noiseSave(_noise_texture_borders, f); + noiseSave(_definition.height_noise, f); - toolsSaveDouble(f, _max_height); - toolsSaveDouble(f, _base_chunk_size); - toolsSaveDouble(f, _visible_chunk_size); - - /* TODO Textures */ /* TODO Modifiers */ } void terrainLoad(FILE* f) { - noiseLoad(_noise_height, f); - noiseLoad(_noise_texture_borders, f); - - _max_height = toolsLoadDouble(f); - _base_chunk_size = toolsLoadDouble(f); - _visible_chunk_size = toolsLoadDouble(f); + noiseLoad(_definition.height_noise, f); + _max_height = noiseGetMaxValue(_definition.height_noise); } -void terrainInit() +TerrainDefinition terrainCreateDefinition() { - _noise_height = noiseCreateGenerator(); - _max_height = noiseGetMaxValue(_noise_height); - - _noise_texture_borders = noiseCreateGenerator(); - noiseGenerateBaseNoise(_noise_texture_borders, 100); - noiseAddLevelsSimple(_noise_texture_borders, 10, 1.0, 1.0); - noiseNormalizeHeight(_noise_texture_borders, 0.0, 1.0, 0); + TerrainDefinition definition; + + definition.height_noise = noiseCreateGenerator(); + + return definition; } -NoiseGenerator* terrainGetNoiseGenerator() +void terrainDeleteDefinition(TerrainDefinition definition) { - return _noise_height; + noiseDeleteGenerator(definition.height_noise); } -void terrainSetNoiseGenerator(NoiseGenerator* generator) +void terrainCopyDefinition(TerrainDefinition source, TerrainDefinition* destination) { - noiseCopy(generator, _noise_height); - _max_height = noiseGetMaxValue(_noise_height); - /* FIXME Max height depends on modifiers*/ + noiseCopy(source.height_noise, destination->height_noise); } -void terrainAddTexture(Texture* tex, double subsurf_scale, Zone* zone, double border_scaling) +void terrainSetDefinition(TerrainDefinition definition) { - TerrainTexture ttex; - if (_texture_count < MAX_TEXTURES) - { - ttex.tex = tex; - ttex.subsurf_scale = subsurf_scale; - ttex.zone = zone; - ttex.border_scaling = border_scaling; - - _textures[_texture_count++] = ttex; - } + terrainCopyDefinition(definition, &_definition); + _max_height = noiseGetMaxValue(_definition.height_noise); + /* FIXME _max_height depends on modifiers */ } -void terrainAddModifier(HeightModifier* modifier) +TerrainDefinition terrainGetDefinition() { - if (_modifiers_count < MAX_MODIFIERS) - { - _modifiers[_modifiers_count++] = modifier; - } + return _definition; } -static inline double _getHeight(double x, double z, double precision) +void terrainSetQuality(TerrainQuality quality) +{ + _quality = quality; +} + +TerrainQuality terrainGetQuality() +{ + return _quality; +} + +static inline double _getHeight(TerrainDefinition* definition, double x, double z, double detail) { Vector3 location; - int i; + /*int i;*/ location.x = x; - location.y = noiseGet2DDetail(_noise_height, x, z, precision); + location.y = noiseGet2DDetail(definition->height_noise, x, z, detail); location.z = z; - for (i = 0; i < _modifiers_count; i++) + /*for (i = 0; i < _modifiers_count; i++) { location = modifierApply(_modifiers[i], location); - } + }*/ return location.y; } -static inline Vector3 _getPoint(double x, double z, double precision) +static inline Vector3 _getPoint(TerrainDefinition* definition, double x, double z, double detail) { Vector3 result; result.x = x; - result.y = _getHeight(x, z, precision); + result.y = _getHeight(definition, x, z, detail); result.z = z; return result; @@ -143,7 +128,7 @@ double terrainGetShadow(Vector3 start, Vector3 direction) inc_vector = v3Scale(direction, inc_value); length += v3Norm(inc_vector); start = v3Add(start, inc_vector); - height = _getHeight(start.x, start.z, inc_value); + height = _getHeight(&_definition, start.x, start.z, inc_value); diff = start.y - height; if (diff < 0.0) { @@ -175,78 +160,12 @@ double terrainGetShadow(Vector3 start, Vector3 direction) } } -static inline Vector3 _getNormal(Vector3 point, double scale) +static Color _getColor(TerrainDefinition* definition, Vector3 point, double precision) { - Vector3 dpoint, ref, normal; - - ref.x = 0.0; - ref.y = 0.0; - - dpoint = _getPoint(point.x - scale, point.z, scale * 0.3); - ref.z = -1.0; - normal = v3Normalize(v3Cross(ref, v3Sub(dpoint, point))); - - dpoint = _getPoint(point.x + scale, point.z, scale * 0.3); - ref.z = 1.0; - normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point)))); - - ref.z = 0.0; - - dpoint = _getPoint(point.x, point.z - scale, scale * 0.3); - ref.x = 1.0; - normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point)))); - - dpoint = _getPoint(point.x, point.z + scale, scale * 0.3); - ref.x = -1.0; - normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point)))); - - return v3Normalize(normal); -} - -static Color _getColor(Vector3 point, double precision) -{ - Vector3 normal; - Color color, tex_color; - int i; - double shadowed, coverage, value; - - shadowed = terrainGetShadow(point, sun_direction_inv); - - /* Apply textures and subsurface lighting */ - color = COLOR_GREEN; - for (i = 0; i < _texture_count; i++) - { - /* TODO Don't recalculate normals for same precision */ - /* TODO Don't compute textures that will be totally covered */ - normal = _getNormal(point, precision * _textures[i].subsurf_scale); - - coverage = zoneGetValue(_textures[i].zone, point, normal); - if (coverage > 0.0) - { - if (coverage < 1.0) - { - value = noiseGet2DTotal(_noise_texture_borders, point.x / _textures[i].border_scaling, point.z / _textures[i].border_scaling); - if (value < coverage) - { - /* TODO Make smoothness precision-dependant */ - value = (coverage - value) / 0.1; - coverage = (value > 1.0) ? 1.0 : value; - } - else - { - coverage = 0.0; - } - } - if (coverage > 0.0) - { - tex_color = textureApply(_textures[i].tex, point, normal); - tex_color = lightingApply(point, normal, shadowed, tex_color, 0.1, 0.1); - tex_color.a = coverage; - colorMask(&color, &tex_color); - } - } - } + Color color; + /* FIXME Environment for textures should be customized */ + color = texturesGetColor(point); color = fogApplyToLocation(point, color); //color = cloudsApplySegmentResult(color, camera_location, point); @@ -269,13 +188,13 @@ int terrainProjectRay(Vector3 start, Vector3 direction, Vector3* hit_point, Colo inc_vector = v3Scale(direction, inc_value); length += v3Norm(inc_vector); start = v3Add(start, inc_vector); - height = _getHeight(start.x, start.z, inc_value); + height = _getHeight(&_definition, start.x, start.z, inc_value); diff = start.y - height; if (diff < 0.0) { start.y = height; *hit_point = start; - *hit_color = _getColor(start, inc_value); + *hit_color = _getColor(&_definition, start, inc_value); return 1; } @@ -304,19 +223,19 @@ static int _postProcessFragment(RenderFragment* fragment) point = fragment->vertex.location; precision = renderGetPrecision(point); - point = _getPoint(point.x, point.z, precision); + point = _getPoint(&_definition, point.x, point.z, precision); - fragment->vertex.color = _getColor(point, precision); + fragment->vertex.color = _getColor(&_definition, point, precision); return 1; } -static Vertex _getFirstPassVertex(double x, double z, double precision) +static Vertex _getFirstPassVertex(double x, double z, double detail) { Vertex result; double value; - result.location = _getPoint(x, z, 0.0); + result.location = _getPoint(&_definition, x, z, 0.0); value = sin(x) * sin(x) * cos(z) * cos(z); result.color.r = value; result.color.g = value; @@ -341,23 +260,22 @@ static void _renderQuad(double x, double z, double size) double terrainGetHeight(double x, double z) { - return _getHeight(x, z, 0.01 / (double)render_quality); + return _getHeight(&_definition, x, z, 0.01 / (double)render_quality); } double terrainGetHeightNormalized(double x, double z) { - return 0.5 + _getHeight(x, z, 0.01 / (double)render_quality) / (_max_height * 2.0); + return 0.5 + _getHeight(&_definition, x, z, 0.01 / (double)render_quality) / (_max_height * 2.0); } -Color terrainGetColor(double x, double z, double precision) +Color terrainGetColorCustom(double x, double z, double detail, TerrainDefinition* definition, TerrainQuality* quality, TerrainEnvironment* environment) { - return _getColor(_getPoint(x, z, precision), precision); + return _getColor(definition, _getPoint(definition, x, z, detail), detail); } -void terrainSetChunkSize(double min_size, double visible_size) +Color terrainGetColor(double x, double z, double detail) { - _base_chunk_size = min_size; - _visible_chunk_size = visible_size; + return terrainGetColorCustom(x, z, detail, &_definition, &_quality, &_environment); } void terrainRender(RenderProgressCallback callback) @@ -370,8 +288,8 @@ void terrainRender(RenderProgressCallback callback) chunk_factor = 1; chunk_count = 2; radius_int = 0.0; - radius_ext = _base_chunk_size; - chunk_size = _base_chunk_size; + radius_ext = _quality.min_chunk_size; + chunk_size = _quality.min_chunk_size; while (radius_ext < 1000.0) { @@ -388,14 +306,14 @@ void terrainRender(RenderProgressCallback callback) _renderQuad(cx - radius_ext, cz + radius_int - chunk_size * i, chunk_size); } - if (chunk_count % 64 == 0 && chunk_size / radius_int < _visible_chunk_size) + if (chunk_count % 64 == 0 && chunk_size / radius_int < _quality.visible_chunk_size) { chunk_count /= 2; chunk_factor *= 2; /* TODO Fill in gaps with triangles */ } chunk_count += 2; - chunk_size = _base_chunk_size * chunk_factor; + chunk_size = _quality.min_chunk_size * chunk_factor; radius_int = radius_ext; radius_ext += chunk_size; } diff --git a/lib_paysages/terrain.h b/lib_paysages/terrain.h new file mode 100644 index 0000000..250a981 --- /dev/null +++ b/lib_paysages/terrain.h @@ -0,0 +1,54 @@ +#ifndef _PAYSAGES_TERRAIN_H_ +#define _PAYSAGES_TERRAIN_H_ + +#include "shared/types.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + NoiseGenerator* height_noise; +} TerrainDefinition; + +typedef struct +{ + double min_chunk_size; + double visible_chunk_size; +} TerrainQuality; + +typedef struct +{ + int unused; +} TerrainEnvironment; + +void terrainInit(); +void terrainSave(FILE* f); +void terrainLoad(FILE* f); + +TerrainDefinition terrainCreateDefinition(); +void terrainDeleteDefinition(TerrainDefinition definition); +void terrainCopyDefinition(TerrainDefinition source, TerrainDefinition* destination); +void terrainSetDefinition(TerrainDefinition definition); +TerrainDefinition terrainGetDefinition(); + +void terrainSetQuality(TerrainQuality quality); +TerrainQuality terrainGetQuality(); + +double terrainGetShadow(Vector3 start, Vector3 direction); +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); +double terrainGetHeightNormalizedCustom(double x, double z, TerrainDefinition* definition); +double terrainGetHeightNormalized(double x, double z); +Color terrainGetColorCustom(double x, double z, double detail, TerrainDefinition* definition, TerrainQuality* quality, TerrainEnvironment* environment); +Color terrainGetColor(double x, double z, double detail); +void terrainRender(RenderProgressCallback callback); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib_paysages/textures.c b/lib_paysages/textures.c index 725699b..83c8543 100644 --- a/lib_paysages/textures.c +++ b/lib_paysages/textures.c @@ -1,137 +1,201 @@ #include #include #include +#include #include "shared/types.h" #include "shared/functions.h" #include "shared/constants.h" #include "shared/globals.h" -#include "IL/il.h" -#include "IL/ilu.h" +#include "textures.h" +#include "terrain.h" #define TEXTURES_MAX 50 +static TextureQuality _quality; +static TextureEnvironment _environment; static int _textures_count = 0; -static Texture _textures[TEXTURES_MAX]; +static TextureDefinition _textures[TEXTURES_MAX]; + +void texturesInit() +{ + _textures_count = 0; +} void texturesSave(FILE* f) { + int i; + + toolsSaveInt(f, _textures_count); + for (i = 0; i < _textures_count; i++) + { + zoneSave(_textures[i].zone, f); + noiseSave(_textures[i].bump_noise, f); + colorSave(_textures[i].color, f); + } } void texturesLoad(FILE* f) { + // TODO } -Texture* textureCreateFromFile(const char* filename) +int texturesGetLayerCount() { - Texture* result; - ILuint imageid; + return _textures_count; +} - if (_textures_count >= TEXTURES_MAX) +int texturesAddLayer() +{ + if (_textures_count < TEXTURES_MAX) { - return _textures + (TEXTURES_MAX - 1); + _textures[_textures_count] = texturesCreateDefinition(); + + return _textures_count++; } else { - result = _textures + _textures_count; - _textures_count++; - - ilGenImages(1, &imageid); - ilBindImage(imageid); - ilLoadImage(filename); - - result->bytes_per_pixel = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL); - result->picture_width = ilGetInteger(IL_IMAGE_WIDTH); - result->picture_height = ilGetInteger(IL_IMAGE_HEIGHT); - result->pixels = malloc(result->bytes_per_pixel * result->picture_width * result->picture_height); - memcpy(result->pixels, ilGetData(), result->bytes_per_pixel * result->picture_width * result->picture_height); - result->scaling_x = 1.0; - result->scaling_y = 1.0; - result->scaling_z = 1.0; - - ilDeleteImages(1, &imageid); - - return result; + return -1; } } -static inline Color _getRawValue(Texture* tex, int x, int y) +void texturesDeleteLayer(int layer) { - Color result; - void* texdata; + // TODO +} - x = x % tex->picture_width; - if (x < 0) - { - x += tex->picture_width; - } - y = y % tex->picture_height; - if (y < 0) - { - y += tex->picture_height; - } +TextureDefinition texturesCreateDefinition() +{ + TextureDefinition result; - texdata = tex->pixels + (y * tex->picture_width + x) * tex->bytes_per_pixel; - - result.r = ((double)(unsigned int)*((unsigned char*)texdata)) / 255.0; - result.g = ((double)(unsigned int)*((unsigned char*)(texdata + 1))) / 255.0; - result.b = ((double)(unsigned int)*((unsigned char*)(texdata + 2))) / 255.0; + result.zone = zoneCreate(); + result.bump_noise = noiseCreateGenerator(); + result.color = COLOR_GREEN; return result; } -static inline Color _getInterpolatedValue(Texture* tex, double fx, double fy) +void texturesDeleteDefinition(TextureDefinition definition) +{ + zoneDelete(definition.zone); + noiseDeleteGenerator(definition.bump_noise); +} + +void texturesCopyDefinition(TextureDefinition source, TextureDefinition* destination) +{ + destination->color = source.color; + noiseCopy(source.bump_noise, destination->bump_noise); + zoneCopy(source.zone, destination->zone); +} + +void texturesSetDefinition(int layer, TextureDefinition definition) +{ + TextureDefinition* destination; + + if (layer >= 0 && layer < _textures_count) + { + destination = _textures + layer; + texturesCopyDefinition(definition, destination); + } +} + +TextureDefinition texturesGetDefinition(int layer) +{ + assert(layer >= 0); + assert(layer < _textures_count); + + return _textures[layer]; +} + +void texturesSetQuality(TextureQuality quality) +{ + _quality = quality; +} + +TextureQuality texturesGetQuality() +{ + return _quality; +} + +static inline Vector3 _getNormal(TextureDefinition* definition, Vector3 point, double scale) +{ + Vector3 dpoint, ref, normal; + + ref.x = 0.0; + ref.y = 0.0; + + dpoint.x = point.x - scale; + dpoint.z = point.z; + dpoint.y = terrainGetHeight(dpoint.x, dpoint.z) + noiseGet2DTotal(definition->bump_noise, dpoint.x, dpoint.z); + ref.z = -1.0; + normal = v3Normalize(v3Cross(ref, v3Sub(dpoint, point))); + + dpoint.x = point.x + scale; + dpoint.z = point.z; + dpoint.y = terrainGetHeight(dpoint.x, dpoint.z) + noiseGet2DTotal(definition->bump_noise, dpoint.x, dpoint.z); + ref.z = 1.0; + normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point)))); + + ref.z = 0.0; + + dpoint.x = point.x; + dpoint.z = point.z - scale; + dpoint.y = terrainGetHeight(dpoint.x, dpoint.z) + noiseGet2DTotal(definition->bump_noise, dpoint.x, dpoint.z); + ref.x = 1.0; + normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point)))); + + dpoint.x = point.x; + dpoint.z = point.z + scale; + dpoint.y = terrainGetHeight(dpoint.x, dpoint.z) + noiseGet2DTotal(definition->bump_noise, dpoint.x, dpoint.z); + ref.x = -1.0; + normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point)))); + + return v3Normalize(normal); +} + +Color texturesGetLayerColorCustom(Vector3 location, double shadowing, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment) { Color result; - double r[16]; - double g[16]; - double b[16]; - int ix, iy; - int sx, sy; + Vector3 normal; + double coverage; + + result.a = 0.0; + normal = _getNormal(definition, location, detail * 0.3); - ix = (int)floor(fx); - iy = (int)floor(fy); - fx -= (double)ix; - fy -= (double)iy; - - for (sy = 0; sy < 4; sy++) + coverage = zoneGetValue(definition->zone, location, normal); + if (coverage > 0.0) { - for (sx = 0; sx < 4; sx++) + result = lightingApply(location, normal, shadowing, definition->color, 0.1, 0.1); + result.a = coverage; + } + return result; +} + +Color texturesGetColorCustom(Vector3 location, double shadowing, double detail, TextureQuality* quality, TextureEnvironment* environment) +{ + Color result, tex_color; + int i; + + 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); + if (tex_color.a > 0.0001) { - result = _getRawValue(tex, ix + sx - 1, iy + sy - 1); - r[sy * 4 + sx] = result.r; - g[sy * 4 + sx] = result.g; - b[sy * 4 + sx] = result.b; + colorMask(&result, &tex_color); } } - - result.r = toolsBicubicInterpolate(r, fx, fy); - result.g = toolsBicubicInterpolate(g, fx, fy); - result.b = toolsBicubicInterpolate(b, fx, fy); - result.a = 1.0; + return result; } -Color textureApply(Texture* tex, Vector3 location, Vector3 normal) +Color texturesGetColor(Vector3 location) { - Color col_x, col_y, col_z, result; - double x, y, z; - double distance; - - distance = v3Norm(v3Sub(camera_location, location)) / 10.0; - - x = location.x / (tex->scaling_x * distance); - y = location.y / (tex->scaling_y * distance); - z = location.z / (tex->scaling_z * distance); - - col_x = _getInterpolatedValue(tex, y, z); - col_y = _getInterpolatedValue(tex, x, z); - col_z = _getInterpolatedValue(tex, x, y); - - result.r = (col_x.r + col_y.r + col_z.r) / 3.0; - result.g = (col_x.g + col_y.g + col_z.g) / 3.0; - result.b = (col_x.b + col_y.b + col_z.b) / 3.0; - result.a = (col_x.a + col_y.a + col_z.a) / 3.0; - return result; + double shadowing; + + /* TODO Use environment to get lights to apply */ + shadowing = terrainGetShadow(location, sun_direction_inv); + + return texturesGetColorCustom(location, shadowing, renderGetPrecision(location), &_quality, &_environment); } - diff --git a/lib_paysages/textures.h b/lib_paysages/textures.h new file mode 100644 index 0000000..345bc12 --- /dev/null +++ b/lib_paysages/textures.h @@ -0,0 +1,53 @@ +#ifndef _PAYSAGES_TEXTURES_H_ +#define _PAYSAGES_TEXTURES_H_ + +#include "shared/types.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + Zone* zone; + NoiseGenerator* bump_noise; + Color color; +} TextureDefinition; + +typedef struct +{ + int unused; +} TextureQuality; + +typedef struct +{ + int unused; +} TextureEnvironment; + +void texturesInit(); +void texturesSave(FILE* f); +void texturesLoad(FILE* f); + +int texturesGetLayerCount(); +int texturesAddLayer(); +void texturesDeleteLayer(int layer); + +TextureDefinition texturesCreateDefinition(); +void texturesDeleteDefinition(TextureDefinition definition); +void texturesCopyDefinition(TextureDefinition source, TextureDefinition* destination); +void texturesSetDefinition(int layer, TextureDefinition definition); +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 texturesGetColor(Vector3 location); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib_paysages/water.c b/lib_paysages/water.c index 81741e5..6539d2b 100644 --- a/lib_paysages/water.c +++ b/lib_paysages/water.c @@ -2,7 +2,9 @@ #include "shared/functions.h" #include "shared/constants.h" #include "shared/globals.h" + #include "water.h" +#include "terrain.h" #include diff --git a/lib_paysages/zone.c b/lib_paysages/zone.c index d9519d3..f624a56 100644 --- a/lib_paysages/zone.c +++ b/lib_paysages/zone.c @@ -39,14 +39,6 @@ struct Zone { #include "shared/types.h" #include "shared/functions.h" -void zoneSave(Zone* zone, FILE* f) -{ -} - -void zoneLoad(Zone* zone, FILE* f) -{ -} - Zone* zoneCreate() { Zone* result; @@ -56,7 +48,7 @@ Zone* zoneCreate() result->steepness_ranges_count = 0; result->circles_included_count = 0; result->circles_excluded_count = 0; - + return result; } @@ -65,6 +57,101 @@ void zoneDelete(Zone* zone) free(zone); } +void zoneSave(Zone* zone, FILE* f) +{ + int i; + + toolsSaveInt(f, zone->height_ranges_count); + for (i = 0; i < zone->height_ranges_count; i++) + { + toolsSaveDouble(f, zone->height_ranges[i].value); + toolsSaveDouble(f, zone->height_ranges[i].hardmin); + toolsSaveDouble(f, zone->height_ranges[i].softmin); + toolsSaveDouble(f, zone->height_ranges[i].softmax); + toolsSaveDouble(f, zone->height_ranges[i].hardmax); + } + + toolsSaveInt(f, zone->steepness_ranges_count); + for (i = 0; i < zone->steepness_ranges_count; i++) + { + toolsSaveDouble(f, zone->steepness_ranges[i].value); + toolsSaveDouble(f, zone->steepness_ranges[i].hardmin); + toolsSaveDouble(f, zone->steepness_ranges[i].softmin); + toolsSaveDouble(f, zone->steepness_ranges[i].softmax); + toolsSaveDouble(f, zone->steepness_ranges[i].hardmax); + } + + toolsSaveInt(f, zone->circles_included_count); + for (i = 0; i < zone->circles_included_count; i++) + { + toolsSaveDouble(f, zone->circles_included[i].value); + toolsSaveDouble(f, zone->circles_included[i].centerx); + toolsSaveDouble(f, zone->circles_included[i].centerz); + toolsSaveDouble(f, zone->circles_included[i].softradius); + toolsSaveDouble(f, zone->circles_included[i].hardradius); + } + + toolsSaveInt(f, zone->circles_excluded_count); + for (i = 0; i < zone->circles_excluded_count; i++) + { + toolsSaveDouble(f, zone->circles_excluded[i].value); + toolsSaveDouble(f, zone->circles_excluded[i].centerx); + toolsSaveDouble(f, zone->circles_excluded[i].centerz); + toolsSaveDouble(f, zone->circles_excluded[i].softradius); + toolsSaveDouble(f, zone->circles_excluded[i].hardradius); + } +} + +void zoneLoad(Zone* zone, FILE* f) +{ + int i; + + zone->height_ranges_count = toolsLoadInt(f); + for (i = 0; i < zone->height_ranges_count; i++) + { + zone->height_ranges[i].value = toolsLoadDouble(f); + zone->height_ranges[i].hardmin = toolsLoadDouble(f); + zone->height_ranges[i].softmin = toolsLoadDouble(f); + zone->height_ranges[i].softmax = toolsLoadDouble(f); + zone->height_ranges[i].hardmax = toolsLoadDouble(f); + } + + zone->steepness_ranges_count = toolsLoadInt(f); + for (i = 0; i < zone->steepness_ranges_count; i++) + { + zone->steepness_ranges[i].value = toolsLoadDouble(f); + zone->steepness_ranges[i].hardmin = toolsLoadDouble(f); + zone->steepness_ranges[i].softmin = toolsLoadDouble(f); + zone->steepness_ranges[i].softmax = toolsLoadDouble(f); + zone->steepness_ranges[i].hardmax = toolsLoadDouble(f); + } + + zone->circles_included_count = toolsLoadInt(f); + for (i = 0; i < zone->circles_included_count; i++) + { + zone->circles_included[i].value = toolsLoadDouble(f); + zone->circles_included[i].centerx = toolsLoadDouble(f); + zone->circles_included[i].centerz = toolsLoadDouble(f); + zone->circles_included[i].softradius = toolsLoadDouble(f); + zone->circles_included[i].hardradius = toolsLoadDouble(f); + } + + zone->circles_excluded_count = toolsLoadInt(f); + for (i = 0; i < zone->circles_excluded_count; i++) + { + zone->circles_excluded[i].value = toolsLoadDouble(f); + zone->circles_excluded[i].centerx = toolsLoadDouble(f); + zone->circles_excluded[i].centerz = toolsLoadDouble(f); + zone->circles_excluded[i].softradius = toolsLoadDouble(f); + zone->circles_excluded[i].hardradius = toolsLoadDouble(f); + } +} + +void zoneCopy(Zone* source, Zone* destination) +{ + *source = *destination; +} + void zoneIncludeCircleArea(Zone* zone, double value, double centerx, double centerz, double softradius, double hardradius) { Circle circle = {value, centerx, centerz, softradius, hardradius};