[Broken WIP] Refactoring terrain, textures and water renderer

This commit is contained in:
Michaël Lemaire 2013-12-08 20:54:34 +01:00
parent b0d9ead01d
commit 74634dfaf1
53 changed files with 896 additions and 1197 deletions

View file

@ -31,6 +31,8 @@ public:
double getPower() const; double getPower() const;
void limitPower(double max_power); void limitPower(double max_power);
Color add(const Color& other) const;
public: public:
double r; double r;
double g; double g;

View file

@ -182,3 +182,8 @@ METHSPEC void Color::limitPower(double max_power)
b *= factor; b *= factor;
} }
} }
METHSPEC Color Color::add(const Color& other) const
{
return Color(r + other.r, g + other.g, b + other.b, a);
}

View file

@ -2,8 +2,8 @@
#include "SoftwareRenderer.h" #include "SoftwareRenderer.h"
#include "AtmosphereRenderer.h" #include "AtmosphereRenderer.h"
#include "AtmosphereResult.h"
#include "CameraDefinition.h" #include "CameraDefinition.h"
#include "tools/lighting.h"
#include "SurfaceMaterial.h" #include "SurfaceMaterial.h"
#include "Scenery.h" #include "Scenery.h"
#include "BasePreview.h" #include "BasePreview.h"
@ -180,13 +180,13 @@ Color AtmosphereColorPreviewRenderer::getColor2D(double x, double y, double)
normal = rotation.transform(normal); normal = rotation.transform(normal);
hit = rotation.transform(hit); hit = rotation.transform(hit);
color = this->applyLightingToSurface(this, hit, normal, &MOUNT_MATERIAL); color = applyLightingToSurface(hit, normal, MOUNT_MATERIAL);
return this->atmosphere->applyAerialPerspective(this, hit, color).final; return applyMediumTraversal(hit, color);
} }
else else
{ {
direction = rotation.transform(direction); direction = rotation.transform(direction);
return this->atmosphere->getSkyColor(this, direction).final; return getAtmosphereRenderer()->getSkyColor(direction).final;
} }
} }

View file

@ -1,15 +1,17 @@
#include "CloudsAspectPreviewRenderer.h" #include "CloudsAspectPreviewRenderer.h"
#include "atmosphere/public.h"
#include "BasePreview.h" #include "BasePreview.h"
#include "Scenery.h" #include "Scenery.h"
#include "CloudsDefinition.h" #include "CloudsDefinition.h"
#include "CloudLayerDefinition.h" #include "CloudLayerDefinition.h"
#include "CloudsRenderer.h" #include "CloudsRenderer.h"
#include "LightStatus.h"
#include "LightComponent.h"
#include "AtmosphereResult.h"
static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int) static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
{ {
LightDefinition light; LightComponent light;
light.color.r = 0.5; light.color.r = 0.5;
light.color.g = 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.direction = Vector3(-1.0, 0.5, 1.0).normalize();
light.altered = 1; light.altered = 1;
light.reflection = 0.0; light.reflection = 0.0;
lightingPushLight(status, &light); status->pushComponent(light);
light.color.r = 0.1; light.color.r = 0.1;
light.color.g = 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.direction = Vector3(1.0, -0.5, -1.0).normalize();
light.altered = 0; light.altered = 0;
light.reflection = 0.0; light.reflection = 0.0;
lightingPushLight(status, &light); status->pushComponent(light);
} }
static double _getDensity(Renderer*, CloudLayerDefinition* layer, Vector3 location) static double _getDensity(Renderer*, CloudLayerDefinition* layer, Vector3 location)
@ -81,8 +83,8 @@ void CloudsAspectPreviewRenderer::updateEvent()
prepare(); prepare();
//clouds->getLayerDensity = _getDensity; //clouds->getLayerDensity = _getDensity;
atmosphere->getLightingStatus = _getLightingStatus; //atmosphere->getLightingStatus = _getLightingStatus;
atmosphere->applyAerialPerspective = _fakeApplyAerialPerspective; //atmosphere->applyAerialPerspective = _fakeApplyAerialPerspective;
} }
Color CloudsAspectPreviewRenderer::getColor2D(double x, double y, double) Color CloudsAspectPreviewRenderer::getColor2D(double x, double y, double)

View file

@ -6,11 +6,6 @@
#include "CloudLayerDefinition.h" #include "CloudLayerDefinition.h"
#include "CloudsRenderer.h" #include "CloudsRenderer.h"
Color _fakeApplyLightingToSurface(Renderer*, Vector3, Vector3, SurfaceMaterial*)
{
return COLOR_WHITE;
}
CloudsCoveragePreviewRenderer::CloudsCoveragePreviewRenderer(CloudLayerDefinition* layer): CloudsCoveragePreviewRenderer::CloudsCoveragePreviewRenderer(CloudLayerDefinition* layer):
layer(layer) layer(layer)
{ {
@ -31,7 +26,6 @@ void CloudsCoveragePreviewRenderer::updateEvent()
{ {
layer->copy(getScenery()->getClouds()->getCloudLayer(0)); layer->copy(getScenery()->getClouds()->getCloudLayer(0));
prepare(); prepare();
applyLightingToSurface = _fakeApplyLightingToSurface;
} }
Color CloudsCoveragePreviewRenderer::getColor2D(double x, double y, double scaling) Color CloudsCoveragePreviewRenderer::getColor2D(double x, double y, double scaling)
@ -70,3 +64,8 @@ void CloudsCoveragePreviewRenderer::toggleChangeEvent(const std::string &key, bo
perspective = value; perspective = value;
} }
} }
Color CloudsCoveragePreviewRenderer::applyLightingToSurface(const Vector3 &, const Vector3 &, const SurfaceMaterial &)
{
return COLOR_WHITE;
}

View file

@ -19,6 +19,8 @@ public:
virtual void toggleChangeEvent(const std::string &key, bool value) override; virtual void toggleChangeEvent(const std::string &key, bool value) override;
virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material) override;
private: private:
bool perspective; bool perspective;
CloudLayerDefinition* layer; CloudLayerDefinition* layer;

