[Broken WIP] Refactoring terrain, textures and water renderer
This commit is contained in:
parent
b0d9ead01d
commit
74634dfaf1
53 changed files with 896 additions and 1197 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
266
src/render/software/TerrainRenderer.cpp
Normal file
266
src/render/software/TerrainRenderer.cpp
Normal 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;
|
||||||
|
}
|
38
src/render/software/TerrainRenderer.h
Normal file
38
src/render/software/TerrainRenderer.h
Normal 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
|
213
src/render/software/TexturesRenderer.cpp
Normal file
213
src/render/software/TexturesRenderer.cpp
Normal 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;
|
||||||
|
}
|
52
src/render/software/TexturesRenderer.h
Normal file
52
src/render/software/TexturesRenderer.h
Normal 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
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
};
|
|
42
src/render/software/WaterRenderer.h
Normal file
42
src/render/software/WaterRenderer.h
Normal 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
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#ifndef _PAYSAGES_TERRAIN_PRIVATE_H_
|
|
||||||
#define _PAYSAGES_TERRAIN_PRIVATE_H_
|
|
||||||
|
|
||||||
#include "public.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -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
|
|
|
@ -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
|
|
||||||
};
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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
|
|
||||||
};
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
#ifndef _PAYSAGES_WATER_PRIVATE_H_
|
|
||||||
#define _PAYSAGES_WATER_PRIVATE_H_
|
|
||||||
|
|
||||||
#include "public.h"
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -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
|
|
Loading…
Reference in a new issue