diff --git a/lib_paysages/renderer.c b/lib_paysages/renderer.c index 0301292..69bcca0 100644 --- a/lib_paysages/renderer.c +++ b/lib_paysages/renderer.c @@ -3,6 +3,7 @@ #include "lighting.h" RayCastingResult _RAYCASTING_NULL = {0}; +HeightInfo _WATER_HEIGHT_INFO = {-1000000.0, -1000000.0, -1000000.0}; static Color _filterLight(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light) { @@ -29,6 +30,11 @@ static double _getTerrainHeight(Renderer* renderer, double x, double z) return 0.0; } +static HeightInfo _getWaterHeightInfo(Renderer* renderer) +{ + return _WATER_HEIGHT_INFO; +} + static Color _applyTextures(Renderer* renderer, Vector3 location, double precision) { return COLOR_TRANSPARENT; @@ -71,6 +77,7 @@ Renderer rendererGetFake() result.applyLightingToSurface = _applyLightingToSurface; result.rayWalking = _rayWalking; result.getTerrainHeight = _getTerrainHeight; + result.getWaterHeightInfo = _getWaterHeightInfo; result.applyTextures = _applyTextures; result.applyAtmosphere = _applyAtmosphere; result.applyClouds = _applyClouds; diff --git a/lib_paysages/renderer.h b/lib_paysages/renderer.h index 665e92d..917ce9d 100644 --- a/lib_paysages/renderer.h +++ b/lib_paysages/renderer.h @@ -23,6 +23,7 @@ struct Renderer /* Scenery related */ RayCastingResult (*rayWalking)(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds); double (*getTerrainHeight)(Renderer* renderer, double x, double z); + HeightInfo (*getWaterHeightInfo)(Renderer* renderer); Color (*applyTextures)(Renderer* renderer, Vector3 location, double precision); Color (*applyAtmosphere)(Renderer* renderer, Vector3 location, Color base); Color (*applyClouds)(Renderer* renderer, Color base, Vector3 start, Vector3 end); diff --git a/lib_paysages/scenery.c b/lib_paysages/scenery.c index 618fff8..ecd08df 100644 --- a/lib_paysages/scenery.c +++ b/lib_paysages/scenery.c @@ -250,6 +250,11 @@ static double _getTerrainHeight(Renderer* renderer, double x, double z) return terrainGetHeight(&_terrain, x, z); } +static HeightInfo _getWaterHeightInfo(Renderer* renderer) +{ + return waterGetHeightInfo(&_water); +} + static Color _applyTextures(Renderer* renderer, Vector3 location, double precision) { return texturesGetColor(&_textures, renderer, location, precision); @@ -306,6 +311,7 @@ Renderer sceneryGetStandardRenderer(int quality) result.applyLightingToSurface = _applyLightingToSurface; result.rayWalking = _rayWalking; result.getTerrainHeight = _getTerrainHeight; + result.getWaterHeightInfo = _getWaterHeightInfo; result.applyTextures = _applyTextures; result.applyAtmosphere = _applyAtmosphere; result.applyClouds = _applyClouds; diff --git a/lib_paysages/shared/types.h b/lib_paysages/shared/types.h index 12c831b..49f312c 100644 --- a/lib_paysages/shared/types.h +++ b/lib_paysages/shared/types.h @@ -114,6 +114,13 @@ typedef struct } RayCastingResult; typedef RayCastingResult (*RayCastingFunction)(Vector3 start, Vector3 direction); +typedef struct +{ + double min_height; + double max_height; + double base_height; +} HeightInfo; + #ifdef __cplusplus } #endif diff --git a/lib_paysages/terrain.c b/lib_paysages/terrain.c index 0ff4f88..96f91fc 100644 --- a/lib_paysages/terrain.c +++ b/lib_paysages/terrain.c @@ -311,7 +311,7 @@ static Vertex _getFirstPassVertex(TerrainDefinition* definition, double x, doubl return result; } -static void _renderQuad(TerrainDefinition* definition, Renderer* renderer, double x, double z, double size) +static void _renderQuad(TerrainDefinition* definition, Renderer* renderer, double x, double z, double size, double water_height) { Vertex v1, v2, v3, v4; @@ -319,7 +319,11 @@ static void _renderQuad(TerrainDefinition* definition, Renderer* renderer, doubl v2 = _getFirstPassVertex(definition, x, z + size, size); v3 = _getFirstPassVertex(definition, x + size, z + size, size); v4 = _getFirstPassVertex(definition, x + size, z, size); - renderPushQuad(renderer, &v1, &v2, &v3, &v4); + + if (v1.location.y > water_height || v2.location.y > water_height || v3.location.y > water_height || v4.location.y > water_height) + { + renderPushQuad(renderer, &v1, &v2, &v3, &v4); + } } double terrainGetHeight(TerrainDefinition* definition, double x, double z) @@ -352,6 +356,7 @@ void terrainRender(TerrainDefinition* definition, Renderer* renderer, RenderProg double cz = renderer->camera_location.z; double min_chunk_size, visible_chunk_size; double radius_int, radius_ext, chunk_size; + double water_height; min_chunk_size = 0.1 / (double)renderer->render_quality; visible_chunk_size = 0.05 / (double)renderer->render_quality; @@ -361,7 +366,8 @@ void terrainRender(TerrainDefinition* definition, Renderer* renderer, RenderProg radius_int = 0.0; radius_ext = min_chunk_size; chunk_size = min_chunk_size; - + + water_height = renderer->getWaterHeightInfo(renderer).max_height; while (radius_ext < 1000.0) { @@ -372,10 +378,10 @@ void terrainRender(TerrainDefinition* definition, Renderer* renderer, RenderProg for (i = 0; i < chunk_count - 1; i++) { - _renderQuad(definition, renderer, cx - radius_ext + chunk_size * i, cz - radius_ext, chunk_size); - _renderQuad(definition, renderer, cx + radius_int, cz - radius_ext + chunk_size * i, chunk_size); - _renderQuad(definition, renderer, cx + radius_int - chunk_size * i, cz + radius_int, chunk_size); - _renderQuad(definition, renderer, cx - radius_ext, cz + radius_int - chunk_size * i, chunk_size); + _renderQuad(definition, renderer, cx - radius_ext + chunk_size * i, cz - radius_ext, chunk_size, water_height); + _renderQuad(definition, renderer, cx + radius_int, cz - radius_ext + chunk_size * i, chunk_size, water_height); + _renderQuad(definition, renderer, cx + radius_int - chunk_size * i, cz + radius_int, chunk_size, water_height); + _renderQuad(definition, renderer, cx - radius_ext, cz + radius_int - chunk_size * i, chunk_size, water_height); } if (chunk_count % 64 == 0 && chunk_size / radius_int < visible_chunk_size) diff --git a/lib_paysages/water.c b/lib_paysages/water.c index d604689..3f5fcdf 100644 --- a/lib_paysages/water.c +++ b/lib_paysages/water.c @@ -136,6 +136,17 @@ static inline Vector3 _refractRay(Vector3 incoming, Vector3 normal) } } +HeightInfo waterGetHeightInfo(WaterDefinition* definition) +{ + HeightInfo info; + + info.base_height = definition->height; + info.min_height = definition->height - noiseGetMaxValue(definition->waves_noise) * definition->waves_noise_height; + info.max_height = definition->height + noiseGetMaxValue(definition->waves_noise) * definition->waves_noise_height; + + return info; +} + Color waterLightFilter(WaterDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light) { double factor; diff --git a/lib_paysages/water.h b/lib_paysages/water.h index f760fe1..857d08e 100644 --- a/lib_paysages/water.h +++ b/lib_paysages/water.h @@ -43,6 +43,7 @@ void waterDeleteDefinition(WaterDefinition* definition); void waterCopyDefinition(WaterDefinition* source, WaterDefinition* destination); void waterValidateDefinition(WaterDefinition* definition); +HeightInfo waterGetHeightInfo(WaterDefinition* definition); Color waterLightFilter(WaterDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light); WaterResult waterGetColorDetail(WaterDefinition* definition, Renderer* renderer, Vector3 location, Vector3 look); Color waterGetColor(WaterDefinition* definition, Renderer* renderer, Vector3 location, Vector3 look);