View file

@ -4,12 +4,6 @@
#include "BasePreview.h" #include "BasePreview.h"
#include "Scenery.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) static Vector3 _getCameraLocation(Renderer*, Vector3 location)
{ {
return v3Add(location, v3Scale(VECTOR_UP, 50.0)); return v3Add(location, v3Scale(VECTOR_UP, 50.0));

View file

@ -6,16 +6,12 @@
#include "SurfaceMaterial.h" #include "SurfaceMaterial.h"
#include "NoiseGenerator.h" #include "NoiseGenerator.h"
#include "BasePreview.h" #include "BasePreview.h"
#include "LightComponent.h"
// TEMP #include "LightStatus.h"
#include "atmosphere/public.h"
#include "tools/lighting.h"
#include "textures/public.h"
#include "water/public.h"
static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int) static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
{ {
LightDefinition light; LightComponent light;
light.color.r = 0.6; light.color.r = 0.6;
light.color.g = 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.direction = v3Normalize(light.direction);
light.altered = 1; light.altered = 1;
light.reflection = 0.0; light.reflection = 0.0;
lightingPushLight(status, &light); status->pushComponent(light);
light.color.r = 0.2; light.color.r = 0.2;
light.color.g = 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.direction = v3Normalize(light.direction);
light.altered = 0; light.altered = 0;
light.reflection = 0.0; light.reflection = 0.0;
lightingPushLight(status, &light); status->pushComponent(light);
} }
static Vector3 _getCameraLocation(Renderer*, Vector3 location) static Vector3 _getCameraLocation(Renderer*, Vector3 location)

View file

@ -5,17 +5,12 @@
#include "WaterDefinition.h" #include "WaterDefinition.h"
#include "CameraDefinition.h" #include "CameraDefinition.h"
// TEMP
#include "water/public.h"
#include "terrain/public.h"
#include "atmosphere/public.h"
static double _getWaterHeight(Renderer*) static double _getWaterHeight(Renderer*)
{ {
return 0.0; 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; RayCastingResult result;
int background = *(int*)renderer->customData[1]; 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 < 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; result.hit_color = COLOR_BLACK;
} }
else 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.r *= 1.0 - attenuation;
result.hit_color.g *= 1.0 - attenuation; result.hit_color.g *= 1.0 - attenuation;
result.hit_color.b *= 1.0 - attenuation; result.hit_color.b *= 1.0 - attenuation;
@ -119,9 +115,9 @@ void WaterAspectPreviewRenderer::updateEvent()
getScenery()->getCamera()->setTarget(VECTOR_ZERO); getScenery()->getCamera()->setTarget(VECTOR_ZERO);
prepare(); prepare();
terrain->getWaterHeight = _getWaterHeight; //terrain->getWaterHeight = _getWaterHeight;
atmosphere->getLightingStatus = _getLightingStatus; //atmosphere->getLightingStatus = _getLightingStatus;
rayWalking = _rayWalking; //rayWalking = _rayWalking;
getPrecision = _getPrecision; getPrecision = _getPrecision;
} }

View file

