diff --git a/src/basics/Color.h b/src/basics/Color.h index 594dd4c..4cd6293 100644 --- a/src/basics/Color.h +++ b/src/basics/Color.h @@ -31,6 +31,8 @@ public: double getPower() const; void limitPower(double max_power); + Color add(const Color& other) const; + public: double r; double g; diff --git a/src/basics/Color.inline.cpp b/src/basics/Color.inline.cpp index 3d6c601..ff6df17 100644 --- a/src/basics/Color.inline.cpp +++ b/src/basics/Color.inline.cpp @@ -182,3 +182,8 @@ METHSPEC void Color::limitPower(double max_power) b *= factor; } } + +METHSPEC Color Color::add(const Color& other) const +{ + return Color(r + other.r, g + other.g, b + other.b, a); +} diff --git a/src/render/preview/AtmosphereColorPreviewRenderer.cpp b/src/render/preview/AtmosphereColorPreviewRenderer.cpp index 814b1bd..90cd9e0 100644 --- a/src/render/preview/AtmosphereColorPreviewRenderer.cpp +++ b/src/render/preview/AtmosphereColorPreviewRenderer.cpp @@ -2,8 +2,8 @@ #include "SoftwareRenderer.h" #include "AtmosphereRenderer.h" +#include "AtmosphereResult.h" #include "CameraDefinition.h" -#include "tools/lighting.h" #include "SurfaceMaterial.h" #include "Scenery.h" #include "BasePreview.h" @@ -180,13 +180,13 @@ Color AtmosphereColorPreviewRenderer::getColor2D(double x, double y, double) normal = rotation.transform(normal); hit = rotation.transform(hit); - color = this->applyLightingToSurface(this, hit, normal, &MOUNT_MATERIAL); - return this->atmosphere->applyAerialPerspective(this, hit, color).final; + color = applyLightingToSurface(hit, normal, MOUNT_MATERIAL); + return applyMediumTraversal(hit, color); } else { direction = rotation.transform(direction); - return this->atmosphere->getSkyColor(this, direction).final; + return getAtmosphereRenderer()->getSkyColor(direction).final; } } diff --git a/src/render/preview/CloudsAspectPreviewRenderer.cpp b/src/render/preview/CloudsAspectPreviewRenderer.cpp index 3d460e5..9f2df0d 100644 --- a/src/render/preview/CloudsAspectPreviewRenderer.cpp +++ b/src/render/preview/CloudsAspectPreviewRenderer.cpp @@ -1,15 +1,17 @@ #include "CloudsAspectPreviewRenderer.h" -#include "atmosphere/public.h" #include "BasePreview.h" #include "Scenery.h" #include "CloudsDefinition.h" #include "CloudLayerDefinition.h" #include "CloudsRenderer.h" +#include "LightStatus.h" +#include "LightComponent.h" +#include "AtmosphereResult.h" static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int) { - LightDefinition light; + LightComponent light; light.color.r = 0.5; light.color.g = 0.5; @@ -17,7 +19,7 @@ static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int) light.direction = Vector3(-1.0, 0.5, 1.0).normalize(); light.altered = 1; light.reflection = 0.0; - lightingPushLight(status, &light); + status->pushComponent(light); light.color.r = 0.1; light.color.g = 0.1; @@ -25,7 +27,7 @@ static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int) light.direction = Vector3(1.0, -0.5, -1.0).normalize(); light.altered = 0; light.reflection = 0.0; - lightingPushLight(status, &light); + status->pushComponent(light); } static double _getDensity(Renderer*, CloudLayerDefinition* layer, Vector3 location) @@ -81,8 +83,8 @@ void CloudsAspectPreviewRenderer::updateEvent() prepare(); //clouds->getLayerDensity = _getDensity; - atmosphere->getLightingStatus = _getLightingStatus; - atmosphere->applyAerialPerspective = _fakeApplyAerialPerspective; + //atmosphere->getLightingStatus = _getLightingStatus; + //atmosphere->applyAerialPerspective = _fakeApplyAerialPerspective; } Color CloudsAspectPreviewRenderer::getColor2D(double x, double y, double) diff --git a/src/render/preview/CloudsCoveragePreviewRenderer.cpp b/src/render/preview/CloudsCoveragePreviewRenderer.cpp index 8fbbe68..6c6b43f 100644 --- a/src/render/preview/CloudsCoveragePreviewRenderer.cpp +++ b/src/render/preview/CloudsCoveragePreviewRenderer.cpp @@ -6,11 +6,6 @@ #include "CloudLayerDefinition.h" #include "CloudsRenderer.h" -Color _fakeApplyLightingToSurface(Renderer*, Vector3, Vector3, SurfaceMaterial*) -{ - return COLOR_WHITE; -} - CloudsCoveragePreviewRenderer::CloudsCoveragePreviewRenderer(CloudLayerDefinition* layer): layer(layer) { @@ -31,7 +26,6 @@ void CloudsCoveragePreviewRenderer::updateEvent() { layer->copy(getScenery()->getClouds()->getCloudLayer(0)); prepare(); - applyLightingToSurface = _fakeApplyLightingToSurface; } Color CloudsCoveragePreviewRenderer::getColor2D(double x, double y, double scaling) @@ -70,3 +64,8 @@ void CloudsCoveragePreviewRenderer::toggleChangeEvent(const std::string &key, bo perspective = value; } } + +Color CloudsCoveragePreviewRenderer::applyLightingToSurface(const Vector3 &, const Vector3 &, const SurfaceMaterial &) +{ + return COLOR_WHITE; +} diff --git a/src/render/preview/CloudsCoveragePreviewRenderer.h b/src/render/preview/CloudsCoveragePreviewRenderer.h index fc1c558..10c4975 100644 --- a/src/render/preview/CloudsCoveragePreviewRenderer.h +++ b/src/render/preview/CloudsCoveragePreviewRenderer.h @@ -19,6 +19,8 @@ public: virtual void toggleChangeEvent(const std::string &key, bool value) override; + virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material) override; + private: bool perspective; CloudLayerDefinition* layer; diff --git a/src/render/preview/SceneryTopDownPreviewRenderer.cpp b/src/render/preview/SceneryTopDownPreviewRenderer.cpp index 8cae985..da88b76 100644 --- a/src/render/preview/SceneryTopDownPreviewRenderer.cpp +++ b/src/render/preview/SceneryTopDownPreviewRenderer.cpp @@ -4,12 +4,6 @@ #include "BasePreview.h" #include "Scenery.h" -// TEMP -#include "atmosphere/public.h" -#include "tools/lighting.h" -#include "terrain/public.h" -#include "water/public.h" - static Vector3 _getCameraLocation(Renderer*, Vector3 location) { return v3Add(location, v3Scale(VECTOR_UP, 50.0)); diff --git a/src/render/preview/TerrainShapePreviewRenderer.cpp b/src/render/preview/TerrainShapePreviewRenderer.cpp index 3304a7f..5fc4b55 100644 --- a/src/render/preview/TerrainShapePreviewRenderer.cpp +++ b/src/render/preview/TerrainShapePreviewRenderer.cpp @@ -6,16 +6,12 @@ #include "SurfaceMaterial.h" #include "NoiseGenerator.h" #include "BasePreview.h" - -// TEMP -#include "atmosphere/public.h" -#include "tools/lighting.h" -#include "textures/public.h" -#include "water/public.h" +#include "LightComponent.h" +#include "LightStatus.h" static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int) { - LightDefinition light; + LightComponent light; light.color.r = 0.6; light.color.g = 0.6; @@ -26,7 +22,7 @@ static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int) light.direction = v3Normalize(light.direction); light.altered = 1; light.reflection = 0.0; - lightingPushLight(status, &light); + status->pushComponent(light); light.color.r = 0.2; light.color.g = 0.2; @@ -37,7 +33,7 @@ static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int) light.direction = v3Normalize(light.direction); light.altered = 0; light.reflection = 0.0; - lightingPushLight(status, &light); + status->pushComponent(light); } static Vector3 _getCameraLocation(Renderer*, Vector3 location) diff --git a/src/render/preview/WaterAspectPreviewRenderer.cpp b/src/render/preview/WaterAspectPreviewRenderer.cpp index 8b9094c..f0a4319 100644 --- a/src/render/preview/WaterAspectPreviewRenderer.cpp +++ b/src/render/preview/WaterAspectPreviewRenderer.cpp @@ -5,17 +5,12 @@ #include "WaterDefinition.h" #include "CameraDefinition.h" -// TEMP -#include "water/public.h" -#include "terrain/public.h" -#include "atmosphere/public.h" - static double _getWaterHeight(Renderer*) { return 0.0; } -static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int, int, int, int) +static RayCastingResult _rayWalking(SoftwareRenderer* renderer, Vector3 location, Vector3 direction, int, int, int, int) { RayCastingResult result; int background = *(int*)renderer->customData[1]; @@ -49,13 +44,14 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector if (result.hit_location.y < 0.0) { - if (result.hit_location.y < -renderer->water->definition->lighting_depth) + double lighting_depth = renderer->getScenery()->getWater()->lighting_depth; + if (result.hit_location.y < -lighting_depth) { result.hit_color = COLOR_BLACK; } else { - double attenuation = -result.hit_location.y / renderer->water->definition->lighting_depth; + double attenuation = -result.hit_location.y / lighting_depth; result.hit_color.r *= 1.0 - attenuation; result.hit_color.g *= 1.0 - attenuation; result.hit_color.b *= 1.0 - attenuation; @@ -119,9 +115,9 @@ void WaterAspectPreviewRenderer::updateEvent() getScenery()->getCamera()->setTarget(VECTOR_ZERO); prepare(); - terrain->getWaterHeight = _getWaterHeight; - atmosphere->getLightingStatus = _getLightingStatus; - rayWalking = _rayWalking; + //terrain->getWaterHeight = _getWaterHeight; + //atmosphere->getLightingStatus = _getLightingStatus; + //rayWalking = _rayWalking; getPrecision = _getPrecision; } diff --git a/src/render/preview/WaterCoveragePreviewRenderer.cpp b/src/render/preview/WaterCoveragePreviewRenderer.cpp index 04af2bb..f3a26df 100644 --- a/src/render/preview/WaterCoveragePreviewRenderer.cpp +++ b/src/render/preview/WaterCoveragePreviewRenderer.cpp @@ -3,11 +3,10 @@ #include "BasePreview.h" #include "Scenery.h" #include "TerrainDefinition.h" +#include "WaterRenderer.h" // TEMP #include "RenderingScenery.h" -#include "terrain/public.h" -#include "water/public.h" WaterCoveragePreviewRenderer::WaterCoveragePreviewRenderer(WaterDefinition* definition): TerrainShapePreviewRenderer(new TerrainDefinition(NULL)), definition(definition) @@ -44,14 +43,13 @@ void WaterCoveragePreviewRenderer::updateEvent() TerrainShapePreviewRenderer::updateEvent(); getScenery()->setWater(definition); - WaterRendererClass.bind(this, definition); } Color WaterCoveragePreviewRenderer::getWaterColor(double x, double y, double) { Color base; - base = water->getResult(this, x, y).final; + base = getWaterRenderer()->getResult(x, y).final; if (highlight) { diff --git a/src/render/software/AtmosphereModelBruneton.cpp b/src/render/software/AtmosphereModelBruneton.cpp index 5fef2d8..01a4588 100644 --- a/src/render/software/AtmosphereModelBruneton.cpp +++ b/src/render/software/AtmosphereModelBruneton.cpp @@ -1,12 +1,5 @@ #include "AtmosphereModelBruneton.h" -/* Factor to convert software units to kilometers */ -#define WORLD_SCALING 0.05 -#define SUN_DISTANCE 149597870.0 -#define SUN_DISTANCE_SCALED (SUN_DISTANCE / WORLD_SCALING) -#define SUN_RADIUS 6.955e5 -#define SUN_RADIUS_SCALED (SUN_RADIUS / WORLD_SCALING) - /* * Atmospheric scattering, based on E. Bruneton and F.Neyret work. * http://evasion.inrialpes.fr/~Eric.Bruneton/ @@ -18,12 +11,26 @@ #include #include "System.h" #include "PackStream.h" +#include "Scenery.h" #include "AtmosphereDefinition.h" +#include "AtmosphereRenderer.h" +#include "SoftwareRenderer.h" +#include "WaterRenderer.h" +#include "LightComponent.h" +#include "LightStatus.h" #include "tools/cache.h" #include "tools/texture.h" #include "tools/parallel.h" #include "renderer.h" -#include "water/public.h" + +/* Factor to convert software units to kilometers */ +// TODO This is copied in AtmosphereRenderer +#define SPHERE_SIZE 20000.0 +#define WORLD_SCALING 0.05 +#define SUN_DISTANCE 149597870.0 +#define SUN_DISTANCE_SCALED (SUN_DISTANCE / WORLD_SCALING) +#define SUN_RADIUS 6.955e5 +#define SUN_RADIUS_SCALED (SUN_RADIUS / WORLD_SCALING) /*********************** Constants ***********************/ @@ -1157,14 +1164,14 @@ int brunetonInit() static const int _init = brunetonInit(); -AtmosphereModelBruneton::AtmosphereModelBruneton(AtmosphereRenderer *parent): +AtmosphereModelBruneton::AtmosphereModelBruneton(SoftwareRenderer *parent): parent(parent) { } -AtmosphereResult getSkyColor(const Vector3 &eye, const Vector3 &direction, const Vector3 &sun_position, const Color &) +AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &) { - double yoffset = GROUND_OFFSET - renderer->water->getHeightInfo(renderer).base_height; + double yoffset = GROUND_OFFSET - parent->getWaterRenderer()->getHeightInfo().base_height; eye.y += yoffset; if (eye.y < 0.0) { @@ -1180,9 +1187,8 @@ AtmosphereResult getSkyColor(const Vector3 &eye, const Vector3 &direction, const AtmosphereResult result; Vector3 attenuation; - Color sunColor = _sunColor(v, s, r, mu, renderer->atmosphere->definition->sun_radius); /* L0 */ + Color sunColor = _sunColor(v, s, r, mu, parent->getScenery()->getAtmosphere()->sun_radius); /* L0 */ - atmosphereInitResult(&result); /*result.base.r = base.r + sunColor.r; result.base.g = base.g + sunColor.g; result.base.b = base.b + sunColor.b;*/ @@ -1191,17 +1197,17 @@ AtmosphereResult getSkyColor(const Vector3 &eye, const Vector3 &direction, const /* TODO Use atmosphere attenuation */ result.distance = SPHERE_SIZE; - atmosphereUpdateResult(&result); + result.updateFinal(); return result; } -AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &base) +AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 location, const Color &base) { - Vector3 eye = renderer->getCameraLocation(renderer, location); - Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), SUN_DISTANCE); + Vector3 eye = parent->getCameraLocation(parent, location); + Vector3 sun_position = v3Scale(parent->getAtmosphereRenderer()->getSunDirection(), SUN_DISTANCE); - double yoffset = GROUND_OFFSET - renderer->water->getHeightInfo(renderer).base_height; + double yoffset = GROUND_OFFSET - parent->getWaterRenderer()->getHeightInfo().base_height; eye.y += yoffset; location.y += yoffset; if (eye.y < 0.0) @@ -1230,8 +1236,6 @@ AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &ba AtmosphereResult result; Vector3 attenuation; - atmosphereInitResult(&result); - result.base = base; result.inscattering = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */ result.attenuation.r = attenuation.x; @@ -1239,19 +1243,19 @@ AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &ba result.attenuation.b = attenuation.z; result.distance = t / WORLD_SCALING; - atmosphereUpdateResult(&result); + result.updateFinal(); return result; } -void fillLightingStatus(LightStatus *status, const Vector3 &, int) +void AtmosphereModelBruneton::fillLightingStatus(LightStatus *status, const Vector3 &, int) { - LightDefinition sun, irradiance; + LightComponent sun, irradiance; double muS; - double altitude = lightingGetStatusLocation(status).y; + double altitude = status->getLocation().y; - double yoffset = GROUND_OFFSET - renderer->water->getHeightInfo(renderer).base_height; + double yoffset = GROUND_OFFSET - parent->getWaterRenderer()->getHeightInfo().base_height; altitude += yoffset; if (altitude < 0.0) { @@ -1260,7 +1264,7 @@ void fillLightingStatus(LightStatus *status, const Vector3 &, int) double r0 = Rg + altitude * WORLD_SCALING; Vector3 up = {0.0, 1.0, 0.0}; - Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), SUN_DISTANCE); + Vector3 sun_position = v3Scale(parent->getAtmosphereRenderer()->getSunDirection(), SUN_DISTANCE); Vector3 x = {0.0, r0, 0.0}; Vector3 s = v3Normalize(v3Sub(sun_position, x)); @@ -1270,12 +1274,12 @@ void fillLightingStatus(LightStatus *status, const Vector3 &, int) sun.reflection = ISun; sun.altered = 1; - lightingPushLight(status, &sun); + status->pushComponent(sun); irradiance.color = _irradiance(_irradianceTexture, r0, muS); irradiance.direction = VECTOR_DOWN; irradiance.reflection = 0.0; irradiance.altered = 0; - lightingPushLight(status, &irradiance); + status->pushComponent(irradiance); } diff --git a/src/render/software/AtmosphereModelBruneton.h b/src/render/software/AtmosphereModelBruneton.h index 747b195..71d768c 100644 --- a/src/render/software/AtmosphereModelBruneton.h +++ b/src/render/software/AtmosphereModelBruneton.h @@ -11,14 +11,14 @@ namespace software { class SOFTWARESHARED_EXPORT AtmosphereModelBruneton { public: - AtmosphereModelBruneton(AtmosphereRenderer *parent); + AtmosphereModelBruneton(SoftwareRenderer *parent); - AtmosphereResult getSkyColor(const Vector3 &eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base); - AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &base); + AtmosphereResult getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base); + AtmosphereResult applyAerialPerspective(Vector3 location, const Color &base); void fillLightingStatus(LightStatus *status, const Vector3 &normal, int opaque); private: - AtmosphereRenderer* parent; + SoftwareRenderer* parent; }; } diff --git a/src/render/software/AtmosphereRenderer.cpp b/src/render/software/AtmosphereRenderer.cpp index 25c62b2..ca469f5 100644 --- a/src/render/software/AtmosphereRenderer.cpp +++ b/src/render/software/AtmosphereRenderer.cpp @@ -3,8 +3,19 @@ #include #include "SoftwareRenderer.h" #include "AtmosphereDefinition.h" +#include "AtmosphereModelBruneton.h" +#include "AtmosphereResult.h" +#include "LightComponent.h" +#include "LightStatus.h" #include "Scenery.h" +/* Factor to convert software units to kilometers */ +#define WORLD_SCALING 0.05 +#define SUN_DISTANCE 149597870.0 +#define SUN_DISTANCE_SCALED (SUN_DISTANCE / WORLD_SCALING) +#define SUN_RADIUS 6.955e5 +#define SUN_RADIUS_SCALED (SUN_RADIUS / WORLD_SCALING) + static inline double _getDayFactor(double daytime) { daytime = 1.0 - fabs(0.5 - daytime) / 0.5; @@ -53,7 +64,7 @@ static inline void _applyWeatherEffects(AtmosphereDefinition* definition, Atmosp result->attenuation.g *= 1.0 - 0.4 * distancefactor * definition->humidity; result->attenuation.b *= 1.0 - 0.4 * distancefactor * definition->humidity; - atmosphereUpdateResult(result); + result->updateFinal(); } @@ -65,7 +76,7 @@ BaseAtmosphereRenderer::BaseAtmosphereRenderer(SoftwareRenderer* renderer): void BaseAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3, int) { - LightDefinition light; + LightComponent light; light.color.r = 1.0; light.color.g = 1.0; @@ -75,7 +86,7 @@ void BaseAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3, int light.direction.z = 0.7; light.altered = 0; light.reflection = 0.0; - lightingPushLight(status, &light); + status->pushComponent(light); light.color.r = 0.3; light.color.g = 0.31; light.color.b = 0.34; @@ -84,7 +95,7 @@ void BaseAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3, int light.direction.z = -0.7; light.altered = 0; light.reflection = 0.0; - lightingPushLight(status, &light); + status->pushComponent(light); } AtmosphereResult BaseAtmosphereRenderer::applyAerialPerspective(Vector3, Color base) @@ -115,9 +126,20 @@ AtmosphereDefinition* BaseAtmosphereRenderer::getDefinition() return renderer->getScenery()->getAtmosphere(); } +SoftwareBrunetonAtmosphereRenderer::SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer): + BaseAtmosphereRenderer(renderer) +{ + model = new AtmosphereModelBruneton(this); +} + +SoftwareBrunetonAtmosphereRenderer::~SoftwareBrunetonAtmosphereRenderer() +{ + delete model; +} + void SoftwareBrunetonAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3 normal, int opaque) { - return brunetonGetLightingStatus(renderer, status, normal, opaque); + return model->fillLightingStatus(status, normal, opaque); } AtmosphereResult SoftwareBrunetonAtmosphereRenderer::applyAerialPerspective(Vector3 location, Color base) @@ -129,7 +151,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::applyAerialPerspective(Vect switch (definition->model) { case AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON: - result = brunetonApplyAerialPerspective(renderer, location, base); + result = model->applyAerialPerspective(location, base); break; default: ; @@ -188,7 +210,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(Vector3 directi switch (definition->model) { case AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON: - result = brunetonGetSkyColor(renderer, camera_location, direction, sun_position, base); + result = model->getSkyColor(camera_location, direction, sun_position, base); break; default: result = BaseAtmosphereRenderer::applyAerialPerspective(location, result.base); diff --git a/src/render/software/AtmosphereRenderer.h b/src/render/software/AtmosphereRenderer.h index ff24ba9..ee619f6 100644 --- a/src/render/software/AtmosphereRenderer.h +++ b/src/render/software/AtmosphereRenderer.h @@ -3,6 +3,8 @@ #include "software_global.h" +#include "Color.h" + namespace paysages { namespace software { @@ -25,11 +27,15 @@ protected: class SoftwareBrunetonAtmosphereRenderer: public BaseAtmosphereRenderer { public: - SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer):BaseAtmosphereRenderer(renderer) {} + SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer); + virtual ~SoftwareBrunetonAtmosphereRenderer(); virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque) override; virtual AtmosphereResult applyAerialPerspective(Vector3 location, Color base) override; virtual AtmosphereResult getSkyColor(Vector3 direction) override; + +private: + AtmosphereModelBruneton* model; }; } diff --git a/src/render/software/BaseCloudLayerRenderer.cpp b/src/render/software/BaseCloudLayerRenderer.cpp index 05f28a3..70a79d0 100644 --- a/src/render/software/BaseCloudLayerRenderer.cpp +++ b/src/render/software/BaseCloudLayerRenderer.cpp @@ -1,6 +1,7 @@ #include "BaseCloudLayerRenderer.h" #include "clouds/BaseCloudsModel.h" +#include "Vector3.h" BaseCloudLayerRenderer::BaseCloudLayerRenderer(SoftwareRenderer* parent): parent(parent) @@ -17,7 +18,7 @@ Color BaseCloudLayerRenderer::getColor(BaseCloudsModel *, const Vector3 &, const return COLOR_TRANSPARENT; } -bool BaseCloudLayerRenderer::alterLight(BaseCloudsModel *, LightDefinition *, const Vector3 &, const Vector3 &) +bool BaseCloudLayerRenderer::alterLight(BaseCloudsModel *, LightComponent *, const Vector3 &, const Vector3 &) { return false; } diff --git a/src/render/software/BaseCloudLayerRenderer.h b/src/render/software/BaseCloudLayerRenderer.h index 5b229bf..bc8e714 100644 --- a/src/render/software/BaseCloudLayerRenderer.h +++ b/src/render/software/BaseCloudLayerRenderer.h @@ -3,8 +3,6 @@ #include "software_global.h" -#include "tools/lighting.h" - namespace paysages { namespace software { @@ -17,7 +15,7 @@ public: virtual bool optimizeSearchLimits(BaseCloudsModel *model, Vector3 *start, Vector3 *end); virtual Color getColor(BaseCloudsModel *model, const Vector3 &eye, const Vector3 &location); - virtual bool alterLight(BaseCloudsModel *model, LightDefinition* light, const Vector3 &eye, const Vector3 &location); + virtual bool alterLight(BaseCloudsModel *model, LightComponent* light, const Vector3 &eye, const Vector3 &location); protected: SoftwareRenderer* parent; diff --git a/src/render/software/CloudBasicLayerRenderer.cpp b/src/render/software/CloudBasicLayerRenderer.cpp index c2633a3..0c4f810 100644 --- a/src/render/software/CloudBasicLayerRenderer.cpp +++ b/src/render/software/CloudBasicLayerRenderer.cpp @@ -5,6 +5,8 @@ #include "NoiseGenerator.h" #include "Curve.h" #include "AtmosphereRenderer.h" +#include "AtmosphereResult.h" +#include "LightComponent.h" #include "clouds/BaseCloudsModel.h" #include "SurfaceMaterial.h" @@ -171,7 +173,7 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e material.shininess = 0.8; materialValidate(&material); - col = parent->applyLightingToSurface(parent, segments[i].start, parent->getAtmosphereRenderer()->getSunDirection(), &material); + col = parent->applyLightingToSurface(segments[i].start, parent->getAtmosphereRenderer()->getSunDirection(), material); col.a = (segments[i].length >= transparency_depth) ? 1.0 : (segments[i].length / transparency_depth); colorMask(&result, &col); @@ -188,7 +190,7 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e return result; } -bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightDefinition* light, const Vector3 &, const Vector3 &location) +bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightComponent* light, const Vector3 &, const Vector3 &location) { Vector3 start, end; double inside_depth, total_depth, factor; diff --git a/src/render/software/CloudBasicLayerRenderer.h b/src/render/software/CloudBasicLayerRenderer.h index 4236191..83305f2 100644 --- a/src/render/software/CloudBasicLayerRenderer.h +++ b/src/render/software/CloudBasicLayerRenderer.h @@ -5,8 +5,6 @@ #include "BaseCloudLayerRenderer.h" -#include "tools/lighting.h" - namespace paysages { namespace software { @@ -22,7 +20,7 @@ public: CloudBasicLayerRenderer(SoftwareRenderer* parent); virtual Color getColor(BaseCloudsModel *model, const Vector3 &eye, const Vector3 &location) override; - virtual bool alterLight(BaseCloudsModel *model, LightDefinition* light, const Vector3 &eye, const Vector3 &location) override; + virtual bool alterLight(BaseCloudsModel *model, LightComponent* light, const Vector3 &eye, const Vector3 &location) override; }; } diff --git a/src/render/software/CloudsRenderer.cpp b/src/render/software/CloudsRenderer.cpp index e9e7bec..e88eb17 100644 --- a/src/render/software/CloudsRenderer.cpp +++ b/src/render/software/CloudsRenderer.cpp @@ -132,7 +132,7 @@ Color CloudsRenderer::getColor(const Vector3 &eye, const Vector3 &location, cons return cumul; } -bool CloudsRenderer::alterLight(LightDefinition* light, const Vector3 &eye, const Vector3 &location) +bool CloudsRenderer::alterLight(LightComponent* light, const Vector3 &eye, const Vector3 &location) { CloudsDefinition* definition = parent->getScenery()->getClouds(); diff --git a/src/render/software/CloudsRenderer.h b/src/render/software/CloudsRenderer.h index 891e3dd..60daca8 100644 --- a/src/render/software/CloudsRenderer.h +++ b/src/render/software/CloudsRenderer.h @@ -3,8 +3,6 @@ #include "software_global.h" -#include "tools/lighting.h" - namespace paysages { namespace software { @@ -48,7 +46,7 @@ public: * * Return true if the light was altered. */ - virtual bool alterLight(LightDefinition* light, const Vector3 &eye, const Vector3 &location); + virtual bool alterLight(LightComponent* light, const Vector3 &eye, const Vector3 &location); private: SoftwareRenderer* parent; diff --git a/src/render/software/LightStatus.cpp b/src/render/software/LightStatus.cpp index 262e04d..cceac2e 100644 --- a/src/render/software/LightStatus.cpp +++ b/src/render/software/LightStatus.cpp @@ -1,5 +1,9 @@ #include "LightStatus.h" +#include "LightingManager.h" +#include "Color.h" +#include "SurfaceMaterial.h" + LightStatus::LightStatus(LightingManager *manager, const Vector3 &location, const Vector3 &eye) { this->manager = manager; @@ -9,21 +13,21 @@ LightStatus::LightStatus(LightingManager *manager, const Vector3 &location, cons void LightStatus::pushComponent(LightComponent component) { - if (manager->filter(&component, location)) + if (manager->alterLight(component, location)) { - components.add(component); + components.push_back(component); } } Color LightStatus::apply(const Vector3 &normal, const SurfaceMaterial &material) { - Color final(); + Color final; for (auto component: components) { - final.add(manager->applyFinalComponent(component, eye, location, normal, material)); + final = final.add(manager->applyFinalComponent(component, eye, location, normal, material)); } - final.a = material->base.a; + final.a = material.base.a; return final; } diff --git a/src/render/software/LightStatus.h b/src/render/software/LightStatus.h index 5bbc3b3..048bd31 100644 --- a/src/render/software/LightStatus.h +++ b/src/render/software/LightStatus.h @@ -18,8 +18,12 @@ class SOFTWARESHARED_EXPORT LightStatus public: LightStatus(LightingManager *manager, const Vector3 &location, const Vector3 &eye); + inline Vector3 getLocation() const {return location;} + void pushComponent(LightComponent component); + Color apply(const Vector3 &normal, const SurfaceMaterial &material); + private: LightingManager* manager; Vector3 location; diff --git a/src/render/software/LightingManager.cpp b/src/render/software/LightingManager.cpp index cff702e..e15d2ff 100644 --- a/src/render/software/LightingManager.cpp +++ b/src/render/software/LightingManager.cpp @@ -3,6 +3,7 @@ #include "LightFilter.h" #include "LightComponent.h" #include "Color.h" +#include "SurfaceMaterial.h" LightingManager::LightingManager() { @@ -11,10 +12,7 @@ LightingManager::LightingManager() void LightingManager::registerFilter(LightFilter* filter) { - if (not filters.contains(filter)) - { - filters.add(filter); - } + filters.insert(filter); } bool LightingManager::alterLight(LightComponent &component, const Vector3 &location) @@ -23,7 +21,7 @@ bool LightingManager::alterLight(LightComponent &component, const Vector3 &locat { for (auto filter:filters) { - if (not filter.app(component, location)) + if (not filter->applyLightFilter(component, location)) { return false; } @@ -43,43 +41,42 @@ void LightingManager::setSpecularity(bool enabled) specularity = enabled; } -void applyFinalComponent(const LightComponent &component, const Vector3 &eye, const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material) +Color LightingManager::applyFinalComponent(const LightComponent &component, const Vector3 &eye, const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material) { Color result, light_color; double normal_norm; Vector3 direction_inv; - light_color = component->color; - direction_inv = v3Scale(v3Normalize(component->direction), -1.0); + light_color = component.color; + direction_inv = v3Scale(v3Normalize(component.direction), -1.0); normal_norm = v3Norm(normal); if (normal_norm > 1.0) { normal_norm = 1.0; } - normal = v3Normalize(normal); result = COLOR_BLACK; /* diffused light */ - double diffuse = v3Dot(direction_inv, normal); + double diffuse = v3Dot(direction_inv, normal.normalize()); diffuse = (diffuse + (1.0 - normal_norm)) / (1.0 + (1.0 - normal_norm)); if (diffuse > 0.0) { - result.r += diffuse * material->_rgb.r * light_color.r; - result.g += diffuse * material->_rgb.g * light_color.g; - result.b += diffuse * material->_rgb.b * light_color.b; + result.r += diffuse * material._rgb.r * light_color.r; + result.g += diffuse * material._rgb.g * light_color.g; + result.b += diffuse * material._rgb.b * light_color.b; } /* specular reflection */ - if (material->reflection > 0.0 && light->reflection > 0.0) + if (material.reflection > 0.0 && component.reflection > 0.0) { Vector3 view = v3Normalize(v3Sub(location, eye)); Vector3 reflect = v3Sub(direction_inv, v3Scale(normal, 2.0 * v3Dot(direction_inv, normal))); double specular = v3Dot(reflect, view); if (specular > 0.0) { - specular = pow(specular, material->shininess) * material->reflection * light->reflection * normal_norm; + specular = pow(specular, material.shininess) * material.reflection * component.reflection * normal_norm; if (specular > 0.0) { result.r += specular * light_color.r; diff --git a/src/render/software/LightingManager.h b/src/render/software/LightingManager.h index b26b9e2..2d9d9d6 100644 --- a/src/render/software/LightingManager.h +++ b/src/render/software/LightingManager.h @@ -3,6 +3,8 @@ #include "software_global.h" +#include + namespace paysages { namespace software { @@ -35,12 +37,12 @@ public: /** * @brief Apply a final component on a surface material. */ - void applyFinalComponent(const LightComponent &component, const Vector3 &eye, const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material); + Color applyFinalComponent(const LightComponent &component, const Vector3 &eye, const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material); private: int specularity; - std::vector filters; + std::set filters; }; } diff --git a/src/render/software/SkyRasterizer.cpp b/src/render/software/SkyRasterizer.cpp index f829288..156cb4b 100644 --- a/src/render/software/SkyRasterizer.cpp +++ b/src/render/software/SkyRasterizer.cpp @@ -4,6 +4,7 @@ #include "Color.h" #include "SoftwareRenderer.h" #include "AtmosphereRenderer.h" +#include "AtmosphereResult.h" #include "CloudsRenderer.h" #define SPHERE_SIZE 20000.0 @@ -22,7 +23,7 @@ static Color _postProcessFragment(SoftwareRenderer* renderer, Vector3 location, direction = v3Sub(location, camera_location); /* TODO Don't compute result->color if it's fully covered by clouds */ - result = renderer->atmosphere->getSkyColor(renderer, v3Normalize(direction)).final; + result = renderer->getAtmosphereRenderer()->getSkyColor(v3Normalize(direction)).final; result = renderer->getCloudsRenderer()->getColor(camera_location, v3Add(camera_location, v3Scale(direction, 10.0)), result); return result; diff --git a/src/render/software/SoftwareRenderer.cpp b/src/render/software/SoftwareRenderer.cpp index 5bf7f2d..dc5d042 100644 --- a/src/render/software/SoftwareRenderer.cpp +++ b/src/render/software/SoftwareRenderer.cpp @@ -5,51 +5,20 @@ #include "FluidMediumManager.h" #include "AtmosphereRenderer.h" #include "AtmosphereDefinition.h" +#include "AtmosphereResult.h" #include "CloudsRenderer.h" +#include "TerrainRenderer.h" +#include "TexturesRenderer.h" +#include "WaterRenderer.h" #include "SkyRasterizer.h" #include "TerrainRasterizer.h" #include "WaterRasterizer.h" +#include "LightStatus.h" +#include "LightingManager.h" // Legacy compatibility #include "renderer.h" -#include "terrain/public.h" -#include "textures/public.h" -#include "water/public.h" -static AtmosphereResult _legacyApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base) -{ - return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->applyAerialPerspective(location, base); -} -static AtmosphereResult _legacyGetSkyColor(Renderer* renderer, Vector3 direction) -{ - return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->getSkyColor(direction); -} -static void _legacyGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque) -{ - return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->getLightingStatus(status, normal, opaque); -} -static Vector3 _legacyGetSunDirection(Renderer* renderer) -{ - return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->getSunDirection(); -} -static RayCastingResult _rayWalking(Renderer* renderer_, Vector3 location, Vector3 direction, int, int, int, int) -{ - SoftwareRenderer* renderer = (SoftwareRenderer*)renderer_; - RayCastingResult result; - Color sky_color; - - result = renderer->terrain->castRay(renderer, location, direction); - if (!result.hit) - { - sky_color = renderer->atmosphere->getSkyColor(renderer, direction).final; - - result.hit = 1; - result.hit_location = v3Add(location, v3Scale(direction, 1000.0)); - result.hit_color = renderer->getCloudsRenderer()->getColor(location, result.hit_location, sky_color); - } - - return result; -} static double _getPrecision(Renderer* renderer, Vector3 location) { Vector3 projected; @@ -65,6 +34,9 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery) { atmosphere_renderer = new BaseAtmosphereRenderer(this); clouds_renderer = new CloudsRenderer(this); + terrain_renderer = new TerrainRenderer(this); + textures_renderer = new TexturesRenderer(this); + water_renderer = new WaterRenderer(this); fluid_medium = new FluidMediumManager(this); @@ -84,6 +56,9 @@ SoftwareRenderer::~SoftwareRenderer() { delete atmosphere_renderer; delete clouds_renderer; + delete terrain_renderer; + delete textures_renderer; + delete water_renderer; delete fluid_medium; @@ -113,21 +88,18 @@ void SoftwareRenderer::prepare() clouds_renderer = new CloudsRenderer(this); clouds_renderer->update(); + delete terrain_renderer; + terrain_renderer = new TerrainRenderer(this); + + delete textures_renderer; + textures_renderer = new TexturesRenderer(this); + + delete water_renderer; + water_renderer = new WaterRenderer(this); + // Setup transitional renderers (for C-legacy subsystems) - rayWalking = _rayWalking; getPrecision = _getPrecision; - scenery->getAtmosphere()->copy(atmosphere->definition); - atmosphere->applyAerialPerspective = _legacyApplyAerialPerspective; - atmosphere->getSkyColor = _legacyGetSkyColor; - atmosphere->getLightingStatus = _legacyGetLightingStatus; - atmosphere->getSunDirection = _legacyGetSunDirection; - - scenery->getCamera()->copy(render_camera); - TerrainRendererClass.bind(this, scenery->getTerrain()); - TexturesRendererClass.bind(this, scenery->getTextures()); - WaterRendererClass.bind(this, scenery->getWater()); - // Prepare global tools fluid_medium->clearMedia(); //fluid_medium->registerMedium(water_renderer); @@ -145,9 +117,16 @@ void SoftwareRenderer::rasterize() sky.rasterize(); } +Color SoftwareRenderer::applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material) +{ + LightStatus status(lighting, location, getCameraLocation(this, location)); + atmosphere_renderer->getLightingStatus(&status, normal, 0); + return status.apply(normal, material); +} + Color SoftwareRenderer::applyMediumTraversal(Vector3 location, Color color) { - color = atmosphere->applyAerialPerspective(this, location, color).final; + color = atmosphere_renderer->applyAerialPerspective(location, color).final; color = clouds_renderer->getColor(getCameraLocation(this, location), location, color); return color; @@ -155,11 +134,20 @@ Color SoftwareRenderer::applyMediumTraversal(Vector3 location, Color color) return fluid_medium->applyTraversal(eye, location, color);*/ } -Color SoftwareRenderer::applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material) +RayCastingResult SoftwareRenderer::rayWalking(const Vector3 &location, const Vector3 &direction, int, int, int, int) { - LightStatus* light = lightingCreateStatus(lighting, location, getCameraLocation(renderer, location)); - atmosphere->getLightingStatus(renderer, light, normal, 0); - Color result = lightingApplyStatus(light, normal, material); - lightingDeleteStatus(light); + RayCastingResult result; + Color sky_color; + + result = terrain_renderer->castRay(location, direction); + if (!result.hit) + { + sky_color = atmosphere_renderer->getSkyColor(direction).final; + + result.hit = 1; + result.hit_location = v3Add(location, v3Scale(direction, 1000.0)); + result.hit_color = clouds_renderer->getColor(location, result.hit_location, sky_color); + } + return result; } diff --git a/src/render/software/SoftwareRenderer.h b/src/render/software/SoftwareRenderer.h index 7d09a0b..9f3dbfa 100644 --- a/src/render/software/SoftwareRenderer.h +++ b/src/render/software/SoftwareRenderer.h @@ -42,18 +42,29 @@ public: inline BaseAtmosphereRenderer* getAtmosphereRenderer() const {return atmosphere_renderer;} inline CloudsRenderer* getCloudsRenderer() const {return clouds_renderer;} + inline TerrainRenderer* getTerrainRenderer() const {return terrain_renderer;} + inline TexturesRenderer* getTexturesRenderer() const {return textures_renderer;} + inline WaterRenderer* getWaterRenderer() const {return water_renderer;} inline FluidMediumManager* getFluidMediumManager() const {return fluid_medium;} + inline LightingManager* getLightingManager() const {return lighting;} - virtual Color applyMediumTraversal(Vector3 location, Color color) override; virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material) override; + virtual Color applyMediumTraversal(Vector3 location, Color color) override; + virtual RayCastingResult rayWalking(const Vector3 &location, const Vector3 &direction, int terrain, int water, int sky, int clouds) override; private: Scenery* scenery; bool own_scenery; + FluidMediumManager* fluid_medium; + LightingManager* lighting; + BaseAtmosphereRenderer* atmosphere_renderer; CloudsRenderer* clouds_renderer; + TerrainRenderer* terrain_renderer; + TexturesRenderer* textures_renderer; + WaterRenderer* water_renderer; }; } diff --git a/src/render/software/TerrainRasterizer.cpp b/src/render/software/TerrainRasterizer.cpp index 2fc964a..8dcb8e0 100644 --- a/src/render/software/TerrainRasterizer.cpp +++ b/src/render/software/TerrainRasterizer.cpp @@ -3,23 +3,24 @@ #include "SoftwareRenderer.h" #include "BoundingBox.h" #include "CameraDefinition.h" +#include "TerrainRenderer.h" +#include "WaterRenderer.h" +#include "TexturesRenderer.h" +#include "Scenery.h" #include "tools/parallel.h" -#include "terrain/public.h" -#include "water/public.h" -#include "textures/public.h" TerrainRasterizer::TerrainRasterizer(SoftwareRenderer* renderer): renderer(renderer) { } -static inline Vector3 _getPoint(TerrainDefinition*, SoftwareRenderer* renderer, double x, double z) +static inline Vector3 _getPoint(SoftwareRenderer* renderer, double x, double z) { Vector3 result; result.x = x; - result.y = renderer->terrain->getHeight(renderer, x, z, 1); + result.y = renderer->getTerrainRenderer()->getHeight(x, z, 1); result.z = z; return result; @@ -30,13 +31,13 @@ static Color _postProcessFragment(Renderer* renderer_, Vector3 point, void*) double precision; SoftwareRenderer* renderer = (SoftwareRenderer*)renderer_; - point = _getPoint(renderer->terrain->definition, renderer, point.x, point.z); + point = _getPoint(renderer, point.x, point.z); precision = renderer->getPrecision(renderer, point); - return renderer->terrain->getFinalColor(renderer, point, precision); + return renderer->getTerrainRenderer()->getFinalColor(point, precision); } -static void _renderQuad(Renderer* renderer, double x, double z, double size, double water_height) +static void _renderQuad(SoftwareRenderer* renderer, double x, double z, double size, double water_height) { Vector3 ov1, ov2, ov3, ov4; Vector3 dv1, dv2, dv3, dv4; @@ -45,19 +46,19 @@ static void _renderQuad(Renderer* renderer, double x, double z, double size, dou ov1.x = x; ov1.z = z; - dv1 = renderer->terrain->getResult(renderer, x, z, 1, 1).location; + dv1 = renderer->getTerrainRenderer()->getResult(x, z, 1, 1).location; ov2.x = x; ov2.z = z + size; - dv2 = renderer->terrain->getResult(renderer, x, z + size, 1, 1).location; + dv2 = renderer->getTerrainRenderer()->getResult(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; + dv3 = renderer->getTerrainRenderer()->getResult(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; + dv4 = renderer->getTerrainRenderer()->getResult(x + size, z, 1, 1).location; if (dv1.y > water_height || dv2.y > water_height || dv3.y > water_height || dv4.y > water_height) { @@ -72,7 +73,7 @@ void TerrainRasterizer::tessellateChunk(TerrainChunkInfo* chunk, int detail) return; } - double water_height = renderer->water->getHeightInfo(renderer).min_height; + double water_height = renderer->getWaterRenderer()->getHeightInfo().min_height; double startx = chunk->point_nw.x; double startz = chunk->point_nw.z; @@ -88,12 +89,12 @@ void TerrainRasterizer::tessellateChunk(TerrainChunkInfo* chunk, int detail) } } -static void _getChunk(Renderer* renderer, TerrainRasterizer::TerrainChunkInfo* chunk, double x, double z, double size, int displaced) +static void _getChunk(SoftwareRenderer* renderer, TerrainRasterizer::TerrainChunkInfo* chunk, double x, double z, double size, int displaced) { - chunk->point_nw = renderer->terrain->getResult(renderer, x, z, 1, displaced).location; - chunk->point_sw = renderer->terrain->getResult(renderer, x, z + size, 1, displaced).location; - chunk->point_se = renderer->terrain->getResult(renderer, x + size, z + size, 1, displaced).location; - chunk->point_ne = renderer->terrain->getResult(renderer, x + size, z, 1, displaced).location; + chunk->point_nw = renderer->getTerrainRenderer()->getResult(x, z, 1, displaced).location; + chunk->point_sw = renderer->getTerrainRenderer()->getResult(x, z + size, 1, displaced).location; + chunk->point_se = renderer->getTerrainRenderer()->getResult(x + size, z + size, 1, displaced).location; + chunk->point_ne = renderer->getTerrainRenderer()->getResult(x + size, z, 1, displaced).location; double displacement_power; if (displaced) @@ -102,7 +103,7 @@ static void _getChunk(Renderer* renderer, TerrainRasterizer::TerrainChunkInfo* c } else { - displacement_power = texturesGetMaximalDisplacement(renderer->textures->definition); + displacement_power = renderer->getTexturesRenderer()->getMaximalDisplacement(renderer->getScenery()->getTextures()); } BoundingBox box; diff --git a/src/render/software/TerrainRenderer.cpp b/src/render/software/TerrainRenderer.cpp new file mode 100644 index 0000000..bccfc67 --- /dev/null +++ b/src/render/software/TerrainRenderer.cpp @@ -0,0 +1,266 @@ +#include "TerrainRenderer.h" + +#include "SoftwareRenderer.h" +#include "Scenery.h" +#include "TerrainDefinition.h" +#include "TexturesRenderer.h" +#include "LightComponent.h" + +TerrainRenderer::TerrainRenderer(SoftwareRenderer* parent): + parent(parent) +{ +} + +TerrainRenderer::~TerrainRenderer() +{ +} + +double TerrainRenderer::getHeight(double x, double z, int with_painting) +{ + return parent->getScenery()->getTerrain()->getInterpolatedHeight(x, z, 1, with_painting); +} + +static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west) +{ + Vector3 dnorth, deast, dsouth, dwest, normal; + + dnorth = v3Sub(north, center); + deast = v3Sub(east, center); + dsouth = v3Sub(south, center); + dwest = v3Sub(west, center); + + normal = v3Cross(deast, dnorth); + normal = v3Add(normal, v3Cross(dsouth, deast)); + normal = v3Add(normal, v3Cross(dwest, dsouth)); + normal = v3Add(normal, v3Cross(dnorth, dwest)); + + return v3Normalize(normal); +} + +static inline Vector3 _getNormal2(Vector3 center, Vector3 east, Vector3 south) +{ + return v3Normalize(v3Cross(v3Sub(south, center), v3Sub(east, center))); +} + +TerrainRenderer::TerrainResult TerrainRenderer::getResult(double x, double z, int with_painting, int with_textures) +{ + TerrainResult result; + double detail = 0.001; /* TODO */ + + /* Normal */ + Vector3 center, north, east, south, west; + + center.x = x; + center.z = z; + center.y = getHeight(center.x, center.z, with_painting); + + east.x = x + detail; + east.z = z; + east.y = getHeight(east.x, east.z, with_painting); + + south.x = x; + south.z = z + detail; + south.y = getHeight(south.x, south.z, with_painting); + + if (parent->render_quality > 6) + { + west.x = x - detail; + west.z = z; + west.y = getHeight(west.x, west.z, with_painting); + + north.x = x; + north.z = z - detail; + north.y = getHeight(north.x, north.z, with_painting); + + result.normal = _getNormal4(center, north, east, south, west); + } + else + { + result.normal = _getNormal2(center, east, south); + } + + /* Location */ + result.location = center; + + /* Texture displacement */ + if (with_textures) + { + center = parent->getTexturesRenderer()->displaceTerrain(result); + result.location = center; + + /* Recompute normal */ + if (parent->render_quality > 6) + { + /* Use 5 points on displaced terrain */ + east = parent->getTexturesRenderer()->displaceTerrain(getResult(east.x, east.z, with_painting, 0)); + south = parent->getTexturesRenderer()->displaceTerrain(getResult(south.x, south.z, with_painting, 0)); + west = parent->getTexturesRenderer()->displaceTerrain(getResult(west.x, west.z, with_painting, 0)); + north = parent->getTexturesRenderer()->displaceTerrain(getResult(north.x, north.z, with_painting, 0)); + + result.normal = _getNormal4(center, north, east, south, west); + } + else if (parent->render_quality > 2) + { + /* Use 3 points on displaced terrain */ + east = parent->getTexturesRenderer()->displaceTerrain(getResult(east.x, east.z, with_painting, 0)); + south = parent->getTexturesRenderer()->displaceTerrain(getResult(south.x, south.z, with_painting, 0)); + + result.normal = _getNormal2(center, east, south); + } + else + { + /* TODO Use texture noise directly, as if terrain was a plane */ + } + } + + return result; +} + +Color TerrainRenderer::getFinalColor(const Vector3 &location, double) +{ + /* TODO Restore precision control */ + TexturesRenderer::TexturesResult textures = parent->getTexturesRenderer()->applyToTerrain(location.x, location.z); + return parent->applyMediumTraversal(textures.final_location, textures.final_color); +} + +RayCastingResult TerrainRenderer::castRay(const Vector3 &start, const Vector3 &direction) +{ + RayCastingResult result; + TerrainDefinition* definition = parent->getScenery()->getTerrain(); + Vector3 inc_vector, direction_norm, cursor; + double inc_value, inc_base, inc_factor, height, diff, lastdiff, length; + + cursor = start; + direction_norm = direction.normalize(); + inc_factor = (double)parent->render_quality; + inc_base = 1.0; + inc_value = inc_base / inc_factor; + lastdiff = start.y - getHeight(start.x, start.z, 1); + + length = 0.0; + do + { + inc_vector = v3Scale(direction_norm, inc_value); + length += v3Norm(inc_vector); + cursor = v3Add(cursor, inc_vector); + height = getHeight(cursor.x, cursor.z, 1); + diff = cursor.y - height; + if (diff < 0.0) + { + if (fabs(diff - lastdiff) > 0.00001) + { + cursor = v3Add(cursor, v3Scale(inc_vector, -diff / (diff - lastdiff))); + cursor.y = getHeight(cursor.x, cursor.z, 1); + } + else + { + cursor.y = height; + } + result.hit = 1; + result.hit_location = cursor; + result.hit_color = getFinalColor(cursor, parent->getPrecision(parent, result.hit_location)); + return result; + } + + if (diff < inc_base / inc_factor) + { + inc_value = inc_base / inc_factor; + } + else if (diff > inc_base) + { + inc_value = inc_base; + } + else + { + inc_value = diff; + } + lastdiff = diff; + } + while (length < 50.0 && cursor.y <= definition->_max_height); + + result.hit = 0; + return result; +} + +int TerrainRenderer::alterLight(LightComponent *light, const Vector3 &location) +{ + TerrainDefinition* definition = parent->getScenery()->getTerrain(); + Vector3 inc_vector, direction_to_light, cursor; + double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length; + + direction_to_light = v3Scale(light->direction, -1.0); + if (direction_to_light.y < -0.05) + { + light->color = COLOR_BLACK; + return 1; + } + else if (direction_to_light.y < 0.0000) + { + light->color.r *= (0.05 + direction_to_light.y) / 0.05; + light->color.g *= (0.05 + direction_to_light.y) / 0.05; + light->color.b *= (0.05 + direction_to_light.y) / 0.05; + } + + cursor = location; + inc_factor = (double)parent->render_quality; + inc_base = definition->height / definition->scaling; + inc_value = inc_base / inc_factor; + smoothing = definition->shadow_smoothing; + + light_factor = 1.0; + length = 0.0; + diff = 0.0; + do + { + inc_vector = v3Scale(direction_to_light, inc_value); + length += v3Norm(inc_vector); + cursor = v3Add(cursor, inc_vector); + height = parent->getTerrainRenderer()->getResult(location.x, location.z, 1, 1).location.y; + diff = location.y - height; + if (diff < 0.0) + { + if (length * smoothing > 0.000001) + { + light_factor += diff * v3Norm(inc_vector) / (length * smoothing); + } + else + { + light_factor = 0.0; + } + } + + if (diff < inc_base / inc_factor) + { + inc_value = inc_base / inc_factor; + } + else if (diff > inc_base) + { + inc_value = inc_base; + } + else + { + inc_value = diff; + } + } + while (light_factor > 0.0 && length < (10.0 * inc_factor) && location.y <= definition->_max_height); + + if (light_factor <= 0.0) + { + light->color = COLOR_BLACK; + return 1; + } + else + { + light->color.r *= light_factor; + light->color.g *= light_factor; + light->color.b *= light_factor; + + return 1; + } +} + +double TerrainRenderer::getWaterHeight() +{ + TerrainDefinition* terrain = parent->getScenery()->getTerrain(); + return terrain->water_height * terrain->height * terrain->scaling; +} diff --git a/src/render/software/TerrainRenderer.h b/src/render/software/TerrainRenderer.h new file mode 100644 index 0000000..5a9fe9b --- /dev/null +++ b/src/render/software/TerrainRenderer.h @@ -0,0 +1,38 @@ +#ifndef TERRAINRENDERER_H +#define TERRAINRENDERER_H + +#include "software_global.h" + +#include "shared/types.h" + +namespace paysages { +namespace software { + +class SOFTWARESHARED_EXPORT TerrainRenderer +{ +public: + typedef struct + { + Vector3 location; + Vector3 normal; + } TerrainResult; + +public: + TerrainRenderer(SoftwareRenderer* parent); + virtual ~TerrainRenderer(); + + virtual RayCastingResult castRay(const Vector3 &start, const Vector3 &direction); + virtual double getHeight(double x, double z, int with_painting); + virtual TerrainResult getResult(double x, double z, int with_painting, int with_textures); + virtual Color getFinalColor(const Vector3 &location, double precision); + virtual double getWaterHeight(); + virtual int alterLight(LightComponent *light, const Vector3 &location); + +private: + SoftwareRenderer* parent; +}; + +} +} + +#endif // TERRAINRENDERER_H diff --git a/src/render/software/TexturesRenderer.cpp b/src/render/software/TexturesRenderer.cpp new file mode 100644 index 0000000..e0c3a7b --- /dev/null +++ b/src/render/software/TexturesRenderer.cpp @@ -0,0 +1,213 @@ +#include "TexturesRenderer.h" + +#include "Scenery.h" +#include "SoftwareRenderer.h" +#include "TextureLayerDefinition.h" +#include "TexturesDefinition.h" +#include "Zone.h" +#include "NoiseGenerator.h" + +TexturesRenderer::TexturesRenderer(SoftwareRenderer *parent): + parent(parent) +{ +} + +TexturesRenderer::~TexturesRenderer() +{ +} + +/* + * Get the base presence factor of a layer, not accounting for other layers. + */ +double TexturesRenderer::getLayerBasePresence(TextureLayerDefinition *layer, const TerrainRenderer::TerrainResult &terrain) +{ + return layer->terrain_zone->getValue(terrain.location, terrain.normal); +} + +/* + * Get triplanar noise value, depending on the normal direction. + */ +double TexturesRenderer::getTriplanarNoise(NoiseGenerator *noise, const Vector3 &location, const Vector3 &normal) +{ + double noiseXY = noise->get2DTotal(location.x, location.y); + double noiseXZ = noise->get2DTotal(location.x, location.z); + double noiseYZ = noise->get2DTotal(location.y, location.z); + + double mXY = fabs(normal.z); + double mXZ = fabs(normal.y); + double mYZ = fabs(normal.x); + double total = mXY + mXZ + mYZ; + mXY /= total; + mXZ /= total; + mYZ /= total; + + return noiseXY * mXY + noiseXZ * mXZ + noiseYZ * mYZ; +} + +double TexturesRenderer::getMaximalDisplacement(TexturesDefinition *textures) +{ + int i, n; + double disp = 0.0; + n = textures->count(); + for (i = 0; i < n; i++) + { + TextureLayerDefinition* layer = textures->getTextureLayer(i); + + if (layer->displacement_height > 0.0) + { + disp += layer->displacement_height; + } + } + return disp; +} + +static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west) +{ + /* TODO This is duplicated in terrain/main.c */ + Vector3 dnorth, deast, dsouth, dwest, normal; + + dnorth = v3Sub(north, center); + deast = v3Sub(east, center); + dsouth = v3Sub(south, center); + dwest = v3Sub(west, center); + + normal = v3Cross(deast, dnorth); + normal = v3Add(normal, v3Cross(dsouth, deast)); + normal = v3Add(normal, v3Cross(dwest, dsouth)); + normal = v3Add(normal, v3Cross(dnorth, dwest)); + + return v3Normalize(normal); +} + +static inline Vector3 _getNormal2(Vector3 center, Vector3 east, Vector3 south) +{ + /* TODO This is duplicated in terrain/main.c */ + return v3Normalize(v3Cross(v3Sub(south, center), v3Sub(east, center))); +} + +static Vector3 _getDetailNormal(SoftwareRenderer* renderer, Vector3 base_location, Vector3 base_normal, TextureLayerDefinition* layer) +{ + TexturesRenderer* textures = renderer->getTexturesRenderer(); + Vector3 result; + double offset = 0.01; + + /* Find guiding vectors in the appoximated local plane */ + Vector3 dx, dy; + Vector3 pivot; + if (base_normal.y > 0.95) + { + pivot = VECTOR_NORTH; + } + else + { + pivot = VECTOR_UP; + } + dx = v3Normalize(v3Cross(base_normal, pivot)); + dy = v3Cross(base_normal, dx); + + /* Apply detail noise locally */ + Vector3 center, north, east, south, west; + + center = v3Add(base_location, v3Scale(base_normal, textures->getTriplanarNoise(layer->_detail_noise, base_location, base_normal))); + + east = v3Add(base_location, v3Scale(dx, offset)); + east = v3Add(east, v3Scale(base_normal, textures->getTriplanarNoise(layer->_detail_noise, east, base_normal))); + + south = v3Add(base_location, v3Scale(dy, offset)); + south = v3Add(south, v3Scale(base_normal, textures->getTriplanarNoise(layer->_detail_noise, south, base_normal))); + + if (renderer->render_quality > 6) + { + west = v3Add(base_location, v3Scale(dx, -offset)); + west = v3Add(west, v3Scale(base_normal, textures->getTriplanarNoise(layer->_detail_noise, west, base_normal))); + + north = v3Add(base_location, v3Scale(dy, -offset)); + north = v3Add(north, v3Scale(base_normal, textures->getTriplanarNoise(layer->_detail_noise, north, base_normal))); + + result = _getNormal4(center, north, east, south, west); + } + else + { + result = _getNormal2(center, east, south); + } + + if (v3Dot(result, base_normal) < 0.0) + { + result = v3Scale(result, -1.0); + } + return result; +} + +Vector3 TexturesRenderer::displaceTerrain(const TerrainRenderer::TerrainResult &terrain) +{ + TexturesDefinition* textures = parent->getScenery()->getTextures(); + double offset = 0.0; + int i, n; + + n = textures->count(); + for (i = 0; i < n; i++) + { + TextureLayerDefinition* layer = textures->getTextureLayer(i); + + if (layer->displacement_height > 0.0) + { + double presence = getLayerBasePresence(layer, terrain); + Vector3 location = {terrain.location.x / layer->displacement_scaling, terrain.location.y / layer->displacement_scaling, terrain.location.z / layer->displacement_scaling}; + offset += getTriplanarNoise(layer->_displacement_noise, location, terrain.normal) * presence * layer->displacement_height; + } + } + + return v3Add(terrain.location, v3Scale(v3Normalize(terrain.normal), offset)); +} + +double TexturesRenderer::getBasePresence(int layer, const TerrainRenderer::TerrainResult &terrain) +{ + TextureLayerDefinition* layerdef = parent->getScenery()->getTextures()->getTextureLayer(layer); + return getLayerBasePresence(layerdef, terrain); +} + +TexturesRenderer::TexturesResult TexturesRenderer::applyToTerrain(double x, double z) +{ + TexturesDefinition* textures = parent->getScenery()->getTextures(); + TexturesResult result; + + /* Displacement */ + TerrainRenderer::TerrainResult terrain = parent->getTerrainRenderer()->getResult(x, z, 1, 1); + + /* TODO Displaced textures had their presence already computed before, store that result and use it */ + + /* Find presence of each layer */ + int i, n; + n = textures->count(); + for (i = 0; i < n; i++) + { + TexturesLayerResult* info = result.layers + i; + info->layer = textures->getTextureLayer(i); + info->presence = getBasePresence(i, terrain); + if (info->presence > 0.0) + { + Vector3 normal = _getDetailNormal(parent, terrain.location, terrain.normal, info->layer); + info->color = parent->applyLightingToSurface(terrain.location, normal, *info->layer->material); + } + else + { + info->color = COLOR_TRANSPARENT; + } + } + result.layer_count = n; + + result.base_location = terrain.location; + result.base_normal = terrain.normal; + result.final_location = terrain.location; + result.final_color = COLOR_GREEN; + for (i = 0; i < n; i++) + { + if (result.layers[i].presence > 0.0) + { + result.layers[i].color.a = result.layers[i].presence; + colorMask(&result.final_color, &result.layers[i].color); + } + } + + return result; +} diff --git a/src/render/software/TexturesRenderer.h b/src/render/software/TexturesRenderer.h new file mode 100644 index 0000000..c7dea63 --- /dev/null +++ b/src/render/software/TexturesRenderer.h @@ -0,0 +1,52 @@ +#ifndef TEXTURESRENDERER_H +#define TEXTURESRENDERER_H + +#include "software_global.h" + +#include "TerrainRenderer.h" + +#define TEXTURES_MAX_LAYERS 50 + +namespace paysages { +namespace software { + +class SOFTWARESHARED_EXPORT TexturesRenderer +{ +public: + typedef struct + { + TextureLayerDefinition* layer; + double presence; + Color color; + } TexturesLayerResult; + + typedef struct + { + Vector3 base_location; + Vector3 base_normal; + int layer_count; + TexturesLayerResult layers[TEXTURES_MAX_LAYERS]; + Vector3 final_location; + Color final_color; + } TexturesResult; + +public: + TexturesRenderer(SoftwareRenderer *parent); + virtual ~TexturesRenderer(); + + virtual double getMaximalDisplacement(TexturesDefinition *textures); + virtual double getLayerBasePresence(TextureLayerDefinition *layer, const TerrainRenderer::TerrainResult &terrain); + virtual double getTriplanarNoise(NoiseGenerator *noise, const Vector3 &location, const Vector3 &normal); + + virtual Vector3 displaceTerrain(const TerrainRenderer::TerrainResult &terrain); + virtual double getBasePresence(int layer, const TerrainRenderer::TerrainResult &terrain); + virtual TexturesResult applyToTerrain(double x, double z); + +private: + SoftwareRenderer *parent; +}; + +} +} + +#endif // TEXTURESRENDERER_H diff --git a/src/render/software/WaterRasterizer.cpp b/src/render/software/WaterRasterizer.cpp index ae271a5..4dae5b5 100644 --- a/src/render/software/WaterRasterizer.cpp +++ b/src/render/software/WaterRasterizer.cpp @@ -1,7 +1,7 @@ #include "WaterRasterizer.h" #include "SoftwareRenderer.h" -#include "water/public.h" +#include "WaterRenderer.h" #include "tools/parallel.h" WaterRasterizer::WaterRasterizer(SoftwareRenderer* renderer): @@ -9,23 +9,24 @@ WaterRasterizer::WaterRasterizer(SoftwareRenderer* renderer): { } -static Color _postProcessFragment(Renderer* renderer, Vector3 location, void*) +static Color _postProcessFragment(Renderer* renderer_, Vector3 location, void*) { - return renderer->water->getResult(renderer, location.x, location.z).final; + SoftwareRenderer* renderer = (SoftwareRenderer*) renderer_; + return renderer->getWaterRenderer()->getResult(location.x, location.z).final; } -static Vector3 _getFirstPassVertex(Renderer* renderer, double x, double z) +static Vector3 _getFirstPassVertex(SoftwareRenderer* renderer, double x, double z) { Vector3 result; result.x = x; - result.y = renderer->water->getHeight(renderer, x, z); + result.y = renderer->getWaterRenderer()->getHeight(x, z); result.z = z; return result; } -static void _renderQuad(Renderer* renderer, double x, double z, double size) +static void _renderQuad(SoftwareRenderer* renderer, double x, double z, double size) { Vector3 v1, v2, v3, v4; diff --git a/src/rendering/water/wat_render.cpp b/src/render/software/WaterRenderer.cpp similarity index 64% rename from src/rendering/water/wat_render.cpp rename to src/render/software/WaterRenderer.cpp index 60ee1da..3e5af7c 100644 --- a/src/rendering/water/wat_render.cpp +++ b/src/render/software/WaterRenderer.cpp @@ -1,43 +1,22 @@ -#include "private.h" +#include "WaterRenderer.h" -#include -#include "../renderer.h" +#include "SoftwareRenderer.h" +#include "TerrainRenderer.h" #include "WaterDefinition.h" -#include "SurfaceMaterial.h" #include "NoiseGenerator.h" -#include "terrain/public.h" +#include "LightComponent.h" +#include "Scenery.h" +#include "SurfaceMaterial.h" -static HeightInfo _FAKE_HEIGHT_INFO = {0.0, 0.0, 0.0}; - -/******************** Fake ********************/ -static HeightInfo _fakeGetHeightInfo(Renderer*) +WaterRenderer::WaterRenderer(SoftwareRenderer* parent): + parent(parent) { - return _FAKE_HEIGHT_INFO; } -static double _fakeGetHeight(Renderer*, double, double) +WaterRenderer::~WaterRenderer() { - return 0.0; } -static WaterResult _fakeGetResult(Renderer*, double x, double z) -{ - WaterResult result; - - result.location.x = x; - result.location.y = 0.0; - result.location.z = z; - - result.base = COLOR_BLUE; - result.reflected = COLOR_BLACK; - result.refracted = COLOR_BLACK; - result.foam = COLOR_BLACK; - result.final = COLOR_BLUE; - - return result; -} - -/******************** Helpers ********************/ static inline double _getHeight(WaterDefinition* definition, double base_height, double x, double z) { return base_height + definition->_waves_noise->get2DTotal(x, z); @@ -89,13 +68,13 @@ static inline Vector3 _refractRay(Vector3 incoming, Vector3 normal) } } -static inline Color _getFoamMask(Renderer* renderer, WaterDefinition* definition, Vector3 location, Vector3 normal, double detail) +static inline Color _getFoamMask(SoftwareRenderer* renderer, WaterDefinition* definition, Vector3 location, Vector3 normal, double detail) { Color result; double foam_factor, normal_diff, location_offset; double base_height; - base_height = renderer->terrain->getWaterHeight(renderer); + base_height = renderer->getTerrainRenderer()->getWaterHeight(); location_offset = 2.0 * detail; foam_factor = 0.0; @@ -156,13 +135,13 @@ static inline Color _getFoamMask(Renderer* renderer, WaterDefinition* definition return result; } -static int _alterLight(Renderer* renderer, LightDefinition* light, Vector3 at) +int WaterRenderer::alterLight(LightComponent *light, const Vector3 &at) { - WaterDefinition* definition = renderer->water->definition; + WaterDefinition* definition = parent->getScenery()->getWater(); double factor; double base_height; - base_height = renderer->terrain->getWaterHeight(renderer); + base_height = parent->getTerrainRenderer()->getWaterHeight(); if (at.y < base_height) { if (light->direction.y <= -0.00001) @@ -193,14 +172,13 @@ static int _alterLight(Renderer* renderer, LightDefinition* light, Vector3 at) } } -/******************** Real ********************/ -static HeightInfo _realGetHeightInfo(Renderer* renderer) +HeightInfo WaterRenderer::getHeightInfo() { - WaterDefinition* definition = renderer->water->definition; + WaterDefinition* definition = parent->getScenery()->getWater(); HeightInfo info; double noise_minvalue, noise_maxvalue; - info.base_height = renderer->terrain->getWaterHeight(renderer); + info.base_height = parent->getTerrainRenderer()->getWaterHeight(); definition->_waves_noise->getRange(&noise_minvalue, &noise_maxvalue); info.min_height = info.base_height + noise_minvalue; info.max_height = info.base_height + noise_maxvalue; @@ -208,35 +186,35 @@ static HeightInfo _realGetHeightInfo(Renderer* renderer) return info; } -static double _realGetHeight(Renderer* renderer, double x, double z) +double WaterRenderer::getHeight(double x, double z) { - return _getHeight(renderer->water->definition, renderer->terrain->getWaterHeight(renderer), x, z); + return _getHeight(parent->getScenery()->getWater(), parent->getTerrainRenderer()->getWaterHeight(), x, z); } -static WaterResult _realGetResult(Renderer* renderer, double x, double z) +WaterRenderer::WaterResult WaterRenderer::getResult(double x, double z) { - WaterDefinition* definition = renderer->water->definition; + WaterDefinition* definition = parent->getScenery()->getWater(); WaterResult result; RayCastingResult refracted; Vector3 location, normal, look_direction; Color color, foam; double base_height, detail, depth; - base_height = renderer->terrain->getWaterHeight(renderer); + base_height = parent->getTerrainRenderer()->getWaterHeight(); location.x = x; location.y = _getHeight(definition, base_height, x, z); location.z = z; result.location = location; - detail = renderer->getPrecision(renderer, location) * 0.1; + detail = parent->getPrecision(parent, location) * 0.1; if (detail < 0.00001) { detail = 0.00001; } normal = _getNormal(definition, base_height, location, detail); - look_direction = v3Normalize(v3Sub(location, renderer->getCameraLocation(renderer, location))); + look_direction = v3Normalize(v3Sub(location, parent->getCameraLocation(parent, location))); /* Reflection */ if (definition->reflection == 0.0) @@ -245,7 +223,7 @@ static WaterResult _realGetResult(Renderer* renderer, double x, double z) } else { - result.reflected = renderer->rayWalking(renderer, location, _reflectRay(look_direction, normal), 1, 0, 1, 1).hit_color; + result.reflected = parent->rayWalking(location, _reflectRay(look_direction, normal), 1, 0, 1, 1).hit_color; } /* Transparency/refraction */ @@ -256,7 +234,7 @@ static WaterResult _realGetResult(Renderer* renderer, double x, double z) else { Color depth_color = *definition->depth_color; - refracted = renderer->rayWalking(renderer, location, _refractRay(look_direction, normal), 1, 0, 1, 1); + refracted = parent->rayWalking(location, _refractRay(look_direction, normal), 1, 0, 1, 1); depth = v3Norm(v3Sub(location, refracted.hit_location)); colorLimitPower(&depth_color, colorGetPower(&refracted.hit_color)); if (depth > definition->transparency_depth) @@ -274,59 +252,21 @@ static WaterResult _realGetResult(Renderer* renderer, double x, double z) } /* Lighting from environment */ - color = renderer->applyLightingToSurface(location, normal, *definition->material); + color = parent->applyLightingToSurface(location, normal, *definition->material); color.r += result.reflected.r * definition->reflection + result.refracted.r * definition->transparency; color.g += result.reflected.g * definition->reflection + result.refracted.g * definition->transparency; color.b += result.reflected.b * definition->reflection + result.refracted.b * definition->transparency; /* Merge with foam */ - foam = _getFoamMask(renderer, definition, location, normal, detail); + foam = _getFoamMask(parent, definition, location, normal, detail); colorMask(&color, &foam); /* Bring color to the camera */ - color = renderer->applyMediumTraversal(location, color); + color = parent->applyMediumTraversal(location, color); result.base = definition->material->_rgb; result.final = color; return result; } - -/******************** Renderer ********************/ -static WaterRenderer* _createRenderer() -{ - WaterRenderer* result; - - result = new WaterRenderer; - result->definition = new WaterDefinition(NULL); - - result->getHeightInfo = _fakeGetHeightInfo; - result->getHeight = _fakeGetHeight; - result->getResult = _fakeGetResult; - - return result; -} - -static void _deleteRenderer(WaterRenderer* renderer) -{ - delete renderer->definition; - delete renderer; -} - -static void _bindRenderer(Renderer* renderer, WaterDefinition* definition) -{ - definition->copy(renderer->water->definition); - - renderer->water->getHeightInfo = _realGetHeightInfo; - renderer->water->getHeight = _realGetHeight; - renderer->water->getResult = _realGetResult; - - lightingManagerRegisterFilter(renderer->lighting, (FuncLightingAlterLight)_alterLight, renderer); -} - -StandardRenderer WaterRendererClass = { - (FuncObjectCreate)_createRenderer, - (FuncObjectDelete)_deleteRenderer, - (FuncObjectBind)_bindRenderer -}; diff --git a/src/render/software/WaterRenderer.h b/src/render/software/WaterRenderer.h new file mode 100644 index 0000000..055edbc --- /dev/null +++ b/src/render/software/WaterRenderer.h @@ -0,0 +1,42 @@ +#ifndef WATERRENDERER_H +#define WATERRENDERER_H + +#include "software_global.h" + +#include "TerrainDefinition.h" +#include "Vector3.h" +#include "Color.h" + +namespace paysages { +namespace software { + +class SOFTWARESHARED_EXPORT WaterRenderer +{ +public: + typedef struct + { + Vector3 location; + Color base; + Color reflected; + Color refracted; + Color foam; + Color final; + } WaterResult; + +public: + WaterRenderer(SoftwareRenderer* parent); + virtual ~WaterRenderer(); + + virtual HeightInfo getHeightInfo(); + virtual double getHeight(double x, double z); + virtual WaterResult getResult(double x, double z); + virtual int alterLight(LightComponent *light, const Vector3 &at); + +private: + SoftwareRenderer* parent; +}; + +} +} + +#endif // WATERRENDERER_H diff --git a/src/render/software/software.pro b/src/render/software/software.pro index d423a34..c6cce86 100644 --- a/src/render/software/software.pro +++ b/src/render/software/software.pro @@ -29,9 +29,11 @@ SOURCES += SoftwareRenderer.cpp \ LightStatus.cpp \ LightFilter.cpp \ LightComponent.cpp \ - WaterRasterizer.cpp \ AtmosphereResult.cpp \ - AtmosphereModelBruneton.cpp + AtmosphereModelBruneton.cpp \ + TerrainRenderer.cpp \ + TexturesRenderer.cpp \ + WaterRenderer.cpp HEADERS += SoftwareRenderer.h\ software_global.h \ @@ -50,9 +52,11 @@ HEADERS += SoftwareRenderer.h\ LightStatus.h \ LightFilter.h \ LightComponent.h \ - WaterRasterizer.h \ AtmosphereResult.h \ - AtmosphereModelBruneton.h + AtmosphereModelBruneton.h \ + TerrainRenderer.h \ + TexturesRenderer.h \ + WaterRenderer.h unix:!symbian { maemo5 { diff --git a/src/render/software/software_global.h b/src/render/software/software_global.h index c2badc8..67cf73f 100644 --- a/src/render/software/software_global.h +++ b/src/render/software/software_global.h @@ -21,11 +21,17 @@ namespace software { class BaseAtmosphereRenderer; class SoftwareBrunetonAtmosphereRenderer; + class AtmosphereResult; + class AtmosphereModelBruneton; class CloudsRenderer; class BaseCloudLayerRenderer; class BaseCloudsModel; + class TerrainRenderer; + class TexturesRenderer; + class WaterRenderer; + class SkyRasterizer; class TerrainRasterizer; diff --git a/src/rendering/RenderingScenery.cpp b/src/rendering/RenderingScenery.cpp index 609bfc3..e5f8317 100644 --- a/src/rendering/RenderingScenery.cpp +++ b/src/rendering/RenderingScenery.cpp @@ -1,10 +1,6 @@ #include "RenderingScenery.h" #include "renderer.h" -#include "terrain/public.h" -#include "textures/public.h" -#include "water/public.h" -#include "CameraDefinition.h" static RenderingScenery _main_scenery; diff --git a/src/rendering/renderer.cpp b/src/rendering/renderer.cpp index e88b025..fc9dee1 100644 --- a/src/rendering/renderer.cpp +++ b/src/rendering/renderer.cpp @@ -5,9 +5,7 @@ #include "render.h" #include "RenderingScenery.h" #include "CameraDefinition.h" -#include "terrain/public.h" -#include "textures/public.h" -#include "water/public.h" +#include "SurfaceMaterial.h" static RayCastingResult _RAYCASTING_NULL = {0, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; @@ -84,11 +82,6 @@ static void _pushDisplacedQuad(Renderer* renderer, Vector3 v1, Vector3 v2, Vecto renderer->pushDisplacedTriangle(renderer, v4, v1, v3, ov4, ov1, ov3, callback, callback_data); } -static RayCastingResult _rayWalking(Renderer*, Vector3, Vector3, int, int, int, int) -{ - return _RAYCASTING_NULL; -} - @@ -118,22 +111,12 @@ Renderer::Renderer() pushQuad = _pushQuad; pushDisplacedTriangle = _pushDisplacedTriangle; pushDisplacedQuad = _pushDisplacedQuad; - - rayWalking = _rayWalking; - - terrain = (TerrainRenderer*)TerrainRendererClass.create(); - textures = (TexturesRenderer*)TexturesRendererClass.create(); - water = (WaterRenderer*)WaterRendererClass.create(); } Renderer::~Renderer() { delete render_camera; - TerrainRendererClass.destroy(terrain); - TexturesRendererClass.destroy(textures); - WaterRendererClass.destroy(water); - renderDeleteArea(render_area); } @@ -147,6 +130,11 @@ Color Renderer::applyLightingToSurface(const Vector3 &, const Vector3 &, const S return material._rgb; } +RayCastingResult Renderer::rayWalking(const Vector3 &, const Vector3 &, int, int, int, int) +{ + return _RAYCASTING_NULL; +} + diff --git a/src/rendering/renderer.h b/src/rendering/renderer.h index a469cec..d1d4f10 100644 --- a/src/rendering/renderer.h +++ b/src/rendering/renderer.h @@ -5,11 +5,6 @@ #include "shared/types.h" #include "render.h" -class LightingManager; -class TerrainRenderer; -class TexturesRenderer; -class WaterRenderer; - class Renderer { public: @@ -45,14 +40,7 @@ public: /* Shortcuts */ virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material); virtual Color applyMediumTraversal(Vector3 location, Color color); - - /* Scenery related */ - RayCastingResult(*rayWalking)(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds); - - /* Autonomous sub-renderers */ - TerrainRenderer* terrain; - TexturesRenderer* textures; - WaterRenderer* water; + virtual RayCastingResult rayWalking(const Vector3 &location, const Vector3 &direction, int terrain, int water, int sky, int clouds); /* Custom data */ void* customData[10]; diff --git a/src/rendering/rendering.pro b/src/rendering/rendering.pro index 439d71f..be934d7 100644 --- a/src/rendering/rendering.pro +++ b/src/rendering/rendering.pro @@ -11,16 +11,10 @@ include(../common.pri) SOURCES += main.cpp \ renderer.cpp \ render.cpp \ - terrain/ter_render.cpp \ - terrain/ter_painting.cpp \ - textures/tex_tools.cpp \ - textures/tex_rendering.cpp \ - textures/tex_preview.cpp \ tools/texture.cpp \ tools/parallel.cpp \ tools/data.cpp \ tools/cache.cpp \ - water/wat_render.cpp \ RenderingScenery.cpp HEADERS += \ @@ -28,17 +22,10 @@ HEADERS += \ render.h \ main.h \ shared/types.h \ - terrain/public.h \ - terrain/private.h \ - textures/tex_preview.h \ - textures/public.h \ - textures/private.h \ tools/texture.h \ tools/parallel.h \ tools/data.h \ tools/cache.h \ - water/public.h \ - water/private.h \ rendering_global.h \ RenderingScenery.h diff --git a/src/rendering/terrain/private.h b/src/rendering/terrain/private.h deleted file mode 100644 index 286ab87..0000000 --- a/src/rendering/terrain/private.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _PAYSAGES_TERRAIN_PRIVATE_H_ -#define _PAYSAGES_TERRAIN_PRIVATE_H_ - -#include "public.h" - - - -#endif diff --git a/src/rendering/terrain/public.h b/src/rendering/terrain/public.h deleted file mode 100644 index bfc2060..0000000 --- a/src/rendering/terrain/public.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _PAYSAGES_TERRAIN_PUBLIC_H_ -#define _PAYSAGES_TERRAIN_PUBLIC_H_ - -#include "../rendering_global.h" -#include "../shared/types.h" -#include "Color.h" - -typedef struct -{ - Vector3 location; - Vector3 normal; -} TerrainResult; - -typedef double (*FuncTerrainGetHeight)(Renderer* renderer, double x, double z, int with_painting); -typedef TerrainResult (*FuncTerrainGetResult)(Renderer* renderer, double x, double z, int with_painting, int with_textures); -typedef Color (*FuncTerrainGetFinalColor)(Renderer* renderer, Vector3 location, double precision); -typedef double (*FuncGetWaterHeight)(Renderer* renderer); - -class TerrainRenderer -{ -public: - TerrainDefinition* definition; - - FuncGeneralCastRay castRay; - FuncTerrainGetHeight getHeight; - FuncTerrainGetResult getResult; - FuncTerrainGetFinalColor getFinalColor; - FuncGetWaterHeight getWaterHeight; - - void* _internal_data; -}; - -RENDERINGSHARED_EXPORT extern StandardRenderer TerrainRendererClass; - -#endif diff --git a/src/rendering/terrain/ter_painting.cpp b/src/rendering/terrain/ter_painting.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/rendering/terrain/ter_render.cpp b/src/rendering/terrain/ter_render.cpp deleted file mode 100644 index 593e70c..0000000 --- a/src/rendering/terrain/ter_render.cpp +++ /dev/null @@ -1,332 +0,0 @@ -#include "private.h" - -#include -#include -#include "../renderer.h" -#include "textures/public.h" -#include "TerrainDefinition.h" - -/******************** Binding ********************/ -static double _fakeGetHeight(Renderer*, double, double, int) -{ - return 0.0; -} - -static double _realGetHeight(Renderer* renderer, double x, double z, int with_painting) -{ - return renderer->terrain->definition->getInterpolatedHeight(x, z, 1, with_painting); -} - -static TerrainResult _fakeGetResult(Renderer*, double x, double z, int, int) -{ - TerrainResult result; - - result.location.x = x; - result.location.y = 0.0; - result.location.z = z; - result.normal = VECTOR_UP; - - return result; -} - -static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west) -{ - Vector3 dnorth, deast, dsouth, dwest, normal; - - dnorth = v3Sub(north, center); - deast = v3Sub(east, center); - dsouth = v3Sub(south, center); - dwest = v3Sub(west, center); - - normal = v3Cross(deast, dnorth); - normal = v3Add(normal, v3Cross(dsouth, deast)); - normal = v3Add(normal, v3Cross(dwest, dsouth)); - normal = v3Add(normal, v3Cross(dnorth, dwest)); - - return v3Normalize(normal); -} - -static inline Vector3 _getNormal2(Vector3 center, Vector3 east, Vector3 south) -{ - return v3Normalize(v3Cross(v3Sub(south, center), v3Sub(east, center))); -} - -static TerrainResult _realGetResult(Renderer* renderer, double x, double z, int with_painting, int with_textures) -{ - TerrainResult result; - double detail = 0.001; /* TODO */ - - /* Normal */ - Vector3 center, north, east, south, west; - - center.x = x; - center.z = z; - center.y = renderer->terrain->getHeight(renderer, center.x, center.z, with_painting); - - east.x = x + detail; - east.z = z; - east.y = renderer->terrain->getHeight(renderer, east.x, east.z, with_painting); - - south.x = x; - south.z = z + detail; - south.y = renderer->terrain->getHeight(renderer, south.x, south.z, with_painting); - - if (renderer->render_quality > 6) - { - west.x = x - detail; - west.z = z; - west.y = renderer->terrain->getHeight(renderer, west.x, west.z, with_painting); - - north.x = x; - north.z = z - detail; - north.y = renderer->terrain->getHeight(renderer, north.x, north.z, with_painting); - - result.normal = _getNormal4(center, north, east, south, west); - } - else - { - result.normal = _getNormal2(center, east, south); - } - - /* Location */ - result.location = center; - - /* Texture displacement */ - if (with_textures) - { - center = renderer->textures->displaceTerrain(renderer, result); - result.location = center; - - /* Recompute normal */ - if (renderer->render_quality > 6) - { - /* Use 5 points on displaced terrain */ - east = renderer->textures->displaceTerrain(renderer, _realGetResult(renderer, east.x, east.z, with_painting, 0)); - south = renderer->textures->displaceTerrain(renderer, _realGetResult(renderer, south.x, south.z, with_painting, 0)); - west = renderer->textures->displaceTerrain(renderer, _realGetResult(renderer, west.x, west.z, with_painting, 0)); - north = renderer->textures->displaceTerrain(renderer, _realGetResult(renderer, north.x, north.z, with_painting, 0)); - - result.normal = _getNormal4(center, north, east, south, west); - } - else if (renderer->render_quality > 2) - { - /* Use 3 points on displaced terrain */ - east = renderer->textures->displaceTerrain(renderer, _realGetResult(renderer, east.x, east.z, with_painting, 0)); - south = renderer->textures->displaceTerrain(renderer, _realGetResult(renderer, south.x, south.z, with_painting, 0)); - - result.normal = _getNormal2(center, east, south); - } - else - { - /* TODO Use texture noise directly, as if terrain was a plane */ - } - } - - return result; -} - -static Color _fakeGetFinalColor(Renderer*, Vector3, double) -{ - return COLOR_GREEN; -} - -static Color _realGetFinalColor(Renderer* renderer, Vector3 location, double) -{ - /* TODO Restore precision control */ - TexturesResult textures = renderer->textures->applyToTerrain(renderer, location.x, location.z); - return renderer->applyMediumTraversal(textures.final_location, textures.final_color); -} - -static RayCastingResult _fakeCastRay(Renderer*, Vector3, Vector3) -{ - RayCastingResult result; - result.hit = 0; - return result; -} - -static RayCastingResult _realCastRay(Renderer* renderer, Vector3 start, Vector3 direction) -{ - RayCastingResult result; - TerrainDefinition* definition = renderer->terrain->definition; - Vector3 inc_vector; - double inc_value, inc_base, inc_factor, height, diff, lastdiff, length; - - direction = v3Normalize(direction); - inc_factor = (double)renderer->render_quality; - inc_base = 1.0; - inc_value = inc_base / inc_factor; - lastdiff = start.y - _realGetHeight(renderer, start.x, start.z, 1); - - length = 0.0; - do - { - inc_vector = v3Scale(direction, inc_value); - length += v3Norm(inc_vector); - start = v3Add(start, inc_vector); - height = _realGetHeight(renderer, start.x, start.z, 1); - diff = start.y - height; - if (diff < 0.0) - { - if (fabs(diff - lastdiff) > 0.00001) - { - start = v3Add(start, v3Scale(inc_vector, -diff / (diff - lastdiff))); - start.y = _realGetHeight(renderer, start.x, start.z, 1); - } - else - { - start.y = height; - } - result.hit = 1; - result.hit_location = start; - result.hit_color = _realGetFinalColor(renderer, start, renderer->getPrecision(renderer, result.hit_location)); - return result; - } - - if (diff < inc_base / inc_factor) - { - inc_value = inc_base / inc_factor; - } - else if (diff > inc_base) - { - inc_value = inc_base; - } - else - { - inc_value = diff; - } - lastdiff = diff; - } - while (length < 50.0 && start.y <= definition->_max_height); - - result.hit = 0; - return result; -} - -static int _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location) -{ - TerrainDefinition* definition = renderer->terrain->definition; - Vector3 inc_vector, direction_to_light; - double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length; - - direction_to_light = v3Scale(light->direction, -1.0); - if (direction_to_light.y < -0.05) - { - light->color = COLOR_BLACK; - return 1; - } - else if (direction_to_light.y < 0.0000) - { - light->color.r *= (0.05 + direction_to_light.y) / 0.05; - light->color.g *= (0.05 + direction_to_light.y) / 0.05; - light->color.b *= (0.05 + direction_to_light.y) / 0.05; - } - - inc_factor = (double)renderer->render_quality; - inc_base = definition->height / definition->scaling; - inc_value = inc_base / inc_factor; - smoothing = definition->shadow_smoothing; - - light_factor = 1.0; - length = 0.0; - diff = 0.0; - do - { - inc_vector = v3Scale(direction_to_light, inc_value); - length += v3Norm(inc_vector); - location = v3Add(location, inc_vector); - height = renderer->terrain->getResult(renderer, location.x, location.z, 1, 1).location.y; - diff = location.y - height; - if (diff < 0.0) - { - if (length * smoothing > 0.000001) - { - light_factor += diff * v3Norm(inc_vector) / (length * smoothing); - } - else - { - light_factor = 0.0; - } - } - - if (diff < inc_base / inc_factor) - { - inc_value = inc_base / inc_factor; - } - else if (diff > inc_base) - { - inc_value = inc_base; - } - else - { - inc_value = diff; - } - } - while (light_factor > 0.0 && length < (10.0 * inc_factor) && location.y <= definition->_max_height); - - if (light_factor <= 0.0) - { - light->color = COLOR_BLACK; - return 1; - } - else - { - light->color.r *= light_factor; - light->color.g *= light_factor; - light->color.b *= light_factor; - - return 1; - } -} - -static double _fakeGetWaterHeight(Renderer*) -{ - return -1000.0; -} - -static double _realGetWaterHeight(Renderer* renderer) -{ - return renderer->terrain->definition->water_height * renderer->terrain->definition->height * renderer->terrain->definition->scaling; -} - -/******************** Renderer ********************/ -static TerrainRenderer* _createRenderer() -{ - TerrainRenderer* result; - - result = new TerrainRenderer; - result->definition = new TerrainDefinition(NULL); - - result->castRay = _fakeCastRay; - result->getHeight = _fakeGetHeight; - result->getResult = _fakeGetResult; - result->getFinalColor = _fakeGetFinalColor; - result->getWaterHeight = _fakeGetWaterHeight; - - return result; -} - -static void _deleteRenderer(TerrainRenderer* renderer) -{ - delete renderer->definition; - delete renderer; -} - -static void _bindRenderer(Renderer* renderer, TerrainDefinition* definition) -{ - definition->copy(renderer->terrain->definition); - - renderer->terrain->castRay = _realCastRay; - renderer->terrain->getHeight = _realGetHeight; - renderer->terrain->getResult = _realGetResult; - renderer->terrain->getFinalColor = _realGetFinalColor; - renderer->terrain->getWaterHeight = _realGetWaterHeight; - - lightingManagerRegisterFilter(renderer->lighting, (FuncLightingAlterLight)_alterLight, renderer); -} - -StandardRenderer TerrainRendererClass = { - (FuncObjectCreate)_createRenderer, - (FuncObjectDelete)_deleteRenderer, - (FuncObjectBind)_bindRenderer -}; - diff --git a/src/rendering/textures/private.h b/src/rendering/textures/private.h deleted file mode 100644 index 535bdc0..0000000 --- a/src/rendering/textures/private.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _PAYSAGES_TEXTURES_PRIVATE_H_ -#define _PAYSAGES_TEXTURES_PRIVATE_H_ - -#include "public.h" - -/* - * Get the base presence factor of a layer, not accounting for other layers. - */ -double texturesGetLayerBasePresence(TextureLayerDefinition* layer, TerrainResult terrain); - -/* - * Get triplanar noise value, depending on the normal direction. - */ -double texturesGetTriplanarNoise(NoiseGenerator* noise, Vector3 location, Vector3 normal); - -/* - * Apply texture displacement on a terrain result. - */ -/*TerrainResult texturesApplyLayerDisplacement(Renderer* renderer, TexturesLayerDefinition* layer, TerrainResult initial, TerrainResult support, double presence, double cancel_factor);*/ - -#endif diff --git a/src/rendering/textures/public.h b/src/rendering/textures/public.h deleted file mode 100644 index 51f1ba6..0000000 --- a/src/rendering/textures/public.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _PAYSAGES_TEXTURES_PUBLIC_H_ -#define _PAYSAGES_TEXTURES_PUBLIC_H_ - -#include "../rendering_global.h" -#include "Layers.h" -#include "terrain/public.h" -#include "SurfaceMaterial.h" - -#define TEXTURES_MAX_LAYERS 50 - -typedef struct -{ - TextureLayerDefinition* layer; - double presence; - Color color; -} TexturesLayerResult; - -typedef struct -{ - Vector3 base_location; - Vector3 base_normal; - int layer_count; - TexturesLayerResult layers[TEXTURES_MAX_LAYERS]; - Vector3 final_location; - Color final_color; -} TexturesResult; - -typedef Vector3 (*FuncTexturesDisplaceTerrain)(Renderer* renderer, TerrainResult terrain); -typedef double (*FuncTexturesGetBasePresence)(Renderer* renderer, int layer, TerrainResult terrain); -typedef TexturesResult (*FuncTexturesApplyToTerrain)(Renderer* renderer, double x, double z); - -class TexturesRenderer -{ -public: - TexturesDefinition* definition; - - FuncTexturesDisplaceTerrain displaceTerrain; - FuncTexturesGetBasePresence getBasePresence; - FuncTexturesApplyToTerrain applyToTerrain; -}; - - -RENDERINGSHARED_EXPORT extern StandardRenderer TexturesRendererClass; - -RENDERINGSHARED_EXPORT double texturesGetMaximalDisplacement(TexturesDefinition* textures); - -#endif diff --git a/src/rendering/textures/tex_preview.cpp b/src/rendering/textures/tex_preview.cpp deleted file mode 100644 index 6b7f271..0000000 --- a/src/rendering/textures/tex_preview.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "tex_preview.h" -#include "private.h" - -#include "RenderingScenery.h" -#include "TexturesDefinition.h" - -void TexturesPreviewLayerCoverage_bind(Renderer* renderer, TexturesDefinition* definition) -{ - TerrainRendererClass.bind(renderer, RenderingScenery::getCurrent()->getTerrain()); - TexturesRendererClass.bind(renderer, definition); -} - -Color TexturesPreviewLayerCoverage_getColor(Renderer* renderer, double x, double y, double, int layer) -{ - TextureLayerDefinition* layerdef; - TerrainResult terrain; - double presence; - Color result; - - layerdef = renderer->textures->definition->getTextureLayer(layer); - if (layerdef) - { - terrain = renderer->terrain->getResult(renderer, x, y, 1, 1); - presence = texturesGetLayerBasePresence(layerdef, terrain); - - result.r = result.g = result.b = presence; - result.a = 1.0; - } - else - { - result = COLOR_BLACK; - } - - return result; -} - -static double _getPresenceFull(Renderer*, int, TerrainResult) -{ - return 1.0; -} - -void TexturesPreviewLayerLook_bind(Renderer* renderer, TexturesDefinition* definition) -{ - TexturesRendererClass.bind(renderer, definition); - renderer->textures->getBasePresence = _getPresenceFull; -} - -Color TexturesPreviewLayerLook_getColor(Renderer* renderer, double x, double y, double, int layer) -{ - TexturesResult result = renderer->textures->applyToTerrain(renderer, x, y); - if (layer >= 0 && layer < result.layer_count) - { - return result.layers[layer].color; - } - else - { - return COLOR_BLACK; - } -} - - -void TexturesPreviewCumul_bind(Renderer* renderer, TexturesDefinition* definition) -{ - TerrainRendererClass.bind(renderer, RenderingScenery::getCurrent()->getTerrain()); - TexturesRendererClass.bind(renderer, definition); -} - -Color TexturesPreviewCumul_getColor(Renderer* renderer, double x, double y, double, int) -{ - return renderer->textures->applyToTerrain(renderer, x, y).final_color; -} diff --git a/src/rendering/textures/tex_preview.h b/src/rendering/textures/tex_preview.h deleted file mode 100644 index bee8f4c..0000000 --- a/src/rendering/textures/tex_preview.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef TEX_PREVIEW_H -#define TEX_PREVIEW_H - -#include "renderer.h" -#include "textures/public.h" - -/* Single layer coverage */ -RENDERINGSHARED_EXPORT void TexturesPreviewLayerCoverage_bind(Renderer* renderer, TexturesDefinition* definition); -RENDERINGSHARED_EXPORT Color TexturesPreviewLayerCoverage_getColor(Renderer* renderer, double x, double y, double scaling, int layer); - -/* Single layer look */ -RENDERINGSHARED_EXPORT void TexturesPreviewLayerLook_bind(Renderer* renderer, TexturesDefinition* definition); -RENDERINGSHARED_EXPORT Color TexturesPreviewLayerLook_getColor(Renderer* renderer, double x, double y, double scaling, int layer); - -/* Cumulative color preview */ -RENDERINGSHARED_EXPORT void TexturesPreviewCumul_bind(Renderer* renderer, TexturesDefinition* definition); -RENDERINGSHARED_EXPORT Color TexturesPreviewCumul_getColor(Renderer* renderer, double x, double y, double scaling, int layer); - -#endif diff --git a/src/rendering/textures/tex_rendering.cpp b/src/rendering/textures/tex_rendering.cpp deleted file mode 100644 index 39c3571..0000000 --- a/src/rendering/textures/tex_rendering.cpp +++ /dev/null @@ -1,220 +0,0 @@ -#include "private.h" - -#include -#include "TexturesDefinition.h" -#include "TextureLayerDefinition.h" -#include "../renderer.h" - -/******************** Tools ********************/ -static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west) -{ - /* TODO This is duplicated in terrain/main.c */ - Vector3 dnorth, deast, dsouth, dwest, normal; - - dnorth = v3Sub(north, center); - deast = v3Sub(east, center); - dsouth = v3Sub(south, center); - dwest = v3Sub(west, center); - - normal = v3Cross(deast, dnorth); - normal = v3Add(normal, v3Cross(dsouth, deast)); - normal = v3Add(normal, v3Cross(dwest, dsouth)); - normal = v3Add(normal, v3Cross(dnorth, dwest)); - - return v3Normalize(normal); -} - -static inline Vector3 _getNormal2(Vector3 center, Vector3 east, Vector3 south) -{ - /* TODO This is duplicated in terrain/main.c */ - return v3Normalize(v3Cross(v3Sub(south, center), v3Sub(east, center))); -} - -static Vector3 _getDetailNormal(Renderer* renderer, Vector3 base_location, Vector3 base_normal, TextureLayerDefinition* layer) -{ - Vector3 result; - double offset = 0.01; - - /* Find guiding vectors in the appoximated local plane */ - Vector3 dx, dy; - Vector3 pivot; - if (base_normal.y > 0.95) - { - pivot = VECTOR_NORTH; - } - else - { - pivot = VECTOR_UP; - } - dx = v3Normalize(v3Cross(base_normal, pivot)); - dy = v3Cross(base_normal, dx); - - /* Apply detail noise locally */ - Vector3 center, north, east, south, west; - - center = v3Add(base_location, v3Scale(base_normal, texturesGetTriplanarNoise(layer->_detail_noise, base_location, base_normal))); - - east = v3Add(base_location, v3Scale(dx, offset)); - east = v3Add(east, v3Scale(base_normal, texturesGetTriplanarNoise(layer->_detail_noise, east, base_normal))); - - south = v3Add(base_location, v3Scale(dy, offset)); - south = v3Add(south, v3Scale(base_normal, texturesGetTriplanarNoise(layer->_detail_noise, south, base_normal))); - - if (renderer->render_quality > 6) - { - west = v3Add(base_location, v3Scale(dx, -offset)); - west = v3Add(west, v3Scale(base_normal, texturesGetTriplanarNoise(layer->_detail_noise, west, base_normal))); - - north = v3Add(base_location, v3Scale(dy, -offset)); - north = v3Add(north, v3Scale(base_normal, texturesGetTriplanarNoise(layer->_detail_noise, north, base_normal))); - - result = _getNormal4(center, north, east, south, west); - } - else - { - result = _getNormal2(center, east, south); - } - - if (v3Dot(result, base_normal) < 0.0) - { - result = v3Scale(result, -1.0); - } - return result; -} - -/******************** Real ********************/ -static Vector3 _realDisplaceTerrain(Renderer* renderer, TerrainResult terrain) -{ - TexturesDefinition* textures = renderer->textures->definition; - double offset = 0.0; - int i, n; - - n = textures->count(); - for (i = 0; i < n; i++) - { - TextureLayerDefinition* layer = textures->getTextureLayer(i); - - if (layer->displacement_height > 0.0) - { - double presence = texturesGetLayerBasePresence(layer, terrain); - Vector3 location = {terrain.location.x / layer->displacement_scaling, terrain.location.y / layer->displacement_scaling, terrain.location.z / layer->displacement_scaling}; - offset += texturesGetTriplanarNoise(layer->_displacement_noise, location, terrain.normal) * presence * layer->displacement_height; - } - } - - return v3Add(terrain.location, v3Scale(v3Normalize(terrain.normal), offset)); -} - -static double _realGetBasePresence(Renderer* renderer, int layer, TerrainResult terrain) -{ - TextureLayerDefinition* layerdef = renderer->textures->definition->getTextureLayer(layer); - return texturesGetLayerBasePresence(layerdef, terrain); -} - -static TexturesResult _realApplyToTerrain(Renderer* renderer, double x, double z) -{ - TexturesDefinition* textures = renderer->textures->definition; - TexturesResult result; - - /* Displacement */ - TerrainResult terrain = renderer->terrain->getResult(renderer, x, z, 1, 1); - - /* TODO Displaced textures had their presence already computed before, store that result and use it */ - - /* Find presence of each layer */ - int i, n; - n = textures->count(); - for (i = 0; i < n; i++) - { - TexturesLayerResult* info = result.layers + i; - info->layer = textures->getTextureLayer(i); - info->presence = renderer->textures->getBasePresence(renderer, i, terrain); - if (info->presence > 0.0) - { - Vector3 normal = _getDetailNormal(renderer, terrain.location, terrain.normal, info->layer); - info->color = renderer->applyLightingToSurface(terrain.location, normal, *info->layer->material); - } - else - { - info->color = COLOR_TRANSPARENT; - } - } - result.layer_count = n; - - result.base_location = terrain.location; - result.base_normal = terrain.normal; - result.final_location = terrain.location; - result.final_color = COLOR_GREEN; - for (i = 0; i < n; i++) - { - if (result.layers[i].presence > 0.0) - { - result.layers[i].color.a = result.layers[i].presence; - colorMask(&result.final_color, &result.layers[i].color); - } - } - - return result; -} - -/******************** Fake ********************/ -static Vector3 _fakeDisplaceTerrain(Renderer*, TerrainResult terrain) -{ - return terrain.location; -} - -static double _fakeGetBasePresence(Renderer*, int, TerrainResult) -{ - return 1.0; -} - -static TexturesResult _fakeApplyToTerrain(Renderer*, double x, double z) -{ - TexturesResult result; - - result.base_location.x = x; - result.base_location.y = 0.0; - result.base_location.z = z; - result.base_normal = VECTOR_UP; - result.layer_count = 0; - result.final_location = result.base_location; - result.final_color = COLOR_WHITE; - - return result; -} - -/******************** Renderer ********************/ -static TexturesRenderer* _createRenderer() -{ - TexturesRenderer* result; - - result = new TexturesRenderer; - result->definition = new TexturesDefinition(NULL); - - result->displaceTerrain = _fakeDisplaceTerrain; - result->getBasePresence = _fakeGetBasePresence; - result->applyToTerrain = _fakeApplyToTerrain; - - return result; -} - -static void _deleteRenderer(TexturesRenderer* renderer) -{ - delete renderer->definition; - delete renderer; -} - -static void _bindRenderer(Renderer* renderer, TexturesDefinition* definition) -{ - definition->copy(renderer->textures->definition); - - renderer->textures->displaceTerrain = _realDisplaceTerrain; - renderer->textures->getBasePresence = _realGetBasePresence; - renderer->textures->applyToTerrain = _realApplyToTerrain; -} - -StandardRenderer TexturesRendererClass = { - (FuncObjectCreate)_createRenderer, - (FuncObjectDelete)_deleteRenderer, - (FuncObjectBind)_bindRenderer -}; diff --git a/src/rendering/textures/tex_tools.cpp b/src/rendering/textures/tex_tools.cpp deleted file mode 100644 index bd43094..0000000 --- a/src/rendering/textures/tex_tools.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "private.h" - -#include -#include "NoiseGenerator.h" -#include "TexturesDefinition.h" -#include "TextureLayerDefinition.h" -#include "Zone.h" - -/* - * Get the base presence factor of a layer, not accounting for other layers. - */ -double texturesGetLayerBasePresence(TextureLayerDefinition* layer, TerrainResult terrain) -{ - return layer->terrain_zone->getValue(terrain.location, terrain.normal); -} - -/* - * Get triplanar noise value, depending on the normal direction. - */ -double texturesGetTriplanarNoise(NoiseGenerator* noise, Vector3 location, Vector3 normal) -{ - double noiseXY = noise->get2DTotal(location.x, location.y); - double noiseXZ = noise->get2DTotal(location.x, location.z); - double noiseYZ = noise->get2DTotal(location.y, location.z); - - double mXY = fabs(normal.z); - double mXZ = fabs(normal.y); - double mYZ = fabs(normal.x); - double total = mXY + mXZ + mYZ; - mXY /= total; - mXZ /= total; - mYZ /= total; - - return noiseXY * mXY + noiseXZ * mXZ + noiseYZ * mYZ; -} - -double texturesGetMaximalDisplacement(TexturesDefinition* textures) -{ - int i, n; - double disp = 0.0; - n = textures->count(); - for (i = 0; i < n; i++) - { - TextureLayerDefinition* layer = textures->getTextureLayer(i); - - if (layer->displacement_height > 0.0) - { - disp += layer->displacement_height; - } - } - return disp; -} diff --git a/src/rendering/water/private.h b/src/rendering/water/private.h deleted file mode 100644 index 624f459..0000000 --- a/src/rendering/water/private.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _PAYSAGES_WATER_PRIVATE_H_ -#define _PAYSAGES_WATER_PRIVATE_H_ - -#include "public.h" - - -#endif diff --git a/src/rendering/water/public.h b/src/rendering/water/public.h deleted file mode 100644 index ccd1e50..0000000 --- a/src/rendering/water/public.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _PAYSAGES_WATER_PUBLIC_H_ -#define _PAYSAGES_WATER_PUBLIC_H_ - -#include "../rendering_global.h" -#include "../shared/types.h" -#include "TerrainDefinition.h" - -typedef struct -{ - Vector3 location; - Color base; - Color reflected; - Color refracted; - Color foam; - Color final; -} WaterResult; - -typedef HeightInfo (*FuncWaterGetHeightInfo)(Renderer* renderer); -typedef double (*FuncWaterGetHeight)(Renderer* renderer, double x, double z); -typedef WaterResult (*FuncWaterGetResult)(Renderer* renderer, double x, double z); - -class WaterRenderer -{ -public: - WaterDefinition* definition; - - FuncWaterGetHeightInfo getHeightInfo; - FuncWaterGetHeight getHeight; - FuncWaterGetResult getResult; -}; - - -RENDERINGSHARED_EXPORT extern StandardRenderer WaterRendererClass; - -RENDERINGSHARED_EXPORT void waterAlterPreviewCoverageRenderer(Renderer* renderer); -RENDERINGSHARED_EXPORT Color waterGetPreviewCoverage(Renderer* renderer, double x, double y, double scaling, int highlight_enabled); - -RENDERINGSHARED_EXPORT Renderer* waterCreatePreviewColorRenderer(); -RENDERINGSHARED_EXPORT Color waterGetPreviewColor(Renderer* renderer, double x, double y, double scaling); - -#endif