paysages : Atmosphere/sky fusion + refactoring + keep skydome lights in cache.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@468 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
98c64cc5eb
commit
15fe1cb0e1
33 changed files with 630 additions and 1102 deletions
5
TODO
5
TODO
|
@ -9,11 +9,6 @@ Technology Preview 2 :
|
||||||
- Finalize Preetham's model usage
|
- Finalize Preetham's model usage
|
||||||
=> Apply model to atmosphere (aerial perspective)
|
=> Apply model to atmosphere (aerial perspective)
|
||||||
=> Find a proper model for night sky (maybe Shirley)
|
=> Find a proper model for night sky (maybe Shirley)
|
||||||
- Merge atmosphere and sky in a coherent model.
|
|
||||||
=> All stopper rendering (terrain, water and skydome) should pass through an atmosphere walker.
|
|
||||||
=> The atmosphere walker collects callbacks (clouds, water...) to alter the medium.
|
|
||||||
=> God rays are possible with particle lighting through the walker.
|
|
||||||
- Keep skydome lights in cache for a render.
|
|
||||||
- Clouds should keep distance to ground.
|
- Clouds should keep distance to ground.
|
||||||
- Rethink the quality settings and detail smoothing in the distance.
|
- Rethink the quality settings and detail smoothing in the distance.
|
||||||
=> When quality setting is set to 10, add boost options
|
=> When quality setting is set to 10, add boost options
|
||||||
|
|
|
@ -4,9 +4,8 @@
|
||||||
#include "baseexplorerchunk.h"
|
#include "baseexplorerchunk.h"
|
||||||
#include "../lib_paysages/camera.h"
|
#include "../lib_paysages/camera.h"
|
||||||
|
|
||||||
ExplorerChunkSky::ExplorerChunkSky(Renderer* renderer, SkyDefinition* sky, double size, SkyboxOrientation orientation) : BaseExplorerChunk(renderer)
|
ExplorerChunkSky::ExplorerChunkSky(Renderer* renderer, double size, SkyboxOrientation orientation) : BaseExplorerChunk(renderer)
|
||||||
{
|
{
|
||||||
_sky = sky;
|
|
||||||
_box_size = size;
|
_box_size = size;
|
||||||
_orientation = orientation;
|
_orientation = orientation;
|
||||||
|
|
||||||
|
@ -131,5 +130,5 @@ Color ExplorerChunkSky::getTextureColor(double x, double y)
|
||||||
location.z = y;
|
location.z = y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return skyGetColor(_sky, renderer(), VECTOR_ZERO, v3Normalize(location));
|
return renderer()->atmosphere->getSkyColor(renderer(), v3Normalize(location));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "baseexplorerchunk.h"
|
#include "baseexplorerchunk.h"
|
||||||
#include "../lib_paysages/renderer.h"
|
#include "../lib_paysages/renderer.h"
|
||||||
#include "../lib_paysages/euclid.h"
|
#include "../lib_paysages/euclid.h"
|
||||||
#include "../lib_paysages/sky.h"
|
|
||||||
|
|
||||||
enum SkyboxOrientation
|
enum SkyboxOrientation
|
||||||
{
|
{
|
||||||
|
@ -19,14 +18,13 @@ enum SkyboxOrientation
|
||||||
class ExplorerChunkSky:public BaseExplorerChunk
|
class ExplorerChunkSky:public BaseExplorerChunk
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExplorerChunkSky(Renderer* renderer, SkyDefinition* sky, double size, SkyboxOrientation orientation);
|
ExplorerChunkSky(Renderer* renderer, double size, SkyboxOrientation orientation);
|
||||||
|
|
||||||
void onRenderEvent(QGLWidget* widget);
|
void onRenderEvent(QGLWidget* widget);
|
||||||
double getDisplayedSizeHint(CameraDefinition* camera);
|
double getDisplayedSizeHint(CameraDefinition* camera);
|
||||||
Color getTextureColor(double x, double y);
|
Color getTextureColor(double x, double y);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkyDefinition* _sky;
|
|
||||||
SkyboxOrientation _orientation;
|
SkyboxOrientation _orientation;
|
||||||
double _box_size;
|
double _box_size;
|
||||||
|
|
||||||
|
|
|
@ -1,91 +1,131 @@
|
||||||
#include "formatmosphere.h"
|
#include "formatmosphere.h"
|
||||||
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "../lib_paysages/atmosphere.h"
|
|
||||||
#include "../lib_paysages/scenery.h"
|
|
||||||
#include "../lib_paysages/euclid.h"
|
|
||||||
#include "../lib_paysages/color.h"
|
|
||||||
|
|
||||||
static AtmosphereDefinition _definition;
|
#include <QColor>
|
||||||
|
#include <QSlider>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "../lib_paysages/atmosphere/atmosphere.h"
|
||||||
|
#include "../lib_paysages/scenery.h"
|
||||||
|
#include "../lib_paysages/renderer.h"
|
||||||
|
|
||||||
|
static AtmosphereDefinition* _definition;
|
||||||
|
|
||||||
/**************** Previews ****************/
|
/**************** Previews ****************/
|
||||||
class PreviewAtmosphereColor:public BasePreview
|
class PreviewSkyEast:public BasePreview
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PreviewAtmosphereColor(QWidget* parent):
|
PreviewSkyEast(QWidget* parent):
|
||||||
BasePreview(parent)
|
BasePreview(parent)
|
||||||
{
|
{
|
||||||
_renderer = rendererCreate();
|
_renderer = rendererCreate();
|
||||||
_preview_definition = atmosphereCreateDefinition();
|
|
||||||
|
|
||||||
configScaling(100.0, 1000.0, 20.0, 200.0);
|
configScaling(0.5, 5.0, 0.5, 2.5);
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
QColor getColor(double x, double y)
|
QColor getColor(double x, double y)
|
||||||
{
|
{
|
||||||
Vector3 eye, look, location;
|
y -= 100.0 * scaling;
|
||||||
|
if (y > 0.0)
|
||||||
eye.x = 0.0;
|
|
||||||
eye.y = scaling * 5.0;
|
|
||||||
eye.z = -10.0 * scaling;
|
|
||||||
_renderer.camera_location = eye;
|
|
||||||
look.x = x * 0.01 / scaling;
|
|
||||||
look.y = -y * 0.01 / scaling - 0.3;
|
|
||||||
look.z = 1.0;
|
|
||||||
look = v3Normalize(look);
|
|
||||||
|
|
||||||
if (look.y > -0.0001)
|
|
||||||
{
|
{
|
||||||
return colorToQColor(COLOR_BLUE);
|
return QColor(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vector3 look;
|
||||||
|
|
||||||
location.x = eye.x - look.x * eye.y / look.y;
|
look.x = 1.0;
|
||||||
location.y = 0.0;
|
look.y = -y;
|
||||||
location.z = eye.z - look.z * eye.y / look.y;
|
look.z = x;
|
||||||
|
|
||||||
return colorToQColor(atmosphereApply(&_preview_definition, &_renderer, location, COLOR_BLACK));
|
return colorToQColor(_renderer.atmosphere->getSkyColor(&_renderer, look));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void updateData()
|
void updateData()
|
||||||
{
|
{
|
||||||
atmosphereCopyDefinition(&_definition, &_preview_definition);
|
AtmosphereRendererClass.bind(_renderer.atmosphere, _definition);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Renderer _renderer;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PreviewSkyWest:public BasePreview
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PreviewSkyWest(QWidget* parent):
|
||||||
|
BasePreview(parent)
|
||||||
|
{
|
||||||
|
_renderer = rendererCreate();
|
||||||
|
|
||||||
|
configScaling(0.5, 5.0, 0.5, 2.5);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
QColor getColor(double x, double y)
|
||||||
|
{
|
||||||
|
y -= 100.0 * scaling;
|
||||||
|
if (y > 0.0)
|
||||||
|
{
|
||||||
|
return QColor(0, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vector3 look;
|
||||||
|
|
||||||
|
look.x = -1.0;
|
||||||
|
look.y = -y;
|
||||||
|
look.z = -x;
|
||||||
|
|
||||||
|
return colorToQColor(_renderer.atmosphere->getSkyColor(&_renderer, look));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void updateData()
|
||||||
|
{
|
||||||
|
AtmosphereRendererClass.bind(_renderer.atmosphere, _definition);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Renderer _renderer;
|
Renderer _renderer;
|
||||||
AtmosphereDefinition _preview_definition;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**************** Form ****************/
|
/**************** Form ****************/
|
||||||
FormAtmosphere::FormAtmosphere(QWidget *parent):
|
FormAtmosphere::FormAtmosphere(QWidget *parent):
|
||||||
BaseForm(parent)
|
BaseForm(parent)
|
||||||
{
|
{
|
||||||
_definition = atmosphereCreateDefinition();
|
BaseInput* input;
|
||||||
|
|
||||||
previewColor = new PreviewAtmosphereColor(this);
|
_definition = (AtmosphereDefinition*)AtmosphereDefinitionClass.create();
|
||||||
addPreview(previewColor, QString(tr("Color preview")));
|
|
||||||
|
|
||||||
addInputDouble(tr("Start distance"), &_definition.distance_near, -500.0, 500.0, 5.0, 50.0);
|
previewWest = new PreviewSkyWest(this);
|
||||||
addInputDouble(tr("End distance"), &_definition.distance_far, -500.0, 500.0, 5.0, 50.0);
|
addPreview(previewWest, QString(tr("West preview")));
|
||||||
addInputDouble(tr("Masking power"), &_definition.full_mask, 0.0, 1.0, 0.01, 0.1);
|
previewEast = new PreviewSkyEast(this);
|
||||||
addInputBoolean(tr("Lock on horizon color"), &_definition.auto_lock_on_haze);
|
addPreview(previewEast, QString(tr("East preview")));
|
||||||
addInputColor(tr("Color"), &_definition.color)->setEnabledCondition(&_definition.auto_lock_on_haze, 0);
|
|
||||||
|
addInputEnum(tr("Color model"), (int*)&_definition->model, QStringList(tr("Preetham/Shirley analytic model")) << tr("Bruneton/Neyret precomputed model"));
|
||||||
|
addInputDouble(tr("Day time"), &_definition->daytime, 0.14, 0.86, 0.002, 0.1);
|
||||||
|
addInputColor(tr("Sun color"), &_definition->sun_color);
|
||||||
|
addInputDouble(tr("Sun radius"), &_definition->sun_radius, 0.0, 0.4, 0.004, 0.04);
|
||||||
|
addInputDouble(tr("Sun halo radius"), &_definition->sun_halo_size, 0.0, 0.4, 0.004, 0.04);
|
||||||
|
addInputCurve(tr("Sun halo profile"), _definition->sun_halo_profile, 0.0, 1.0, 0.0, 1.0, tr("Distance to center of the sun"), tr("Light influence (halo opacity)"));
|
||||||
|
addInputDouble(tr("Influence of skydome on lighting"), &_definition->dome_lighting, 0.0, 2.0, 0.01, 0.1);
|
||||||
|
input = addInputDouble(tr("Humidity"), &_definition->humidity, 1.8, 6.0, 0.05, 0.5);
|
||||||
|
|
||||||
revertConfig();
|
revertConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormAtmosphere::revertConfig()
|
void FormAtmosphere::revertConfig()
|
||||||
{
|
{
|
||||||
sceneryGetAtmosphere(&_definition);
|
sceneryGetAtmosphere(_definition);
|
||||||
BaseForm::revertConfig();
|
BaseForm::revertConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormAtmosphere::applyConfig()
|
void FormAtmosphere::applyConfig()
|
||||||
{
|
{
|
||||||
scenerySetAtmosphere(&_definition);
|
scenerySetAtmosphere(_definition);
|
||||||
BaseForm::applyConfig();
|
BaseForm::applyConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormAtmosphere::configChangeEvent()
|
void FormAtmosphere::configChangeEvent()
|
||||||
{
|
{
|
||||||
atmosphereValidateDefinition(&_definition);
|
AtmosphereDefinitionClass.validate(_definition);
|
||||||
BaseForm::configChangeEvent();
|
BaseForm::configChangeEvent();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,8 @@ protected slots:
|
||||||
virtual void configChangeEvent();
|
virtual void configChangeEvent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BasePreview* previewColor;
|
BasePreview* previewEast;
|
||||||
|
BasePreview* previewWest;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,7 +19,6 @@ public:
|
||||||
_renderer.getTerrainHeight = _getTerrainHeight;
|
_renderer.getTerrainHeight = _getTerrainHeight;
|
||||||
_renderer.alterLight = _alterLight;
|
_renderer.alterLight = _alterLight;
|
||||||
_renderer.getLightStatus = _getLightStatus;
|
_renderer.getLightStatus = _getLightStatus;
|
||||||
_renderer.getSkyDomeLights = _getSkyDomeLights;
|
|
||||||
_renderer.camera_location.x = 0.0;
|
_renderer.camera_location.x = 0.0;
|
||||||
_renderer.camera_location.y = 50.0;
|
_renderer.camera_location.y = 50.0;
|
||||||
_renderer.camera_location.z = 0.0;
|
_renderer.camera_location.z = 0.0;
|
||||||
|
@ -28,13 +27,12 @@ public:
|
||||||
_textures = texturesCreateDefinition();
|
_textures = texturesCreateDefinition();
|
||||||
_lighting = lightingCreateDefinition();
|
_lighting = lightingCreateDefinition();
|
||||||
_water = waterCreateDefinition();
|
_water = waterCreateDefinition();
|
||||||
_sky = skyCreateDefinition();
|
_atmosphere = (AtmosphereDefinition*)AtmosphereDefinitionClass.create();
|
||||||
|
|
||||||
_renderer.customData[0] = &_terrain;
|
_renderer.customData[0] = &_terrain;
|
||||||
_renderer.customData[1] = &_textures;
|
_renderer.customData[1] = &_textures;
|
||||||
_renderer.customData[2] = &_lighting;
|
_renderer.customData[2] = &_lighting;
|
||||||
_renderer.customData[3] = &_water;
|
_renderer.customData[3] = &_water;
|
||||||
_renderer.customData[4] = &_sky;
|
|
||||||
|
|
||||||
addOsd(QString("geolocation"));
|
addOsd(QString("geolocation"));
|
||||||
|
|
||||||
|
@ -66,7 +64,9 @@ protected:
|
||||||
sceneryGetLighting(&_lighting);
|
sceneryGetLighting(&_lighting);
|
||||||
sceneryGetTextures(&_textures);
|
sceneryGetTextures(&_textures);
|
||||||
sceneryGetWater(&_water);
|
sceneryGetWater(&_water);
|
||||||
sceneryGetSky(&_sky);
|
|
||||||
|
sceneryGetAtmosphere(_atmosphere);
|
||||||
|
AtmosphereRendererClass.bind(_renderer.atmosphere, _atmosphere);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Renderer _renderer;
|
Renderer _renderer;
|
||||||
|
@ -74,7 +74,7 @@ private:
|
||||||
WaterDefinition _water;
|
WaterDefinition _water;
|
||||||
TexturesDefinition _textures;
|
TexturesDefinition _textures;
|
||||||
LightingDefinition _lighting;
|
LightingDefinition _lighting;
|
||||||
SkyDefinition _sky;
|
AtmosphereDefinition* _atmosphere;
|
||||||
|
|
||||||
static double _getTerrainHeight(Renderer* renderer, double x, double z)
|
static double _getTerrainHeight(Renderer* renderer, double x, double z)
|
||||||
{
|
{
|
||||||
|
@ -86,11 +86,6 @@ private:
|
||||||
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _getSkyDomeLights(Renderer* renderer, LightDefinition* array, int max_lights)
|
|
||||||
{
|
|
||||||
return skyGetLights((SkyDefinition*)(renderer->customData[4]), renderer, array, max_lights);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
|
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
|
||||||
{
|
{
|
||||||
light->color = terrainLightFilter((TerrainDefinition*)(renderer->customData[0]), renderer, light->color, location, v3Scale(light->direction, -1000.0), v3Scale(light->direction, -1.0));
|
light->color = terrainLightFilter((TerrainDefinition*)(renderer->customData[0]), renderer, light->color, location, v3Scale(light->direction, -1000.0), v3Scale(light->direction, -1.0));
|
||||||
|
|
|
@ -1,156 +0,0 @@
|
||||||
#include "formsky.h"
|
|
||||||
|
|
||||||
#include "tools.h"
|
|
||||||
|
|
||||||
#include <QColor>
|
|
||||||
#include <QSlider>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "../lib_paysages/sky.h"
|
|
||||||
#include "../lib_paysages/scenery.h"
|
|
||||||
#include "../lib_paysages/renderer.h"
|
|
||||||
|
|
||||||
static SkyDefinition _definition;
|
|
||||||
|
|
||||||
/**************** Previews ****************/
|
|
||||||
class PreviewSkyEast:public BasePreview
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PreviewSkyEast(QWidget* parent):
|
|
||||||
BasePreview(parent)
|
|
||||||
{
|
|
||||||
_renderer = rendererCreate();
|
|
||||||
_preview_definition = skyCreateDefinition();
|
|
||||||
|
|
||||||
configScaling(0.5, 5.0, 0.5, 2.5);
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
QColor getColor(double x, double y)
|
|
||||||
{
|
|
||||||
y -= 100.0 * scaling;
|
|
||||||
if (y > 0.0)
|
|
||||||
{
|
|
||||||
return QColor(0, 0, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Vector3 eye = {0.0, 0.0, 0.0};
|
|
||||||
Vector3 look;
|
|
||||||
|
|
||||||
look.x = 1.0;
|
|
||||||
look.y = -y;
|
|
||||||
look.z = x;
|
|
||||||
|
|
||||||
return colorToQColor(skyGetColor(&_preview_definition, &_renderer, eye, look));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void updateData()
|
|
||||||
{
|
|
||||||
skyCopyDefinition(&_definition, &_preview_definition);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
Renderer _renderer;
|
|
||||||
SkyDefinition _preview_definition;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PreviewSkyWest:public BasePreview
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PreviewSkyWest(QWidget* parent):
|
|
||||||
BasePreview(parent)
|
|
||||||
{
|
|
||||||
_renderer = rendererCreate();
|
|
||||||
_preview_definition = skyCreateDefinition();
|
|
||||||
|
|
||||||
configScaling(0.5, 5.0, 0.5, 2.5);
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
QColor getColor(double x, double y)
|
|
||||||
{
|
|
||||||
y -= 100.0 * scaling;
|
|
||||||
if (y > 0.0)
|
|
||||||
{
|
|
||||||
return QColor(0, 0, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Vector3 eye = {0.0, 0.0, 0.0};
|
|
||||||
Vector3 look;
|
|
||||||
|
|
||||||
look.x = -1.0;
|
|
||||||
look.y = -y;
|
|
||||||
look.z = -x;
|
|
||||||
|
|
||||||
return colorToQColor(skyGetColor(&_preview_definition, &_renderer, eye, look));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void updateData()
|
|
||||||
{
|
|
||||||
skyCopyDefinition(&_definition, &_preview_definition);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
Renderer _renderer;
|
|
||||||
SkyDefinition _preview_definition;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**************** Form ****************/
|
|
||||||
FormSky::FormSky(QWidget *parent):
|
|
||||||
BaseForm(parent)
|
|
||||||
{
|
|
||||||
BaseInput* input;
|
|
||||||
|
|
||||||
_definition = skyCreateDefinition();
|
|
||||||
|
|
||||||
previewWest = new PreviewSkyWest(this);
|
|
||||||
addPreview(previewWest, QString(tr("West preview")));
|
|
||||||
previewEast = new PreviewSkyEast(this);
|
|
||||||
addPreview(previewEast, QString(tr("East preview")));
|
|
||||||
|
|
||||||
addInputEnum(tr("Color model"), (int*)&_definition.model, QStringList(tr("Custom model")) << tr("Rayleigh/Mie scattering") << tr("Preetham/Shirley analytic model"));
|
|
||||||
addInputDouble(tr("Day time"), &_definition.daytime, 0.14, 0.86, 0.002, 0.1);
|
|
||||||
addInputColor(tr("Sun color"), &_definition.sun_color);
|
|
||||||
addInputDouble(tr("Sun radius"), &_definition.sun_radius, 0.0, 0.4, 0.004, 0.04);
|
|
||||||
addInputDouble(tr("Sun halo radius"), &_definition.sun_halo_size, 0.0, 0.4, 0.004, 0.04);
|
|
||||||
addInputCurve(tr("Sun halo profile"), _definition.sun_halo_profile, 0.0, 1.0, 0.0, 1.0, tr("Distance to center of the sun"), tr("Light influence (halo opacity)"));
|
|
||||||
addInputDouble(tr("Influence of skydome on lighting"), &_definition.dome_lighting, 0.0, 2.0, 0.01, 0.1);
|
|
||||||
input = addInputBoolean(tr("Auto colors from daytime"), &_definition.model_custom.auto_from_daytime);
|
|
||||||
input->setVisibilityCondition((int*)&_definition.model, SKY_MODEL_CUSTOM);
|
|
||||||
input = addInputColor(tr("Zenith color"), &_definition.model_custom.zenith_color);
|
|
||||||
input->setVisibilityCondition((int*)&_definition.model, SKY_MODEL_CUSTOM);
|
|
||||||
input->setEnabledCondition(&_definition.model_custom.auto_from_daytime, 0);
|
|
||||||
input = addInputColor(tr("Haze color"), &_definition.model_custom.haze_color);
|
|
||||||
input->setVisibilityCondition((int*)&_definition.model, SKY_MODEL_CUSTOM);
|
|
||||||
input->setEnabledCondition(&_definition.model_custom.auto_from_daytime, 0);
|
|
||||||
input = addInputDouble(tr("Haze height"), &_definition.model_custom.haze_height, 0.0, 1.0, 0.01, 0.1);
|
|
||||||
input->setVisibilityCondition((int*)&_definition.model, SKY_MODEL_CUSTOM);
|
|
||||||
input = addInputDouble(tr("Haze smoothing"), &_definition.model_custom.haze_smoothing, 0.0, 1.0, 0.01, 0.1);
|
|
||||||
input->setVisibilityCondition((int*)&_definition.model, SKY_MODEL_CUSTOM);
|
|
||||||
input = addInputDouble(tr("Turbidity"), &_definition.model_preetham.turbidity, 1.8, 6.0, 0.05, 0.5);
|
|
||||||
input->setVisibilityCondition((int*)&_definition.model, SKY_MODEL_PREETHAM);
|
|
||||||
|
|
||||||
revertConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormSky::revertConfig()
|
|
||||||
{
|
|
||||||
sceneryGetSky(&_definition);
|
|
||||||
BaseForm::revertConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormSky::applyConfig()
|
|
||||||
{
|
|
||||||
scenerySetSky(&_definition);
|
|
||||||
BaseForm::applyConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormSky::configChangeEvent()
|
|
||||||
{
|
|
||||||
skyValidateDefinition(&_definition);
|
|
||||||
|
|
||||||
if (_definition.model == SKY_MODEL_CUSTOM && _definition.model_custom.auto_from_daytime)
|
|
||||||
{
|
|
||||||
BaseForm::revertConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseForm::configChangeEvent();
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
#ifndef _PAYSAGES_QT_FORMSKY_H_
|
|
||||||
#define _PAYSAGES_QT_FORMSKY_H_
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include "basepreview.h"
|
|
||||||
#include "baseform.h"
|
|
||||||
|
|
||||||
class FormSky : public BaseForm
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit FormSky(QWidget *parent = 0);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
virtual void revertConfig();
|
|
||||||
virtual void applyConfig();
|
|
||||||
|
|
||||||
protected slots:
|
|
||||||
virtual void configChangeEvent();
|
|
||||||
|
|
||||||
private:
|
|
||||||
BasePreview* previewEast;
|
|
||||||
BasePreview* previewWest;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -12,10 +12,9 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include "basepreview.h"
|
#include "basepreview.h"
|
||||||
#include "formatmosphere.h"
|
|
||||||
#include "formclouds.h"
|
#include "formclouds.h"
|
||||||
#include "formlighting.h"
|
#include "formlighting.h"
|
||||||
#include "formsky.h"
|
#include "formatmosphere.h"
|
||||||
#include "formterrain.h"
|
#include "formterrain.h"
|
||||||
#include "formtextures.h"
|
#include "formtextures.h"
|
||||||
#include "formwater.h"
|
#include "formwater.h"
|
||||||
|
@ -93,11 +92,6 @@ QMainWindow(parent)
|
||||||
QObject::connect(form, SIGNAL(configApplied()), this, SLOT(refreshAll()), Qt::QueuedConnection);
|
QObject::connect(form, SIGNAL(configApplied()), this, SLOT(refreshAll()), Qt::QueuedConnection);
|
||||||
_forms.append(form);
|
_forms.append(form);
|
||||||
|
|
||||||
form = new FormSky(tabs);
|
|
||||||
tabs->addTab(form, tr("Sky"));
|
|
||||||
QObject::connect(form, SIGNAL(configApplied()), this, SLOT(refreshAll()), Qt::QueuedConnection);
|
|
||||||
_forms.append(form);
|
|
||||||
|
|
||||||
form = new FormAtmosphere(tabs);
|
form = new FormAtmosphere(tabs);
|
||||||
tabs->addTab(form, tr("Atmosphere"));
|
tabs->addTab(form, tr("Atmosphere"));
|
||||||
QObject::connect(form, SIGNAL(configApplied()), this, SLOT(refreshAll()), Qt::QueuedConnection);
|
QObject::connect(form, SIGNAL(configApplied()), this, SLOT(refreshAll()), Qt::QueuedConnection);
|
||||||
|
|
|
@ -58,11 +58,6 @@ static Color _applyTextures(Renderer* renderer, Vector3 location, double precisi
|
||||||
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _getSkyDomeLights(Renderer* renderer, LightDefinition* array, int max_lights)
|
|
||||||
{
|
|
||||||
return skyGetLights((SkyDefinition*)(renderer->customData[4]), renderer, array, max_lights);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
|
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
|
||||||
{
|
{
|
||||||
light->color = terrainLightFilter((TerrainDefinition*)(renderer->customData[0]), renderer, light->color, location, v3Scale(light->direction, -1000.0), v3Scale(light->direction, -1.0));
|
light->color = terrainLightFilter((TerrainDefinition*)(renderer->customData[0]), renderer, light->color, location, v3Scale(light->direction, -1000.0), v3Scale(light->direction, -1.0));
|
||||||
|
@ -84,8 +79,6 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
||||||
|
|
||||||
_water = waterCreateDefinition();
|
_water = waterCreateDefinition();
|
||||||
sceneryGetWater(&_water);
|
sceneryGetWater(&_water);
|
||||||
_sky = skyCreateDefinition();
|
|
||||||
sceneryGetSky(&_sky);
|
|
||||||
_terrain = terrainCreateDefinition();
|
_terrain = terrainCreateDefinition();
|
||||||
sceneryGetTerrain(&_terrain);
|
sceneryGetTerrain(&_terrain);
|
||||||
_textures = texturesCreateDefinition();
|
_textures = texturesCreateDefinition();
|
||||||
|
@ -93,16 +86,14 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
||||||
_lighting = lightingCreateDefinition();
|
_lighting = lightingCreateDefinition();
|
||||||
sceneryGetLighting(&_lighting);
|
sceneryGetLighting(&_lighting);
|
||||||
|
|
||||||
_renderer = rendererCreate();
|
_renderer = sceneryCreateStandardRenderer();
|
||||||
_renderer.render_quality = 3;
|
_renderer.render_quality = 3;
|
||||||
_renderer.customData[0] = &_terrain;
|
_renderer.customData[0] = &_terrain;
|
||||||
_renderer.customData[1] = &_textures;
|
_renderer.customData[1] = &_textures;
|
||||||
_renderer.customData[2] = &_lighting;
|
_renderer.customData[2] = &_lighting;
|
||||||
_renderer.customData[3] = &_water;
|
_renderer.customData[3] = &_water;
|
||||||
_renderer.customData[4] = &_sky;
|
|
||||||
_renderer.applyTextures = _applyTextures;
|
_renderer.applyTextures = _applyTextures;
|
||||||
_renderer.getTerrainHeight = _getTerrainHeight;
|
_renderer.getTerrainHeight = _getTerrainHeight;
|
||||||
_renderer.getSkyDomeLights = _getSkyDomeLights;
|
|
||||||
_renderer.alterLight = _alterLight;
|
_renderer.alterLight = _alterLight;
|
||||||
_renderer.getLightStatus = _getLightStatus;
|
_renderer.getLightStatus = _getLightStatus;
|
||||||
|
|
||||||
|
@ -126,7 +117,7 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
||||||
// Add skybox
|
// Add skybox
|
||||||
for (int orientation = 0; orientation < 6; orientation++)
|
for (int orientation = 0; orientation < 6; orientation++)
|
||||||
{
|
{
|
||||||
ExplorerChunkSky* chunk = new ExplorerChunkSky(&_renderer, &_sky, 500.0, (SkyboxOrientation)orientation);
|
ExplorerChunkSky* chunk = new ExplorerChunkSky(&_renderer, 500.0, (SkyboxOrientation)orientation);
|
||||||
_chunks.append(chunk);
|
_chunks.append(chunk);
|
||||||
_updateQueue.append(chunk);
|
_updateQueue.append(chunk);
|
||||||
}
|
}
|
||||||
|
@ -437,8 +428,7 @@ void WidgetExplorer::paintGL()
|
||||||
gluLookAt(_current_camera.location.x, _current_camera.location.y, _current_camera.location.z, _current_camera.target.x, _current_camera.target.y, _current_camera.target.z, _current_camera.up.x, _current_camera.up.y, _current_camera.up.z);
|
gluLookAt(_current_camera.location.x, _current_camera.location.y, _current_camera.location.z, _current_camera.target.x, _current_camera.target.y, _current_camera.target.z, _current_camera.up.x, _current_camera.up.y, _current_camera.up.z);
|
||||||
|
|
||||||
// Background
|
// Background
|
||||||
Color zenith_color = skyGetZenithColor(&_sky);
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||||
glClearColor(zenith_color.r, zenith_color.g, zenith_color.b, 0.0);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
// Render water
|
// Render water
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "../lib_paysages/camera.h"
|
#include "../lib_paysages/camera.h"
|
||||||
#include "../lib_paysages/water.h"
|
#include "../lib_paysages/water.h"
|
||||||
#include "../lib_paysages/renderer.h"
|
#include "../lib_paysages/renderer.h"
|
||||||
#include "../lib_paysages/sky.h"
|
|
||||||
#include "../lib_paysages/terrain.h"
|
#include "../lib_paysages/terrain.h"
|
||||||
#include "../lib_paysages/textures.h"
|
#include "../lib_paysages/textures.h"
|
||||||
#include "../lib_paysages/lighting.h"
|
#include "../lib_paysages/lighting.h"
|
||||||
|
@ -51,7 +50,6 @@ private:
|
||||||
QMutex _lock_chunks;
|
QMutex _lock_chunks;
|
||||||
|
|
||||||
WaterDefinition _water;
|
WaterDefinition _water;
|
||||||
SkyDefinition _sky;
|
|
||||||
TerrainDefinition _terrain;
|
TerrainDefinition _terrain;
|
||||||
TexturesDefinition _textures;
|
TexturesDefinition _textures;
|
||||||
LightingDefinition _lighting;
|
LightingDefinition _lighting;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
BUILDMODE = debug
|
BUILDMODE = debug
|
||||||
BUILDPATH = ../build/${BUILDMODE}
|
BUILDPATH = ../build/${BUILDMODE}
|
||||||
OBJPATH = ./obj/${BUILDMODE}
|
OBJPATH = ./obj/${BUILDMODE}
|
||||||
SOURCES = $(wildcard *.c)
|
SOURCES = $(wildcard *.c atmosphere/*.c)
|
||||||
OBJECTS = ${SOURCES:%.c=${OBJPATH}/%.o}
|
OBJECTS = ${SOURCES:%.c=${OBJPATH}/%.o}
|
||||||
HEADERS = $(wildcard shared/*.h *.h)
|
HEADERS = $(wildcard shared/*.h atmosphere/*.h *.h)
|
||||||
RESULT = ${BUILDPATH}/libpaysages.so
|
RESULT = ${BUILDPATH}/libpaysages.so
|
||||||
CC_FLAGS = -Wall -fPIC $(shell pkg-config --cflags glib-2.0 gthread-2.0) -DHAVE_GLIB=1
|
CC_FLAGS = -Wall -fPIC $(shell pkg-config --cflags glib-2.0 gthread-2.0) -DHAVE_GLIB=1
|
||||||
CC_LDFLAGS = $(shell pkg-config --libs glib-2.0 gthread-2.0) -lIL -lILU
|
CC_LDFLAGS = $(shell pkg-config --libs glib-2.0 gthread-2.0) -lIL -lILU
|
||||||
|
@ -27,6 +27,7 @@ clean:
|
||||||
rm -f ${RESULT}
|
rm -f ${RESULT}
|
||||||
|
|
||||||
${OBJPATH}/%.o:%.c ${HEADERS}
|
${OBJPATH}/%.o:%.c ${HEADERS}
|
||||||
|
mkdir -p `dirname $@`
|
||||||
${CC} -c ${CC_FLAGS} $< -o $@
|
${CC} -c ${CC_FLAGS} $< -o $@
|
||||||
|
|
||||||
${RESULT}:${OBJECTS}
|
${RESULT}:${OBJECTS}
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
#include "atmosphere.h"
|
|
||||||
|
|
||||||
#include "scenery.h"
|
|
||||||
#include "euclid.h"
|
|
||||||
#include "color.h"
|
|
||||||
#include "tools.h"
|
|
||||||
|
|
||||||
void atmosphereSave(PackStream* stream, AtmosphereDefinition* definition)
|
|
||||||
{
|
|
||||||
packWriteDouble(stream, &definition->distance_near);
|
|
||||||
packWriteDouble(stream, &definition->distance_far);
|
|
||||||
packWriteDouble(stream, &definition->full_mask);
|
|
||||||
packWriteInt(stream, &definition->auto_lock_on_haze);
|
|
||||||
colorSave(stream, &definition->color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void atmosphereLoad(PackStream* stream, AtmosphereDefinition* definition)
|
|
||||||
{
|
|
||||||
packReadDouble(stream, &definition->distance_near);
|
|
||||||
packReadDouble(stream, &definition->distance_far);
|
|
||||||
packReadDouble(stream, &definition->full_mask);
|
|
||||||
packReadInt(stream, &definition->auto_lock_on_haze);
|
|
||||||
colorLoad(stream, &definition->color);
|
|
||||||
|
|
||||||
atmosphereValidateDefinition(definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
AtmosphereDefinition atmosphereCreateDefinition()
|
|
||||||
{
|
|
||||||
AtmosphereDefinition definition;
|
|
||||||
|
|
||||||
definition.distance_near = 0.0;
|
|
||||||
definition.distance_far = 1.0;
|
|
||||||
definition.full_mask = 0.0;
|
|
||||||
definition.auto_lock_on_haze = 0;
|
|
||||||
definition.color = COLOR_BLACK;
|
|
||||||
|
|
||||||
atmosphereValidateDefinition(&definition);
|
|
||||||
|
|
||||||
return definition;
|
|
||||||
}
|
|
||||||
|
|
||||||
void atmosphereDeleteDefinition(AtmosphereDefinition* definition)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void atmosphereCopyDefinition(AtmosphereDefinition* source, AtmosphereDefinition* destination)
|
|
||||||
{
|
|
||||||
*destination = *source;
|
|
||||||
}
|
|
||||||
|
|
||||||
void atmosphereValidateDefinition(AtmosphereDefinition* definition)
|
|
||||||
{
|
|
||||||
SkyDefinition sky;
|
|
||||||
|
|
||||||
if (definition->distance_far <= definition->distance_near)
|
|
||||||
{
|
|
||||||
definition->distance_far = definition->distance_near + 1.0;
|
|
||||||
}
|
|
||||||
if (definition->full_mask < 0.0)
|
|
||||||
{
|
|
||||||
definition->full_mask = 0.0;
|
|
||||||
}
|
|
||||||
if (definition->full_mask > 1.0)
|
|
||||||
{
|
|
||||||
definition->full_mask = 1.0;
|
|
||||||
}
|
|
||||||
if (definition->auto_lock_on_haze)
|
|
||||||
{
|
|
||||||
sky = skyCreateDefinition();
|
|
||||||
sceneryGetSky(&sky);
|
|
||||||
definition->color = skyGetHorizonColor(&sky);
|
|
||||||
skyDeleteDefinition(&sky);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Color atmosphereApply(AtmosphereDefinition* definition, Renderer* renderer, Vector3 location, Color base)
|
|
||||||
{
|
|
||||||
Color mask = definition->color;
|
|
||||||
double distance = v3Norm(v3Sub(renderer->camera_location, location));
|
|
||||||
double value;
|
|
||||||
double alpha;
|
|
||||||
|
|
||||||
if (distance < definition->distance_near)
|
|
||||||
{
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
else if (distance > definition->distance_far)
|
|
||||||
{
|
|
||||||
distance = definition->distance_far;
|
|
||||||
}
|
|
||||||
|
|
||||||
alpha = base.a;
|
|
||||||
base.a = 1.0;
|
|
||||||
|
|
||||||
value = definition->full_mask * (distance - definition->distance_near) / (definition->distance_far - definition->distance_near);
|
|
||||||
|
|
||||||
mask.a = value;
|
|
||||||
colorMask(&base, &mask);
|
|
||||||
|
|
||||||
base.a = alpha;
|
|
||||||
|
|
||||||
return base;
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
#ifndef _PAYSAGES_ATMOSPHERE_H_
|
|
||||||
#define _PAYSAGES_ATMOSPHERE_H_
|
|
||||||
|
|
||||||
#include "shared/types.h"
|
|
||||||
#include "pack.h"
|
|
||||||
#include "lighting.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
double distance_near;
|
|
||||||
double distance_far;
|
|
||||||
double full_mask;
|
|
||||||
int auto_lock_on_haze;
|
|
||||||
Color color;
|
|
||||||
} AtmosphereDefinition;
|
|
||||||
|
|
||||||
void atmosphereSave(PackStream* stream, AtmosphereDefinition* definition);
|
|
||||||
void atmosphereLoad(PackStream* stream, AtmosphereDefinition* definition);
|
|
||||||
|
|
||||||
AtmosphereDefinition atmosphereCreateDefinition();
|
|
||||||
void atmosphereDeleteDefinition(AtmosphereDefinition* definition);
|
|
||||||
void atmosphereCopyDefinition(AtmosphereDefinition* source, AtmosphereDefinition* destination);
|
|
||||||
void atmosphereValidateDefinition(AtmosphereDefinition* definition);
|
|
||||||
|
|
||||||
Color atmosphereApply(AtmosphereDefinition* definition, Renderer* renderer, Vector3 location, Color base);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
407
lib_paysages/atmosphere/atmosphere.c
Normal file
407
lib_paysages/atmosphere/atmosphere.c
Normal file
|
@ -0,0 +1,407 @@
|
||||||
|
#include "atmosphere.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../tools.h"
|
||||||
|
#include "../renderer.h"
|
||||||
|
#include "../lighting.h"
|
||||||
|
#include "../system.h"
|
||||||
|
|
||||||
|
#define SPHERE_SIZE 1000.0
|
||||||
|
#define MAX_SKYDOME_LIGHTS 100
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Mutex* lock;
|
||||||
|
int nblights;
|
||||||
|
LightDefinition lights[MAX_SKYDOME_LIGHTS];
|
||||||
|
} AtmosphereRendererCache;
|
||||||
|
|
||||||
|
/******************** Definition ********************/
|
||||||
|
static void _validateDefinition(AtmosphereDefinition* definition)
|
||||||
|
{
|
||||||
|
UNUSED(definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
static AtmosphereDefinition* _createDefinition()
|
||||||
|
{
|
||||||
|
AtmosphereDefinition* result;
|
||||||
|
|
||||||
|
result = malloc(sizeof(AtmosphereDefinition));
|
||||||
|
result->model = ATMOSPHERE_MODEL_PREETHAM;
|
||||||
|
result->daytime = 0.0;
|
||||||
|
result->sun_color = COLOR_BLACK;
|
||||||
|
result->sun_color.r = 1.0;
|
||||||
|
result->sun_color.g = 0.95;
|
||||||
|
result->sun_color.b = 0.9;
|
||||||
|
result->sun_color.a = 1.0;
|
||||||
|
result->sun_radius = 0.02;
|
||||||
|
result->sun_halo_size = 0.3;
|
||||||
|
result->sun_halo_profile = curveCreate();
|
||||||
|
curveQuickAddPoint(result->sun_halo_profile, 0.0, 1.0);
|
||||||
|
curveQuickAddPoint(result->sun_halo_profile, 0.1, 0.2);
|
||||||
|
curveQuickAddPoint(result->sun_halo_profile, 1.0, 0.0);
|
||||||
|
result->dome_lighting = 0.6;
|
||||||
|
result->humidity = 2.0;
|
||||||
|
|
||||||
|
_validateDefinition(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _deleteDefinition(AtmosphereDefinition* definition)
|
||||||
|
{
|
||||||
|
curveDelete(definition->sun_halo_profile);
|
||||||
|
free(definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _copyDefinition(AtmosphereDefinition* source, AtmosphereDefinition* destination)
|
||||||
|
{
|
||||||
|
destination->model = source->model;
|
||||||
|
destination->daytime = source->daytime;
|
||||||
|
destination->sun_color = source->sun_color;
|
||||||
|
destination->sun_radius = source->sun_radius;
|
||||||
|
destination->sun_halo_size = source->sun_halo_size;
|
||||||
|
destination->dome_lighting = source->dome_lighting;
|
||||||
|
destination->humidity = source->humidity;
|
||||||
|
|
||||||
|
curveCopy(source->sun_halo_profile, destination->sun_halo_profile);
|
||||||
|
|
||||||
|
_validateDefinition(destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _saveDefinition(PackStream* stream, AtmosphereDefinition* definition)
|
||||||
|
{
|
||||||
|
packWriteInt(stream, (int*)&definition->model);
|
||||||
|
packWriteDouble(stream, &definition->daytime);
|
||||||
|
colorSave(stream, &definition->sun_color);
|
||||||
|
packWriteDouble(stream, &definition->sun_radius);
|
||||||
|
packWriteDouble(stream, &definition->sun_halo_size);
|
||||||
|
curveSave(stream, definition->sun_halo_profile);
|
||||||
|
packWriteDouble(stream, &definition->dome_lighting);
|
||||||
|
packWriteDouble(stream, &definition->humidity);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _loadDefinition(PackStream* stream, AtmosphereDefinition* definition)
|
||||||
|
{
|
||||||
|
packReadInt(stream, (int*)&definition->model);
|
||||||
|
packReadDouble(stream, &definition->daytime);
|
||||||
|
colorLoad(stream, &definition->sun_color);
|
||||||
|
packReadDouble(stream, &definition->sun_radius);
|
||||||
|
packReadDouble(stream, &definition->sun_halo_size);
|
||||||
|
curveLoad(stream, definition->sun_halo_profile);
|
||||||
|
packReadDouble(stream, &definition->dome_lighting);
|
||||||
|
packReadDouble(stream, &definition->humidity);
|
||||||
|
|
||||||
|
_validateDefinition(definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardDefinition AtmosphereDefinitionClass = {
|
||||||
|
(FuncObjectCreate)_createDefinition,
|
||||||
|
(FuncObjectDelete)_deleteDefinition,
|
||||||
|
(FuncObjectCopy)_copyDefinition,
|
||||||
|
(FuncObjectValidate)_validateDefinition,
|
||||||
|
(FuncObjectSave)_saveDefinition,
|
||||||
|
(FuncObjectLoad)_loadDefinition
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************** Binding ********************/
|
||||||
|
extern Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position);
|
||||||
|
extern Color preethamGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position);
|
||||||
|
|
||||||
|
static Color _fakeApplyAerialPerspective(Renderer* renderer, Vector3 direction, Color base)
|
||||||
|
{
|
||||||
|
UNUSED(renderer);
|
||||||
|
UNUSED(direction);
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
static Color _fakeGetSkyColor(Renderer* renderer, Vector3 direction)
|
||||||
|
{
|
||||||
|
UNUSED(renderer);
|
||||||
|
UNUSED(direction);
|
||||||
|
return COLOR_WHITE;
|
||||||
|
}
|
||||||
|
static int _fakeGetSkydomeLights(Renderer* renderer, LightDefinition* lights, int max_lights)
|
||||||
|
{
|
||||||
|
UNUSED(renderer);
|
||||||
|
UNUSED(lights);
|
||||||
|
UNUSED(max_lights);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color _getSkyColor(Renderer* renderer, Vector3 direction)
|
||||||
|
{
|
||||||
|
AtmosphereDefinition* definition;
|
||||||
|
double dist;
|
||||||
|
Vector3 sun_position;
|
||||||
|
Color sky_color, sun_color;
|
||||||
|
|
||||||
|
definition = renderer->atmosphere->definition;
|
||||||
|
|
||||||
|
sun_position = renderer->atmosphere->getSunDirection(renderer);
|
||||||
|
direction = v3Normalize(direction);
|
||||||
|
dist = v3Norm(v3Sub(direction, sun_position));
|
||||||
|
|
||||||
|
/* Get base scattering*/
|
||||||
|
switch (definition->model)
|
||||||
|
{
|
||||||
|
case ATMOSPHERE_MODEL_BRUNETON:
|
||||||
|
sky_color = brunetonGetSkyColor(definition, renderer->camera_location, direction, sun_position);
|
||||||
|
break;
|
||||||
|
case ATMOSPHERE_MODEL_PREETHAM:
|
||||||
|
sky_color = preethamGetSkyColor(definition, renderer->camera_location, direction, sun_position);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sky_color = COLOR_BLUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get sun halo */
|
||||||
|
if (dist < definition->sun_radius + definition->sun_halo_size)
|
||||||
|
{
|
||||||
|
sun_color = definition->sun_color;
|
||||||
|
if (dist <= definition->sun_radius)
|
||||||
|
{
|
||||||
|
return sun_color;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dist = (dist - definition->sun_radius) / definition->sun_halo_size;
|
||||||
|
sun_color.a = curveGetValue(definition->sun_halo_profile, dist);
|
||||||
|
colorMask(&sky_color, &sun_color);
|
||||||
|
return sky_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return sky_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Vector3 _getSunDirection(Renderer* renderer)
|
||||||
|
{
|
||||||
|
Vector3 result;
|
||||||
|
double sun_angle = (renderer->atmosphere->definition->daytime + 0.75) * M_PI * 2.0;
|
||||||
|
result.x = cos(sun_angle);
|
||||||
|
result.y = sin(sun_angle);
|
||||||
|
result.z = 0.0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _addDomeLight(Renderer* renderer, LightDefinition* light, Vector3 direction, double factor)
|
||||||
|
{
|
||||||
|
light->direction = v3Scale(direction, -1.0);
|
||||||
|
light->color = renderer->atmosphere->getSkyColor(renderer, direction);
|
||||||
|
light->color.r *= factor;
|
||||||
|
light->color.g *= factor;
|
||||||
|
light->color.b *= factor;
|
||||||
|
light->reflection = 0.0;
|
||||||
|
light->filtered = 0;
|
||||||
|
light->masked = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _getSkydomeLights(Renderer* renderer, LightDefinition* lights, int max_lights)
|
||||||
|
{
|
||||||
|
AtmosphereRendererCache* cache = (AtmosphereRendererCache*)renderer->atmosphere->_internal_data;
|
||||||
|
AtmosphereDefinition* definition;
|
||||||
|
double sun_angle;
|
||||||
|
Vector3 sun_direction;
|
||||||
|
int nblights = 0;
|
||||||
|
|
||||||
|
mutexAcquire(cache->lock);
|
||||||
|
if (cache->nblights < 0)
|
||||||
|
{
|
||||||
|
definition = renderer->atmosphere->definition;
|
||||||
|
|
||||||
|
sun_angle = (definition->daytime + 0.75) * M_PI * 2.0;
|
||||||
|
sun_direction.x = cos(sun_angle);
|
||||||
|
sun_direction.y = sin(sun_angle);
|
||||||
|
sun_direction.z = 0.0;
|
||||||
|
|
||||||
|
/* TODO Moon light */
|
||||||
|
|
||||||
|
if (max_lights > MAX_SKYDOME_LIGHTS)
|
||||||
|
{
|
||||||
|
max_lights = MAX_SKYDOME_LIGHTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_lights > 0)
|
||||||
|
{
|
||||||
|
/* Direct light from the sun */
|
||||||
|
cache->lights[0].direction = v3Scale(sun_direction, -1.0);
|
||||||
|
cache->lights[0].color = definition->sun_color;
|
||||||
|
cache->lights[0].reflection = 1.0;
|
||||||
|
cache->lights[0].filtered = 1;
|
||||||
|
cache->lights[0].masked = 1;
|
||||||
|
nblights = 1;
|
||||||
|
max_lights--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_lights > 0)
|
||||||
|
{
|
||||||
|
/* Indirect lighting by skydome scattering */
|
||||||
|
int xsamples, ysamples, samples, x, y;
|
||||||
|
double xstep, ystep, factor;
|
||||||
|
Vector3 direction;
|
||||||
|
|
||||||
|
samples = (renderer->render_quality < 5) ? 9 : (renderer->render_quality * 4 + 1);
|
||||||
|
samples = samples > max_lights ? max_lights : samples;
|
||||||
|
|
||||||
|
factor = definition->dome_lighting / (double)samples;
|
||||||
|
|
||||||
|
_addDomeLight(renderer, cache->lights + nblights, VECTOR_UP, factor);
|
||||||
|
nblights++;
|
||||||
|
samples--;
|
||||||
|
|
||||||
|
if (samples >= 2)
|
||||||
|
{
|
||||||
|
xsamples = samples / 2;
|
||||||
|
ysamples = samples / xsamples;
|
||||||
|
|
||||||
|
xstep = M_PI * 2.0 / (double)xsamples;
|
||||||
|
ystep = M_PI * 0.5 / (double)ysamples;
|
||||||
|
|
||||||
|
for (x = 0; x < xsamples; x++)
|
||||||
|
{
|
||||||
|
for (y = 0; y < ysamples; y++)
|
||||||
|
{
|
||||||
|
direction.x = cos(x * xstep) * cos(y * ystep);
|
||||||
|
direction.y = -sin(y * ystep);
|
||||||
|
direction.z = sin(x * xstep) * cos(y * ystep);
|
||||||
|
|
||||||
|
_addDomeLight(renderer, cache->lights + nblights, direction, factor);
|
||||||
|
nblights++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cache->nblights = nblights;
|
||||||
|
}
|
||||||
|
mutexRelease(cache->lock);
|
||||||
|
|
||||||
|
memcpy(lights, cache->lights, sizeof(LightDefinition) * cache->nblights);
|
||||||
|
return cache->nblights;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************** Renderer ********************/
|
||||||
|
static AtmosphereRenderer* _createRenderer()
|
||||||
|
{
|
||||||
|
AtmosphereRenderer* result;
|
||||||
|
AtmosphereRendererCache* cache;
|
||||||
|
|
||||||
|
result = malloc(sizeof(AtmosphereRenderer));
|
||||||
|
result->definition = AtmosphereDefinitionClass.create();
|
||||||
|
|
||||||
|
result->getSunDirection = _getSunDirection;
|
||||||
|
result->applyAerialPerspective = _fakeApplyAerialPerspective;
|
||||||
|
result->getSkydomeLights = _fakeGetSkydomeLights;
|
||||||
|
result->getSkyColor = _fakeGetSkyColor;
|
||||||
|
|
||||||
|
cache = malloc(sizeof(AtmosphereRendererCache));
|
||||||
|
cache->lock = mutexCreate();
|
||||||
|
cache->nblights = -1;
|
||||||
|
result->_internal_data = cache;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _deleteRenderer(AtmosphereRenderer* renderer)
|
||||||
|
{
|
||||||
|
AtmosphereRendererCache* cache = (AtmosphereRendererCache*)renderer->_internal_data;
|
||||||
|
mutexDestroy(cache->lock);
|
||||||
|
free(cache);
|
||||||
|
|
||||||
|
AtmosphereDefinitionClass.destroy(renderer->definition);
|
||||||
|
free(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _bindRenderer(AtmosphereRenderer* renderer, AtmosphereDefinition* definition)
|
||||||
|
{
|
||||||
|
AtmosphereRendererCache* cache = (AtmosphereRendererCache*)renderer->_internal_data;
|
||||||
|
|
||||||
|
AtmosphereDefinitionClass.copy(definition, renderer->definition);
|
||||||
|
|
||||||
|
renderer->getSkyColor = _getSkyColor;
|
||||||
|
renderer->getSkydomeLights = _getSkydomeLights;
|
||||||
|
|
||||||
|
mutexAcquire(cache->lock);
|
||||||
|
cache->nblights = -1;
|
||||||
|
mutexRelease(cache->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardRenderer AtmosphereRendererClass = {
|
||||||
|
(FuncObjectCreate)_createRenderer,
|
||||||
|
(FuncObjectDelete)_deleteRenderer,
|
||||||
|
(FuncObjectBind)_bindRenderer
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************** Utilities ********************/
|
||||||
|
static Color _postProcessFragment(Renderer* renderer, Vector3 location, void* data)
|
||||||
|
{
|
||||||
|
Vector3 direction;
|
||||||
|
Color result;
|
||||||
|
|
||||||
|
UNUSED(data);
|
||||||
|
|
||||||
|
direction = v3Sub(location, renderer->camera_location);
|
||||||
|
|
||||||
|
/* TODO Don't compute result->color if it's fully covered by clouds */
|
||||||
|
result = renderer->atmosphere->getSkyColor(renderer, v3Normalize(direction));
|
||||||
|
result = renderer->applyClouds(renderer, result, renderer->camera_location, v3Add(renderer->camera_location, v3Scale(direction, 10.0)));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void atmosphereRenderSkydome(Renderer* renderer)
|
||||||
|
{
|
||||||
|
int res_i, res_j;
|
||||||
|
int i, j;
|
||||||
|
double step_i, step_j;
|
||||||
|
double current_i, current_j;
|
||||||
|
Vector3 vertex1, vertex2, vertex3, vertex4;
|
||||||
|
Vector3 direction;
|
||||||
|
|
||||||
|
res_i = renderer->render_quality * 40;
|
||||||
|
res_j = renderer->render_quality * 20;
|
||||||
|
step_i = M_PI * 2.0 / (double)res_i;
|
||||||
|
step_j = M_PI / (double)res_j;
|
||||||
|
|
||||||
|
for (j = 0; j < res_j; j++)
|
||||||
|
{
|
||||||
|
if (!renderer->addRenderProgress(renderer, 0.0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_j = (double)(j - res_j / 2) * step_j;
|
||||||
|
|
||||||
|
for (i = 0; i < res_i; i++)
|
||||||
|
{
|
||||||
|
current_i = (double)i * step_i;
|
||||||
|
|
||||||
|
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j);
|
||||||
|
direction.y = SPHERE_SIZE * sin(current_j);
|
||||||
|
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j);
|
||||||
|
vertex1 = v3Add(renderer->camera_location, direction);
|
||||||
|
|
||||||
|
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j);
|
||||||
|
direction.y = SPHERE_SIZE * sin(current_j);
|
||||||
|
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j);
|
||||||
|
vertex2 = v3Add(renderer->camera_location, direction);
|
||||||
|
|
||||||
|
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j + step_j);
|
||||||
|
direction.y = SPHERE_SIZE * sin(current_j + step_j);
|
||||||
|
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j + step_j);
|
||||||
|
vertex3 = v3Add(renderer->camera_location, direction);
|
||||||
|
|
||||||
|
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j + step_j);
|
||||||
|
direction.y = SPHERE_SIZE * sin(current_j + step_j);
|
||||||
|
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j + step_j);
|
||||||
|
vertex4 = v3Add(renderer->camera_location, direction);
|
||||||
|
|
||||||
|
/* TODO Triangles at poles */
|
||||||
|
renderer->pushQuad(renderer, vertex1, vertex4, vertex3, vertex2, _postProcessFragment, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
83
lib_paysages/atmosphere/atmosphere.h
Normal file
83
lib_paysages/atmosphere/atmosphere.h
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
#ifndef _PAYSAGES_ATMOSPHERE_INTERFACE_H_
|
||||||
|
#define _PAYSAGES_ATMOSPHERE_INTERFACE_H_
|
||||||
|
|
||||||
|
#include "../shared/types.h"
|
||||||
|
#include "../euclid.h"
|
||||||
|
#include "../color.h"
|
||||||
|
#include "../pack.h"
|
||||||
|
#include "../layers.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*** TO EXTRACT ***/
|
||||||
|
typedef void* (*FuncObjectCreate)();
|
||||||
|
typedef void (*FuncObjectDelete)(void* object);
|
||||||
|
typedef void (*FuncObjectCopy)(void* source, void* destination);
|
||||||
|
typedef void (*FuncObjectValidate)(void* object);
|
||||||
|
typedef void (*FuncObjectSave)(PackStream* stream, void* object);
|
||||||
|
typedef void (*FuncObjectLoad)(PackStream* stream, void* object);
|
||||||
|
typedef void (*FuncObjectBind)(void* base, void* sub);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FuncObjectCreate create;
|
||||||
|
FuncObjectDelete destroy;
|
||||||
|
FuncObjectCopy copy;
|
||||||
|
FuncObjectValidate validate;
|
||||||
|
FuncObjectSave save;
|
||||||
|
FuncObjectLoad load;
|
||||||
|
} StandardDefinition;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FuncObjectCreate create;
|
||||||
|
FuncObjectDelete destroy;
|
||||||
|
FuncObjectBind bind;
|
||||||
|
} StandardRenderer;
|
||||||
|
/*** TO EXTRACT ***/
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ATMOSPHERE_MODEL_PREETHAM = 0,
|
||||||
|
ATMOSPHERE_MODEL_BRUNETON = 1
|
||||||
|
} AtmosphereModel;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
AtmosphereModel model;
|
||||||
|
double daytime;
|
||||||
|
double humidity;
|
||||||
|
Color sun_color;
|
||||||
|
double sun_radius;
|
||||||
|
double sun_halo_size;
|
||||||
|
Curve* sun_halo_profile;
|
||||||
|
double dome_lighting;
|
||||||
|
} AtmosphereDefinition;
|
||||||
|
|
||||||
|
typedef int (*FuncAtmosphereGetSkydomeLights)(Renderer* renderer, LightDefinition* array, int max_lights);
|
||||||
|
typedef Color (*FuncAtmosphereApplyAerialPerspective)(Renderer* renderer, Vector3 location, Color base);
|
||||||
|
typedef Color (*FuncAtmosphereGetSkyColor)(Renderer* renderer, Vector3 direction);
|
||||||
|
typedef Vector3 (*FuncAtmosphereGetSunDirection)(Renderer* renderer);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
AtmosphereDefinition* definition;
|
||||||
|
|
||||||
|
FuncAtmosphereGetSkydomeLights getSkydomeLights;
|
||||||
|
FuncAtmosphereApplyAerialPerspective applyAerialPerspective;
|
||||||
|
FuncAtmosphereGetSkyColor getSkyColor;
|
||||||
|
FuncAtmosphereGetSunDirection getSunDirection;
|
||||||
|
|
||||||
|
void* _internal_data;
|
||||||
|
} AtmosphereRenderer;
|
||||||
|
|
||||||
|
extern StandardDefinition AtmosphereDefinitionClass;
|
||||||
|
extern StandardRenderer AtmosphereRendererClass;
|
||||||
|
|
||||||
|
void atmosphereRenderSkydome(Renderer* renderer);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
6
lib_paysages/atmosphere/bruneton.c
Normal file
6
lib_paysages/atmosphere/bruneton.c
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include "atmosphere.h"
|
||||||
|
|
||||||
|
Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position)
|
||||||
|
{
|
||||||
|
return COLOR_BLACK;
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
#include "skypreetham.h"
|
#include "atmosphere.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include "../renderer.h"
|
||||||
|
|
||||||
static inline double _angleBetween(double thetav, double phiv, double theta, double phi)
|
static inline double _angleBetween(double thetav, double phiv, double theta, double phi)
|
||||||
{
|
{
|
||||||
|
@ -50,13 +51,13 @@ static inline void _directionToThetaPhi(Vector3 direction, double* theta, double
|
||||||
*theta = M_PI_2 - asin(direction.y);
|
*theta = M_PI_2 - asin(direction.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color skyPreethamGetColor(Vector3 viewer, Vector3 direction, Vector3 sun_direction, double turbidity)
|
Color preethamGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position)
|
||||||
{
|
{
|
||||||
double theta, phi;
|
double theta, phi;
|
||||||
double thetaSun, phiSun;
|
double thetaSun, phiSun;
|
||||||
|
|
||||||
_directionToThetaPhi(direction, &theta, &phi);
|
_directionToThetaPhi(direction, &theta, &phi);
|
||||||
_directionToThetaPhi(sun_direction, &thetaSun, &phiSun);
|
_directionToThetaPhi(sun_position, &thetaSun, &phiSun);
|
||||||
|
|
||||||
if (theta > M_PI / 2.0)
|
if (theta > M_PI / 2.0)
|
||||||
{
|
{
|
||||||
|
@ -74,7 +75,7 @@ Color skyPreethamGetColor(Vector3 viewer, Vector3 direction, Vector3 sun_directi
|
||||||
cosTheta = cos(theta);
|
cosTheta = cos(theta);
|
||||||
}
|
}
|
||||||
|
|
||||||
double T = turbidity;
|
double T = definition->humidity;
|
||||||
double T2 = T * T;
|
double T2 = T * T;
|
||||||
double suntheta = thetaSun;
|
double suntheta = thetaSun;
|
||||||
double suntheta2 = thetaSun * thetaSun;
|
double suntheta2 = thetaSun * thetaSun;
|
||||||
|
@ -129,9 +130,3 @@ Color skyPreethamGetColor(Vector3 viewer, Vector3 direction, Vector3 sun_directi
|
||||||
|
|
||||||
return _xyYToRGB(x, y, Y);
|
return _xyYToRGB(x, y, Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color skyPreethamApplyToObject(Vector3 viewer, Vector3 object_location, Vector3 sun_direction, double turbidity, Color object_color)
|
|
||||||
{
|
|
||||||
/* TODO Aerial perspective */
|
|
||||||
return object_color;
|
|
||||||
}
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "terrain.h"
|
#include "terrain.h"
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
#include "scenery.h"
|
#include "scenery.h"
|
||||||
#include "sky.h"
|
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "water.h"
|
#include "water.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
|
@ -25,9 +24,7 @@ void autoSetDaytime(int hour, int minute)
|
||||||
|
|
||||||
void autoSetDaytimeFraction(double daytime)
|
void autoSetDaytimeFraction(double daytime)
|
||||||
{
|
{
|
||||||
SkyDefinition sky;
|
AtmosphereDefinition* atmosphere;
|
||||||
/*ColorGradation grad_sun;
|
|
||||||
Color sun;*/
|
|
||||||
|
|
||||||
daytime = fmod(daytime, 1.0);
|
daytime = fmod(daytime, 1.0);
|
||||||
if (daytime < 0.0)
|
if (daytime < 0.0)
|
||||||
|
@ -35,33 +32,18 @@ void autoSetDaytimeFraction(double daytime)
|
||||||
daytime += 1.0;
|
daytime += 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*lightingSetSunAngle(0.0, (daytime + 0.25) * M_PI * 2.0);
|
atmosphere = AtmosphereDefinitionClass.create();
|
||||||
|
sceneryGetAtmosphere(atmosphere);
|
||||||
grad_sun = colorGradationCreate();
|
atmosphere->daytime = daytime;
|
||||||
colorGradationAddRgba(&grad_sun, 0.2, 0.1, 0.1, 0.1, 1.0);
|
scenerySetAtmosphere(atmosphere);
|
||||||
colorGradationAddRgba(&grad_sun, 0.25, 0.9, 0.5, 0.5, 1.0);
|
AtmosphereDefinitionClass.destroy(atmosphere);
|
||||||
colorGradationAddRgba(&grad_sun, 0.3, 0.8, 0.8, 0.8, 1.0);
|
|
||||||
colorGradationAddRgba(&grad_sun, 0.5, 1.0, 1.0, 1.0, 1.0);
|
|
||||||
colorGradationAddRgba(&grad_sun, 0.7, 0.8, 0.8, 0.8, 1.0);
|
|
||||||
colorGradationAddRgba(&grad_sun, 0.75, 0.7, 0.6, 0.5, 1.0);
|
|
||||||
colorGradationAddRgba(&grad_sun, 0.8, 0.1, 0.1, 0.1, 1.0);
|
|
||||||
sun = colorGradationGet(&grad_sun, daytime);
|
|
||||||
lightingSetSunColor(sun);*/
|
|
||||||
|
|
||||||
sky = skyCreateDefinition();
|
|
||||||
sceneryGetSky(&sky);
|
|
||||||
sky.daytime = daytime;
|
|
||||||
scenerySetSky(&sky);
|
|
||||||
skyDeleteDefinition(&sky);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void autoGenRealisticLandscape(int seed)
|
void autoGenRealisticLandscape(int seed)
|
||||||
{
|
{
|
||||||
AtmosphereDefinition atmosphere;
|
|
||||||
TerrainDefinition terrain;
|
TerrainDefinition terrain;
|
||||||
WaterDefinition water;
|
WaterDefinition water;
|
||||||
CloudsDefinition clouds;
|
CloudsDefinition clouds;
|
||||||
SkyDefinition sky;
|
|
||||||
TexturesDefinition textures;
|
TexturesDefinition textures;
|
||||||
TextureLayerDefinition* texture;
|
TextureLayerDefinition* texture;
|
||||||
int layer;
|
int layer;
|
||||||
|
@ -84,36 +66,6 @@ void autoGenRealisticLandscape(int seed)
|
||||||
scenerySetWater(&water);
|
scenerySetWater(&water);
|
||||||
waterDeleteDefinition(&water);
|
waterDeleteDefinition(&water);
|
||||||
|
|
||||||
/* Sky */
|
|
||||||
sky = skyCreateDefinition();
|
|
||||||
sky.model = SKY_MODEL_PREETHAM;
|
|
||||||
sky.daytime = 0.0;
|
|
||||||
sky.sun_color.r = 1.0;
|
|
||||||
sky.sun_color.g = 0.95;
|
|
||||||
sky.sun_color.b = 0.9;
|
|
||||||
sky.sun_color.a = 1.0;
|
|
||||||
sky.sun_radius = 0.02;
|
|
||||||
sky.sun_halo_size = 0.3;
|
|
||||||
sky.dome_lighting = 0.6;
|
|
||||||
curveClear(sky.sun_halo_profile);
|
|
||||||
curveQuickAddPoint(sky.sun_halo_profile, 0.0, 1.0);
|
|
||||||
curveQuickAddPoint(sky.sun_halo_profile, 0.1, 0.2);
|
|
||||||
curveQuickAddPoint(sky.sun_halo_profile, 1.0, 0.0);
|
|
||||||
sky.model_custom.auto_from_daytime = 1;
|
|
||||||
sky.model_custom.zenith_color.r = 0.52;
|
|
||||||
sky.model_custom.zenith_color.g = 0.63;
|
|
||||||
sky.model_custom.zenith_color.b = 0.8;
|
|
||||||
sky.model_custom.zenith_color.a = 1.0;
|
|
||||||
sky.model_custom.haze_color.r = 0.92;
|
|
||||||
sky.model_custom.haze_color.g = 0.93;
|
|
||||||
sky.model_custom.haze_color.b = 1.0;
|
|
||||||
sky.model_custom.haze_color.a = 1.0;
|
|
||||||
sky.model_custom.haze_height = 0.75;
|
|
||||||
sky.model_custom.haze_smoothing = 0.3;
|
|
||||||
sky.model_preetham.turbidity = 2.0;
|
|
||||||
scenerySetSky(&sky);
|
|
||||||
skyDeleteDefinition(&sky);
|
|
||||||
|
|
||||||
/* Terrain */
|
/* Terrain */
|
||||||
terrain = terrainCreateDefinition();
|
terrain = terrainCreateDefinition();
|
||||||
noiseClearLevels(terrain.height_noise);
|
noiseClearLevels(terrain.height_noise);
|
||||||
|
@ -180,11 +132,11 @@ void autoGenRealisticLandscape(int seed)
|
||||||
texturesDeleteDefinition(&textures);
|
texturesDeleteDefinition(&textures);
|
||||||
|
|
||||||
/* Atmosphere */
|
/* Atmosphere */
|
||||||
atmosphere = atmosphereCreateDefinition();
|
/*atmosphere = atmosphereCreateDefinition();
|
||||||
atmosphere.distance_near = 20.0;
|
atmosphere.distance_near = 20.0;
|
||||||
atmosphere.distance_far = 100.0;
|
atmosphere.distance_far = 100.0;
|
||||||
atmosphere.full_mask = 0.6;
|
atmosphere.full_mask = 0.6;
|
||||||
atmosphere.auto_lock_on_haze = 1;
|
atmosphere.auto_lock_on_haze = 1;
|
||||||
scenerySetAtmosphere(&atmosphere);
|
scenerySetAtmosphere(&atmosphere);
|
||||||
atmosphereDeleteDefinition(&atmosphere);
|
atmosphereDeleteDefinition(&atmosphere);*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -579,7 +579,7 @@ Color cloudsApplyLayer(CloudsLayerDefinition* definition, Color base, Renderer*
|
||||||
{
|
{
|
||||||
col = _applyLayerLighting(definition, renderer, segments[i].start, detail);
|
col = _applyLayerLighting(definition, renderer, segments[i].start, detail);
|
||||||
col.a = 1.0;
|
col.a = 1.0;
|
||||||
col = renderer->applyAtmosphere(renderer, start, col);
|
col = renderer->atmosphere->applyAerialPerspective(renderer, start, col);
|
||||||
col.a = (segments[i].length >= definition->transparencydepth) ? 1.0 : (segments[i].length / definition->transparencydepth);
|
col.a = (segments[i].length >= definition->transparencydepth) ? 1.0 : (segments[i].length / definition->transparencydepth);
|
||||||
colorMask(&base, &col);
|
colorMask(&base, &col);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "euclid.h"
|
#include "euclid.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "scenery.h"
|
#include "scenery.h"
|
||||||
#include "sky.h"
|
|
||||||
#include "terrain.h"
|
#include "terrain.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "water.h"
|
#include "water.h"
|
||||||
|
@ -224,7 +223,7 @@ void lightingGetStatus(LightingDefinition* definition, Renderer* renderer, Vecto
|
||||||
|
|
||||||
/* Apply skydome lights */
|
/* Apply skydome lights */
|
||||||
/* TODO Cache skydome lights for same render */
|
/* TODO Cache skydome lights for same render */
|
||||||
skydome_lights_count = renderer->getSkyDomeLights(renderer, skydome_lights, LIGHTING_MAX_LIGHTS);
|
skydome_lights_count = renderer->atmosphere->getSkydomeLights(renderer, skydome_lights, LIGHTING_MAX_LIGHTS);
|
||||||
for (i = 0; i < skydome_lights_count; i++)
|
for (i = 0; i < skydome_lights_count; i++)
|
||||||
{
|
{
|
||||||
if (_getLightStatus(skydome_lights + i, renderer, location, result->lights + result->nblights))
|
if (_getLightStatus(skydome_lights + i, renderer, location, result->lights + result->nblights))
|
||||||
|
|
|
@ -54,11 +54,6 @@ static void _pushQuad(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Ve
|
||||||
renderer->pushTriangle(renderer, v4, v1, v3, callback, callback_data);
|
renderer->pushTriangle(renderer, v4, v1, v3, callback, callback_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _getSkyDomeLights(Renderer* renderer, LightDefinition* array, int max_lights)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
|
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -93,11 +88,6 @@ static Color _applyTextures(Renderer* renderer, Vector3 location, double precisi
|
||||||
return COLOR_TRANSPARENT;
|
return COLOR_TRANSPARENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Color _applyAtmosphere(Renderer* renderer, Vector3 location, Color base)
|
|
||||||
{
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Color _applyClouds(Renderer* renderer, Color base, Vector3 start, Vector3 end)
|
static Color _applyClouds(Renderer* renderer, Color base, Vector3 start, Vector3 end)
|
||||||
{
|
{
|
||||||
return base;
|
return base;
|
||||||
|
@ -131,19 +121,20 @@ Renderer rendererCreate()
|
||||||
result.getTerrainHeight = _getTerrainHeight;
|
result.getTerrainHeight = _getTerrainHeight;
|
||||||
result.getWaterHeightInfo = _getWaterHeightInfo;
|
result.getWaterHeightInfo = _getWaterHeightInfo;
|
||||||
result.applyTextures = _applyTextures;
|
result.applyTextures = _applyTextures;
|
||||||
result.applyAtmosphere = _applyAtmosphere;
|
|
||||||
result.applyClouds = _applyClouds;
|
result.applyClouds = _applyClouds;
|
||||||
|
|
||||||
result.getSkyDomeLights = _getSkyDomeLights;
|
|
||||||
result.alterLight = _alterLight;
|
result.alterLight = _alterLight;
|
||||||
result.getLightStatus = _getLightStatus;
|
result.getLightStatus = _getLightStatus;
|
||||||
result.applyLightStatus = _applyLightStatus;
|
result.applyLightStatus = _applyLightStatus;
|
||||||
|
|
||||||
|
result.atmosphere = AtmosphereRendererClass.create();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rendererDelete(Renderer* renderer)
|
void rendererDelete(Renderer* renderer)
|
||||||
{
|
{
|
||||||
|
AtmosphereRendererClass.destroy(renderer->atmosphere);
|
||||||
renderDeleteArea(renderer->render_area);
|
renderDeleteArea(renderer->render_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,12 @@
|
||||||
#define _PAYSAGES_RENDERER_H_
|
#define _PAYSAGES_RENDERER_H_
|
||||||
|
|
||||||
#include "shared/types.h"
|
#include "shared/types.h"
|
||||||
|
#include "atmosphere/atmosphere.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct Renderer Renderer;
|
|
||||||
|
|
||||||
struct Renderer
|
struct Renderer
|
||||||
{
|
{
|
||||||
/* Render base configuration */
|
/* Render base configuration */
|
||||||
|
@ -35,15 +34,16 @@ struct Renderer
|
||||||
double (*getTerrainHeight)(Renderer* renderer, double x, double z);
|
double (*getTerrainHeight)(Renderer* renderer, double x, double z);
|
||||||
HeightInfo (*getWaterHeightInfo)(Renderer* renderer);
|
HeightInfo (*getWaterHeightInfo)(Renderer* renderer);
|
||||||
Color (*applyTextures)(Renderer* renderer, Vector3 location, double precision);
|
Color (*applyTextures)(Renderer* renderer, Vector3 location, double precision);
|
||||||
Color (*applyAtmosphere)(Renderer* renderer, Vector3 location, Color base);
|
|
||||||
Color (*applyClouds)(Renderer* renderer, Color base, Vector3 start, Vector3 end);
|
Color (*applyClouds)(Renderer* renderer, Color base, Vector3 start, Vector3 end);
|
||||||
|
|
||||||
/* Lighting related */
|
/* Lighting related */
|
||||||
int (*getSkyDomeLights)(Renderer* renderer, LightDefinition* array, int max_lights);
|
|
||||||
void (*alterLight)(Renderer* renderer, LightDefinition* light, Vector3 location);
|
void (*alterLight)(Renderer* renderer, LightDefinition* light, Vector3 location);
|
||||||
void (*getLightStatus)(Renderer* renderer, LightStatus* status, Vector3 location);
|
void (*getLightStatus)(Renderer* renderer, LightStatus* status, Vector3 location);
|
||||||
Color (*applyLightStatus)(Renderer* renderer, LightStatus* status, Vector3 location, Vector3 normal, SurfaceMaterial material);
|
Color (*applyLightStatus)(Renderer* renderer, LightStatus* status, Vector3 location, Vector3 normal, SurfaceMaterial material);
|
||||||
|
|
||||||
|
/* Autonomous sub-renderers */
|
||||||
|
AtmosphereRenderer* atmosphere;
|
||||||
|
|
||||||
/* Custom data */
|
/* Custom data */
|
||||||
void* customData[10];
|
void* customData[10];
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,11 +6,10 @@
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
static AtmosphereDefinition _atmosphere;
|
static AtmosphereDefinition* _atmosphere;
|
||||||
static CameraDefinition _camera;
|
static CameraDefinition _camera;
|
||||||
static CloudsDefinition _clouds;
|
static CloudsDefinition _clouds;
|
||||||
static LightingDefinition _lighting;
|
static LightingDefinition _lighting;
|
||||||
static SkyDefinition _sky;
|
|
||||||
static TerrainDefinition _terrain;
|
static TerrainDefinition _terrain;
|
||||||
static TexturesDefinition _textures;
|
static TexturesDefinition _textures;
|
||||||
static WaterDefinition _water;
|
static WaterDefinition _water;
|
||||||
|
@ -24,11 +23,10 @@ void sceneryInit()
|
||||||
noiseInit();
|
noiseInit();
|
||||||
lightingInit();
|
lightingInit();
|
||||||
|
|
||||||
_atmosphere = atmosphereCreateDefinition();
|
_atmosphere = AtmosphereDefinitionClass.create();
|
||||||
_camera = cameraCreateDefinition();
|
_camera = cameraCreateDefinition();
|
||||||
_clouds = cloudsCreateDefinition();
|
_clouds = cloudsCreateDefinition();
|
||||||
_lighting = lightingCreateDefinition();
|
_lighting = lightingCreateDefinition();
|
||||||
_sky = skyCreateDefinition();
|
|
||||||
_terrain = terrainCreateDefinition();
|
_terrain = terrainCreateDefinition();
|
||||||
_textures = texturesCreateDefinition();
|
_textures = texturesCreateDefinition();
|
||||||
_water = waterCreateDefinition();
|
_water = waterCreateDefinition();
|
||||||
|
@ -39,11 +37,10 @@ void sceneryInit()
|
||||||
|
|
||||||
void sceneryQuit()
|
void sceneryQuit()
|
||||||
{
|
{
|
||||||
atmosphereDeleteDefinition(&_atmosphere);
|
AtmosphereDefinitionClass.destroy(_atmosphere);
|
||||||
cameraDeleteDefinition(&_camera);
|
cameraDeleteDefinition(&_camera);
|
||||||
cloudsDeleteDefinition(&_clouds);
|
cloudsDeleteDefinition(&_clouds);
|
||||||
lightingDeleteDefinition(&_lighting);
|
lightingDeleteDefinition(&_lighting);
|
||||||
skyDeleteDefinition(&_sky);
|
|
||||||
terrainDeleteDefinition(&_terrain);
|
terrainDeleteDefinition(&_terrain);
|
||||||
texturesDeleteDefinition(&_textures);
|
texturesDeleteDefinition(&_textures);
|
||||||
waterDeleteDefinition(&_water);
|
waterDeleteDefinition(&_water);
|
||||||
|
@ -62,11 +59,10 @@ void scenerySetCustomDataCallback(SceneryCustomDataCallback callback_save, Scene
|
||||||
void scenerySave(PackStream* stream)
|
void scenerySave(PackStream* stream)
|
||||||
{
|
{
|
||||||
noiseSave(stream);
|
noiseSave(stream);
|
||||||
atmosphereSave(stream, &_atmosphere);
|
AtmosphereDefinitionClass.save(stream, _atmosphere);
|
||||||
cameraSave(stream, &_camera);
|
cameraSave(stream, &_camera);
|
||||||
cloudsSave(stream, &_clouds);
|
cloudsSave(stream, &_clouds);
|
||||||
lightingSave(stream, &_lighting);
|
lightingSave(stream, &_lighting);
|
||||||
skySave(stream, &_sky);
|
|
||||||
terrainSave(stream, &_terrain);
|
terrainSave(stream, &_terrain);
|
||||||
texturesSave(stream, &_textures);
|
texturesSave(stream, &_textures);
|
||||||
waterSave(stream, &_water);
|
waterSave(stream, &_water);
|
||||||
|
@ -82,20 +78,17 @@ void sceneryLoad(PackStream* stream)
|
||||||
/* TODO Use intermediary definitions ? */
|
/* TODO Use intermediary definitions ? */
|
||||||
|
|
||||||
noiseLoad(stream);
|
noiseLoad(stream);
|
||||||
atmosphereLoad(stream, &_atmosphere);
|
AtmosphereDefinitionClass.load(stream, _atmosphere);
|
||||||
cameraLoad(stream, &_camera);
|
cameraLoad(stream, &_camera);
|
||||||
cloudsLoad(stream, &_clouds);
|
cloudsLoad(stream, &_clouds);
|
||||||
lightingLoad(stream, &_lighting);
|
lightingLoad(stream, &_lighting);
|
||||||
skyLoad(stream, &_sky);
|
|
||||||
terrainLoad(stream, &_terrain);
|
terrainLoad(stream, &_terrain);
|
||||||
texturesLoad(stream, &_textures);
|
texturesLoad(stream, &_textures);
|
||||||
waterLoad(stream, &_water);
|
waterLoad(stream, &_water);
|
||||||
|
|
||||||
atmosphereValidateDefinition(&_atmosphere);
|
|
||||||
cameraValidateDefinition(&_camera, 0);
|
cameraValidateDefinition(&_camera, 0);
|
||||||
cloudsValidateDefinition(&_clouds);
|
cloudsValidateDefinition(&_clouds);
|
||||||
lightingValidateDefinition(&_lighting);
|
lightingValidateDefinition(&_lighting);
|
||||||
skyValidateDefinition(&_sky);
|
|
||||||
terrainValidateDefinition(&_terrain);
|
terrainValidateDefinition(&_terrain);
|
||||||
texturesValidateDefinition(&_textures);
|
texturesValidateDefinition(&_textures);
|
||||||
waterValidateDefinition(&_water);
|
waterValidateDefinition(&_water);
|
||||||
|
@ -108,13 +101,13 @@ void sceneryLoad(PackStream* stream)
|
||||||
|
|
||||||
void scenerySetAtmosphere(AtmosphereDefinition* atmosphere)
|
void scenerySetAtmosphere(AtmosphereDefinition* atmosphere)
|
||||||
{
|
{
|
||||||
atmosphereCopyDefinition(atmosphere, &_atmosphere);
|
AtmosphereDefinitionClass.copy(atmosphere, _atmosphere);
|
||||||
atmosphereValidateDefinition(&_atmosphere);
|
AtmosphereDefinitionClass.validate(_atmosphere);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sceneryGetAtmosphere(AtmosphereDefinition* atmosphere)
|
void sceneryGetAtmosphere(AtmosphereDefinition* atmosphere)
|
||||||
{
|
{
|
||||||
atmosphereCopyDefinition(&_atmosphere, atmosphere);
|
AtmosphereDefinitionClass.copy(_atmosphere, atmosphere);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scenerySetCamera(CameraDefinition* camera)
|
void scenerySetCamera(CameraDefinition* camera)
|
||||||
|
@ -150,20 +143,6 @@ void sceneryGetLighting(LightingDefinition* lighting)
|
||||||
lightingCopyDefinition(&_lighting, lighting);
|
lightingCopyDefinition(&_lighting, lighting);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scenerySetSky(SkyDefinition* sky)
|
|
||||||
{
|
|
||||||
skyCopyDefinition(sky, &_sky);
|
|
||||||
skyValidateDefinition(&_sky);
|
|
||||||
|
|
||||||
atmosphereValidateDefinition(&_atmosphere);
|
|
||||||
lightingValidateDefinition(&_lighting);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sceneryGetSky(SkyDefinition* sky)
|
|
||||||
{
|
|
||||||
skyCopyDefinition(&_sky, sky);
|
|
||||||
}
|
|
||||||
|
|
||||||
void scenerySetTerrain(TerrainDefinition* terrain)
|
void scenerySetTerrain(TerrainDefinition* terrain)
|
||||||
{
|
{
|
||||||
terrainCopyDefinition(terrain, &_terrain);
|
terrainCopyDefinition(terrain, &_terrain);
|
||||||
|
@ -205,7 +184,7 @@ void sceneryRenderFirstPass(Renderer* renderer)
|
||||||
{
|
{
|
||||||
terrainRender(&_terrain, renderer);
|
terrainRender(&_terrain, renderer);
|
||||||
waterRender(&_water, renderer);
|
waterRender(&_water, renderer);
|
||||||
skyRender(&_sky, renderer);
|
atmosphereRenderSkydome(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -214,11 +193,6 @@ void sceneryRenderFirstPass(Renderer* renderer)
|
||||||
|
|
||||||
|
|
||||||
/******* Standard renderer *********/
|
/******* Standard renderer *********/
|
||||||
static int _getSkyDomeLights(Renderer* renderer, LightDefinition* array, int max_lights)
|
|
||||||
{
|
|
||||||
return skyGetLights(&_sky, renderer, array, max_lights);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
|
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
|
||||||
{
|
{
|
||||||
Vector3 light_location;
|
Vector3 light_location;
|
||||||
|
@ -256,7 +230,7 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector
|
||||||
|
|
||||||
if (!terrainProjectRay(&_terrain, renderer, location, direction, &result.hit_location, &result.hit_color))
|
if (!terrainProjectRay(&_terrain, renderer, location, direction, &result.hit_location, &result.hit_color))
|
||||||
{
|
{
|
||||||
sky_color = skyGetColor(&_sky, renderer, location, direction);
|
sky_color = renderer->atmosphere->getSkyColor(renderer, direction);
|
||||||
result.hit_location = v3Add(location, v3Scale(direction, 1000.0));
|
result.hit_location = v3Add(location, v3Scale(direction, 1000.0));
|
||||||
result.hit_color = renderer->applyClouds(renderer, sky_color, location, result.hit_location);
|
result.hit_color = renderer->applyClouds(renderer, sky_color, location, result.hit_location);
|
||||||
}
|
}
|
||||||
|
@ -280,11 +254,6 @@ static Color _applyTextures(Renderer* renderer, Vector3 location, double precisi
|
||||||
return texturesGetColor(&_textures, renderer, location.x, location.z, precision);
|
return texturesGetColor(&_textures, renderer, location.x, location.z, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Color _applyAtmosphere(Renderer* renderer, Vector3 location, Color base)
|
|
||||||
{
|
|
||||||
return atmosphereApply(&_atmosphere, renderer, location, base);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Color _applyClouds(Renderer* renderer, Color base, Vector3 start, Vector3 end)
|
static Color _applyClouds(Renderer* renderer, Color base, Vector3 start, Vector3 end)
|
||||||
{
|
{
|
||||||
return cloudsApply(&_clouds, base, renderer, start, end);
|
return cloudsApply(&_clouds, base, renderer, start, end);
|
||||||
|
@ -320,7 +289,6 @@ Renderer sceneryCreateStandardRenderer()
|
||||||
cameraCopyDefinition(&_camera, &result.render_camera);
|
cameraCopyDefinition(&_camera, &result.render_camera);
|
||||||
result.camera_location = _camera.location;
|
result.camera_location = _camera.location;
|
||||||
|
|
||||||
result.getSkyDomeLights = _getSkyDomeLights;
|
|
||||||
result.alterLight = _alterLight;
|
result.alterLight = _alterLight;
|
||||||
result.getLightStatus = _getLightStatus;
|
result.getLightStatus = _getLightStatus;
|
||||||
result.applyLightStatus = _applyLightStatus;
|
result.applyLightStatus = _applyLightStatus;
|
||||||
|
@ -328,12 +296,13 @@ Renderer sceneryCreateStandardRenderer()
|
||||||
result.getTerrainHeight = _getTerrainHeight;
|
result.getTerrainHeight = _getTerrainHeight;
|
||||||
result.getWaterHeightInfo = _getWaterHeightInfo;
|
result.getWaterHeightInfo = _getWaterHeightInfo;
|
||||||
result.applyTextures = _applyTextures;
|
result.applyTextures = _applyTextures;
|
||||||
result.applyAtmosphere = _applyAtmosphere;
|
|
||||||
result.applyClouds = _applyClouds;
|
result.applyClouds = _applyClouds;
|
||||||
result.projectPoint = _projectPoint;
|
result.projectPoint = _projectPoint;
|
||||||
result.unprojectPoint = _unprojectPoint;
|
result.unprojectPoint = _unprojectPoint;
|
||||||
result.getPrecision = _getPrecision;
|
result.getPrecision = _getPrecision;
|
||||||
|
|
||||||
|
AtmosphereRendererClass.bind(result.atmosphere, _atmosphere);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,10 @@
|
||||||
* a standard renderer.
|
* a standard renderer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "atmosphere.h"
|
#include "atmosphere/atmosphere.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "clouds.h"
|
#include "clouds.h"
|
||||||
#include "lighting.h"
|
#include "lighting.h"
|
||||||
#include "sky.h"
|
|
||||||
#include "terrain.h"
|
#include "terrain.h"
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
#include "water.h"
|
#include "water.h"
|
||||||
|
@ -45,9 +44,6 @@ void sceneryGetClouds(CloudsDefinition* clouds);
|
||||||
void scenerySetLighting(LightingDefinition* lighting);
|
void scenerySetLighting(LightingDefinition* lighting);
|
||||||
void sceneryGetLighting(LightingDefinition* lighting);
|
void sceneryGetLighting(LightingDefinition* lighting);
|
||||||
|
|
||||||
void scenerySetSky(SkyDefinition* sky);
|
|
||||||
void sceneryGetSky(SkyDefinition* sky);
|
|
||||||
|
|
||||||
void scenerySetTerrain(TerrainDefinition* terrain);
|
void scenerySetTerrain(TerrainDefinition* terrain);
|
||||||
void sceneryGetTerrain(TerrainDefinition* terrain);
|
void sceneryGetTerrain(TerrainDefinition* terrain);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Renderer;
|
typedef struct Renderer Renderer;
|
||||||
|
|
||||||
typedef struct LightDefinition LightDefinition;
|
typedef struct LightDefinition LightDefinition;
|
||||||
typedef struct LightStatus LightStatus;
|
typedef struct LightStatus LightStatus;
|
||||||
|
|
|
@ -1,374 +0,0 @@
|
||||||
#include "sky.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "shared/types.h"
|
|
||||||
#include "color.h"
|
|
||||||
#include "clouds.h"
|
|
||||||
#include "euclid.h"
|
|
||||||
#include "lighting.h"
|
|
||||||
#include "render.h"
|
|
||||||
#include "tools.h"
|
|
||||||
#include "skypreetham.h"
|
|
||||||
#include "skyrayleigh.h"
|
|
||||||
|
|
||||||
#define SPHERE_SIZE 1000.0
|
|
||||||
|
|
||||||
/******************************** Configuration ********************************/
|
|
||||||
void skySave(PackStream* stream, SkyDefinition* definition)
|
|
||||||
{
|
|
||||||
packWriteInt(stream, (int*)&definition->model);
|
|
||||||
packWriteDouble(stream, &definition->daytime);
|
|
||||||
colorSave(stream, &definition->sun_color);
|
|
||||||
packWriteDouble(stream, &definition->sun_radius);
|
|
||||||
packWriteDouble(stream, &definition->sun_halo_size);
|
|
||||||
curveSave(stream, definition->sun_halo_profile);
|
|
||||||
packWriteDouble(stream, &definition->dome_lighting);
|
|
||||||
|
|
||||||
packWriteInt(stream, &definition->model_custom.auto_from_daytime);
|
|
||||||
colorSave(stream, &definition->model_custom.zenith_color);
|
|
||||||
colorSave(stream, &definition->model_custom.haze_color);
|
|
||||||
packWriteDouble(stream, &definition->model_custom.haze_height);
|
|
||||||
packWriteDouble(stream, &definition->model_custom.haze_smoothing);
|
|
||||||
|
|
||||||
packWriteDouble(stream, &definition->model_preetham.turbidity);
|
|
||||||
}
|
|
||||||
|
|
||||||
void skyLoad(PackStream* stream, SkyDefinition* definition)
|
|
||||||
{
|
|
||||||
packReadInt(stream, (int*)&definition->model);
|
|
||||||
packReadDouble(stream, &definition->daytime);
|
|
||||||
colorLoad(stream, &definition->sun_color);
|
|
||||||
packReadDouble(stream, &definition->sun_radius);
|
|
||||||
packReadDouble(stream, &definition->sun_halo_size);
|
|
||||||
curveLoad(stream, definition->sun_halo_profile);
|
|
||||||
packReadDouble(stream, &definition->dome_lighting);
|
|
||||||
|
|
||||||
packReadInt(stream, &definition->model_custom.auto_from_daytime);
|
|
||||||
colorLoad(stream, &definition->model_custom.zenith_color);
|
|
||||||
colorLoad(stream, &definition->model_custom.haze_color);
|
|
||||||
packReadDouble(stream, &definition->model_custom.haze_height);
|
|
||||||
packReadDouble(stream, &definition->model_custom.haze_smoothing);
|
|
||||||
|
|
||||||
packReadDouble(stream, &definition->model_preetham.turbidity);
|
|
||||||
|
|
||||||
skyValidateDefinition(definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
SkyDefinition skyCreateDefinition()
|
|
||||||
{
|
|
||||||
SkyDefinition def;
|
|
||||||
|
|
||||||
def.model = SKY_MODEL_CUSTOM;
|
|
||||||
def.daytime = 0.0;
|
|
||||||
def.sun_color = COLOR_BLACK;
|
|
||||||
def.sun_radius = 1.0;
|
|
||||||
def.sun_halo_size = 0.0;
|
|
||||||
def.sun_halo_profile = curveCreate();
|
|
||||||
def.dome_lighting = 0.0;
|
|
||||||
def.model_custom.auto_from_daytime = 0;
|
|
||||||
def.model_custom.zenith_color = COLOR_BLACK;
|
|
||||||
def.model_custom.haze_color = COLOR_BLACK;
|
|
||||||
def.model_custom.haze_height = 0.0;
|
|
||||||
def.model_custom.haze_smoothing = 0.0;
|
|
||||||
def.model_custom._sky_gradation = colorGradationCreate();
|
|
||||||
def.model_preetham.turbidity = 0.0;
|
|
||||||
|
|
||||||
skyValidateDefinition(&def);
|
|
||||||
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
|
|
||||||
void skyDeleteDefinition(SkyDefinition* definition)
|
|
||||||
{
|
|
||||||
curveDelete(definition->sun_halo_profile);
|
|
||||||
colorGradationDelete(definition->model_custom._sky_gradation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void skyCopyDefinition(SkyDefinition* source, SkyDefinition* destination)
|
|
||||||
{
|
|
||||||
destination->model = source->model;
|
|
||||||
destination->daytime = source->daytime;
|
|
||||||
destination->sun_color = source->sun_color;
|
|
||||||
destination->sun_radius = source->sun_radius;
|
|
||||||
destination->sun_halo_size = source->sun_halo_size;
|
|
||||||
destination->dome_lighting = source->dome_lighting;
|
|
||||||
destination->model_custom.auto_from_daytime = source->model_custom.auto_from_daytime;
|
|
||||||
destination->model_custom.zenith_color = source->model_custom.zenith_color;
|
|
||||||
destination->model_custom.haze_color = source->model_custom.haze_color;
|
|
||||||
destination->model_custom.haze_height = source->model_custom.haze_height;
|
|
||||||
destination->model_custom.haze_smoothing = source->model_custom.haze_smoothing;
|
|
||||||
destination->model_preetham.turbidity = source->model_preetham.turbidity;
|
|
||||||
|
|
||||||
curveCopy(source->sun_halo_profile, destination->sun_halo_profile);
|
|
||||||
|
|
||||||
skyValidateDefinition(destination);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _setAutoCustomModel(SkyDefinition* definition)
|
|
||||||
{
|
|
||||||
ColorGradation* zenith_gradation;
|
|
||||||
ColorGradation* haze_gradation;
|
|
||||||
|
|
||||||
zenith_gradation = colorGradationCreate();
|
|
||||||
haze_gradation = colorGradationCreate();
|
|
||||||
|
|
||||||
colorGradationQuickAddRgb(zenith_gradation, 0.2, 0.03, 0.03, 0.05);
|
|
||||||
colorGradationQuickAddRgb(zenith_gradation, 0.25, 0.25, 0.33, 0.37);
|
|
||||||
colorGradationQuickAddRgb(zenith_gradation, 0.35, 0.52, 0.63, 0.8);
|
|
||||||
colorGradationQuickAddRgb(zenith_gradation, 0.65, 0.52, 0.63, 0.8);
|
|
||||||
colorGradationQuickAddRgb(zenith_gradation, 0.75, 0.25, 0.33, 0.37);
|
|
||||||
colorGradationQuickAddRgb(zenith_gradation, 0.8, 0.03, 0.03, 0.05);
|
|
||||||
colorGradationQuickAddRgb(haze_gradation, 0.2, 0.05, 0.05, 0.08);
|
|
||||||
colorGradationQuickAddRgb(haze_gradation, 0.25, 0.55, 0.42, 0.42);
|
|
||||||
colorGradationQuickAddRgb(haze_gradation, 0.3, 0.6, 0.6, 0.6);
|
|
||||||
colorGradationQuickAddRgb(haze_gradation, 0.4, 0.92, 0.93, 1.0);
|
|
||||||
colorGradationQuickAddRgb(haze_gradation, 0.6, 0.92, 0.93, 1.0);
|
|
||||||
colorGradationQuickAddRgb(haze_gradation, 0.7, 0.6, 0.6, 0.8);
|
|
||||||
colorGradationQuickAddRgb(haze_gradation, 0.75, 0.62, 0.50, 0.42);
|
|
||||||
colorGradationQuickAddRgb(haze_gradation, 0.8, 0.05, 0.05, 0.08);
|
|
||||||
|
|
||||||
definition->model_custom.zenith_color = colorGradationGet(zenith_gradation, definition->daytime);
|
|
||||||
definition->model_custom.haze_color = colorGradationGet(haze_gradation, definition->daytime);
|
|
||||||
|
|
||||||
colorGradationDelete(zenith_gradation);
|
|
||||||
colorGradationDelete(haze_gradation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void skyValidateDefinition(SkyDefinition* definition)
|
|
||||||
{
|
|
||||||
if (definition->model == SKY_MODEL_CUSTOM)
|
|
||||||
{
|
|
||||||
if (definition->model_custom.auto_from_daytime)
|
|
||||||
{
|
|
||||||
_setAutoCustomModel(definition);
|
|
||||||
}
|
|
||||||
colorGradationClear(definition->model_custom._sky_gradation);
|
|
||||||
colorGradationQuickAdd(definition->model_custom._sky_gradation, 0.0, &definition->model_custom.haze_color);
|
|
||||||
colorGradationQuickAdd(definition->model_custom._sky_gradation, definition->model_custom.haze_height - definition->model_custom.haze_smoothing, &definition->model_custom.haze_color);
|
|
||||||
colorGradationQuickAdd(definition->model_custom._sky_gradation, definition->model_custom.haze_height, &definition->model_custom.zenith_color);
|
|
||||||
colorGradationQuickAdd(definition->model_custom._sky_gradation, 1.0, &definition->model_custom.zenith_color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void _addDomeLight(SkyDefinition* sky, Renderer* renderer, LightDefinition* light, Vector3 direction, double factor)
|
|
||||||
{
|
|
||||||
light->direction = v3Scale(direction, -1.0);
|
|
||||||
light->color = skyGetColor(sky, renderer, VECTOR_ZERO, direction);
|
|
||||||
light->color.r *= factor;
|
|
||||||
light->color.g *= factor;
|
|
||||||
light->color.b *= factor;
|
|
||||||
light->reflection = 0.0;
|
|
||||||
light->filtered = 0;
|
|
||||||
light->masked = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int skyGetLights(SkyDefinition* sky, Renderer* renderer, LightDefinition* lights, int max_lights)
|
|
||||||
{
|
|
||||||
double sun_angle;
|
|
||||||
Vector3 sun_direction;
|
|
||||||
int nblights = 0;
|
|
||||||
|
|
||||||
sun_angle = (sky->daytime + 0.75) * M_PI * 2.0;
|
|
||||||
sun_direction.x = cos(sun_angle);
|
|
||||||
sun_direction.y = sin(sun_angle);
|
|
||||||
sun_direction.z = 0.0;
|
|
||||||
|
|
||||||
/* TODO Moon light */
|
|
||||||
|
|
||||||
if (max_lights > 0)
|
|
||||||
{
|
|
||||||
/* Direct light from the sun */
|
|
||||||
lights[0].direction = v3Scale(sun_direction, -1.0);
|
|
||||||
lights[0].color = sky->sun_color;
|
|
||||||
lights[0].reflection = 1.0;
|
|
||||||
lights[0].filtered = 1;
|
|
||||||
lights[0].masked = 1;
|
|
||||||
nblights = 1;
|
|
||||||
max_lights--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max_lights > 0)
|
|
||||||
{
|
|
||||||
/* Indirect lighting by skydome scattering */
|
|
||||||
int xsamples, ysamples, samples, x, y;
|
|
||||||
double xstep, ystep, factor;
|
|
||||||
Vector3 direction;
|
|
||||||
|
|
||||||
samples = (renderer->render_quality < 5) ? 9 : (renderer->render_quality * 4 + 1);
|
|
||||||
samples = samples > max_lights ? max_lights : samples;
|
|
||||||
|
|
||||||
factor = sky->dome_lighting / (double)samples;
|
|
||||||
|
|
||||||
_addDomeLight(sky, renderer, lights + nblights, VECTOR_UP, factor);
|
|
||||||
nblights++;
|
|
||||||
samples--;
|
|
||||||
|
|
||||||
if (samples >= 2)
|
|
||||||
{
|
|
||||||
xsamples = samples / 2;
|
|
||||||
ysamples = samples / xsamples;
|
|
||||||
|
|
||||||
xstep = M_PI * 2.0 / (double)xsamples;
|
|
||||||
ystep = M_PI * 0.5 / (double)ysamples;
|
|
||||||
|
|
||||||
for (x = 0; x < xsamples; x++)
|
|
||||||
{
|
|
||||||
for (y = 0; y < ysamples; y++)
|
|
||||||
{
|
|
||||||
direction.x = cos(x * xstep) * cos(y * ystep);
|
|
||||||
direction.y = -sin(y * ystep);
|
|
||||||
direction.z = sin(x * xstep) * cos(y * ystep);
|
|
||||||
|
|
||||||
_addDomeLight(sky, renderer, lights + nblights, direction, factor);
|
|
||||||
nblights++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nblights;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************** Rendering ********************************/
|
|
||||||
Color skyGetColor(SkyDefinition* definition, Renderer* renderer, Vector3 eye, Vector3 look)
|
|
||||||
{
|
|
||||||
double dist;
|
|
||||||
Vector3 sun_position;
|
|
||||||
Color sun_color, sky_color;
|
|
||||||
|
|
||||||
sun_position = skyGetSunDirection(definition);
|
|
||||||
|
|
||||||
look = v3Normalize(look);
|
|
||||||
dist = v3Norm(v3Sub(look, sun_position));
|
|
||||||
|
|
||||||
if (definition->model == SKY_MODEL_PREETHAM)
|
|
||||||
{
|
|
||||||
sky_color = skyPreethamGetColor(eye, look, sun_position, definition->model_preetham.turbidity);
|
|
||||||
}
|
|
||||||
else if (definition->model == SKY_MODEL_RAYLEIGH_MIE)
|
|
||||||
{
|
|
||||||
sky_color = skyRayleighGetColor(eye, look, sun_position);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sky_color = colorGradationGet(definition->model_custom._sky_gradation, look.y * 0.5 + 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dist < definition->sun_radius + definition->sun_halo_size)
|
|
||||||
{
|
|
||||||
sun_color = definition->sun_color;
|
|
||||||
if (dist <= definition->sun_radius)
|
|
||||||
{
|
|
||||||
return sun_color;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dist = (dist - definition->sun_radius) / definition->sun_halo_size;
|
|
||||||
sun_color.a = curveGetValue(definition->sun_halo_profile, dist);
|
|
||||||
colorMask(&sky_color, &sun_color);
|
|
||||||
return sky_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return sky_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Color _postProcessFragment(Renderer* renderer, Vector3 location, void* data)
|
|
||||||
{
|
|
||||||
Vector3 direction;
|
|
||||||
Color result;
|
|
||||||
SkyDefinition* definition;
|
|
||||||
|
|
||||||
definition = (SkyDefinition*)data;
|
|
||||||
|
|
||||||
direction = v3Sub(location, renderer->camera_location);
|
|
||||||
|
|
||||||
result = skyGetColor(definition, renderer, renderer->camera_location, v3Normalize(direction));
|
|
||||||
result = renderer->applyClouds(renderer, result, renderer->camera_location, v3Add(renderer->camera_location, v3Scale(direction, 10.0)));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void skyRender(SkyDefinition* definition, Renderer* renderer)
|
|
||||||
{
|
|
||||||
int res_i, res_j;
|
|
||||||
int i, j;
|
|
||||||
double step_i, step_j;
|
|
||||||
double current_i, current_j;
|
|
||||||
Vector3 vertex1, vertex2, vertex3, vertex4;
|
|
||||||
Vector3 direction;
|
|
||||||
|
|
||||||
res_i = renderer->render_quality * 40;
|
|
||||||
res_j = renderer->render_quality * 20;
|
|
||||||
step_i = M_PI * 2.0 / (double)res_i;
|
|
||||||
step_j = M_PI / (double)res_j;
|
|
||||||
|
|
||||||
for (j = 0; j < res_j; j++)
|
|
||||||
{
|
|
||||||
if (!renderer->addRenderProgress(renderer, 0.0))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_j = (double)(j - res_j / 2) * step_j;
|
|
||||||
|
|
||||||
for (i = 0; i < res_i; i++)
|
|
||||||
{
|
|
||||||
current_i = (double)i * step_i;
|
|
||||||
|
|
||||||
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j);
|
|
||||||
direction.y = SPHERE_SIZE * sin(current_j);
|
|
||||||
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j);
|
|
||||||
vertex1 = v3Add(renderer->camera_location, direction);
|
|
||||||
|
|
||||||
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j);
|
|
||||||
direction.y = SPHERE_SIZE * sin(current_j);
|
|
||||||
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j);
|
|
||||||
vertex2 = v3Add(renderer->camera_location, direction);
|
|
||||||
|
|
||||||
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j + step_j);
|
|
||||||
direction.y = SPHERE_SIZE * sin(current_j + step_j);
|
|
||||||
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j + step_j);
|
|
||||||
vertex3 = v3Add(renderer->camera_location, direction);
|
|
||||||
|
|
||||||
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j + step_j);
|
|
||||||
direction.y = SPHERE_SIZE * sin(current_j + step_j);
|
|
||||||
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j + step_j);
|
|
||||||
vertex4 = v3Add(renderer->camera_location, direction);
|
|
||||||
|
|
||||||
/* TODO Triangles at poles */
|
|
||||||
renderer->pushQuad(renderer, vertex1, vertex4, vertex3, vertex2, _postProcessFragment, definition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 skyGetSunDirection(SkyDefinition* definition)
|
|
||||||
{
|
|
||||||
Vector3 result;
|
|
||||||
double sun_angle = (definition->daytime + 0.75) * M_PI * 2.0;
|
|
||||||
result.x = cos(sun_angle);
|
|
||||||
result.y = sin(sun_angle);
|
|
||||||
result.z = 0.0;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color skyGetSunColor(SkyDefinition* definition)
|
|
||||||
{
|
|
||||||
return definition->sun_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color skyGetZenithColor(SkyDefinition* definition)
|
|
||||||
{
|
|
||||||
Vector3 look = {0.0, 1.0, 0.0};
|
|
||||||
return skyGetColor(definition, NULL, VECTOR_ZERO, look);
|
|
||||||
}
|
|
||||||
|
|
||||||
Color skyGetHorizonColor(SkyDefinition* definition)
|
|
||||||
{
|
|
||||||
Vector3 look = {0.0, 0.0, 1.0};
|
|
||||||
return skyGetColor(definition, NULL, VECTOR_ZERO, look);
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
#ifndef _PAYSAGES_SKY_H_
|
|
||||||
#define _PAYSAGES_SKY_H_
|
|
||||||
|
|
||||||
#include "shared/types.h"
|
|
||||||
#include "color.h"
|
|
||||||
#include "lighting.h"
|
|
||||||
#include "pack.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
SKY_MODEL_CUSTOM = 0,
|
|
||||||
SKY_MODEL_RAYLEIGH_MIE = 1,
|
|
||||||
SKY_MODEL_PREETHAM = 2
|
|
||||||
} SkyModel;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SkyModel model;
|
|
||||||
double daytime;
|
|
||||||
Color sun_color;
|
|
||||||
double sun_radius;
|
|
||||||
double sun_halo_size;
|
|
||||||
Curve* sun_halo_profile;
|
|
||||||
double dome_lighting;
|
|
||||||
struct {
|
|
||||||
int auto_from_daytime;
|
|
||||||
Color zenith_color;
|
|
||||||
Color haze_color;
|
|
||||||
double haze_height;
|
|
||||||
double haze_smoothing;
|
|
||||||
ColorGradation* _sky_gradation;
|
|
||||||
} model_custom;
|
|
||||||
struct {
|
|
||||||
double turbidity;
|
|
||||||
} model_preetham;
|
|
||||||
} SkyDefinition;
|
|
||||||
|
|
||||||
void skySave(PackStream* stream, SkyDefinition* definition);
|
|
||||||
void skyLoad(PackStream* stream, SkyDefinition* definition);
|
|
||||||
|
|
||||||
SkyDefinition skyCreateDefinition();
|
|
||||||
void skyDeleteDefinition(SkyDefinition* definition);
|
|
||||||
void skyCopyDefinition(SkyDefinition* source, SkyDefinition* destination);
|
|
||||||
void skyValidateDefinition(SkyDefinition* definition);
|
|
||||||
|
|
||||||
int skyGetLights(SkyDefinition* sky, Renderer* renderer, LightDefinition* lights, int max_lights);
|
|
||||||
Color skyGetColor(SkyDefinition* definition, Renderer* renderer, Vector3 eye, Vector3 look);
|
|
||||||
void skyRender(SkyDefinition* definition, Renderer* renderer);
|
|
||||||
Vector3 skyGetSunDirection(SkyDefinition* definition);
|
|
||||||
Color skyGetSunColor(SkyDefinition* definition);
|
|
||||||
Color skyGetZenithColor(SkyDefinition* definition);
|
|
||||||
Color skyGetHorizonColor(SkyDefinition* definition);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,20 +0,0 @@
|
||||||
#ifndef _PAYSAGES_PREETHAM_H_
|
|
||||||
#define _PAYSAGES_PREETHAM_H_
|
|
||||||
|
|
||||||
/* Implementation of Preetham/Shirley light scattering */
|
|
||||||
|
|
||||||
#include "color.h"
|
|
||||||
#include "euclid.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Color skyPreethamGetColor(Vector3 viewer, Vector3 direction, Vector3 sun_direction, double turbidity);
|
|
||||||
Color skyPreethamApplyToObject(Vector3 viewer, Vector3 object_location, Vector3 sun_direction, double turbidity, Color object_color);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,82 +0,0 @@
|
||||||
#include "skyrayleigh.h"
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static Vector3 _betaR = {5.5e-6, 13.0e-6, 22.4e-6}; /* Rayleigh scattering coefficients at sea level */
|
|
||||||
static Vector3 _betaM = {21e-6, 0.0, 0.0}; /* Mie scattering coefficients at sea level */
|
|
||||||
static double _Hr = 7994; /* Rayleigh scale height */
|
|
||||||
static double _Hm = 1200; /* Mie scale height */
|
|
||||||
static double _radiusEarth = 6360e3; /* Earth radius */
|
|
||||||
static double _radiusAtmosphere = 6420e3; /* Atmosphere radius */
|
|
||||||
static double _sunIntensity = 20.0; /* Sun intensity */
|
|
||||||
static double _g = 0.76; /* Mean cosine */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*typedef struct
|
|
||||||
{
|
|
||||||
double tmin;
|
|
||||||
double tmax;
|
|
||||||
} Ray;
|
|
||||||
|
|
||||||
static Vector3 _computeIncidentLight(Ray r)
|
|
||||||
{
|
|
||||||
double t0, t1;
|
|
||||||
int numSamples = 16;
|
|
||||||
int numSamplesLight = 8;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
if (!intersect<T>(r, radiusAtmosphere, t0, t1) || t1 < 0) return Vec3<T>(0);
|
|
||||||
if (t0 > r.tmin && t0 > 0) r.tmin = t0;
|
|
||||||
if (t1 < r.tmax) r.tmax = t1;
|
|
||||||
double segmentLength = (r.tmax - r.tmin) / (double)numSamples;
|
|
||||||
double tCurrent = r.tmin;
|
|
||||||
Vector3 sumR = VECTOR_ZERO;
|
|
||||||
Vector3 sumM = VECTOR_ZERO;
|
|
||||||
double opticalDepthR = 0.0;
|
|
||||||
double opticalDepthM = 0.0;
|
|
||||||
double mu = r.direction.dot(sunDirection);
|
|
||||||
double phaseR = 3.0 / (16.0 * M_PI) * (1.0 + mu * mu);
|
|
||||||
double phaseM = 3.0 / (8.0 * M_PI) * ((1.0 - _g * _g) * (1 + mu * mu)) / ((2 + _g * _g) * pow(1 + _g * _g - 2 * _g * mu, 1.5));
|
|
||||||
for (i = 0; i < numSamples; ++i)
|
|
||||||
{
|
|
||||||
Vector3 samplePosition = r(tCurrent + T(0.5) * segmentLength);
|
|
||||||
double height = samplePosition.magnitude() - radiusEarth;
|
|
||||||
double hr = exp(-height / _Hr) * segmentLength;
|
|
||||||
double hm = exp(-height / _Hm) * segmentLength;
|
|
||||||
opticalDepthR += hr;
|
|
||||||
opticalDepthM += hm;
|
|
||||||
Ray lightRay(samplePosition, sunDirection);
|
|
||||||
intersect(lightRay, radiusAtmosphere, lightRay.tmin, lightRay.tmax);
|
|
||||||
double segmentLengthLight = lightRay.tmax / numSamplesLight;
|
|
||||||
double tCurrentLight = 0.0;
|
|
||||||
double opticalDepthLightR = 0.0;
|
|
||||||
double opticalDepthLightM = 0.0;
|
|
||||||
for (j = 0; j < numSamplesLight; ++j) {
|
|
||||||
Vector3 samplePositionLight = lightRay(tCurrentLight + T(0.5) * segmentLengthLight);
|
|
||||||
T heightLight = samplePositionLight.magnitude() - radiusEarth;
|
|
||||||
if (heightLight < 0) break;
|
|
||||||
opticalDepthLightR += exp(-heightLight / Hr) * segmentLengthLight;
|
|
||||||
opticalDepthLightM += exp(-heightLight / Hm) * segmentLengthLight;
|
|
||||||
tCurrentLight += segmentLengthLight;
|
|
||||||
}
|
|
||||||
if (j == numSamplesLight) {
|
|
||||||
Vec3<T> tau = betaR * (opticalDepthR + opticalDepthLightR) + betaM * 1.1 * (opticalDepthM + opticalDepthLightM);
|
|
||||||
Vec3<T> attenuation(exp(-tau.x), exp(-tau.y), exp(-tau.z));
|
|
||||||
sumR += hr * attenuation;
|
|
||||||
sumM += hm * attenuation;
|
|
||||||
}
|
|
||||||
tCurrent += segmentLength;
|
|
||||||
}
|
|
||||||
return 20 * (sumR * phaseR * _betaR + sumM * phaseM * _betaM);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
Color skyRayleighGetColor(Vector3 viewer, Vector3 direction, Vector3 sun_direction)
|
|
||||||
{
|
|
||||||
return COLOR_BLACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color skyRayleighApplyToObject(Vector3 viewer, Vector3 object_location, Vector3 sun_direction, Color object_color)
|
|
||||||
{
|
|
||||||
return COLOR_BLACK;
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
#ifndef _PAYSAGES_RAYLEIGH_H_
|
|
||||||
#define _PAYSAGES_RAYLEIGH_H_
|
|
||||||
|
|
||||||
/* Implementation of Rayleigh/Mie atmospheric light scattering */
|
|
||||||
|
|
||||||
#include "color.h"
|
|
||||||
#include "euclid.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Color skyRayleighGetColor(Vector3 viewer, Vector3 direction, Vector3 sun_direction);
|
|
||||||
Color skyRayleighApplyToObject(Vector3 viewer, Vector3 object_location, Vector3 sun_direction, Color object_color);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -231,7 +231,7 @@ static Color _getColor(TerrainDefinition* definition, Renderer* renderer, Vector
|
||||||
Color color;
|
Color color;
|
||||||
|
|
||||||
color = renderer->applyTextures(renderer, point, precision);
|
color = renderer->applyTextures(renderer, point, precision);
|
||||||
color = renderer->applyAtmosphere(renderer, point, color);
|
color = renderer->atmosphere->applyAerialPerspective(renderer, point, color);
|
||||||
color = renderer->applyClouds(renderer, color, renderer->camera_location, point);
|
color = renderer->applyClouds(renderer, color, renderer->camera_location, point);
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
|
|
|
@ -357,7 +357,7 @@ WaterResult waterGetColorDetail(WaterDefinition* definition, Renderer* renderer,
|
||||||
|
|
||||||
renderer->getLightStatus(renderer, &light, location);
|
renderer->getLightStatus(renderer, &light, location);
|
||||||
color = renderer->applyLightStatus(renderer, &light, location, normal, material);
|
color = renderer->applyLightStatus(renderer, &light, location, normal, material);
|
||||||
color = renderer->applyAtmosphere(renderer, location, color);
|
color = renderer->atmosphere->applyAerialPerspective(renderer, location, color);
|
||||||
color = renderer->applyClouds(renderer, color, renderer->camera_location, location);
|
color = renderer->applyClouds(renderer, color, renderer->camera_location, location);
|
||||||
|
|
||||||
result.base = definition->material.base;
|
result.base = definition->material.base;
|
||||||
|
|
Loading…
Reference in a new issue