@ -3,11 +3,10 @@
#include "BasePreview.h" #include "BasePreview.h"
#include "Scenery.h" #include "Scenery.h"
#include "TerrainDefinition.h" #include "TerrainDefinition.h"
#include "WaterRenderer.h"
// TEMP // TEMP
#include "RenderingScenery.h" #include "RenderingScenery.h"
#include "terrain/public.h"
#include "water/public.h"
WaterCoveragePreviewRenderer::WaterCoveragePreviewRenderer(WaterDefinition* definition): WaterCoveragePreviewRenderer::WaterCoveragePreviewRenderer(WaterDefinition* definition):
TerrainShapePreviewRenderer(new TerrainDefinition(NULL)), definition(definition) TerrainShapePreviewRenderer(new TerrainDefinition(NULL)), definition(definition)
@ -44,14 +43,13 @@ void WaterCoveragePreviewRenderer::updateEvent()
TerrainShapePreviewRenderer::updateEvent(); TerrainShapePreviewRenderer::updateEvent();
getScenery()->setWater(definition); getScenery()->setWater(definition);
WaterRendererClass.bind(this, definition);
} }
Color WaterCoveragePreviewRenderer::getWaterColor(double x, double y, double) Color WaterCoveragePreviewRenderer::getWaterColor(double x, double y, double)
{ {
Color base; Color base;
base = water->getResult(this, x, y).final; base = getWaterRenderer()->getResult(x, y).final;
if (highlight) if (highlight)
{ {

View file

@ -1,12 +1,5 @@
#include "AtmosphereModelBruneton.h" #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. * Atmospheric scattering, based on E. Bruneton and F.Neyret work.
* http://evasion.inrialpes.fr/~Eric.Bruneton/ * http://evasion.inrialpes.fr/~Eric.Bruneton/
@ -18,12 +11,26 @@
#include <cstdlib> #include <cstdlib>
#include "System.h" #include "System.h"
#include "PackStream.h" #include "PackStream.h"
#include "Scenery.h"
#include "AtmosphereDefinition.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/cache.h"
#include "tools/texture.h" #include "tools/texture.h"
#include "tools/parallel.h" #include "tools/parallel.h"
#include "renderer.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 ***********************/ /*********************** Constants ***********************/
@ -1157,14 +1164,14 @@ int brunetonInit()
static const int _init = brunetonInit(); static const int _init = brunetonInit();
AtmosphereModelBruneton::AtmosphereModelBruneton(AtmosphereRenderer *parent): AtmosphereModelBruneton::AtmosphereModelBruneton(SoftwareRenderer *parent):
parent(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; eye.y += yoffset;
if (eye.y < 0.0) if (eye.y < 0.0)
{ {
@ -1180,9 +1187,8 @@ AtmosphereResult getSkyColor(const Vector3 &eye, const Vector3 &direction, const
AtmosphereResult result; AtmosphereResult result;
Vector3 attenuation; 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.r = base.r + sunColor.r;
result.base.g = base.g + sunColor.g; result.base.g = base.g + sunColor.g;
result.base.b = base.b + sunColor.b;*/ result.base.b = base.b + sunColor.b;*/
@ -1191,17 +1197,17 @@ AtmosphereResult getSkyColor(const Vector3 &eye, const Vector3 &direction, const
/* TODO Use atmosphere attenuation */ /* TODO Use atmosphere attenuation */
result.distance = SPHERE_SIZE; result.distance = SPHERE_SIZE;
atmosphereUpdateResult(&result); result.updateFinal();
return result; 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 eye = parent->getCameraLocation(parent, location);
Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), SUN_DISTANCE); 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; eye.y += yoffset;
location.y += yoffset; location.y += yoffset;
if (eye.y < 0.0) if (eye.y < 0.0)
@ -1230,8 +1236,6 @@ AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &ba
AtmosphereResult result; AtmosphereResult result;
Vector3 attenuation; Vector3 attenuation;
atmosphereInitResult(&result);
result.base = base; result.base = base;
result.inscattering = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */ result.inscattering = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
result.attenuation.r = attenuation.x; result.attenuation.r = attenuation.x;
@ -1239,19 +1243,19 @@ AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &ba
result.attenuation.b = attenuation.z; result.attenuation.b = attenuation.z;
result.distance = t / WORLD_SCALING; result.distance = t / WORLD_SCALING;
atmosphereUpdateResult(&result); result.updateFinal();
return result; 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 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; altitude += yoffset;
if (altitude < 0.0) if (altitude < 0.0)
{ {
@ -1260,7 +1264,7 @@ void fillLightingStatus(LightStatus *status, const Vector3 &, int)
double r0 = Rg + altitude * WORLD_SCALING; double r0 = Rg + altitude * WORLD_SCALING;
Vector3 up = {0.0, 1.0, 0.0}; 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 x = {0.0, r0, 0.0};
Vector3 s = v3Normalize(v3Sub(sun_position, x)); Vector3 s = v3Normalize(v3Sub(sun_position, x));
@ -1270,12 +1274,12 @@ void fillLightingStatus(LightStatus *status, const Vector3 &, int)
sun.reflection = ISun; sun.reflection = ISun;
sun.altered = 1; sun.altered = 1;
lightingPushLight(status, &sun); status->pushComponent(sun);
irradiance.color = _irradiance(_irradianceTexture, r0, muS); irradiance.color = _irradiance(_irradianceTexture, r0, muS);
irradiance.direction = VECTOR_DOWN; irradiance.direction = VECTOR_DOWN;
irradiance.reflection = 0.0; irradiance.reflection = 0.0;
irradiance.altered = 0; irradiance.altered = 0;
lightingPushLight(status, &irradiance); status->pushComponent(irradiance);
} }

View file

@ -11,14 +11,14 @@ namespace software {
class SOFTWARESHARED_EXPORT AtmosphereModelBruneton class SOFTWARESHARED_EXPORT AtmosphereModelBruneton
{ {
public: public:
AtmosphereModelBruneton(AtmosphereRenderer *parent); AtmosphereModelBruneton(SoftwareRenderer *parent);
AtmosphereResult getSkyColor(const Vector3 &eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base); AtmosphereResult getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base);
AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &base); AtmosphereResult applyAerialPerspective(Vector3 location, const Color &base);
void fillLightingStatus(LightStatus *status, const Vector3 &normal, int opaque); void fillLightingStatus(LightStatus *status, const Vector3 &normal, int opaque);
private: private:
AtmosphereRenderer* parent; SoftwareRenderer* parent;
}; };
} }

View file

@ -3,8 +3,19 @@
#include <cmath> #include <cmath>
#include "SoftwareRenderer.h" #include "SoftwareRenderer.h"
#include "AtmosphereDefinition.h" #include "AtmosphereDefinition.h"
#include "AtmosphereModelBruneton.h"
#include "AtmosphereResult.h"
#include "LightComponent.h"
#include "LightStatus.h"
#include "Scenery.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) static inline double _getDayFactor(double daytime)
{ {
daytime = 1.0 - fabs(0.5 - daytime) / 0.5; 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.g *= 1.0 - 0.4 * distancefactor * definition->humidity;
result->attenuation.b *= 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) void BaseAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3, int)
{ {
LightDefinition light; LightComponent light;
light.color.r = 1.0; light.color.r = 1.0;
light.color.g = 1.0; light.color.g = 1.0;
@ -75,7 +86,7 @@ void BaseAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3, int
light.direction.z = 0.7; light.direction.z = 0.7;
light.altered = 0; light.altered = 0;
light.reflection = 0.0; light.reflection = 0.0;
lightingPushLight(status, &light); status->pushComponent(light);
light.color.r = 0.3; light.color.r = 0.3;
light.color.g = 0.31; light.color.g = 0.31;
light.color.b = 0.34; light.color.b = 0.34;
@ -84,7 +95,7 @@ void BaseAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3, int
light.direction.z = -0.7; light.direction.z = -0.7;
light.altered = 0; light.altered = 0;
light.reflection = 0.0; light.reflection = 0.0;
lightingPushLight(status, &light); status->pushComponent(light);
} }
AtmosphereResult BaseAtmosphereRenderer::applyAerialPerspective(Vector3, Color base) AtmosphereResult BaseAtmosphereRenderer::applyAerialPerspective(Vector3, Color base)
@ -115,9 +126,20 @@ AtmosphereDefinition* BaseAtmosphereRenderer::getDefinition()
return renderer->getScenery()->getAtmosphere(); 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) 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) AtmosphereResult SoftwareBrunetonAtmosphereRenderer::applyAerialPerspective(Vector3 location, Color base)
@ -129,7 +151,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::applyAerialPerspective(Vect
switch (definition->model) switch (definition->model)
{ {
case AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON: case AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON:
result = brunetonApplyAerialPerspective(renderer, location, base); result = model->applyAerialPerspective(location, base);
break; break;
default: default:
; ;
@ -188,7 +210,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(Vector3 directi
switch (definition->model) switch (definition->model)
{ {
case AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON: case AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON:
result = brunetonGetSkyColor(renderer, camera_location, direction, sun_position, base); result = model->getSkyColor(camera_location, direction, sun_position, base);
break; break;
default: default:
result = BaseAtmosphereRenderer::applyAerialPerspective(location, result.base); result = BaseAtmosphereRenderer::applyAerialPerspective(location, result.base);

View file

@ -3,6 +3,8 @@
#include "software_global.h" #include "software_global.h"
#include "Color.h"
namespace paysages { namespace paysages {
namespace software { namespace software {
@ -25,11 +27,15 @@ protected:
class SoftwareBrunetonAtmosphereRenderer: public BaseAtmosphereRenderer class SoftwareBrunetonAtmosphereRenderer: public BaseAtmosphereRenderer
{ {
public: public:
SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer):BaseAtmosphereRenderer(renderer) {} SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer);
virtual ~SoftwareBrunetonAtmosphereRenderer();
virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque) override; virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque) override;
virtual AtmosphereResult applyAerialPerspective(Vector3 location, Color base) override; virtual AtmosphereResult applyAerialPerspective(Vector3 location, Color base) override;
virtual AtmosphereResult getSkyColor(Vector3 direction) override; virtual AtmosphereResult getSkyColor(Vector3 direction) override;
private:
AtmosphereModelBruneton* model;
}; };
} }

View file

@ -1,6 +1,7 @@
#include "BaseCloudLayerRenderer.h" #include "BaseCloudLayerRenderer.h"
#include "clouds/BaseCloudsModel.h" #include "clouds/BaseCloudsModel.h"
#include "Vector3.h"
BaseCloudLayerRenderer::BaseCloudLayerRenderer(SoftwareRenderer* parent): BaseCloudLayerRenderer::BaseCloudLayerRenderer(SoftwareRenderer* parent):
parent(parent) parent(parent)
@ -17,7 +18,7 @@ Color BaseCloudLayerRenderer::getColor(BaseCloudsModel *, const Vector3 &, const
return COLOR_TRANSPARENT; return COLOR_TRANSPARENT;
} }
bool BaseCloudLayerRenderer::alterLight(BaseCloudsModel *, LightDefinition *, const Vector3 &, const Vector3 &) bool BaseCloudLayerRenderer::alterLight(BaseCloudsModel *, LightComponent *, const Vector3 &, const Vector3 &)
{ {
return false; return false;
} }

View file

@ -3,8 +3,6 @@
#include "software_global.h" #include "software_global.h"
#include "tools/lighting.h"
namespace paysages { namespace paysages {
namespace software { namespace software {
@ -17,7 +15,7 @@ public:
virtual bool optimizeSearchLimits(BaseCloudsModel *model, Vector3 *start, Vector3 *end); virtual bool optimizeSearchLimits(BaseCloudsModel *model, Vector3 *start, Vector3 *end);
virtual Color getColor(BaseCloudsModel *model, const Vector3 &eye, const Vector3 &location); 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: protected:
SoftwareRenderer* parent; SoftwareRenderer* parent;

View file

@ -5,6 +5,8 @@
#include "NoiseGenerator.h" #include "NoiseGenerator.h"
#include "Curve.h" #include "Curve.h"
#include "AtmosphereRenderer.h" #include "AtmosphereRenderer.h"
#include "AtmosphereResult.h"
#include "LightComponent.h"
#include "clouds/BaseCloudsModel.h" #include "clouds/BaseCloudsModel.h"
#include "SurfaceMaterial.h" #include "SurfaceMaterial.h"
@ -171,7 +173,7 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e
material.shininess = 0.8; material.shininess = 0.8;
materialValidate(&material); 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); col.a = (segments[i].length >= transparency_depth) ? 1.0 : (segments[i].length / transparency_depth);
colorMask(&result, &col); colorMask(&result, &col);
@ -188,7 +190,7 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e
return result; 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; Vector3 start, end;
double inside_depth, total_depth, factor; double inside_depth, total_depth, factor;

View file

@ -5,8 +5,6 @@
#include "BaseCloudLayerRenderer.h" #include "BaseCloudLayerRenderer.h"
#include "tools/lighting.h"
namespace paysages { namespace paysages {
namespace software { namespace software {
@ -22,7 +20,7 @@ public:
CloudBasicLayerRenderer(SoftwareRenderer* parent); CloudBasicLayerRenderer(SoftwareRenderer* parent);
virtual Color getColor(BaseCloudsModel *model, const Vector3 &eye, const Vector3 &location) override; 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;
}; };
} }

View file

@ -132,7 +132,7 @@ Color CloudsRenderer::getColor(const Vector3 &eye, const Vector3 &location, cons
return cumul; 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(); CloudsDefinition* definition = parent->getScenery()->getClouds();

View file

@ -3,8 +3,6 @@
#include "software_global.h" #include "software_global.h"
#include "tools/lighting.h"
namespace paysages { namespace paysages {
namespace software { namespace software {
@ -48,7 +46,7 @@ public:
* *
* Return true if the light was altered. * 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: private:
SoftwareRenderer* parent; SoftwareRenderer* parent;

View file

@ -1,5 +1,9 @@
#include "LightStatus.h" #include "LightStatus.h"
#include "LightingManager.h"
#include "Color.h"
#include "SurfaceMaterial.h"
LightStatus::LightStatus(LightingManager *manager, const Vector3 &location, const Vector3 &eye) LightStatus::LightStatus(LightingManager *manager, const Vector3 &location, const Vector3 &eye)
{ {
this->manager = manager; this->manager = manager;
@ -9,21 +13,21 @@ LightStatus::LightStatus(LightingManager *manager, const Vector3 &location, cons
void LightStatus::pushComponent(LightComponent component) 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 LightStatus::apply(const Vector3 &normal, const SurfaceMaterial &material)
{ {
Color final(); Color final;
for (auto component: components) 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; return final;
} }

View file

@ -18,8 +18,12 @@ class SOFTWARESHARED_EXPORT LightStatus
public: public:
LightStatus(LightingManager *manager, const Vector3 &location, const Vector3 &eye); LightStatus(LightingManager *manager, const Vector3 &location, const Vector3 &eye);
inline Vector3 getLocation() const {return location;}
void pushComponent(LightComponent component); void pushComponent(LightComponent component);
Color apply(const Vector3 &normal, const SurfaceMaterial &material);
private: private:
LightingManager* manager; LightingManager* manager;
Vector3 location; Vector3 location;

View file

@ -3,6 +3,7 @@
#include "LightFilter.h" #include "LightFilter.h"
#include "LightComponent.h" #include "LightComponent.h"
#include "Color.h" #include "Color.h"
#include "SurfaceMaterial.h"
LightingManager::LightingManager() LightingManager::LightingManager()
{ {
@ -11,10 +12,7 @@ LightingManager::LightingManager()
void LightingManager::registerFilter(LightFilter* filter) void LightingManager::registerFilter(LightFilter* filter)
{ {
if (not filters.contains(filter)) filters.insert(filter);
{
filters.add(filter);
}
} }
bool LightingManager::alterLight(LightComponent &component, const Vector3 &location) bool LightingManager::alterLight(LightComponent &component, const Vector3 &location)
@ -23,7 +21,7 @@ bool LightingManager::alterLight(LightComponent &component, const Vector3 &locat
{ {
for (auto filter:filters) for (auto filter:filters)
{ {
if (not filter.app(component, location)) if (not filter->applyLightFilter(component, location))
{ {
return false; return false;
} }
@ -43,43 +41,42 @@ void LightingManager::setSpecularity(bool enabled)
specularity = 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; Color result, light_color;
double normal_norm; double normal_norm;
Vector3 direction_inv; Vector3 direction_inv;
light_color = component->color; light_color = component.color;
direction_inv = v3Scale(v3Normalize(component->direction), -1.0); direction_inv = v3Scale(v3Normalize(component.direction), -1.0);
normal_norm = v3Norm(normal); normal_norm = v3Norm(normal);
if (normal_norm > 1.0) if (normal_norm > 1.0)
{ {
normal_norm = 1.0; normal_norm = 1.0;
} }
normal = v3Normalize(normal);
result = COLOR_BLACK; result = COLOR_BLACK;
/* diffused light */ /* 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)); diffuse = (diffuse + (1.0 - normal_norm)) / (1.0 + (1.0 - normal_norm));
if (diffuse > 0.0) if (diffuse > 0.0)
{ {
result.r += diffuse * material->_rgb.r * light_color.r; result.r += diffuse * material._rgb.r * light_color.r;
result.g += diffuse * material->_rgb.g * light_color.g; result.g += diffuse * material._rgb.g * light_color.g;
result.b += diffuse * material->_rgb.b * light_color.b; result.b += diffuse * material._rgb.b * light_color.b;
} }
/* specular reflection */ /* 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 view = v3Normalize(v3Sub(location, eye));
Vector3 reflect = v3Sub(direction_inv, v3Scale(normal, 2.0 * v3Dot(direction_inv, normal))); Vector3 reflect = v3Sub(direction_inv, v3Scale(normal, 2.0 * v3Dot(direction_inv, normal)));
double specular = v3Dot(reflect, view); double specular = v3Dot(reflect, view);
if (specular > 0.0) 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) if (specular > 0.0)
{ {
result.r += specular * light_color.r; result.r += specular * light_color.r;

View file

@ -3,6 +3,8 @@
#include "software_global.h" #include "software_global.h"
#include <set>
namespace paysages { namespace paysages {
namespace software { namespace software {
@ -35,12 +37,12 @@ public:
/** /**
* @brief Apply a final component on a surface material. * @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: private:
int specularity; int specularity;
std::vector<LightFilter*> filters; std::set<LightFilter*> filters;
}; };
} }

View file

@ -4,6 +4,7 @@
#include "Color.h" #include "Color.h"
#include "SoftwareRenderer.h" #include "SoftwareRenderer.h"
#include "AtmosphereRenderer.h" #include "AtmosphereRenderer.h"
#include "AtmosphereResult.h"
#include "CloudsRenderer.h" #include "CloudsRenderer.h"
#define SPHERE_SIZE 20000.0 #define SPHERE_SIZE 20000.0
@ -22,7 +23,7 @@ static Color _postProcessFragment(SoftwareRenderer* renderer, Vector3 location,
direction = v3Sub(location, camera_location); direction = v3Sub(location, camera_location);
/* TODO Don't compute result->color if it's fully covered by clouds */ /* 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); result = renderer->getCloudsRenderer()->getColor(camera_location, v3Add(camera_location, v3Scale(direction, 10.0)), result);
return result; return result;

View file

@ -5,51 +5,20 @@
#include "FluidMediumManager.h" #include "FluidMediumManager.h"
#include "AtmosphereRenderer.h" #include "AtmosphereRenderer.h"
#include "AtmosphereDefinition.h" #include "AtmosphereDefinition.h"
#include "AtmosphereResult.h"
#include "CloudsRenderer.h" #include "CloudsRenderer.h"
#include "TerrainRenderer.h"
#include "TexturesRenderer.h"
#include "WaterRenderer.h"
#include "SkyRasterizer.h" #include "SkyRasterizer.h"
#include "TerrainRasterizer.h" #include "TerrainRasterizer.h"
#include "WaterRasterizer.h" #include "WaterRasterizer.h"
#include "LightStatus.h"
#include "LightingManager.h"
// Legacy compatibility // Legacy compatibility
#include "renderer.h" #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) static double _getPrecision(Renderer* renderer, Vector3 location)
{ {
Vector3 projected; Vector3 projected;
@ -65,6 +34,9 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
{ {
atmosphere_renderer = new BaseAtmosphereRenderer(this); atmosphere_renderer = new BaseAtmosphereRenderer(this);
clouds_renderer = new CloudsRenderer(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); fluid_medium = new FluidMediumManager(this);
@ -84,6 +56,9 @@ SoftwareRenderer::~SoftwareRenderer()
{ {
delete atmosphere_renderer; delete atmosphere_renderer;
delete clouds_renderer; delete clouds_renderer;
delete terrain_renderer;
delete textures_renderer;
delete water_renderer;
delete fluid_medium; delete fluid_medium;
@ -113,21 +88,18 @@ void SoftwareRenderer::prepare()
clouds_renderer = new CloudsRenderer(this); clouds_renderer = new CloudsRenderer(this);
clouds_renderer->update(); 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) // Setup transitional renderers (for C-legacy subsystems)
rayWalking = _rayWalking;
getPrecision = _getPrecision; 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 // Prepare global tools
fluid_medium->clearMedia(); fluid_medium->clearMedia();
//fluid_medium->registerMedium(water_renderer); //fluid_medium->registerMedium(water_renderer);
@ -145,9 +117,16 @@ void SoftwareRenderer::rasterize()
sky.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 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); color = clouds_renderer->getColor(getCameraLocation(this, location), location, color);
return color; return color;
@ -155,11 +134,20 @@ Color SoftwareRenderer::applyMediumTraversal(Vector3 location, Color color)
return fluid_medium->applyTraversal(eye, location, 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)); RayCastingResult result;
atmosphere->getLightingStatus(renderer, light, normal, 0); Color sky_color;
Color result = lightingApplyStatus(light, normal, material);
lightingDeleteStatus(light); 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; return result;
} }

View file

@ -42,18 +42,29 @@ public:
inline BaseAtmosphereRenderer* getAtmosphereRenderer() const {return atmosphere_renderer;} inline BaseAtmosphereRenderer* getAtmosphereRenderer() const {return atmosphere_renderer;}
inline CloudsRenderer* getCloudsRenderer() const {return clouds_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 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 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: private:
Scenery* scenery; Scenery* scenery;
bool own_scenery; bool own_scenery;
FluidMediumManager* fluid_medium; FluidMediumManager* fluid_medium;
LightingManager* lighting;
BaseAtmosphereRenderer* atmosphere_renderer; BaseAtmosphereRenderer* atmosphere_renderer;
CloudsRenderer* clouds_renderer; CloudsRenderer* clouds_renderer;
TerrainRenderer* terrain_renderer;
TexturesRenderer* textures_renderer;
WaterRenderer* water_renderer;
}; };
} }

View file

@ -3,23 +3,24 @@
#include "SoftwareRenderer.h" #include "SoftwareRenderer.h"
#include "BoundingBox.h" #include "BoundingBox.h"
#include "CameraDefinition.h" #include "CameraDefinition.h"
#include "TerrainRenderer.h"
#include "WaterRenderer.h"
#include "TexturesRenderer.h"
#include "Scenery.h"
#include "tools/parallel.h" #include "tools/parallel.h"
#include "terrain/public.h"
#include "water/public.h"
#include "textures/public.h"
TerrainRasterizer::TerrainRasterizer(SoftwareRenderer* renderer): TerrainRasterizer::TerrainRasterizer(SoftwareRenderer* renderer):
renderer(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; Vector3 result;
result.x = x; result.x = x;
result.y = renderer->terrain->getHeight(renderer, x, z, 1); result.y = renderer->getTerrainRenderer()->getHeight(x, z, 1);
result.z = z; result.z = z;
return result; return result;
@ -30,13 +31,13 @@ static Color _postProcessFragment(Renderer* renderer_, Vector3 point, void*)
double precision; double precision;
SoftwareRenderer* renderer = (SoftwareRenderer*)renderer_; 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); 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 ov1, ov2, ov3, ov4;
Vector3 dv1, dv2, dv3, dv4; 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.x = x;
ov1.z = z; 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.x = x;
ov2.z = z + size; 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.x = x + size;
ov3.z = z + 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.x = x + size;
ov4.z = z; 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) 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; 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 startx = chunk->point_nw.x;
double startz = chunk->point_nw.z; 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_nw = renderer->getTerrainRenderer()->getResult(x, z, 1, displaced).location;
chunk->point_sw = renderer->terrain->getResult(renderer, x, z + size, 1, displaced).location; chunk->point_sw = renderer->getTerrainRenderer()->getResult(x, z + size, 1, displaced).location;
chunk->point_se = renderer->terrain->getResult(renderer, x + size, z + size, 1, displaced).location; chunk->point_se = renderer->getTerrainRenderer()->getResult(x + size, z + size, 1, displaced).location;
chunk->point_ne = renderer->terrain->getResult(renderer, x + size, z, 1, displaced).location; chunk->point_ne = renderer->getTerrainRenderer()->getResult(x + size, z, 1, displaced).location;
double displacement_power; double displacement_power;
if (displaced) if (displaced)
@ -102,7 +103,7 @@ static void _getChunk(Renderer* renderer, TerrainRasterizer::TerrainChunkInfo* c
} }
else else
{ {
displacement_power = texturesGetMaximalDisplacement(renderer->textures->definition); displacement_power = renderer->getTexturesRenderer()->getMaximalDisplacement(renderer->getScenery()->getTextures());
} }
BoundingBox box; BoundingBox box;

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -1,7 +1,7 @@
#include "WaterRasterizer.h" #include "WaterRasterizer.h"
#include "SoftwareRenderer.h" #include "SoftwareRenderer.h"
#include "water/public.h" #include "WaterRenderer.h"
#include "tools/parallel.h" #include "tools/parallel.h"
WaterRasterizer::WaterRasterizer(SoftwareRenderer* renderer): 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; Vector3 result;
result.x = x; result.x = x;
result.y = renderer->water->getHeight(renderer, x, z); result.y = renderer->getWaterRenderer()->getHeight(x, z);
result.z = z; result.z = z;
return result; 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; Vector3 v1, v2, v3, v4;

View file

@ -1,43 +1,22 @@
#include "private.h" #include "WaterRenderer.h"
#include <cmath> #include "SoftwareRenderer.h"
#include "../renderer.h" #include "TerrainRenderer.h"
#include "WaterDefinition.h" #include "WaterDefinition.h"
#include "SurfaceMaterial.h"
#include "NoiseGenerator.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}; WaterRenderer::WaterRenderer(SoftwareRenderer* parent):
parent(parent)
/******************** Fake ********************/
static HeightInfo _fakeGetHeightInfo(Renderer*)
{ {
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) static inline double _getHeight(WaterDefinition* definition, double base_height, double x, double z)
{ {
return base_height + definition->_waves_noise->get2DTotal(x, 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; Color result;
double foam_factor, normal_diff, location_offset; double foam_factor, normal_diff, location_offset;
double base_height; double base_height;
base_height = renderer->terrain->getWaterHeight(renderer); base_height = renderer->getTerrainRenderer()->getWaterHeight();
location_offset = 2.0 * detail; location_offset = 2.0 * detail;
foam_factor = 0.0; foam_factor = 0.0;
@ -156,13 +135,13 @@ static inline Color _getFoamMask(Renderer* renderer, WaterDefinition* definition
return result; 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 factor;
double base_height; double base_height;
base_height = renderer->terrain->getWaterHeight(renderer); base_height = parent->getTerrainRenderer()->getWaterHeight();
if (at.y < base_height) if (at.y < base_height)
{ {
if (light->direction.y <= -0.00001) if (light->direction.y <= -0.00001)
@ -193,14 +172,13 @@ static int _alterLight(Renderer* renderer, LightDefinition* light, Vector3 at)
} }
} }
/******************** Real ********************/ HeightInfo WaterRenderer::getHeightInfo()
static HeightInfo _realGetHeightInfo(Renderer* renderer)
{ {
WaterDefinition* definition = renderer->water->definition; WaterDefinition* definition = parent->getScenery()->getWater();
HeightInfo info; HeightInfo info;
double noise_minvalue, noise_maxvalue; 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); definition->_waves_noise->getRange(&noise_minvalue, &noise_maxvalue);
info.min_height = info.base_height + noise_minvalue; info.min_height = info.base_height + noise_minvalue;
info.max_height = info.base_height + noise_maxvalue; info.max_height = info.base_height + noise_maxvalue;
@ -208,35 +186,35 @@ static HeightInfo _realGetHeightInfo(Renderer* renderer)
return info; 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; WaterResult result;
RayCastingResult refracted; RayCastingResult refracted;
Vector3 location, normal, look_direction; Vector3 location, normal, look_direction;
Color color, foam; Color color, foam;
double base_height, detail, depth; double base_height, detail, depth;
base_height = renderer->terrain->getWaterHeight(renderer); base_height = parent->getTerrainRenderer()->getWaterHeight();
location.x = x; location.x = x;
location.y = _getHeight(definition, base_height, x, z); location.y = _getHeight(definition, base_height, x, z);
location.z = z; location.z = z;
result.location = location; result.location = location;
detail = renderer->getPrecision(renderer, location) * 0.1; detail = parent->getPrecision(parent, location) * 0.1;
if (detail < 0.00001) if (detail < 0.00001)
{ {
detail = 0.00001; detail = 0.00001;
} }
normal = _getNormal(definition, base_height, location, detail); 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 */ /* Reflection */
if (definition->reflection == 0.0) if (definition->reflection == 0.0)
@ -245,7 +223,7 @@ static WaterResult _realGetResult(Renderer* renderer, double x, double z)
} }
else 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 */ /* Transparency/refraction */
@ -256,7 +234,7 @@ static WaterResult _realGetResult(Renderer* renderer, double x, double z)
else else
{ {
Color depth_color = *definition->depth_color; 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)); depth = v3Norm(v3Sub(location, refracted.hit_location));
colorLimitPower(&depth_color, colorGetPower(&refracted.hit_color)); colorLimitPower(&depth_color, colorGetPower(&refracted.hit_color));
if (depth > definition->transparency_depth) if (depth > definition->transparency_depth)
@ -274,59 +252,21 @@ static WaterResult _realGetResult(Renderer* renderer, double x, double z)
} }
/* Lighting from environment */ /* 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.r += result.reflected.r * definition->reflection + result.refracted.r * definition->transparency;
color.g += result.reflected.g * definition->reflection + result.refracted.g * 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; color.b += result.reflected.b * definition->reflection + result.refracted.b * definition->transparency;
/* Merge with foam */ /* Merge with foam */
foam = _getFoamMask(renderer, definition, location, normal, detail); foam = _getFoamMask(parent, definition, location, normal, detail);
colorMask(&color, &foam); colorMask(&color, &foam);
/* Bring color to the camera */ /* Bring color to the camera */
color = renderer->applyMediumTraversal(location, color); color = parent->applyMediumTraversal(location, color);
result.base = definition->material->_rgb; result.base = definition->material->_rgb;
result.final = color; result.final = color;
return result; 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
};

View file

@ -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

View file

@ -29,9 +29,11 @@ SOURCES += SoftwareRenderer.cpp \
LightStatus.cpp \ LightStatus.cpp \
LightFilter.cpp \ LightFilter.cpp \
LightComponent.cpp \ LightComponent.cpp \
WaterRasterizer.cpp \
AtmosphereResult.cpp \ AtmosphereResult.cpp \
AtmosphereModelBruneton.cpp AtmosphereModelBruneton.cpp \
TerrainRenderer.cpp \
TexturesRenderer.cpp \
WaterRenderer.cpp
HEADERS += SoftwareRenderer.h\ HEADERS += SoftwareRenderer.h\
software_global.h \ software_global.h \
@ -50,9 +52,11 @@ HEADERS += SoftwareRenderer.h\
LightStatus.h \ LightStatus.h \
LightFilter.h \ LightFilter.h \
LightComponent.h \ LightComponent.h \
WaterRasterizer.h \
AtmosphereResult.h \ AtmosphereResult.h \
AtmosphereModelBruneton.h AtmosphereModelBruneton.h \
TerrainRenderer.h \
TexturesRenderer.h \
WaterRenderer.h
unix:!symbian { unix:!symbian {
maemo5 { maemo5 {

View file

@ -21,11 +21,17 @@ namespace software {
class BaseAtmosphereRenderer; class BaseAtmosphereRenderer;
class SoftwareBrunetonAtmosphereRenderer; class SoftwareBrunetonAtmosphereRenderer;
class AtmosphereResult;
class AtmosphereModelBruneton;
class CloudsRenderer; class CloudsRenderer;
class BaseCloudLayerRenderer; class BaseCloudLayerRenderer;
class BaseCloudsModel; class BaseCloudsModel;
class TerrainRenderer;
class TexturesRenderer;
class WaterRenderer;
class SkyRasterizer; class SkyRasterizer;
class TerrainRasterizer; class TerrainRasterizer;

View file

@ -1,10 +1,6 @@
#include "RenderingScenery.h" #include "RenderingScenery.h"
#include "renderer.h" #include "renderer.h"
#include "terrain/public.h"
#include "textures/public.h"
#include "water/public.h"
#include "CameraDefinition.h"
static RenderingScenery _main_scenery; static RenderingScenery _main_scenery;

View file

@ -5,9 +5,7 @@
#include "render.h" #include "render.h"
#include "RenderingScenery.h" #include "RenderingScenery.h"
#include "CameraDefinition.h" #include "CameraDefinition.h"
#include "terrain/public.h" #include "SurfaceMaterial.h"
#include "textures/public.h"
#include "water/public.h"
static RayCastingResult _RAYCASTING_NULL = {0, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; 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); 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; pushQuad = _pushQuad;
pushDisplacedTriangle = _pushDisplacedTriangle; pushDisplacedTriangle = _pushDisplacedTriangle;
pushDisplacedQuad = _pushDisplacedQuad; pushDisplacedQuad = _pushDisplacedQuad;
rayWalking = _rayWalking;
terrain = (TerrainRenderer*)TerrainRendererClass.create();
textures = (TexturesRenderer*)TexturesRendererClass.create();
water = (WaterRenderer*)WaterRendererClass.create();
} }
Renderer::~Renderer() Renderer::~Renderer()
{ {
delete render_camera; delete render_camera;
TerrainRendererClass.destroy(terrain);
TexturesRendererClass.destroy(textures);
WaterRendererClass.destroy(water);
renderDeleteArea(render_area); renderDeleteArea(render_area);
} }
@ -147,6 +130,11 @@ Color Renderer::applyLightingToSurface(const Vector3 &, const Vector3 &, const S
return material._rgb; return material._rgb;
} }
RayCastingResult Renderer::rayWalking(const Vector3 &, const Vector3 &, int, int, int, int)
{
return _RAYCASTING_NULL;
}

View file

@ -5,11 +5,6 @@
#include "shared/types.h" #include "shared/types.h"
#include "render.h" #include "render.h"
class LightingManager;
class TerrainRenderer;
class TexturesRenderer;
class WaterRenderer;
class Renderer class Renderer
{ {
public: public:
@ -45,14 +40,7 @@ public:
/* Shortcuts */ /* Shortcuts */
virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material); virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material);
virtual Color applyMediumTraversal(Vector3 location, Color color); virtual Color applyMediumTraversal(Vector3 location, Color color);
virtual RayCastingResult rayWalking(const Vector3 &location, const Vector3 &direction, int terrain, int water, int sky, int clouds);
/* 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;
/* Custom data */ /* Custom data */
void* customData[10]; void* customData[10];

View file

@ -11,16 +11,10 @@ include(../common.pri)
SOURCES += main.cpp \ SOURCES += main.cpp \
renderer.cpp \ renderer.cpp \
render.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/texture.cpp \
tools/parallel.cpp \ tools/parallel.cpp \
tools/data.cpp \ tools/data.cpp \
tools/cache.cpp \ tools/cache.cpp \
water/wat_render.cpp \
RenderingScenery.cpp RenderingScenery.cpp
HEADERS += \ HEADERS += \
@ -28,17 +22,10 @@ HEADERS += \
render.h \ render.h \
main.h \ main.h \
shared/types.h \ shared/types.h \
terrain/public.h \
terrain/private.h \
textures/tex_preview.h \
textures/public.h \
textures/private.h \
tools/texture.h \ tools/texture.h \
tools/parallel.h \ tools/parallel.h \
tools/data.h \ tools/data.h \
tools/cache.h \ tools/cache.h \
water/public.h \
water/private.h \
rendering_global.h \ rendering_global.h \
RenderingScenery.h RenderingScenery.h

View file

@ -1,8 +0,0 @@
#ifndef _PAYSAGES_TERRAIN_PRIVATE_H_
#define _PAYSAGES_TERRAIN_PRIVATE_H_
#include "public.h"
#endif

View file

@ -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

View file

@ -1,332 +0,0 @@
#include "private.h"
#include <cstdlib>
#include <cmath>
#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
};

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -1,220 +0,0 @@
#include "private.h"
#include <cstdlib>
#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
};

View file

@ -1,52 +0,0 @@
#include "private.h"
#include <cmath>
#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;
}

View file

@ -1,7 +0,0 @@
#ifndef _PAYSAGES_WATER_PRIVATE_H_
#define _PAYSAGES_WATER_PRIVATE_H_
#include "public.h"
#endif

View file

@ -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