diff --git a/TODO b/TODO index de3288f..75a95e9 100644 --- a/TODO +++ b/TODO @@ -10,6 +10,7 @@ Technology Preview 2 : => Push displaced polygons, but keep undisplaced coordinates for second pass. => Add detail texture. => Displacement on 3d explorer and previews. + => Optimize ray marching (for tracing and shadows), using base terrain and displacement power. - Fix rendering when inside a cloud layer, with other upper or lower layers. - Translations. diff --git a/lib_paysages/renderer.c b/lib_paysages/renderer.c index 25d5f67..4f56de2 100644 --- a/lib_paysages/renderer.c +++ b/lib_paysages/renderer.c @@ -73,6 +73,23 @@ static void _pushQuad(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Ve renderer->pushTriangle(renderer, v4, v1, v3, callback, callback_data); } +static void _pushDisplacedTriangle(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 ov1, Vector3 ov2, Vector3 ov3, f_RenderFragmentCallback callback, void* callback_data) +{ + Vector3 p1, p2, p3; + + p1 = renderer->projectPoint(renderer, v1); + p2 = renderer->projectPoint(renderer, v2); + p3 = renderer->projectPoint(renderer, v3); + + renderPushTriangle(renderer->render_area, p1, p2, p3, ov1, ov2, ov3, callback, callback_data); +} + +static void _pushDisplacedQuad(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Vector3 ov1, Vector3 ov2, Vector3 ov3, Vector3 ov4, f_RenderFragmentCallback callback, void* callback_data) +{ + renderer->pushDisplacedTriangle(renderer, v2, v3, v1, ov2, ov3, ov1, callback, callback_data); + renderer->pushDisplacedTriangle(renderer, v4, v1, v3, ov4, ov1, ov3, callback, callback_data); +} + static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds) { return _RAYCASTING_NULL; @@ -118,6 +135,8 @@ Renderer* rendererCreate() result->unprojectPoint = _unprojectPoint; result->pushTriangle = _pushTriangle; result->pushQuad = _pushQuad; + result->pushDisplacedTriangle = _pushDisplacedTriangle; + result->pushDisplacedQuad = _pushDisplacedQuad; result->rayWalking = _rayWalking; diff --git a/lib_paysages/renderer.h b/lib_paysages/renderer.h index 56b0e02..b6d7ef5 100644 --- a/lib_paysages/renderer.h +++ b/lib_paysages/renderer.h @@ -34,6 +34,8 @@ struct Renderer int (*addRenderProgress)(Renderer* renderer, double progress); void (*pushTriangle)(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, f_RenderFragmentCallback callback, void* callback_data); void (*pushQuad)(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, f_RenderFragmentCallback callback, void* callback_data); + void (*pushDisplacedTriangle)(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 ov1, Vector3 ov2, Vector3 ov3, f_RenderFragmentCallback callback, void* callback_data); + void (*pushDisplacedQuad)(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Vector3 ov1, Vector3 ov2, Vector3 ov3, Vector3 ov4, f_RenderFragmentCallback callback, void* callback_data); /* Shortcuts */ Color (*applyLightingToSurface)(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial* material); diff --git a/lib_paysages/terrain/raster.c b/lib_paysages/terrain/raster.c index fa26ae8..7109435 100644 --- a/lib_paysages/terrain/raster.c +++ b/lib_paysages/terrain/raster.c @@ -31,21 +31,30 @@ static Color _postProcessFragment(Renderer* renderer, Vector3 point, void* data) static void _renderQuad(Renderer* renderer, double x, double z, double size, double water_height) { - Vector3 v1, v2, v3, v4; + Vector3 ov1, ov2, ov3, ov4; + Vector3 dv1, dv2, dv3, dv4; - /*v1 = _getPoint(definition, renderer, x, z); - v2 = _getPoint(definition, renderer, x, z + size); - v3 = _getPoint(definition, renderer, x + size, z + size); - v4 = _getPoint(definition, renderer, x + size, z);*/ + ov1.y = ov2.y = ov3.y = ov4.y; - v1 = renderer->terrain->getResult(renderer, x, z, 1, 1).location; - v2 = renderer->terrain->getResult(renderer, x, z + size, 1, 1).location; - v3 = renderer->terrain->getResult(renderer, x + size, z + size, 1, 1).location; - v4 = renderer->terrain->getResult(renderer, x + size, z, 1, 1).location; + ov1.x = x; + ov1.z = z; + dv1 = renderer->terrain->getResult(renderer, x, z, 1, 1).location; - if (v1.y > water_height || v2.y > water_height || v3.y > water_height || v4.y > water_height) + ov2.x = x; + ov2.z = z + size; + dv2 = renderer->terrain->getResult(renderer, x, z + size, 1, 1).location; + + ov3.x = x + size; + ov3.z = z + size; + dv3 = renderer->terrain->getResult(renderer, x + size, z + size, 1, 1).location; + + ov4.x = x + size; + ov4.z = z; + dv4 = renderer->terrain->getResult(renderer, x + size, z, 1, 1).location; + + if (dv1.y > water_height || dv2.y > water_height || dv3.y > water_height || dv4.y > water_height) { - renderer->pushQuad(renderer, v1, v2, v3, v4, _postProcessFragment, NULL); + renderer->pushDisplacedQuad(renderer, dv1, dv2, dv3, dv4, ov1, ov2, ov3, ov4, _postProcessFragment, NULL); } }