[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;
|
||||
void limitPower(double max_power);
|
||||
|
||||
Color add(const Color& other) const;
|
||||
|
||||
public:
|
||||
double r;
|
||||
double g;
|
||||
|
|
|
@ -182,3 +182,8 @@ METHSPEC void Color::limitPower(double max_power)
|
|||
b *= factor;
|
||||
}
|
||||
}
|
||||
|
||||
METHSPEC Color Color::add(const Color& other) const
|
||||
{
|
||||
return Color(r + other.r, g + other.g, b + other.b, a);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
#include "SoftwareRenderer.h"
|
||||
#include "AtmosphereRenderer.h"
|
||||
#include "AtmosphereResult.h"
|
||||
#include "CameraDefinition.h"
|
||||
#include "tools/lighting.h"
|
||||
#include "SurfaceMaterial.h"
|
||||
#include "Scenery.h"
|
||||
#include "BasePreview.h"
|
||||
|
@ -180,13 +180,13 @@ Color AtmosphereColorPreviewRenderer::getColor2D(double x, double y, double)
|
|||
normal = rotation.transform(normal);
|
||||
hit = rotation.transform(hit);
|
||||
|
||||
color = this->applyLightingToSurface(this, hit, normal, &MOUNT_MATERIAL);
|
||||
return this->atmosphere->applyAerialPerspective(this, hit, color).final;
|
||||
color = applyLightingToSurface(hit, normal, MOUNT_MATERIAL);
|
||||
return applyMediumTraversal(hit, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
direction = rotation.transform(direction);
|
||||
|
||||
return this->atmosphere->getSkyColor(this, direction).final;
|
||||
return getAtmosphereRenderer()->getSkyColor(direction).final;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
#include "CloudsAspectPreviewRenderer.h"
|
||||
|
||||
#include "atmosphere/public.h"
|
||||
#include "BasePreview.h"
|
||||
#include "Scenery.h"
|
||||
#include "CloudsDefinition.h"
|
||||
#include "CloudLayerDefinition.h"
|
||||
#include "CloudsRenderer.h"
|
||||
#include "LightStatus.h"
|
||||
#include "LightComponent.h"
|
||||
#include "AtmosphereResult.h"
|
||||
|
||||
static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
|
||||
{
|
||||
LightDefinition light;
|
||||
LightComponent light;
|
||||
|
||||
light.color.r = 0.5;
|
||||
light.color.g = 0.5;
|
||||
|
@ -17,7 +19,7 @@ static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
|
|||
light.direction = Vector3(-1.0, 0.5, 1.0).normalize();
|
||||
light.altered = 1;
|
||||
light.reflection = 0.0;
|
||||
lightingPushLight(status, &light);
|
||||
status->pushComponent(light);
|
||||
|
||||
light.color.r = 0.1;
|
||||
light.color.g = 0.1;
|
||||
|
@ -25,7 +27,7 @@ static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
|
|||
light.direction = Vector3(1.0, -0.5, -1.0).normalize();
|
||||
light.altered = 0;
|
||||
light.reflection = 0.0;
|
||||
lightingPushLight(status, &light);
|
||||
status->pushComponent(light);
|
||||
}
|
||||
|
||||
static double _getDensity(Renderer*, CloudLayerDefinition* layer, Vector3 location)
|
||||
|
@ -81,8 +83,8 @@ void CloudsAspectPreviewRenderer::updateEvent()
|
|||
prepare();
|
||||
|
||||
//clouds->getLayerDensity = _getDensity;
|
||||
atmosphere->getLightingStatus = _getLightingStatus;
|
||||
atmosphere->applyAerialPerspective = _fakeApplyAerialPerspective;
|
||||
//atmosphere->getLightingStatus = _getLightingStatus;
|
||||
//atmosphere->applyAerialPerspective = _fakeApplyAerialPerspective;
|
||||
}
|
||||
|
||||
Color CloudsAspectPreviewRenderer::getColor2D(double x, double y, double)
|
||||
|
|
|
@ -6,11 +6,6 @@
|
|||
#include "CloudLayerDefinition.h"
|
||||
#include "CloudsRenderer.h"
|
||||
|
||||
Color _fakeApplyLightingToSurface(Renderer*, Vector3, Vector3, SurfaceMaterial*)
|
||||
{
|
||||
return COLOR_WHITE;
|
||||
}
|
||||
|
||||
CloudsCoveragePreviewRenderer::CloudsCoveragePreviewRenderer(CloudLayerDefinition* layer):
|
||||
layer(layer)
|
||||
{
|
||||
|
@ -31,7 +26,6 @@ void CloudsCoveragePreviewRenderer::updateEvent()
|
|||
{
|
||||
layer->copy(getScenery()->getClouds()->getCloudLayer(0));
|
||||
prepare();
|
||||
applyLightingToSurface = _fakeApplyLightingToSurface;
|
||||
}
|
||||
|
||||
Color CloudsCoveragePreviewRenderer::getColor2D(double x, double y, double scaling)
|
||||
|
@ -70,3 +64,8 @@ void CloudsCoveragePreviewRenderer::toggleChangeEvent(const std::string &key, bo
|
|||
perspective = value;
|
||||
}
|
||||
}
|
||||
|
||||
Color CloudsCoveragePreviewRenderer::applyLightingToSurface(const Vector3 &, const Vector3 &, const SurfaceMaterial &)
|
||||
{
|
||||
return COLOR_WHITE;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ public:
|
|||
|
||||
virtual void toggleChangeEvent(const std::string &key, bool value) override;
|
||||
|
||||
virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material) override;
|
||||
|
||||
private:
|
||||
bool perspective;
|
||||
CloudLayerDefinition* layer;
|
||||
|
|
|
@ -4,12 +4,6 @@
|
|||
#include "BasePreview.h"
|
||||
#include "Scenery.h"
|
||||
|
||||
// TEMP
|
||||
#include "atmosphere/public.h"
|
||||
#include "tools/lighting.h"
|
||||
#include "terrain/public.h"
|
||||
#include "water/public.h"
|
||||
|
||||
static Vector3 _getCameraLocation(Renderer*, Vector3 location)
|
||||
{
|
||||
return v3Add(location, v3Scale(VECTOR_UP, 50.0));
|
||||
|
|
|
@ -6,16 +6,12 @@
|
|||
#include "SurfaceMaterial.h"
|
||||
#include "NoiseGenerator.h"
|
||||
#include "BasePreview.h"
|
||||
|
||||
// TEMP
|
||||
#include "atmosphere/public.h"
|
||||
#include "tools/lighting.h"
|
||||
#include "textures/public.h"
|
||||
#include "water/public.h"
|
||||
#include "LightComponent.h"
|
||||
#include "LightStatus.h"
|
||||
|
||||
static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
|
||||
{
|
||||
LightDefinition light;
|
||||
LightComponent light;
|
||||
|
||||
light.color.r = 0.6;
|
||||
light.color.g = 0.6;
|
||||
|
@ -26,7 +22,7 @@ static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
|
|||
light.direction = v3Normalize(light.direction);
|
||||
light.altered = 1;
|
||||
light.reflection = 0.0;
|
||||
lightingPushLight(status, &light);
|
||||
status->pushComponent(light);
|
||||
|
||||
light.color.r = 0.2;
|
||||
light.color.g = 0.2;
|
||||
|
@ -37,7 +33,7 @@ static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
|
|||
light.direction = v3Normalize(light.direction);
|
||||
light.altered = 0;
|
||||
light.reflection = 0.0;
|
||||
lightingPushLight(status, &light);
|
||||
status->pushComponent(light);
|
||||
}
|
||||
|
||||
static Vector3 _getCameraLocation(Renderer*, Vector3 location)
|
||||
|
|
|
@ -5,17 +5,12 @@
|
|||
#include "WaterDefinition.h"
|
||||
#include "CameraDefinition.h"
|
||||
|
||||
// TEMP
|
||||
#include "water/public.h"
|
||||
#include "terrain/public.h"
|
||||
#include "atmosphere/public.h"
|
||||
|
||||
static double _getWaterHeight(Renderer*)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int, int, int, int)
|
||||
static RayCastingResult _rayWalking(SoftwareRenderer* renderer, Vector3 location, Vector3 direction, int, int, int, int)
|
||||
{
|
||||
RayCastingResult result;
|
||||
int background = *(int*)renderer->customData[1];
|
||||
|
@ -49,13 +44,14 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector
|
|||
|
||||
if (result.hit_location.y < 0.0)
|
||||
{
|
||||
if (result.hit_location.y < -renderer->water->definition->lighting_depth)
|
||||
double lighting_depth = renderer->getScenery()->getWater()->lighting_depth;
|
||||
if (result.hit_location.y < -lighting_depth)
|
||||
{
|
||||
result.hit_color = COLOR_BLACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
double attenuation = -result.hit_location.y / renderer->water->definition->lighting_depth;
|
||||
double attenuation = -result.hit_location.y / lighting_depth;
|
||||
result.hit_color.r *= 1.0 - attenuation;
|
||||
result.hit_color.g *= 1.0 - attenuation;
|
||||
result.hit_color.b *= 1.0 - attenuation;
|
||||
|
@ -119,9 +115,9 @@ void WaterAspectPreviewRenderer::updateEvent()
|
|||
getScenery()->getCamera()->setTarget(VECTOR_ZERO);
|
||||
prepare();
|
||||
|
||||
terrain->getWaterHeight = _getWaterHeight;
|
||||
atmosphere->getLightingStatus = _getLightingStatus;
|
||||
rayWalking = _rayWalking;
|
||||
//terrain->getWaterHeight = _getWaterHeight;
|
||||
//atmosphere->getLightingStatus = _getLightingStatus;
|
||||
//rayWalking = _rayWalking;
|
||||
getPrecision = _getPrecision;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,10 @@
|
|||
#include "BasePreview.h"
|
||||
#include "Scenery.h"
|
||||
#include "TerrainDefinition.h"
|
||||
#include "WaterRenderer.h"
|
||||
|
||||
// TEMP
|
||||
#include "RenderingScenery.h"
|
||||
#include "terrain/public.h"
|
||||
#include "water/public.h"
|
||||
|
||||
WaterCoveragePreviewRenderer::WaterCoveragePreviewRenderer(WaterDefinition* definition):
|
||||
TerrainShapePreviewRenderer(new TerrainDefinition(NULL)), definition(definition)
|
||||
|
@ -44,14 +43,13 @@ void WaterCoveragePreviewRenderer::updateEvent()
|
|||
TerrainShapePreviewRenderer::updateEvent();
|
||||
|
||||
getScenery()->setWater(definition);
|
||||
WaterRendererClass.bind(this, definition);
|
||||
}
|
||||
|
||||
Color WaterCoveragePreviewRenderer::getWaterColor(double x, double y, double)
|
||||
{
|
||||
Color base;
|
||||
|
||||
base = water->getResult(this, x, y).final;
|
||||
base = getWaterRenderer()->getResult(x, y).final;
|
||||
|
||||
if (highlight)
|
||||
{
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
#include "AtmosphereModelBruneton.h"
|
||||
|
||||
/* Factor to convert software units to kilometers */
|
||||
#define WORLD_SCALING 0.05
|
||||
#define SUN_DISTANCE 149597870.0
|
||||
#define SUN_DISTANCE_SCALED (SUN_DISTANCE / WORLD_SCALING)
|
||||
#define SUN_RADIUS 6.955e5
|
||||
#define SUN_RADIUS_SCALED (SUN_RADIUS / WORLD_SCALING)
|
||||
|
||||
/*
|
||||
* Atmospheric scattering, based on E. Bruneton and F.Neyret work.
|
||||
* http://evasion.inrialpes.fr/~Eric.Bruneton/
|
||||
|
@ -18,12 +11,26 @@
|
|||
#include <cstdlib>
|
||||
#include "System.h"
|
||||
#include "PackStream.h"
|
||||
#include "Scenery.h"
|
||||
#include "AtmosphereDefinition.h"
|
||||
#include "AtmosphereRenderer.h"
|
||||
#include "SoftwareRenderer.h"
|
||||
#include "WaterRenderer.h"
|
||||
#include "LightComponent.h"
|
||||
#include "LightStatus.h"
|
||||
#include "tools/cache.h"
|
||||
#include "tools/texture.h"
|
||||
#include "tools/parallel.h"
|
||||
#include "renderer.h"
|
||||
#include "water/public.h"
|
||||
|
||||
/* Factor to convert software units to kilometers */
|
||||
// TODO This is copied in AtmosphereRenderer
|
||||
#define SPHERE_SIZE 20000.0
|
||||
#define WORLD_SCALING 0.05
|
||||
#define SUN_DISTANCE 149597870.0
|
||||
#define SUN_DISTANCE_SCALED (SUN_DISTANCE / WORLD_SCALING)
|
||||
#define SUN_RADIUS 6.955e5
|
||||
#define SUN_RADIUS_SCALED (SUN_RADIUS / WORLD_SCALING)
|
||||
|
||||
/*********************** Constants ***********************/
|
||||
|
||||
|
@ -1157,14 +1164,14 @@ int brunetonInit()
|
|||
|
||||
static const int _init = brunetonInit();
|
||||
|
||||
AtmosphereModelBruneton::AtmosphereModelBruneton(AtmosphereRenderer *parent):
|
||||
AtmosphereModelBruneton::AtmosphereModelBruneton(SoftwareRenderer *parent):
|
||||
parent(parent)
|
||||
{
|
||||
}
|
||||
|
||||
AtmosphereResult getSkyColor(const Vector3 &eye, const Vector3 &direction, const Vector3 &sun_position, const Color &)
|
||||
AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &)
|
||||
{
|
||||
double yoffset = GROUND_OFFSET - renderer->water->getHeightInfo(renderer).base_height;
|
||||
double yoffset = GROUND_OFFSET - parent->getWaterRenderer()->getHeightInfo().base_height;
|
||||
eye.y += yoffset;
|
||||
if (eye.y < 0.0)
|
||||
{
|
||||
|
@ -1180,9 +1187,8 @@ AtmosphereResult getSkyColor(const Vector3 &eye, const Vector3 &direction, const
|
|||
|
||||
AtmosphereResult result;
|
||||
Vector3 attenuation;
|
||||
Color sunColor = _sunColor(v, s, r, mu, renderer->atmosphere->definition->sun_radius); /* L0 */
|
||||
Color sunColor = _sunColor(v, s, r, mu, parent->getScenery()->getAtmosphere()->sun_radius); /* L0 */
|
||||
|
||||
atmosphereInitResult(&result);
|
||||
/*result.base.r = base.r + sunColor.r;
|
||||
result.base.g = base.g + sunColor.g;
|
||||
result.base.b = base.b + sunColor.b;*/
|
||||
|
@ -1191,17 +1197,17 @@ AtmosphereResult getSkyColor(const Vector3 &eye, const Vector3 &direction, const
|
|||
/* TODO Use atmosphere attenuation */
|
||||
result.distance = SPHERE_SIZE;
|
||||
|
||||
atmosphereUpdateResult(&result);
|
||||
result.updateFinal();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &base)
|
||||
AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 location, const Color &base)
|
||||
{
|
||||
Vector3 eye = renderer->getCameraLocation(renderer, location);
|
||||
Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), SUN_DISTANCE);
|
||||
Vector3 eye = parent->getCameraLocation(parent, location);
|
||||
Vector3 sun_position = v3Scale(parent->getAtmosphereRenderer()->getSunDirection(), SUN_DISTANCE);
|
||||
|
||||
double yoffset = GROUND_OFFSET - renderer->water->getHeightInfo(renderer).base_height;
|
||||
double yoffset = GROUND_OFFSET - parent->getWaterRenderer()->getHeightInfo().base_height;
|
||||
eye.y += yoffset;
|
||||
location.y += yoffset;
|
||||
if (eye.y < 0.0)
|
||||
|
@ -1230,8 +1236,6 @@ AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &ba
|
|||
AtmosphereResult result;
|
||||
Vector3 attenuation;
|
||||
|
||||
atmosphereInitResult(&result);
|
||||
|
||||
result.base = base;
|
||||
result.inscattering = _getInscatterColor(&x, &t, v, s, &r, &mu, &attenuation); /* S[L]-T(x,xs)S[l]|xs */
|
||||
result.attenuation.r = attenuation.x;
|
||||
|
@ -1239,19 +1243,19 @@ AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &ba
|
|||
result.attenuation.b = attenuation.z;
|
||||
result.distance = t / WORLD_SCALING;
|
||||
|
||||
atmosphereUpdateResult(&result);
|
||||
result.updateFinal();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void fillLightingStatus(LightStatus *status, const Vector3 &, int)
|
||||
void AtmosphereModelBruneton::fillLightingStatus(LightStatus *status, const Vector3 &, int)
|
||||
{
|
||||
LightDefinition sun, irradiance;
|
||||
LightComponent sun, irradiance;
|
||||
double muS;
|
||||
|
||||
double altitude = lightingGetStatusLocation(status).y;
|
||||
double altitude = status->getLocation().y;
|
||||
|
||||
double yoffset = GROUND_OFFSET - renderer->water->getHeightInfo(renderer).base_height;
|
||||
double yoffset = GROUND_OFFSET - parent->getWaterRenderer()->getHeightInfo().base_height;
|
||||
altitude += yoffset;
|
||||
if (altitude < 0.0)
|
||||
{
|
||||
|
@ -1260,7 +1264,7 @@ void fillLightingStatus(LightStatus *status, const Vector3 &, int)
|
|||
|
||||
double r0 = Rg + altitude * WORLD_SCALING;
|
||||
Vector3 up = {0.0, 1.0, 0.0};
|
||||
Vector3 sun_position = v3Scale(renderer->atmosphere->getSunDirection(renderer), SUN_DISTANCE);
|
||||
Vector3 sun_position = v3Scale(parent->getAtmosphereRenderer()->getSunDirection(), SUN_DISTANCE);
|
||||
Vector3 x = {0.0, r0, 0.0};
|
||||
Vector3 s = v3Normalize(v3Sub(sun_position, x));
|
||||
|
||||
|
@ -1270,12 +1274,12 @@ void fillLightingStatus(LightStatus *status, const Vector3 &, int)
|
|||
sun.reflection = ISun;
|
||||
sun.altered = 1;
|
||||
|
||||
lightingPushLight(status, &sun);
|
||||
status->pushComponent(sun);
|
||||
|
||||
irradiance.color = _irradiance(_irradianceTexture, r0, muS);
|
||||
irradiance.direction = VECTOR_DOWN;
|
||||
irradiance.reflection = 0.0;
|
||||
irradiance.altered = 0;
|
||||
|
||||
lightingPushLight(status, &irradiance);
|
||||
status->pushComponent(irradiance);
|
||||
}
|
||||
|
|
|
@ -11,14 +11,14 @@ namespace software {
|
|||
class SOFTWARESHARED_EXPORT AtmosphereModelBruneton
|
||||
{
|
||||
public:
|
||||
AtmosphereModelBruneton(AtmosphereRenderer *parent);
|
||||
AtmosphereModelBruneton(SoftwareRenderer *parent);
|
||||
|
||||
AtmosphereResult getSkyColor(const Vector3 &eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base);
|
||||
AtmosphereResult applyAerialPerspective(const Vector3 &location, const Color &base);
|
||||
AtmosphereResult getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base);
|
||||
AtmosphereResult applyAerialPerspective(Vector3 location, const Color &base);
|
||||
void fillLightingStatus(LightStatus *status, const Vector3 &normal, int opaque);
|
||||
|
||||
private:
|
||||
AtmosphereRenderer* parent;
|
||||
SoftwareRenderer* parent;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -3,8 +3,19 @@
|
|||
#include <cmath>
|
||||
#include "SoftwareRenderer.h"
|
||||
#include "AtmosphereDefinition.h"
|
||||
#include "AtmosphereModelBruneton.h"
|
||||
#include "AtmosphereResult.h"
|
||||
#include "LightComponent.h"
|
||||
#include "LightStatus.h"
|
||||
#include "Scenery.h"
|
||||
|
||||
/* Factor to convert software units to kilometers */
|
||||
#define WORLD_SCALING 0.05
|
||||
#define SUN_DISTANCE 149597870.0
|
||||
#define SUN_DISTANCE_SCALED (SUN_DISTANCE / WORLD_SCALING)
|
||||
#define SUN_RADIUS 6.955e5
|
||||
#define SUN_RADIUS_SCALED (SUN_RADIUS / WORLD_SCALING)
|
||||
|
||||
static inline double _getDayFactor(double daytime)
|
||||
{
|
||||
daytime = 1.0 - fabs(0.5 - daytime) / 0.5;
|
||||
|
@ -53,7 +64,7 @@ static inline void _applyWeatherEffects(AtmosphereDefinition* definition, Atmosp
|
|||
result->attenuation.g *= 1.0 - 0.4 * distancefactor * definition->humidity;
|
||||
result->attenuation.b *= 1.0 - 0.4 * distancefactor * definition->humidity;
|
||||
|
||||
atmosphereUpdateResult(result);
|
||||
result->updateFinal();
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,7 +76,7 @@ BaseAtmosphereRenderer::BaseAtmosphereRenderer(SoftwareRenderer* renderer):
|
|||
|
||||
void BaseAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3, int)
|
||||
{
|
||||
LightDefinition light;
|
||||
LightComponent light;
|
||||
|
||||
light.color.r = 1.0;
|
||||
light.color.g = 1.0;
|
||||
|
@ -75,7 +86,7 @@ void BaseAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3, int
|
|||
light.direction.z = 0.7;
|
||||
light.altered = 0;
|
||||
light.reflection = 0.0;
|
||||
lightingPushLight(status, &light);
|
||||
status->pushComponent(light);
|
||||
light.color.r = 0.3;
|
||||
light.color.g = 0.31;
|
||||
light.color.b = 0.34;
|
||||
|
@ -84,7 +95,7 @@ void BaseAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3, int
|
|||
light.direction.z = -0.7;
|
||||
light.altered = 0;
|
||||
light.reflection = 0.0;
|
||||
lightingPushLight(status, &light);
|
||||
status->pushComponent(light);
|
||||
}
|
||||
|
||||
AtmosphereResult BaseAtmosphereRenderer::applyAerialPerspective(Vector3, Color base)
|
||||
|
@ -115,9 +126,20 @@ AtmosphereDefinition* BaseAtmosphereRenderer::getDefinition()
|
|||
return renderer->getScenery()->getAtmosphere();
|
||||
}
|
||||
|
||||
SoftwareBrunetonAtmosphereRenderer::SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer):
|
||||
BaseAtmosphereRenderer(renderer)
|
||||
{
|
||||
model = new AtmosphereModelBruneton(this);
|
||||
}
|
||||
|
||||
SoftwareBrunetonAtmosphereRenderer::~SoftwareBrunetonAtmosphereRenderer()
|
||||
{
|
||||
delete model;
|
||||
}
|
||||
|
||||
void SoftwareBrunetonAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3 normal, int opaque)
|
||||
{
|
||||
return brunetonGetLightingStatus(renderer, status, normal, opaque);
|
||||
return model->fillLightingStatus(status, normal, opaque);
|
||||
}
|
||||
|
||||
AtmosphereResult SoftwareBrunetonAtmosphereRenderer::applyAerialPerspective(Vector3 location, Color base)
|
||||
|
@ -129,7 +151,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::applyAerialPerspective(Vect
|
|||
switch (definition->model)
|
||||
{
|
||||
case AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON:
|
||||
result = brunetonApplyAerialPerspective(renderer, location, base);
|
||||
result = model->applyAerialPerspective(location, base);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
|
@ -188,7 +210,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(Vector3 directi
|
|||
switch (definition->model)
|
||||
{
|
||||
case AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON:
|
||||
result = brunetonGetSkyColor(renderer, camera_location, direction, sun_position, base);
|
||||
result = model->getSkyColor(camera_location, direction, sun_position, base);
|
||||
break;
|
||||
default:
|
||||
result = BaseAtmosphereRenderer::applyAerialPerspective(location, result.base);
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "software_global.h"
|
||||
|
||||
#include "Color.h"
|
||||
|
||||
namespace paysages {
|
||||
namespace software {
|
||||
|
||||
|
@ -25,11 +27,15 @@ protected:
|
|||
class SoftwareBrunetonAtmosphereRenderer: public BaseAtmosphereRenderer
|
||||
{
|
||||
public:
|
||||
SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer):BaseAtmosphereRenderer(renderer) {}
|
||||
SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer);
|
||||
virtual ~SoftwareBrunetonAtmosphereRenderer();
|
||||
|
||||
virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque) override;
|
||||
virtual AtmosphereResult applyAerialPerspective(Vector3 location, Color base) override;
|
||||
virtual AtmosphereResult getSkyColor(Vector3 direction) override;
|
||||
|
||||
private:
|
||||
AtmosphereModelBruneton* model;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "BaseCloudLayerRenderer.h"
|
||||
|
||||
#include "clouds/BaseCloudsModel.h"
|
||||
#include "Vector3.h"
|
||||
|
||||
BaseCloudLayerRenderer::BaseCloudLayerRenderer(SoftwareRenderer* parent):
|
||||
parent(parent)
|
||||
|
@ -17,7 +18,7 @@ Color BaseCloudLayerRenderer::getColor(BaseCloudsModel *, const Vector3 &, const
|
|||
return COLOR_TRANSPARENT;
|
||||
}
|
||||
|
||||
bool BaseCloudLayerRenderer::alterLight(BaseCloudsModel *, LightDefinition *, const Vector3 &, const Vector3 &)
|
||||
bool BaseCloudLayerRenderer::alterLight(BaseCloudsModel *, LightComponent *, const Vector3 &, const Vector3 &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include "software_global.h"
|
||||
|
||||
#include "tools/lighting.h"
|
||||
|
||||
namespace paysages {
|
||||
namespace software {
|
||||
|
||||
|
@ -17,7 +15,7 @@ public:
|
|||
virtual bool optimizeSearchLimits(BaseCloudsModel *model, Vector3 *start, Vector3 *end);
|
||||
|
||||
virtual Color getColor(BaseCloudsModel *model, const Vector3 &eye, const Vector3 &location);
|
||||
virtual bool alterLight(BaseCloudsModel *model, LightDefinition* light, const Vector3 &eye, const Vector3 &location);
|
||||
virtual bool alterLight(BaseCloudsModel *model, LightComponent* light, const Vector3 &eye, const Vector3 &location);
|
||||
|
||||
protected:
|
||||
SoftwareRenderer* parent;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "NoiseGenerator.h"
|
||||
#include "Curve.h"
|
||||
#include "AtmosphereRenderer.h"
|
||||
#include "AtmosphereResult.h"
|
||||
#include "LightComponent.h"
|
||||
#include "clouds/BaseCloudsModel.h"
|
||||
#include "SurfaceMaterial.h"
|
||||
|
||||
|
@ -171,7 +173,7 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e
|
|||
material.shininess = 0.8;
|
||||
materialValidate(&material);
|
||||
|
||||
col = parent->applyLightingToSurface(parent, segments[i].start, parent->getAtmosphereRenderer()->getSunDirection(), &material);
|
||||
col = parent->applyLightingToSurface(segments[i].start, parent->getAtmosphereRenderer()->getSunDirection(), material);
|
||||
|
||||
col.a = (segments[i].length >= transparency_depth) ? 1.0 : (segments[i].length / transparency_depth);
|
||||
colorMask(&result, &col);
|
||||
|
@ -188,7 +190,7 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e
|
|||
return result;
|
||||
}
|
||||
|
||||
bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightDefinition* light, const Vector3 &, const Vector3 &location)
|
||||
bool CloudBasicLayerRenderer::alterLight(BaseCloudsModel *model, LightComponent* light, const Vector3 &, const Vector3 &location)
|
||||
{
|
||||
Vector3 start, end;
|
||||
double inside_depth, total_depth, factor;
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
#include "BaseCloudLayerRenderer.h"
|
||||
|
||||
#include "tools/lighting.h"
|
||||
|
||||
namespace paysages {
|
||||
namespace software {
|
||||
|
||||
|
@ -22,7 +20,7 @@ public:
|
|||
CloudBasicLayerRenderer(SoftwareRenderer* parent);
|
||||
|
||||
virtual Color getColor(BaseCloudsModel *model, const Vector3 &eye, const Vector3 &location) override;
|
||||
virtual bool alterLight(BaseCloudsModel *model, LightDefinition* light, const Vector3 &eye, const Vector3 &location) override;
|
||||
virtual bool alterLight(BaseCloudsModel *model, LightComponent* light, const Vector3 &eye, const Vector3 &location) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ Color CloudsRenderer::getColor(const Vector3 &eye, const Vector3 &location, cons
|
|||
return cumul;
|
||||
}
|
||||
|
||||
bool CloudsRenderer::alterLight(LightDefinition* light, const Vector3 &eye, const Vector3 &location)
|
||||
bool CloudsRenderer::alterLight(LightComponent* light, const Vector3 &eye, const Vector3 &location)
|
||||
{
|
||||
CloudsDefinition* definition = parent->getScenery()->getClouds();
|
||||
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include "software_global.h"
|
||||
|
||||
#include "tools/lighting.h"
|
||||
|
||||
namespace paysages {
|
||||
namespace software {
|
||||
|
||||
|
@ -48,7 +46,7 @@ public:
|
|||
*
|
||||
* Return true if the light was altered.
|
||||
*/
|
||||
virtual bool alterLight(LightDefinition* light, const Vector3 &eye, const Vector3 &location);
|
||||
virtual bool alterLight(LightComponent* light, const Vector3 &eye, const Vector3 &location);
|
||||
private:
|
||||
SoftwareRenderer* parent;
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#include "LightStatus.h"
|
||||
|
||||
#include "LightingManager.h"
|
||||
#include "Color.h"
|
||||
#include "SurfaceMaterial.h"
|
||||
|
||||
LightStatus::LightStatus(LightingManager *manager, const Vector3 &location, const Vector3 &eye)
|
||||
{
|
||||
this->manager = manager;
|
||||
|
@ -9,21 +13,21 @@ LightStatus::LightStatus(LightingManager *manager, const Vector3 &location, cons
|
|||
|
||||
void LightStatus::pushComponent(LightComponent component)
|
||||
{
|
||||
if (manager->filter(&component, location))
|
||||
if (manager->alterLight(component, location))
|
||||
{
|
||||
components.add(component);
|
||||
components.push_back(component);
|
||||
}
|
||||
}
|
||||
|
||||
Color LightStatus::apply(const Vector3 &normal, const SurfaceMaterial &material)
|
||||
{
|
||||
Color final();
|
||||
Color final;
|
||||
|
||||
for (auto component: components)
|
||||
{
|
||||
final.add(manager->applyFinalComponent(component, eye, location, normal, material));
|
||||
final = final.add(manager->applyFinalComponent(component, eye, location, normal, material));
|
||||
}
|
||||
|
||||
final.a = material->base.a;
|
||||
final.a = material.base.a;
|
||||
return final;
|
||||
}
|
||||
|
|
|
@ -18,8 +18,12 @@ class SOFTWARESHARED_EXPORT LightStatus
|
|||
public:
|
||||
LightStatus(LightingManager *manager, const Vector3 &location, const Vector3 &eye);
|
||||
|
||||
inline Vector3 getLocation() const {return location;}
|
||||
|
||||
void pushComponent(LightComponent component);
|
||||
|
||||
Color apply(const Vector3 &normal, const SurfaceMaterial &material);
|
||||
|
||||
private:
|
||||
LightingManager* manager;
|
||||
Vector3 location;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "LightFilter.h"
|
||||
#include "LightComponent.h"
|
||||
#include "Color.h"
|
||||
#include "SurfaceMaterial.h"
|
||||
|
||||
LightingManager::LightingManager()
|
||||
{
|
||||
|
@ -11,10 +12,7 @@ LightingManager::LightingManager()
|
|||
|
||||
void LightingManager::registerFilter(LightFilter* filter)
|
||||
{
|
||||
if (not filters.contains(filter))
|
||||
{
|
||||
filters.add(filter);
|
||||
}
|
||||
filters.insert(filter);
|
||||
}
|
||||
|
||||
bool LightingManager::alterLight(LightComponent &component, const Vector3 &location)
|
||||
|
@ -23,7 +21,7 @@ bool LightingManager::alterLight(LightComponent &component, const Vector3 &locat
|
|||
{
|
||||
for (auto filter:filters)
|
||||
{
|
||||
if (not filter.app(component, location))
|
||||
if (not filter->applyLightFilter(component, location))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -43,43 +41,42 @@ void LightingManager::setSpecularity(bool enabled)
|
|||
specularity = enabled;
|
||||
}
|
||||
|
||||
void applyFinalComponent(const LightComponent &component, const Vector3 &eye, const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material)
|
||||
Color LightingManager::applyFinalComponent(const LightComponent &component, const Vector3 &eye, const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material)
|
||||
{
|
||||
Color result, light_color;
|
||||
double normal_norm;
|
||||
Vector3 direction_inv;
|
||||
|
||||
light_color = component->color;
|
||||
direction_inv = v3Scale(v3Normalize(component->direction), -1.0);
|
||||
light_color = component.color;
|
||||
direction_inv = v3Scale(v3Normalize(component.direction), -1.0);
|
||||
|
||||
normal_norm = v3Norm(normal);
|
||||
if (normal_norm > 1.0)
|
||||
{
|
||||
normal_norm = 1.0;
|
||||
}
|
||||
normal = v3Normalize(normal);
|
||||
|
||||
result = COLOR_BLACK;
|
||||
|
||||
/* diffused light */
|
||||
double diffuse = v3Dot(direction_inv, normal);
|
||||
double diffuse = v3Dot(direction_inv, normal.normalize());
|
||||
diffuse = (diffuse + (1.0 - normal_norm)) / (1.0 + (1.0 - normal_norm));
|
||||
if (diffuse > 0.0)
|
||||
{
|
||||
result.r += diffuse * material->_rgb.r * light_color.r;
|
||||
result.g += diffuse * material->_rgb.g * light_color.g;
|
||||
result.b += diffuse * material->_rgb.b * light_color.b;
|
||||
result.r += diffuse * material._rgb.r * light_color.r;
|
||||
result.g += diffuse * material._rgb.g * light_color.g;
|
||||
result.b += diffuse * material._rgb.b * light_color.b;
|
||||
}
|
||||
|
||||
/* specular reflection */
|
||||
if (material->reflection > 0.0 && light->reflection > 0.0)
|
||||
if (material.reflection > 0.0 && component.reflection > 0.0)
|
||||
{
|
||||
Vector3 view = v3Normalize(v3Sub(location, eye));
|
||||
Vector3 reflect = v3Sub(direction_inv, v3Scale(normal, 2.0 * v3Dot(direction_inv, normal)));
|
||||
double specular = v3Dot(reflect, view);
|
||||
if (specular > 0.0)
|
||||
{
|
||||
specular = pow(specular, material->shininess) * material->reflection * light->reflection * normal_norm;
|
||||
specular = pow(specular, material.shininess) * material.reflection * component.reflection * normal_norm;
|
||||
if (specular > 0.0)
|
||||
{
|
||||
result.r += specular * light_color.r;
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "software_global.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace paysages {
|
||||
namespace software {
|
||||
|
||||
|
@ -35,12 +37,12 @@ public:
|
|||
/**
|
||||
* @brief Apply a final component on a surface material.
|
||||
*/
|
||||
void applyFinalComponent(const LightComponent &component, const Vector3 &eye, const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material);
|
||||
Color applyFinalComponent(const LightComponent &component, const Vector3 &eye, const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material);
|
||||
|
||||
private:
|
||||
int specularity;
|
||||
|
||||
std::vector<LightFilter*> filters;
|
||||
std::set<LightFilter*> filters;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "Color.h"
|
||||
#include "SoftwareRenderer.h"
|
||||
#include "AtmosphereRenderer.h"
|
||||
#include "AtmosphereResult.h"
|
||||
#include "CloudsRenderer.h"
|
||||
|
||||
#define SPHERE_SIZE 20000.0
|
||||
|
@ -22,7 +23,7 @@ static Color _postProcessFragment(SoftwareRenderer* renderer, Vector3 location,
|
|||
direction = v3Sub(location, camera_location);
|
||||
|
||||
/* TODO Don't compute result->color if it's fully covered by clouds */
|
||||
result = renderer->atmosphere->getSkyColor(renderer, v3Normalize(direction)).final;
|
||||
result = renderer->getAtmosphereRenderer()->getSkyColor(v3Normalize(direction)).final;
|
||||
result = renderer->getCloudsRenderer()->getColor(camera_location, v3Add(camera_location, v3Scale(direction, 10.0)), result);
|
||||
|
||||
return result;
|
||||
|
|
|
@ -5,51 +5,20 @@
|
|||
#include "FluidMediumManager.h"
|
||||
#include "AtmosphereRenderer.h"
|
||||
#include "AtmosphereDefinition.h"
|
||||
#include "AtmosphereResult.h"
|
||||
#include "CloudsRenderer.h"
|
||||
#include "TerrainRenderer.h"
|
||||
#include "TexturesRenderer.h"
|
||||
#include "WaterRenderer.h"
|
||||
#include "SkyRasterizer.h"
|
||||
#include "TerrainRasterizer.h"
|
||||
#include "WaterRasterizer.h"
|
||||
#include "LightStatus.h"
|
||||
#include "LightingManager.h"
|
||||
|
||||
|
||||
// Legacy compatibility
|
||||
#include "renderer.h"
|
||||
#include "terrain/public.h"
|
||||
#include "textures/public.h"
|
||||
#include "water/public.h"
|
||||
static AtmosphereResult _legacyApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base)
|
||||
{
|
||||
return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->applyAerialPerspective(location, base);
|
||||
}
|
||||
static AtmosphereResult _legacyGetSkyColor(Renderer* renderer, Vector3 direction)
|
||||
{
|
||||
return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->getSkyColor(direction);
|
||||
}
|
||||
static void _legacyGetLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque)
|
||||
{
|
||||
return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->getLightingStatus(status, normal, opaque);
|
||||
}
|
||||
static Vector3 _legacyGetSunDirection(Renderer* renderer)
|
||||
{
|
||||
return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->getSunDirection();
|
||||
}
|
||||
static RayCastingResult _rayWalking(Renderer* renderer_, Vector3 location, Vector3 direction, int, int, int, int)
|
||||
{
|
||||
SoftwareRenderer* renderer = (SoftwareRenderer*)renderer_;
|
||||
RayCastingResult result;
|
||||
Color sky_color;
|
||||
|
||||
result = renderer->terrain->castRay(renderer, location, direction);
|
||||
if (!result.hit)
|
||||
{
|
||||
sky_color = renderer->atmosphere->getSkyColor(renderer, direction).final;
|
||||
|
||||
result.hit = 1;
|
||||
result.hit_location = v3Add(location, v3Scale(direction, 1000.0));
|
||||
result.hit_color = renderer->getCloudsRenderer()->getColor(location, result.hit_location, sky_color);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
static double _getPrecision(Renderer* renderer, Vector3 location)
|
||||
{
|
||||
Vector3 projected;
|
||||
|
@ -65,6 +34,9 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
|
|||
{
|
||||
atmosphere_renderer = new BaseAtmosphereRenderer(this);
|
||||
clouds_renderer = new CloudsRenderer(this);
|
||||
terrain_renderer = new TerrainRenderer(this);
|
||||
textures_renderer = new TexturesRenderer(this);
|
||||
water_renderer = new WaterRenderer(this);
|
||||
|
||||
fluid_medium = new FluidMediumManager(this);
|
||||
|
||||
|
@ -84,6 +56,9 @@ SoftwareRenderer::~SoftwareRenderer()
|
|||
{
|
||||
delete atmosphere_renderer;
|
||||
delete clouds_renderer;
|
||||
delete terrain_renderer;
|
||||
delete textures_renderer;
|
||||
delete water_renderer;
|
||||
|
||||
delete fluid_medium;
|
||||
|
||||
|
@ -113,21 +88,18 @@ void SoftwareRenderer::prepare()
|
|||
clouds_renderer = new CloudsRenderer(this);
|
||||
clouds_renderer->update();
|
||||
|
||||
delete terrain_renderer;
|
||||
terrain_renderer = new TerrainRenderer(this);
|
||||
|
||||
delete textures_renderer;
|
||||
textures_renderer = new TexturesRenderer(this);
|
||||
|
||||
delete water_renderer;
|
||||
water_renderer = new WaterRenderer(this);
|
||||
|
||||
// Setup transitional renderers (for C-legacy subsystems)
|
||||
rayWalking = _rayWalking;
|
||||
getPrecision = _getPrecision;
|
||||
|
||||
scenery->getAtmosphere()->copy(atmosphere->definition);
|
||||
atmosphere->applyAerialPerspective = _legacyApplyAerialPerspective;
|
||||
atmosphere->getSkyColor = _legacyGetSkyColor;
|
||||
atmosphere->getLightingStatus = _legacyGetLightingStatus;
|
||||
atmosphere->getSunDirection = _legacyGetSunDirection;
|
||||
|
||||
scenery->getCamera()->copy(render_camera);
|
||||
TerrainRendererClass.bind(this, scenery->getTerrain());
|
||||
TexturesRendererClass.bind(this, scenery->getTextures());
|
||||
WaterRendererClass.bind(this, scenery->getWater());
|
||||
|
||||
// Prepare global tools
|
||||
fluid_medium->clearMedia();
|
||||
//fluid_medium->registerMedium(water_renderer);
|
||||
|
@ -145,9 +117,16 @@ void SoftwareRenderer::rasterize()
|
|||
sky.rasterize();
|
||||
}
|
||||
|
||||
Color SoftwareRenderer::applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material)
|
||||
{
|
||||
LightStatus status(lighting, location, getCameraLocation(this, location));
|
||||
atmosphere_renderer->getLightingStatus(&status, normal, 0);
|
||||
return status.apply(normal, material);
|
||||
}
|
||||
|
||||
Color SoftwareRenderer::applyMediumTraversal(Vector3 location, Color color)
|
||||
{
|
||||
color = atmosphere->applyAerialPerspective(this, location, color).final;
|
||||
color = atmosphere_renderer->applyAerialPerspective(location, color).final;
|
||||
color = clouds_renderer->getColor(getCameraLocation(this, location), location, color);
|
||||
return color;
|
||||
|
||||
|
@ -155,11 +134,20 @@ Color SoftwareRenderer::applyMediumTraversal(Vector3 location, Color color)
|
|||
return fluid_medium->applyTraversal(eye, location, color);*/
|
||||
}
|
||||
|
||||
Color SoftwareRenderer::applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material)
|
||||
RayCastingResult SoftwareRenderer::rayWalking(const Vector3 &location, const Vector3 &direction, int, int, int, int)
|
||||
{
|
||||
LightStatus* light = lightingCreateStatus(lighting, location, getCameraLocation(renderer, location));
|
||||
atmosphere->getLightingStatus(renderer, light, normal, 0);
|
||||
Color result = lightingApplyStatus(light, normal, material);
|
||||
lightingDeleteStatus(light);
|
||||
RayCastingResult result;
|
||||
Color sky_color;
|
||||
|
||||
result = terrain_renderer->castRay(location, direction);
|
||||
if (!result.hit)
|
||||
{
|
||||
sky_color = atmosphere_renderer->getSkyColor(direction).final;
|
||||
|
||||
result.hit = 1;
|
||||
result.hit_location = v3Add(location, v3Scale(direction, 1000.0));
|
||||
result.hit_color = clouds_renderer->getColor(location, result.hit_location, sky_color);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -42,18 +42,29 @@ public:
|
|||
|
||||
inline BaseAtmosphereRenderer* getAtmosphereRenderer() const {return atmosphere_renderer;}
|
||||
inline CloudsRenderer* getCloudsRenderer() const {return clouds_renderer;}
|
||||
inline TerrainRenderer* getTerrainRenderer() const {return terrain_renderer;}
|
||||
inline TexturesRenderer* getTexturesRenderer() const {return textures_renderer;}
|
||||
inline WaterRenderer* getWaterRenderer() const {return water_renderer;}
|
||||
|
||||
inline FluidMediumManager* getFluidMediumManager() const {return fluid_medium;}
|
||||
inline LightingManager* getLightingManager() const {return lighting;}
|
||||
|
||||
virtual Color applyMediumTraversal(Vector3 location, Color color) override;
|
||||
virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material) override;
|
||||
virtual Color applyMediumTraversal(Vector3 location, Color color) override;
|
||||
virtual RayCastingResult rayWalking(const Vector3 &location, const Vector3 &direction, int terrain, int water, int sky, int clouds) override;
|
||||
|
||||
private:
|
||||
Scenery* scenery;
|
||||
bool own_scenery;
|
||||
|
||||
FluidMediumManager* fluid_medium;
|
||||
LightingManager* lighting;
|
||||
|
||||
BaseAtmosphereRenderer* atmosphere_renderer;
|
||||
CloudsRenderer* clouds_renderer;
|
||||
TerrainRenderer* terrain_renderer;
|
||||
TexturesRenderer* textures_renderer;
|
||||
WaterRenderer* water_renderer;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -3,23 +3,24 @@
|
|||
#include "SoftwareRenderer.h"
|
||||
#include "BoundingBox.h"
|
||||
#include "CameraDefinition.h"
|
||||
#include "TerrainRenderer.h"
|
||||
#include "WaterRenderer.h"
|
||||
#include "TexturesRenderer.h"
|
||||
#include "Scenery.h"
|
||||
|
||||
#include "tools/parallel.h"
|
||||
#include "terrain/public.h"
|
||||
#include "water/public.h"
|
||||
#include "textures/public.h"
|
||||
|
||||
TerrainRasterizer::TerrainRasterizer(SoftwareRenderer* renderer):
|
||||
renderer(renderer)
|
||||
{
|
||||
}
|
||||
|
||||
static inline Vector3 _getPoint(TerrainDefinition*, SoftwareRenderer* renderer, double x, double z)
|
||||
static inline Vector3 _getPoint(SoftwareRenderer* renderer, double x, double z)
|
||||
{
|
||||
Vector3 result;
|
||||
|
||||
result.x = x;
|
||||
result.y = renderer->terrain->getHeight(renderer, x, z, 1);
|
||||
result.y = renderer->getTerrainRenderer()->getHeight(x, z, 1);
|
||||
result.z = z;
|
||||
|
||||
return result;
|
||||
|
@ -30,13 +31,13 @@ static Color _postProcessFragment(Renderer* renderer_, Vector3 point, void*)
|
|||
double precision;
|
||||
SoftwareRenderer* renderer = (SoftwareRenderer*)renderer_;
|
||||
|
||||
point = _getPoint(renderer->terrain->definition, renderer, point.x, point.z);
|
||||
point = _getPoint(renderer, point.x, point.z);
|
||||
|
||||
precision = renderer->getPrecision(renderer, point);
|
||||
return renderer->terrain->getFinalColor(renderer, point, precision);
|
||||
return renderer->getTerrainRenderer()->getFinalColor(point, precision);
|
||||
}
|
||||
|
||||
static void _renderQuad(Renderer* renderer, double x, double z, double size, double water_height)
|
||||
static void _renderQuad(SoftwareRenderer* renderer, double x, double z, double size, double water_height)
|
||||
{
|
||||
Vector3 ov1, ov2, ov3, ov4;
|
||||
Vector3 dv1, dv2, dv3, dv4;
|
||||
|
@ -45,19 +46,19 @@ static void _renderQuad(Renderer* renderer, double x, double z, double size, dou
|
|||
|
||||
ov1.x = x;
|
||||
ov1.z = z;
|
||||
dv1 = renderer->terrain->getResult(renderer, x, z, 1, 1).location;
|
||||
dv1 = renderer->getTerrainRenderer()->getResult(x, z, 1, 1).location;
|
||||
|
||||
ov2.x = x;
|
||||
ov2.z = z + size;
|
||||
dv2 = renderer->terrain->getResult(renderer, x, z + size, 1, 1).location;
|
||||
dv2 = renderer->getTerrainRenderer()->getResult(x, z + size, 1, 1).location;
|
||||
|
||||
ov3.x = x + size;
|
||||
ov3.z = z + size;
|
||||
dv3 = renderer->terrain->getResult(renderer, x + size, z + size, 1, 1).location;
|
||||
dv3 = renderer->getTerrainRenderer()->getResult(x + size, z + size, 1, 1).location;
|
||||
|
||||
ov4.x = x + size;
|
||||
ov4.z = z;
|
||||
dv4 = renderer->terrain->getResult(renderer, x + size, z, 1, 1).location;
|
||||
dv4 = renderer->getTerrainRenderer()->getResult(x + size, z, 1, 1).location;
|
||||
|
||||
if (dv1.y > water_height || dv2.y > water_height || dv3.y > water_height || dv4.y > water_height)
|
||||
{
|
||||
|
@ -72,7 +73,7 @@ void TerrainRasterizer::tessellateChunk(TerrainChunkInfo* chunk, int detail)
|
|||
return;
|
||||
}
|
||||
|
||||
double water_height = renderer->water->getHeightInfo(renderer).min_height;
|
||||
double water_height = renderer->getWaterRenderer()->getHeightInfo().min_height;
|
||||
|
||||
double startx = chunk->point_nw.x;
|
||||
double startz = chunk->point_nw.z;
|
||||
|
@ -88,12 +89,12 @@ void TerrainRasterizer::tessellateChunk(TerrainChunkInfo* chunk, int detail)
|
|||
}
|
||||
}
|
||||
|
||||
static void _getChunk(Renderer* renderer, TerrainRasterizer::TerrainChunkInfo* chunk, double x, double z, double size, int displaced)
|
||||
static void _getChunk(SoftwareRenderer* renderer, TerrainRasterizer::TerrainChunkInfo* chunk, double x, double z, double size, int displaced)
|
||||
{
|
||||
chunk->point_nw = renderer->terrain->getResult(renderer, x, z, 1, displaced).location;
|
||||
chunk->point_sw = renderer->terrain->getResult(renderer, x, z + size, 1, displaced).location;
|
||||
chunk->point_se = renderer->terrain->getResult(renderer, x + size, z + size, 1, displaced).location;
|
||||
chunk->point_ne = renderer->terrain->getResult(renderer, x + size, z, 1, displaced).location;
|
||||
chunk->point_nw = renderer->getTerrainRenderer()->getResult(x, z, 1, displaced).location;
|
||||
chunk->point_sw = renderer->getTerrainRenderer()->getResult(x, z + size, 1, displaced).location;
|
||||
chunk->point_se = renderer->getTerrainRenderer()->getResult(x + size, z + size, 1, displaced).location;
|
||||
chunk->point_ne = renderer->getTerrainRenderer()->getResult(x + size, z, 1, displaced).location;
|
||||
|
||||
double displacement_power;
|
||||
if (displaced)
|
||||
|
@ -102,7 +103,7 @@ static void _getChunk(Renderer* renderer, TerrainRasterizer::TerrainChunkInfo* c
|
|||
}
|
||||
else
|
||||
{
|
||||
displacement_power = texturesGetMaximalDisplacement(renderer->textures->definition);
|
||||
displacement_power = renderer->getTexturesRenderer()->getMaximalDisplacement(renderer->getScenery()->getTextures());
|
||||
}
|
||||
|
||||
BoundingBox box;
|
||||
|
|
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 "SoftwareRenderer.h"
|
||||
#include "water/public.h"
|
||||
#include "WaterRenderer.h"
|
||||
#include "tools/parallel.h"
|
||||
|
||||
WaterRasterizer::WaterRasterizer(SoftwareRenderer* renderer):
|
||||
|
@ -9,23 +9,24 @@ WaterRasterizer::WaterRasterizer(SoftwareRenderer* renderer):
|
|||
{
|
||||
}
|
||||
|
||||
static Color _postProcessFragment(Renderer* renderer, Vector3 location, void*)
|
||||
static Color _postProcessFragment(Renderer* renderer_, Vector3 location, void*)
|
||||
{
|
||||
return renderer->water->getResult(renderer, location.x, location.z).final;
|
||||
SoftwareRenderer* renderer = (SoftwareRenderer*) renderer_;
|
||||
return renderer->getWaterRenderer()->getResult(location.x, location.z).final;
|
||||
}
|
||||
|
||||
static Vector3 _getFirstPassVertex(Renderer* renderer, double x, double z)
|
||||
static Vector3 _getFirstPassVertex(SoftwareRenderer* renderer, double x, double z)
|
||||
{
|
||||
Vector3 result;
|
||||
|
||||
result.x = x;
|
||||
result.y = renderer->water->getHeight(renderer, x, z);
|
||||
result.y = renderer->getWaterRenderer()->getHeight(x, z);
|
||||
result.z = z;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _renderQuad(Renderer* renderer, double x, double z, double size)
|
||||
static void _renderQuad(SoftwareRenderer* renderer, double x, double z, double size)
|
||||
{
|
||||
Vector3 v1, v2, v3, v4;
|
||||
|
||||
|
|
|
@ -1,43 +1,22 @@
|
|||
#include "private.h"
|
||||
#include "WaterRenderer.h"
|
||||
|
||||
#include <cmath>
|
||||
#include "../renderer.h"
|
||||
#include "SoftwareRenderer.h"
|
||||
#include "TerrainRenderer.h"
|
||||
#include "WaterDefinition.h"
|
||||
#include "SurfaceMaterial.h"
|
||||
#include "NoiseGenerator.h"
|
||||
#include "terrain/public.h"
|
||||
#include "LightComponent.h"
|
||||
#include "Scenery.h"
|
||||
#include "SurfaceMaterial.h"
|
||||
|
||||
static HeightInfo _FAKE_HEIGHT_INFO = {0.0, 0.0, 0.0};
|
||||
|
||||
/******************** Fake ********************/
|
||||
static HeightInfo _fakeGetHeightInfo(Renderer*)
|
||||
WaterRenderer::WaterRenderer(SoftwareRenderer* parent):
|
||||
parent(parent)
|
||||
{
|
||||
return _FAKE_HEIGHT_INFO;
|
||||
}
|
||||
|
||||
static double _fakeGetHeight(Renderer*, double, double)
|
||||
WaterRenderer::~WaterRenderer()
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static WaterResult _fakeGetResult(Renderer*, double x, double z)
|
||||
{
|
||||
WaterResult result;
|
||||
|
||||
result.location.x = x;
|
||||
result.location.y = 0.0;
|
||||
result.location.z = z;
|
||||
|
||||
result.base = COLOR_BLUE;
|
||||
result.reflected = COLOR_BLACK;
|
||||
result.refracted = COLOR_BLACK;
|
||||
result.foam = COLOR_BLACK;
|
||||
result.final = COLOR_BLUE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/******************** Helpers ********************/
|
||||
static inline double _getHeight(WaterDefinition* definition, double base_height, double x, double z)
|
||||
{
|
||||
return base_height + definition->_waves_noise->get2DTotal(x, z);
|
||||
|
@ -89,13 +68,13 @@ static inline Vector3 _refractRay(Vector3 incoming, Vector3 normal)
|
|||
}
|
||||
}
|
||||
|
||||
static inline Color _getFoamMask(Renderer* renderer, WaterDefinition* definition, Vector3 location, Vector3 normal, double detail)
|
||||
static inline Color _getFoamMask(SoftwareRenderer* renderer, WaterDefinition* definition, Vector3 location, Vector3 normal, double detail)
|
||||
{
|
||||
Color result;
|
||||
double foam_factor, normal_diff, location_offset;
|
||||
double base_height;
|
||||
|
||||
base_height = renderer->terrain->getWaterHeight(renderer);
|
||||
base_height = renderer->getTerrainRenderer()->getWaterHeight();
|
||||
location_offset = 2.0 * detail;
|
||||
|
||||
foam_factor = 0.0;
|
||||
|
@ -156,13 +135,13 @@ static inline Color _getFoamMask(Renderer* renderer, WaterDefinition* definition
|
|||
return result;
|
||||
}
|
||||
|
||||
static int _alterLight(Renderer* renderer, LightDefinition* light, Vector3 at)
|
||||
int WaterRenderer::alterLight(LightComponent *light, const Vector3 &at)
|
||||
{
|
||||
WaterDefinition* definition = renderer->water->definition;
|
||||
WaterDefinition* definition = parent->getScenery()->getWater();
|
||||
double factor;
|
||||
double base_height;
|
||||
|
||||
base_height = renderer->terrain->getWaterHeight(renderer);
|
||||
base_height = parent->getTerrainRenderer()->getWaterHeight();
|
||||
if (at.y < base_height)
|
||||
{
|
||||
if (light->direction.y <= -0.00001)
|
||||
|
@ -193,14 +172,13 @@ static int _alterLight(Renderer* renderer, LightDefinition* light, Vector3 at)
|
|||
}
|
||||
}
|
||||
|
||||
/******************** Real ********************/
|
||||
static HeightInfo _realGetHeightInfo(Renderer* renderer)
|
||||
HeightInfo WaterRenderer::getHeightInfo()
|
||||
{
|
||||
WaterDefinition* definition = renderer->water->definition;
|
||||
WaterDefinition* definition = parent->getScenery()->getWater();
|
||||
HeightInfo info;
|
||||
double noise_minvalue, noise_maxvalue;
|
||||
|
||||
info.base_height = renderer->terrain->getWaterHeight(renderer);
|
||||
info.base_height = parent->getTerrainRenderer()->getWaterHeight();
|
||||
definition->_waves_noise->getRange(&noise_minvalue, &noise_maxvalue);
|
||||
info.min_height = info.base_height + noise_minvalue;
|
||||
info.max_height = info.base_height + noise_maxvalue;
|
||||
|
@ -208,35 +186,35 @@ static HeightInfo _realGetHeightInfo(Renderer* renderer)
|
|||
return info;
|
||||
}
|
||||
|
||||
static double _realGetHeight(Renderer* renderer, double x, double z)
|
||||
double WaterRenderer::getHeight(double x, double z)
|
||||
{
|
||||
return _getHeight(renderer->water->definition, renderer->terrain->getWaterHeight(renderer), x, z);
|
||||
return _getHeight(parent->getScenery()->getWater(), parent->getTerrainRenderer()->getWaterHeight(), x, z);
|
||||
}
|
||||
|
||||
static WaterResult _realGetResult(Renderer* renderer, double x, double z)
|
||||
WaterRenderer::WaterResult WaterRenderer::getResult(double x, double z)
|
||||
{
|
||||
WaterDefinition* definition = renderer->water->definition;
|
||||
WaterDefinition* definition = parent->getScenery()->getWater();
|
||||
WaterResult result;
|
||||
RayCastingResult refracted;
|
||||
Vector3 location, normal, look_direction;
|
||||
Color color, foam;
|
||||
double base_height, detail, depth;
|
||||
|
||||
base_height = renderer->terrain->getWaterHeight(renderer);
|
||||
base_height = parent->getTerrainRenderer()->getWaterHeight();
|
||||
|
||||
location.x = x;
|
||||
location.y = _getHeight(definition, base_height, x, z);
|
||||
location.z = z;
|
||||
result.location = location;
|
||||
|
||||
detail = renderer->getPrecision(renderer, location) * 0.1;
|
||||
detail = parent->getPrecision(parent, location) * 0.1;
|
||||
if (detail < 0.00001)
|
||||
{
|
||||
detail = 0.00001;
|
||||
}
|
||||
|
||||
normal = _getNormal(definition, base_height, location, detail);
|
||||
look_direction = v3Normalize(v3Sub(location, renderer->getCameraLocation(renderer, location)));
|
||||
look_direction = v3Normalize(v3Sub(location, parent->getCameraLocation(parent, location)));
|
||||
|
||||
/* Reflection */
|
||||
if (definition->reflection == 0.0)
|
||||
|
@ -245,7 +223,7 @@ static WaterResult _realGetResult(Renderer* renderer, double x, double z)
|
|||
}
|
||||
else
|
||||
{
|
||||
result.reflected = renderer->rayWalking(renderer, location, _reflectRay(look_direction, normal), 1, 0, 1, 1).hit_color;
|
||||
result.reflected = parent->rayWalking(location, _reflectRay(look_direction, normal), 1, 0, 1, 1).hit_color;
|
||||
}
|
||||
|
||||
/* Transparency/refraction */
|
||||
|
@ -256,7 +234,7 @@ static WaterResult _realGetResult(Renderer* renderer, double x, double z)
|
|||
else
|
||||
{
|
||||
Color depth_color = *definition->depth_color;
|
||||
refracted = renderer->rayWalking(renderer, location, _refractRay(look_direction, normal), 1, 0, 1, 1);
|
||||
refracted = parent->rayWalking(location, _refractRay(look_direction, normal), 1, 0, 1, 1);
|
||||
depth = v3Norm(v3Sub(location, refracted.hit_location));
|
||||
colorLimitPower(&depth_color, colorGetPower(&refracted.hit_color));
|
||||
if (depth > definition->transparency_depth)
|
||||
|
@ -274,59 +252,21 @@ static WaterResult _realGetResult(Renderer* renderer, double x, double z)
|
|||
}
|
||||
|
||||
/* Lighting from environment */
|
||||
color = renderer->applyLightingToSurface(location, normal, *definition->material);
|
||||
color = parent->applyLightingToSurface(location, normal, *definition->material);
|
||||
|
||||
color.r += result.reflected.r * definition->reflection + result.refracted.r * definition->transparency;
|
||||
color.g += result.reflected.g * definition->reflection + result.refracted.g * definition->transparency;
|
||||
color.b += result.reflected.b * definition->reflection + result.refracted.b * definition->transparency;
|
||||
|
||||
/* Merge with foam */
|
||||
foam = _getFoamMask(renderer, definition, location, normal, detail);
|
||||
foam = _getFoamMask(parent, definition, location, normal, detail);
|
||||
colorMask(&color, &foam);
|
||||
|
||||
/* Bring color to the camera */
|
||||
color = renderer->applyMediumTraversal(location, color);
|
||||
color = parent->applyMediumTraversal(location, color);
|
||||
|
||||
result.base = definition->material->_rgb;
|
||||
result.final = color;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/******************** Renderer ********************/
|
||||
static WaterRenderer* _createRenderer()
|
||||
{
|
||||
WaterRenderer* result;
|
||||
|
||||
result = new WaterRenderer;
|
||||
result->definition = new WaterDefinition(NULL);
|
||||
|
||||
result->getHeightInfo = _fakeGetHeightInfo;
|
||||
result->getHeight = _fakeGetHeight;
|
||||
result->getResult = _fakeGetResult;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _deleteRenderer(WaterRenderer* renderer)
|
||||
{
|
||||
delete renderer->definition;
|
||||
delete renderer;
|
||||
}
|
||||
|
||||
static void _bindRenderer(Renderer* renderer, WaterDefinition* definition)
|
||||
{
|
||||
definition->copy(renderer->water->definition);
|
||||
|
||||
renderer->water->getHeightInfo = _realGetHeightInfo;
|
||||
renderer->water->getHeight = _realGetHeight;
|
||||
renderer->water->getResult = _realGetResult;
|
||||
|
||||
lightingManagerRegisterFilter(renderer->lighting, (FuncLightingAlterLight)_alterLight, renderer);
|
||||
}
|
||||
|
||||
StandardRenderer WaterRendererClass = {
|
||||
(FuncObjectCreate)_createRenderer,
|
||||
(FuncObjectDelete)_deleteRenderer,
|
||||
(FuncObjectBind)_bindRenderer
|
||||
};
|
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 \
|
||||
LightFilter.cpp \
|
||||
LightComponent.cpp \
|
||||
WaterRasterizer.cpp \
|
||||
AtmosphereResult.cpp \
|
||||
AtmosphereModelBruneton.cpp
|
||||
AtmosphereModelBruneton.cpp \
|
||||
TerrainRenderer.cpp \
|
||||
TexturesRenderer.cpp \
|
||||
WaterRenderer.cpp
|
||||
|
||||
HEADERS += SoftwareRenderer.h\
|
||||
software_global.h \
|
||||
|
@ -50,9 +52,11 @@ HEADERS += SoftwareRenderer.h\
|
|||
LightStatus.h \
|
||||
LightFilter.h \
|
||||
LightComponent.h \
|
||||
WaterRasterizer.h \
|
||||
AtmosphereResult.h \
|
||||
AtmosphereModelBruneton.h
|
||||
AtmosphereModelBruneton.h \
|
||||
TerrainRenderer.h \
|
||||
TexturesRenderer.h \
|
||||
WaterRenderer.h
|
||||
|
||||
unix:!symbian {
|
||||
maemo5 {
|
||||
|
|
|
@ -21,11 +21,17 @@ namespace software {
|
|||
|
||||
class BaseAtmosphereRenderer;
|
||||
class SoftwareBrunetonAtmosphereRenderer;
|
||||
class AtmosphereResult;
|
||||
class AtmosphereModelBruneton;
|
||||
|
||||
class CloudsRenderer;
|
||||
class BaseCloudLayerRenderer;
|
||||
class BaseCloudsModel;
|
||||
|
||||
class TerrainRenderer;
|
||||
class TexturesRenderer;
|
||||
class WaterRenderer;
|
||||
|
||||
class SkyRasterizer;
|
||||
class TerrainRasterizer;
|
||||
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
#include "RenderingScenery.h"
|
||||
|
||||
#include "renderer.h"
|
||||
#include "terrain/public.h"
|
||||
#include "textures/public.h"
|
||||
#include "water/public.h"
|
||||
#include "CameraDefinition.h"
|
||||
|
||||
static RenderingScenery _main_scenery;
|
||||
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
#include "render.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "CameraDefinition.h"
|
||||
#include "terrain/public.h"
|
||||
#include "textures/public.h"
|
||||
#include "water/public.h"
|
||||
#include "SurfaceMaterial.h"
|
||||
|
||||
static RayCastingResult _RAYCASTING_NULL = {0, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
|
||||
|
||||
|
@ -84,11 +82,6 @@ static void _pushDisplacedQuad(Renderer* renderer, Vector3 v1, Vector3 v2, Vecto
|
|||
renderer->pushDisplacedTriangle(renderer, v4, v1, v3, ov4, ov1, ov3, callback, callback_data);
|
||||
}
|
||||
|
||||
static RayCastingResult _rayWalking(Renderer*, Vector3, Vector3, int, int, int, int)
|
||||
{
|
||||
return _RAYCASTING_NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -118,22 +111,12 @@ Renderer::Renderer()
|
|||
pushQuad = _pushQuad;
|
||||
pushDisplacedTriangle = _pushDisplacedTriangle;
|
||||
pushDisplacedQuad = _pushDisplacedQuad;
|
||||
|
||||
rayWalking = _rayWalking;
|
||||
|
||||
terrain = (TerrainRenderer*)TerrainRendererClass.create();
|
||||
textures = (TexturesRenderer*)TexturesRendererClass.create();
|
||||
water = (WaterRenderer*)WaterRendererClass.create();
|
||||
}
|
||||
|
||||
Renderer::~Renderer()
|
||||
{
|
||||
delete render_camera;
|
||||
|
||||
TerrainRendererClass.destroy(terrain);
|
||||
TexturesRendererClass.destroy(textures);
|
||||
WaterRendererClass.destroy(water);
|
||||
|
||||
renderDeleteArea(render_area);
|
||||
}
|
||||
|
||||
|
@ -147,6 +130,11 @@ Color Renderer::applyLightingToSurface(const Vector3 &, const Vector3 &, const S
|
|||
return material._rgb;
|
||||
}
|
||||
|
||||
RayCastingResult Renderer::rayWalking(const Vector3 &, const Vector3 &, int, int, int, int)
|
||||
{
|
||||
return _RAYCASTING_NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -5,11 +5,6 @@
|
|||
#include "shared/types.h"
|
||||
#include "render.h"
|
||||
|
||||
class LightingManager;
|
||||
class TerrainRenderer;
|
||||
class TexturesRenderer;
|
||||
class WaterRenderer;
|
||||
|
||||
class Renderer
|
||||
{
|
||||
public:
|
||||
|
@ -45,14 +40,7 @@ public:
|
|||
/* Shortcuts */
|
||||
virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material);
|
||||
virtual Color applyMediumTraversal(Vector3 location, Color color);
|
||||
|
||||
/* Scenery related */
|
||||
RayCastingResult(*rayWalking)(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds);
|
||||
|
||||
/* Autonomous sub-renderers */
|
||||
TerrainRenderer* terrain;
|
||||
TexturesRenderer* textures;
|
||||
WaterRenderer* water;
|
||||
virtual RayCastingResult rayWalking(const Vector3 &location, const Vector3 &direction, int terrain, int water, int sky, int clouds);
|
||||
|
||||
/* Custom data */
|
||||
void* customData[10];
|
||||
|
|
|
@ -11,16 +11,10 @@ include(../common.pri)
|
|||
SOURCES += main.cpp \
|
||||
renderer.cpp \
|
||||
render.cpp \
|
||||
terrain/ter_render.cpp \
|
||||
terrain/ter_painting.cpp \
|
||||
textures/tex_tools.cpp \
|
||||
textures/tex_rendering.cpp \
|
||||
textures/tex_preview.cpp \
|
||||
tools/texture.cpp \
|
||||
tools/parallel.cpp \
|
||||
tools/data.cpp \
|
||||
tools/cache.cpp \
|
||||
water/wat_render.cpp \
|
||||
RenderingScenery.cpp
|
||||
|
||||
HEADERS += \
|
||||
|
@ -28,17 +22,10 @@ HEADERS += \
|
|||
render.h \
|
||||
main.h \
|
||||
shared/types.h \
|
||||
terrain/public.h \
|
||||
terrain/private.h \
|
||||
textures/tex_preview.h \
|
||||
textures/public.h \
|
||||
textures/private.h \
|
||||
tools/texture.h \
|
||||
tools/parallel.h \
|
||||
tools/data.h \
|
||||
tools/cache.h \
|
||||
water/public.h \
|
||||
water/private.h \
|
||||
rendering_global.h \
|
||||
RenderingScenery.h
|
||||
|
||||
|
|
|
@ -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