paysages : Textures refactoring (WIP).

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@544 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2013-03-31 20:27:21 +00:00 committed by ThunderK
parent d99eab3a43
commit bf87e72a4a
27 changed files with 577 additions and 649 deletions

View file

@ -15,12 +15,12 @@ Textures :
* Textures ranges are now using curves.
Water :
* Revamped light-based coloring.
* Added foam.
Atmosphere :
* Merged with sky module.
* New sky model (based on Preetham's work).
* Added sun halo control.
* New sky model and aerial perspective (based on Preetham's work).
* Better previews.
Clouds :

23
TODO
View file

@ -1,23 +1,26 @@
Technology Preview 2 :
- Better time selection widget for atmosphere.
- Replace terrain canvas editor by full sculpting editor.
=> Add a generation dialog, with fixed resolution.
=> Store local terrain modifications in fully dynamic canvas.
=> Add map preview with editor area.
=> Allow camera move and zoom.
- Finalize terrain editor.
=> Add a generation dialog for base noise (overwriting changes).
=> Implement chunks merging (with max size control).
- Get rid of noise dialogs, for simpler settings.
- Finalize lighting refactoring
- Finalize lighting/clouds refactoring
=> Restore cloud lighting
=> Improve cloud rendering precision (and beware of precision discontinuity when rendering clouds in front of ground (shorter distance)).
- Improve textures (current model is greatly incorrect).
=> Convert to new architecture model.
=> Use triplanar projection.
=> Separate models (basic texture and covering texture).
=> Covering texture height should inpact terrain height.
=> Add texture shadowing.
- Clouds should keep distance to ground.
- Fix rendering when inside a cloud layer, with other upper or lower layers.
- Improve cloud rendering precision (and beware of precision discontinuity when rendering clouds in front of ground (shorter distance)).
- Translations.
Technlogy Preview 3 :
- Improve terrain 3D editor:
=> Add a map preview with edit area highlighted.
=> Allow zooming and simplified camera control.
- Better time selection widget for atmosphere.
- Clouds should keep distance to ground.
- Find a proper model for night sky (maybe Shirley).
- Create a StandardPreviewClass in C-lib (with renderer, updateData, changeView, getColor, choices and toggles).
- Fully move layer management from BaseForm to BaseFormLayer.
@ -27,7 +30,7 @@ Technlogy Preview 3 :
- Add fresnel effect to specular lighting.
- Add "hardness to light" and shadow control ("minimum lighting") to material.
- Start using OpenCL to optimize rendering.
- Restore render progress.
- Fully restore render progress (with first pass).
- Rethink the quality settings and detail smoothing in the distance.
=> When quality setting is set to 10, add boost options
=> Add detail boost (adds granularity)

View file

@ -108,7 +108,7 @@ void ExplorerChunkTerrain::onCameraEvent(CameraDefinition* camera)
}
_distance_to_camera = v3Norm(v3Sub(getCenter(), camera->location));
_lock_data.unlock();
}
@ -166,7 +166,7 @@ double ExplorerChunkTerrain::getDisplayedSizeHint(CameraDefinition* camera)
Color ExplorerChunkTerrain::getTextureColor(double x, double y)
{
Vector3 location = {_startx + x * _size, 0.0, _startz + y * _size};
return renderer()->applyTextures(renderer(), location, 0.01);
return renderer()->terrain->getFinalColor(renderer(), location, 0.01);
}
Vector3 ExplorerChunkTerrain::getCenter()

View file

@ -115,6 +115,15 @@ FormClouds::FormClouds(QWidget *parent):
setLayers(_definition->layers);
}
FormClouds::~FormClouds()
{
CloudsDefinitionClass.destroy(_definition);
cloudsGetLayerType().callback_delete(_layer);
delete _previewCoverage;
delete _previewColor;
}
void FormClouds::revertConfig()
{
sceneryGetClouds(_definition);
@ -142,4 +151,3 @@ void FormClouds::autoPresetSelected(int preset)
cloudsLayerAutoPreset(_layer, (CloudsLayerPreset)preset);
BaseForm::autoPresetSelected(preset);
}

View file

@ -12,6 +12,7 @@ class FormClouds : public BaseFormLayer
public:
explicit FormClouds(QWidget *parent = 0);
~FormClouds();
public slots:
virtual void revertConfig();

View file

@ -13,19 +13,10 @@ public:
PreviewRenderLandscape(QWidget* parent):BasePreview(parent)
{
_renderer = sceneryCreateStandardRenderer();
_renderer->applyTextures = _applyTextures;
_renderer->getCameraLocation = _getCameraLocation;
lightingManagerDisableSpecularity(_renderer->lighting);
_textures = texturesCreateDefinition();
_atmosphere = (AtmosphereDefinition*)AtmosphereDefinitionClass.create();
_terrain = (TerrainDefinition*)TerrainDefinitionClass.create();
_water = (WaterDefinition*)WaterDefinitionClass.create();
_clouds = (CloudsDefinition*)CloudsDefinitionClass.create();
_renderer->customData[0] = &_textures;
_no_clouds = (CloudsDefinition*)CloudsDefinitionClass.create();
_clouds_enabled = true;
addOsd(QString("geolocation"));
@ -41,7 +32,7 @@ protected:
Vector3 location;
double height = _renderer->terrain->getHeight(_renderer, x, y, 1);
if (height < _water->height)
if (height < _renderer->water->getHeightInfo(_renderer).max_height)
{
return _renderer->water->getResult(_renderer, x, y).final;
}
@ -55,14 +46,12 @@ protected:
}
void updateData()
{
sceneryGetTextures(&_textures);
sceneryBindRenderer(_renderer);
_renderer->atmosphere->applyAerialPerspective = _applyAerialPerspective;
if (!_clouds_enabled)
{
CloudsRendererClass.bind(_renderer, _clouds);
CloudsRendererClass.bind(_renderer, _no_clouds);
}
}
void toggleChangeEvent(QString key, bool value)
@ -76,16 +65,7 @@ protected:
private:
Renderer* _renderer;
bool _clouds_enabled;
CloudsDefinition* _clouds;
TerrainDefinition* _terrain;
WaterDefinition *_water;
TexturesDefinition _textures;
AtmosphereDefinition* _atmosphere;
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
{
return texturesGetColor((TexturesDefinition*)(renderer->customData[0]), renderer, location.x, location.z, precision);
}
CloudsDefinition* _no_clouds;
static Vector3 _getCameraLocation(Renderer*, Vector3 location)
{

View file

@ -1,21 +1,13 @@
#include "formtextures.h"
#include "../lib_paysages/textures.h"
#include "../lib_paysages/scenery.h"
#include "tools.h"
typedef struct
{
Curve* height_curve;
Curve* slope_curve;
} TextureSupp;
static TextureSupp _supp;
/**************** Previews ****************/
class PreviewTexturesCoverage:public BasePreview
{
public:
PreviewTexturesCoverage(QWidget* parent, TextureLayerDefinition* layer):BasePreview(parent)
PreviewTexturesCoverage(QWidget* parent, TexturesLayerDefinition* layer):BasePreview(parent)
{
_terrain = (TerrainDefinition*)TerrainDefinitionClass.create();
@ -23,7 +15,7 @@ public:
_renderer->render_quality = 3;
_original_layer = layer;
_preview_layer = texturesLayerCreateDefinition();
//_preview_definition = (TexturesDefinition*)TexturesDefinitionClass.create();
addOsd(QString("geolocation"));
@ -32,7 +24,7 @@ public:
}
~PreviewTexturesCoverage()
{
texturesLayerDeleteDefinition(_preview_layer);
//TexturesDefinitionClass.destroy(_preview_layer);
}
protected:
Color getColor(double x, double y)
@ -42,7 +34,7 @@ protected:
location.x = x;
location.y = _renderer->terrain->getHeight(_renderer, x, y, 1);
location.z = y;
result.r = result.g = result.b = texturesGetLayerCoverage(_preview_layer, _renderer, location, this->scaling);
//result.r = result.g = result.b = texturesGetLayerCoverage(_preview_layer, _renderer, location, this->scaling);
return result;
}
void updateData()
@ -50,23 +42,23 @@ protected:
sceneryGetTerrain(_terrain);
TerrainRendererClass.bind(_renderer, _terrain);
texturesLayerCopyDefinition(_original_layer, _preview_layer);
//TexturesDefinitionClass.copy(_original_layer, _preview_layer);
}
private:
Renderer* _renderer;
TextureLayerDefinition* _original_layer;
TextureLayerDefinition* _preview_layer;
TexturesLayerDefinition* _original_layer;
TexturesDefinition* _preview_definition;
TerrainDefinition* _terrain;
};
class PreviewTexturesColor:public BasePreview
{
public:
PreviewTexturesColor(QWidget* parent, TextureLayerDefinition* layer):BasePreview(parent)
PreviewTexturesColor(QWidget* parent, TexturesLayerDefinition* layer):BasePreview(parent)
{
_original_layer = layer;
_preview_layer = texturesLayerCreateDefinition();
//_preview_layer = (TexturesLayerDefinition*)TexturesDefinitionClass.create();
_renderer = rendererCreate();
_renderer->render_quality = 3;
@ -74,14 +66,12 @@ public:
_renderer->render_camera.location.y = 20.0;
_renderer->render_camera.location.z = 0.0;
_zone = zoneCreate();
configScaling(0.01, 1.0, 0.01, 0.1);
configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0);
}
~PreviewTexturesColor()
{
texturesLayerDeleteDefinition(_preview_layer);
//TexturesDefinitionClass.destroy(_preview_layer);
}
protected:
Color getColor(double x, double y)
@ -90,35 +80,32 @@ protected:
location.x = x;
location.y = 0.0;
location.z = y;
return texturesGetLayerColor(_preview_layer, _renderer, location, this->scaling);
//return texturesGetLayerColor(_preview_layer, _renderer, location, this->scaling);
return COLOR_BLACK;
}
void updateData()
{
texturesLayerCopyDefinition(_original_layer, _preview_layer);
zoneCopy(_zone, _preview_layer->zone);
//TexturesDefinitionClass.copy(_original_layer, _preview_layer);
}
private:
Zone* _zone;
Renderer* _renderer;
TextureLayerDefinition* _original_layer;
TextureLayerDefinition* _preview_layer;
TexturesLayerDefinition* _original_layer;
TexturesLayerDefinition* _preview_layer;
};
/**************** Form ****************/
FormTextures::FormTextures(QWidget *parent):
BaseFormLayer(parent)
{
_definition = texturesCreateDefinition();
_layer = texturesLayerCreateDefinition();
_supp.height_curve = curveCreate();
_supp.slope_curve = curveCreate();
_definition = (TexturesDefinition*)TexturesDefinitionClass.create();
_layer = (TexturesLayerDefinition*)texturesGetLayerType().callback_create();
_previewCoverage = new PreviewTexturesCoverage(this, _layer);
_previewColor = new PreviewTexturesColor(this, _layer);
addPreview(_previewCoverage, tr("Coverage preview"));
addPreview(_previewColor, tr("Lighted sample"));
addInputNoise(tr("Surface noise"), _layer->bump_noise);
/*addInputNoise(tr("Surface noise"), _layer->bump_noise);
addInputDouble(tr("Surface noise height"), &_layer->bump_height, 0.0, 0.1, 0.001, 0.01);
addInputDouble(tr("Surface noise scaling"), &_layer->bump_scaling, 0.003, 0.3, 0.003, 0.03);
addInputMaterial(tr("Material"), &_layer->material);
@ -126,45 +113,41 @@ FormTextures::FormTextures(QWidget *parent):
addInputCurve(tr("Coverage by slope"), _supp.slope_curve, 0.0, 5.0, 0.0, 1.0, tr("Terrain slope"), tr("Texture coverage"));
addInputDouble(tr("Amplitude for slope coverage"), &_layer->slope_range, 0.001, 0.1, 0.001, 0.01);
addInputDouble(tr("Layer thickness"), &_layer->thickness, 0.0, 0.1, 0.001, 0.01);
addInputDouble(tr("Transparency thickness"), &_layer->thickness_transparency, 0.0, 0.1, 0.001, 0.01);
addInputDouble(tr("Transparency thickness"), &_layer->thickness_transparency, 0.0, 0.1, 0.001, 0.01);*/
setLayers(_definition.layers);
setLayers(_definition->layers);
}
FormTextures::~FormTextures()
{
texturesDeleteDefinition(&_definition);
texturesLayerDeleteDefinition(_layer);
curveDelete(_supp.height_curve);
curveDelete(_supp.slope_curve);
TexturesDefinitionClass.destroy(_definition);
texturesGetLayerType().callback_delete(_layer);
}
void FormTextures::revertConfig()
{
sceneryGetTextures(&_definition);
sceneryGetTextures(_definition);
BaseFormLayer::revertConfig();
}
void FormTextures::applyConfig()
{
BaseFormLayer::applyConfig();
scenerySetTextures(&_definition);
scenerySetTextures(_definition);
}
void FormTextures::layerReadCurrentFrom(void* layer_definition)
{
TextureLayerDefinition* source = (TextureLayerDefinition*)layer_definition;
texturesLayerCopyDefinition(source, _layer);
zoneGetHeightCurve(source->zone, _supp.height_curve);
zoneGetSlopeCurve(source->zone, _supp.slope_curve);
texturesGetLayerType().callback_copy((TexturesLayerDefinition*)layer_definition, _layer);
}
void FormTextures::layerWriteCurrentTo(void* layer_definition)
{
TextureLayerDefinition* destination = (TextureLayerDefinition*)layer_definition;
texturesLayerCopyDefinition(_layer, destination);
zoneSetHeightCurve(destination->zone, _supp.height_curve);
zoneSetSlopeCurve(destination->zone, _supp.slope_curve);
texturesGetLayerType().callback_copy(_layer, (TexturesLayerDefinition*)layer_definition);
}
void FormTextures::autoPresetSelected(int preset)
{
texturesLayerAutoPreset(_layer, (TexturesLayerPreset)preset);
BaseForm::autoPresetSelected(preset);
}

View file

@ -4,7 +4,7 @@
#include <QWidget>
#include "basepreview.h"
#include "baseformlayer.h"
#include "../lib_paysages/textures.h"
#include "../lib_paysages/textures/public.h"
class FormTextures : public BaseFormLayer
{
@ -21,10 +21,11 @@ public slots:
protected:
virtual void layerReadCurrentFrom(void* layer_definition);
virtual void layerWriteCurrentTo(void* layer_definition);
virtual void autoPresetSelected(int preset);
private:
TexturesDefinition _definition;
TextureLayerDefinition* _layer;
TexturesDefinition* _definition;
TexturesLayerDefinition* _layer;
BasePreview* _previewCoverage;
BasePreview* _previewColor;
};

View file

@ -48,11 +48,6 @@ private:
static QVector<ChunkMaintenanceThread*> _threads;
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
{
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
}
static Vector3 _getCameraLocation(Renderer* renderer, Vector3)
{
return ((CameraDefinition*)renderer->customData[2])->location;
@ -67,14 +62,9 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
_base_camera = camera;
cameraCopyDefinition(camera, &_current_camera);
_textures = texturesCreateDefinition();
sceneryGetTextures(&_textures);
_renderer = sceneryCreateStandardRenderer();
_renderer->render_quality = 3;
_renderer->customData[1] = &_textures;
_renderer->customData[2] = _base_camera;
_renderer->applyTextures = _applyTextures;
_renderer->getCameraLocation = _getCameraLocation;
lightingManagerDisableSpecularity(_renderer->lighting);

View file

@ -5,7 +5,6 @@
#include "baseexplorerchunk.h"
#include "../lib_paysages/camera.h"
#include "../lib_paysages/renderer.h"
#include "../lib_paysages/textures.h"
class WidgetExplorer : public QGLWidget
{
@ -47,8 +46,6 @@ private:
bool _alive;
QMutex _lock_chunks;
TexturesDefinition _textures;
double _average_frame_time;
int _quality;

View file

@ -1,9 +1,9 @@
BUILDMODE = debug
BUILDPATH = ../build/${BUILDMODE}
OBJPATH = ./obj/${BUILDMODE}
SOURCES = $(wildcard *.c atmosphere/*.c clouds/*.c terrain/*.c water/*.c tools/*.c shared/*.c)
SOURCES = $(wildcard *.c atmosphere/*.c clouds/*.c terrain/*.c textures/*.c water/*.c tools/*.c shared/*.c)
OBJECTS = ${SOURCES:%.c=${OBJPATH}/%.o}
HEADERS = $(wildcard *.h atmosphere/*.h clouds/*.h terrain/*.h water/*.h tools/*.h shared/*.h)
HEADERS = $(wildcard *.h atmosphere/*.h clouds/*.h terrain/*.h textures/*.h water/*.h tools/*.h shared/*.h)
RESULT = ${BUILDPATH}/libpaysages.so
LIBS = glib-2.0 gthread-2.0 IL ILU
CC_FLAGS = -Wall -fPIC -DHAVE_GLIB=1

View file

@ -5,17 +5,12 @@
#include <time.h>
#include "render.h"
#include "textures.h"
#include "scenery.h"
#include "system.h"
#include "zone.h"
void autoGenRealisticLandscape(int seed)
{
TexturesDefinition textures;
TextureLayerDefinition* texture;
int layer;
if (!seed)
{
seed = time(NULL);
@ -23,60 +18,4 @@ void autoGenRealisticLandscape(int seed)
srand(seed);
sceneryAutoPreset();
/* Textures */
textures = texturesCreateDefinition();
layer = layersAddLayer(textures.layers, NULL);
layersSetName(textures.layers, layer, "Ground");
texture = layersGetLayer(textures.layers, layer);
noiseClearLevels(texture->bump_noise);
noiseRandomizeOffsets(texture->bump_noise);
noiseAddLevelsSimple(texture->bump_noise, 8, 1.0, -0.5, 0.5, 0.5);
texture->bump_height = 0.01;
texture->bump_scaling = 0.045;
texture->material.base.r = 0.6;
texture->material.base.g = 0.55;
texture->material.base.b = 0.57;
texture->material.reflection = 0.02;
texture->material.shininess = 3.0;
texture->thickness = 0.001;
texture->slope_range = 0.001;
texture->thickness_transparency = 0.0;
layer = layersAddLayer(textures.layers, NULL);
layersSetName(textures.layers, layer, "Grass");
texture = layersGetLayer(textures.layers, layer);
zoneAddHeightRangeQuick(texture->zone, 1.0, -6.0, -5.0, 3.0, 15.0);
zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.05, 0.4);
noiseClearLevels(texture->bump_noise);
noiseRandomizeOffsets(texture->bump_noise);
noiseAddLevelsSimple(texture->bump_noise, 5, 1.0, -0.2, 0.2, 0.5);
noiseAddLevelsSimple(texture->bump_noise, 2, 0.03, -0.04, 0.04, 0.5);
texture->bump_height = 0.002;
texture->bump_scaling = 0.03;
texture->material.base.r = 0.12;
texture->material.base.g = 0.19;
texture->material.base.b = 0.035;
texture->material.reflection = 0.003;
texture->material.shininess = 2.0;
texture->thickness = 0.02;
texture->slope_range = 0.03;
texture->thickness_transparency = 0.005;
/*texture = texturesGetLayer(&textures, texturesAddLayer(&textures));
zoneAddHeightRangeQuick(texture->zone, 1.0, 4.0, 5.0, 100.0, 100.0);
zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.2, 1.0);
noiseGenerateBaseNoise(texture->bump_noise, 102400);
noiseClearLevels(texture->bump_noise);
noiseAddLevelsSimple(texture->bump_noise, 6, 1.0, 1.0);
texture->bump_height = 0.002;
texture->bump_scaling = 0.03;
texture->material.base.r = 1.0;
texture->material.base.g = 1.0;
texture->material.base.b = 1.0;
texture->material.reflection = 0.25;
texture->material.shininess = 0.6;
texture->thickness = 0.05;
texture->slope_range = 0.3;
texture->thickness_transparency = 0.015;*/
scenerySetTextures(&textures);
texturesDeleteDefinition(&textures);
}

View file

@ -78,11 +78,6 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector
return _RAYCASTING_NULL;
}
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
{
return COLOR_TRANSPARENT;
}
static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial* material)
{
LightStatus* light = lightingCreateStatus(renderer->lighting, location, renderer->getCameraLocation(renderer, location));
@ -125,7 +120,6 @@ Renderer* rendererCreate()
result->pushQuad = _pushQuad;
result->rayWalking = _rayWalking;
result->applyTextures = _applyTextures;
result->applyLightingToSurface = _applyLightingToSurface;
result->applyMediumTraversal = _applyMediumTraversal;
@ -135,6 +129,7 @@ Renderer* rendererCreate()
result->atmosphere = AtmosphereRendererClass.create();
result->clouds = CloudsRendererClass.create();
result->terrain = TerrainRendererClass.create();
result->textures = TexturesRendererClass.create();
result->water = WaterRendererClass.create();
return result;
@ -147,6 +142,7 @@ void rendererDelete(Renderer* renderer)
AtmosphereRendererClass.destroy(renderer->atmosphere);
CloudsRendererClass.destroy(renderer->clouds);
TerrainRendererClass.destroy(renderer->terrain);
TexturesRendererClass.destroy(renderer->textures);
WaterRendererClass.destroy(renderer->water);
renderDeleteArea(renderer->render_area);

View file

@ -5,6 +5,7 @@
#include "atmosphere/public.h"
#include "clouds/public.h"
#include "terrain/public.h"
#include "textures/public.h"
#include "water/public.h"
#include "render.h"
@ -40,7 +41,6 @@ struct Renderer
/* Scenery related */
RayCastingResult (*rayWalking)(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds);
Color (*applyTextures)(Renderer* renderer, Vector3 location, double precision);
/* Autonomous tools */
LightingManager* lighting;
@ -48,6 +48,7 @@ struct Renderer
/* Autonomous sub-renderers */
AtmosphereRenderer* atmosphere;
TerrainRenderer* terrain;
TexturesRenderer* textures;
CloudsRenderer* clouds;
WaterRenderer* water;

View file

@ -9,7 +9,7 @@ static AtmosphereDefinition* _atmosphere;
static CameraDefinition _camera;
static CloudsDefinition* _clouds;
static TerrainDefinition* _terrain;
static TexturesDefinition _textures;
static TexturesDefinition* _textures;
static WaterDefinition* _water;
static SceneryCustomDataCallback _custom_save = NULL;
@ -24,7 +24,7 @@ void sceneryInit()
_camera = cameraCreateDefinition();
_clouds = CloudsDefinitionClass.create();
_terrain = TerrainDefinitionClass.create();
_textures = texturesCreateDefinition();
_textures = TexturesDefinitionClass.create();
_water = WaterDefinitionClass.create();
_custom_save = NULL;
@ -37,7 +37,7 @@ void sceneryQuit()
cameraDeleteDefinition(&_camera);
CloudsDefinitionClass.destroy(_clouds);
TerrainDefinitionClass.destroy(_terrain);
texturesDeleteDefinition(&_textures);
TexturesDefinitionClass.destroy(_textures);
AtmosphereDefinitionClass.destroy(_water);
noiseQuit();
@ -46,6 +46,7 @@ void sceneryQuit()
void sceneryAutoPreset()
{
terrainAutoPreset(_terrain, TERRAIN_PRESET_STANDARD);
texturesAutoPreset(_textures, TEXTURES_PRESET_IRELAND);
atmosphereAutoPreset(_atmosphere, ATMOSPHERE_PRESET_CLEAR_DAY);
waterAutoPreset(_water, WATER_PRESET_LAKE);
cloudsAutoPreset(_clouds, CLOUDS_PRESET_PARTLY_CLOUDY);
@ -65,7 +66,7 @@ void scenerySave(PackStream* stream)
cameraSave(stream, &_camera);
CloudsDefinitionClass.save(stream, _clouds);
TerrainDefinitionClass.save(stream, _terrain);
texturesSave(stream, &_textures);
TexturesDefinitionClass.save(stream, _textures);
WaterDefinitionClass.save(stream, _water);
if (_custom_save)
@ -83,12 +84,9 @@ void sceneryLoad(PackStream* stream)
cameraLoad(stream, &_camera);
CloudsDefinitionClass.load(stream, _clouds);
TerrainDefinitionClass.load(stream, _terrain);
texturesLoad(stream, &_textures);
TexturesDefinitionClass.load(stream, _textures);
WaterDefinitionClass.load(stream, _water);
cameraValidateDefinition(&_camera, 0);
texturesValidateDefinition(&_textures);
if (_custom_load)
{
_custom_load(stream, _custom_data);
@ -140,13 +138,14 @@ void sceneryGetTerrain(TerrainDefinition* terrain)
void scenerySetTextures(TexturesDefinition* textures)
{
texturesCopyDefinition(textures, &_textures);
texturesValidateDefinition(&_textures);
TexturesDefinitionClass.copy(textures, _textures);
cameraValidateDefinition(&_camera, 1);
}
void sceneryGetTextures(TexturesDefinition* textures)
{
texturesCopyDefinition(&_textures, textures);
TexturesDefinitionClass.copy(_textures, textures);
}
void scenerySetWater(WaterDefinition* water)
@ -192,11 +191,6 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector
return result;
}
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
{
return texturesGetColor(&_textures, renderer, location.x, location.z, precision);
}
static Vector3 _projectPoint(Renderer* renderer, Vector3 point)
{
return cameraProject(&renderer->render_camera, renderer, point);
@ -227,7 +221,6 @@ Renderer* sceneryCreateStandardRenderer()
cameraCopyDefinition(&_camera, &result->render_camera);
result->rayWalking = _rayWalking;
result->applyTextures = _applyTextures;
result->projectPoint = _projectPoint;
result->unprojectPoint = _unprojectPoint;
result->getPrecision = _getPrecision;
@ -241,6 +234,7 @@ void sceneryBindRenderer(Renderer* renderer)
{
AtmosphereRendererClass.bind(renderer, _atmosphere);
TerrainRendererClass.bind(renderer, _terrain);
TexturesRendererClass.bind(renderer, _textures);
CloudsRendererClass.bind(renderer, _clouds);
WaterRendererClass.bind(renderer, _water);
}

View file

@ -12,9 +12,9 @@
#include "atmosphere/public.h"
#include "clouds/public.h"
#include "terrain/public.h"
#include "textures/public.h"
#include "water/public.h"
#include "camera.h"
#include "textures.h"
#include "renderer.h"
#ifdef __cplusplus

View file

@ -93,11 +93,45 @@ static double _fakeGetHeight(Renderer* renderer, double x, double z, int with_pa
return 0.0;
}
static double _getHeight(Renderer* renderer, double x, double z, int with_painting)
static double _realGetHeight(Renderer* renderer, double x, double z, int with_painting)
{
return terrainGetInterpolatedHeight(renderer->terrain->definition, x, z, with_painting);
}
static TerrainResult _fakeGetResult(Renderer* renderer, double x, double z, int with_painting, int with_textures)
{
TerrainResult result;
UNUSED(renderer);
UNUSED(x);
UNUSED(z);
UNUSED(with_painting);
UNUSED(with_textures);
result.location.x = x;
result.location.y = 0.0;
result.location.z = z;
result.normal = VECTOR_UP;
return result;
}
static TerrainResult _realGetResult(Renderer* renderer, double x, double z, int with_painting, int with_textures)
{
TerrainResult result;
result.location.x = x;
result.location.y = renderer->terrain->getHeight(renderer, x, z, with_painting);
result.location.z = z;
if (with_textures)
{
result = renderer->textures->displaceTerrain(renderer, result);
}
return result;
}
static Color _fakeGetFinalColor(Renderer* renderer, Vector3 location, double precision)
{
UNUSED(renderer);
@ -106,14 +140,11 @@ static Color _fakeGetFinalColor(Renderer* renderer, Vector3 location, double pre
return COLOR_GREEN;
}
static Color _getFinalColor(Renderer* renderer, Vector3 location, double precision)
static Color _realgetFinalColor(Renderer* renderer, Vector3 location, double precision)
{
Color color;
color = renderer->applyTextures(renderer, location, precision);
color = renderer->applyMediumTraversal(renderer, location, color);
return color;
TerrainResult terrain = renderer->terrain->getResult(renderer, location.x, location.z, 1, 1);
TexturesResult textures = renderer->textures->applyToTerrain(renderer, terrain);
return renderer->applyMediumTraversal(renderer, textures.final_location, textures.final_color);
}
static RayCastingResult _fakeCastRay(Renderer* renderer, Vector3 start, Vector3 direction)
@ -127,7 +158,7 @@ static RayCastingResult _fakeCastRay(Renderer* renderer, Vector3 start, Vector3
return result;
}
static RayCastingResult _castRay(Renderer* renderer, Vector3 start, Vector3 direction)
static RayCastingResult _realCastRay(Renderer* renderer, Vector3 start, Vector3 direction)
{
RayCastingResult result;
TerrainDefinition* definition = renderer->terrain->definition;
@ -138,7 +169,7 @@ static RayCastingResult _castRay(Renderer* renderer, Vector3 start, Vector3 dire
inc_factor = (double)renderer->render_quality;
inc_base = 1.0;
inc_value = inc_base / inc_factor;
lastdiff = start.y - _getHeight(renderer, start.x, start.z, 1);
lastdiff = start.y - _realGetHeight(renderer, start.x, start.z, 1);
length = 0.0;
do
@ -146,14 +177,14 @@ static RayCastingResult _castRay(Renderer* renderer, Vector3 start, Vector3 dire
inc_vector = v3Scale(direction, inc_value);
length += v3Norm(inc_vector);
start = v3Add(start, inc_vector);
height = _getHeight(renderer, start.x, start.z, 1);
height = _realGetHeight(renderer, start.x, start.z, 1);
diff = start.y - height;
if (diff < 0.0)
{
if (fabs(diff - lastdiff) > 0.00001)
{
start = v3Add(start, v3Scale(inc_vector, -diff / (diff - lastdiff)));
start.y = _getHeight(renderer, start.x, start.z, 1);
start.y = _realGetHeight(renderer, start.x, start.z, 1);
}
else
{
@ -161,7 +192,7 @@ static RayCastingResult _castRay(Renderer* renderer, Vector3 start, Vector3 dire
}
result.hit = 1;
result.hit_location = start;
result.hit_color = _getFinalColor(renderer, start, renderer->getPrecision(renderer, result.hit_location));
result.hit_color = _realgetFinalColor(renderer, start, renderer->getPrecision(renderer, result.hit_location));
return result;
}
@ -220,7 +251,7 @@ static int _alterLight(Renderer* renderer, LightDefinition* light, Vector3 locat
inc_vector = v3Scale(direction_to_light, inc_value);
length += v3Norm(inc_vector);
location = v3Add(location, inc_vector);
height = _getHeight(renderer, location.x, location.z, 1);
height = _realGetHeight(renderer, location.x, location.z, 1);
diff = location.y - height;
if (diff < 0.0)
{
@ -300,6 +331,7 @@ static TerrainRenderer* _createRenderer()
result->castRay = _fakeCastRay;
result->getHeight = _fakeGetHeight;
result->getResult = _fakeGetResult;
result->getFinalColor = _fakeGetFinalColor;
return result;
@ -315,9 +347,10 @@ static void _bindRenderer(Renderer* renderer, TerrainDefinition* definition)
{
TerrainDefinitionClass.copy(definition, renderer->terrain->definition);
renderer->terrain->castRay = _castRay;
renderer->terrain->getHeight = _getHeight;
renderer->terrain->getFinalColor = _getFinalColor;
renderer->terrain->castRay = _realCastRay;
renderer->terrain->getHeight = _realGetHeight;
renderer->terrain->getResult = _realGetResult;
renderer->terrain->getFinalColor = _realgetFinalColor;
lightingManagerRegisterFilter(renderer->lighting, (FuncLightingAlterLight)_alterLight, renderer);
}

View file

@ -4,20 +4,11 @@
#include "../tools.h"
#include "../tools/lighting.h"
#include "../renderer.h"
#include "../textures.h"
/*
* Terrain previews.
*/
static TexturesDefinition _textures;
static int _inited = 0;
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
{
return texturesGetColor(&_textures, renderer, location.x, location.z, precision);
}
static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque)
{
LightDefinition light;
@ -63,26 +54,9 @@ Renderer* terrainCreatePreviewRenderer()
Renderer* result = rendererCreate();
result->render_quality = 3;
result->applyTextures = _applyTextures;
result->getCameraLocation = _getCameraLocation;
result->atmosphere->getLightingStatus = _getLightingStatus;
if (!_inited)
{
/*LightDefinition light;*/
TextureLayerDefinition* texture;
_inited = 1;
_textures = texturesCreateDefinition();
texture = (TextureLayerDefinition*)layersGetLayer(_textures.layers, layersAddLayer(_textures.layers, NULL));
texture->material.base = COLOR_WHITE;
texture->material.reflection = 0.3;
texture->material.shininess = 2.0;
texture->bump_height = 0.0;
texturesLayerValidateDefinition(texture);
}
return result;
}

View file

@ -32,7 +32,14 @@ typedef struct
double _max_height;
} TerrainDefinition;
typedef struct
{
Vector3 location;
Vector3 normal;
} TerrainResult;
typedef double (*FuncTerrainGetHeight)(Renderer* renderer, double x, double z, int with_painting);
typedef TerrainResult (*FuncTerrainGetResult)(Renderer* renderer, double x, double z, int with_painting, int with_textures);
typedef Color (*FuncTerrainGetFinalColor)(Renderer* renderer, Vector3 location, double precision);
typedef struct
@ -41,6 +48,7 @@ typedef struct
FuncGeneralCastRay castRay;
FuncTerrainGetHeight getHeight;
FuncTerrainGetResult getResult;
FuncTerrainGetFinalColor getFinalColor;
void* _internal_data;

View file

@ -1,358 +0,0 @@
#include "textures.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "terrain/public.h"
#include "tools/lighting.h"
#include "renderer.h"
#include "tools.h"
#define TEXTURES_MAX_LAYERS 50
typedef struct
{
double thickness;
Vector3 location;
Vector3 normal;
TextureLayerDefinition* definition;
} TextureResult;
TexturesDefinition texturesCreateDefinition()
{
TexturesDefinition result;
result.layers = layersCreate(texturesGetLayerType(), TEXTURES_MAX_LAYERS);
return result;
}
void texturesDeleteDefinition(TexturesDefinition* definition)
{
layersDelete(definition->layers);
}
void texturesCopyDefinition(TexturesDefinition* source, TexturesDefinition* destination)
{
layersCopy(source->layers, destination->layers);
}
void texturesValidateDefinition(TexturesDefinition* definition)
{
layersValidate(definition->layers);
}
void texturesSave(PackStream* stream, TexturesDefinition* definition)
{
layersSave(stream, definition->layers);
}
void texturesLoad(PackStream* stream, TexturesDefinition* definition)
{
layersLoad(stream, definition->layers);
}
TextureLayerDefinition* texturesLayerCreateDefinition()
{
TextureLayerDefinition* result;
result = malloc(sizeof(TextureLayerDefinition));
result->zone = zoneCreate();
result->bump_noise = noiseCreateGenerator();
noiseAddLevelsSimple(result->bump_noise, 8, 1.0, -0.5, 0.5, 0.5);
result->bump_height = 0.1;
result->bump_scaling = 0.1;
result->material.base = COLOR_WHITE;
result->material.reflection = 0.0;
result->material.shininess = 0.0;
result->thickness = 0.0;
result->slope_range = 0.001;
result->thickness_transparency = 0.0;
return result;
}
void texturesLayerDeleteDefinition(TextureLayerDefinition* definition)
{
zoneDelete(definition->zone);
noiseDeleteGenerator(definition->bump_noise);
free(definition);
}
void texturesLayerCopyDefinition(TextureLayerDefinition* source, TextureLayerDefinition* destination)
{
destination->material = source->material;
destination->bump_height = source->bump_height;
destination->bump_scaling = source->bump_scaling;
destination->thickness = source->thickness;
destination->slope_range = source->slope_range;
destination->thickness_transparency = source->thickness_transparency;
noiseCopy(source->bump_noise, destination->bump_noise);
zoneCopy(source->zone, destination->zone);
}
void texturesLayerValidateDefinition(TextureLayerDefinition* definition)
{
if (definition->bump_scaling < 0.000001)
{
definition->bump_scaling = 0.000001;
}
if (definition->slope_range < 0.001)
{
definition->slope_range = 0.001;
}
}
static void _texturesLayerSave(PackStream* stream, TextureLayerDefinition* layer)
{
zoneSave(stream, layer->zone);
noiseSaveGenerator(stream, layer->bump_noise);
packWriteDouble(stream, &layer->bump_height);
packWriteDouble(stream, &layer->bump_scaling);
materialSave(stream, &layer->material);
packWriteDouble(stream, &layer->thickness);
packWriteDouble(stream, &layer->slope_range);
packWriteDouble(stream, &layer->thickness_transparency);
}
static void _texturesLayerLoad(PackStream* stream, TextureLayerDefinition* layer)
{
zoneLoad(stream, layer->zone);
noiseLoadGenerator(stream, layer->bump_noise);
packReadDouble(stream, &layer->bump_height);
packReadDouble(stream, &layer->bump_scaling);
materialLoad(stream, &layer->material);
packReadDouble(stream, &layer->thickness);
packReadDouble(stream, &layer->slope_range);
packReadDouble(stream, &layer->thickness_transparency);
}
LayerType texturesGetLayerType()
{
LayerType result;
result.callback_create = (LayerCallbackCreate)texturesLayerCreateDefinition;
result.callback_delete = (LayerCallbackDelete)texturesLayerDeleteDefinition;
result.callback_copy = (LayerCallbackCopy)texturesLayerCopyDefinition;
result.callback_validate = (LayerCallbackValidate)texturesLayerValidateDefinition;
result.callback_save = (LayerCallbackSave)_texturesLayerSave;
result.callback_load = (LayerCallbackLoad)_texturesLayerLoad;
return result;
}
static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west)
{
Vector3 dnorth, deast, dsouth, dwest, normal;
dnorth = v3Sub(north, center);
deast = v3Sub(east, center);
dsouth = v3Sub(south, center);
dwest = v3Sub(west, center);
normal = v3Cross(deast, dnorth);
normal = v3Add(normal, v3Cross(dsouth, deast));
normal = v3Add(normal, v3Cross(dwest, dsouth));
normal = v3Add(normal, v3Cross(dnorth, dwest));
return v3Normalize(normal);
}
static inline Vector3 _getNormal2(Vector3 center, Vector3 east, Vector3 south)
{
return v3Normalize(v3Cross(v3Sub(south, center), v3Sub(east, center)));
}
static inline TextureResult _getTerrainResult(Renderer* renderer, double x, double z, double detail)
{
TextureResult result;
Vector3 center, north, east, south, west;
/* TODO This method is better suited in terrain.c */
center.x = x;
center.z = z;
center.y = renderer->terrain->getHeight(renderer, center.x, center.z, 1);
east.x = x + detail;
east.z = z;
east.y = renderer->terrain->getHeight(renderer, east.x, east.z, 1);
south.x = x;
south.z = z + detail;
south.y = renderer->terrain->getHeight(renderer, south.x, south.z, 1);
if (renderer->render_quality > 5)
{
west.x = x - detail;
west.z = z;
west.y = renderer->terrain->getHeight(renderer, west.x, west.z, 1);
north.x = x;
north.z = z - detail;
north.y = renderer->terrain->getHeight(renderer, north.x, north.z, 1);
result.normal = _getNormal4(center, north, east, south, west);
}
else
{
result.normal = _getNormal2(center, east, south);
}
result.location = center;
result.thickness = -100.0;
result.definition = NULL;
return result;
}
static inline void _getLayerThickness(TextureLayerDefinition* definition, Renderer* renderer, double x, double z, TextureResult* result)
{
TextureResult base;
double coverage;
base = _getTerrainResult(renderer, x, z, definition->slope_range);
coverage = zoneGetValue(definition->zone, base.location, base.normal);
if (coverage > 0.0)
{
result->thickness = coverage * definition->thickness;
result->thickness += noiseGet2DTotal(definition->bump_noise, base.location.x / definition->bump_scaling, base.location.z / definition->bump_scaling) * definition->bump_height;
result->location = v3Add(base.location, v3Scale(base.normal, result->thickness));
}
else
{
result->thickness = -1000.0;
result->location = base.location;
}
}
static inline TextureResult _getLayerResult(TextureLayerDefinition* definition, Renderer* renderer, double x, double z, double detail)
{
TextureResult result_center, result_north, result_east, result_south, result_west;
_getLayerThickness(definition, renderer, x, z, &result_center);
_getLayerThickness(definition, renderer, x + detail, z, &result_east);
_getLayerThickness(definition, renderer, x, z + detail, &result_south);
if (renderer->render_quality > 5)
{
_getLayerThickness(definition, renderer, x - detail, z, &result_west);
_getLayerThickness(definition, renderer, x, z - detail, &result_north);
result_center.normal = _getNormal4(result_center.location, result_north.location, result_east.location, result_south.location, result_west.location);
}
else
{
result_center.normal = _getNormal2(result_center.location, result_east.location, result_south.location);
}
result_center.definition = definition;
return result_center;
}
static int _cmpResults(const void* result1, const void* result2)
{
return ((TextureResult*)result1)->thickness > ((TextureResult*)result2)->thickness;
}
double texturesGetLayerCoverage(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail)
{
TextureResult base = _getTerrainResult(renderer, location.x, location.z, definition->slope_range);
return zoneGetValue(definition->zone, base.location, base.normal);
}
static inline Color _getLayerColor(Renderer* renderer, TextureResult texture)
{
return renderer->applyLightingToSurface(renderer, texture.location, texture.normal, &texture.definition->material);
}
Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail)
{
TextureResult result = _getLayerResult(definition, renderer, location.x, location.z, detail);
return _getLayerColor(renderer, result);
}
Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, double x, double z, double detail)
{
TextureResult results[TEXTURES_MAX_LAYERS + 1];
Color result, color;
double thickness, last_height;
int i, start, nblayers;
detail *= 0.1;
results[0] = _getTerrainResult(renderer, x, z, detail);
nblayers = layersCount(definition->layers);
for (i = 0; i < nblayers; i++)
{
results[i + 1] = _getLayerResult(layersGetLayer(definition->layers, i), renderer, x, z, detail);
}
qsort(results, nblayers + 1, sizeof(TextureResult), _cmpResults);
/* Pre compute alpha channel */
start = 0;
last_height = results[0].thickness;
results[0].thickness = 1.0;
for (i = 1; i <= nblayers; i++)
{
thickness = results[i].thickness - last_height;
last_height = results[i].thickness;
if (results[i].definition)
{
if (thickness < results[i].definition->thickness_transparency)
{
results[i].thickness = thickness / results[i].definition->thickness_transparency;
}
else
{
results[i].thickness = (thickness > 0.0) ? 1.0 : 0.0;
}
}
else
{
results[i].thickness = 1.0;
}
if (results[i].thickness >= 0.999999)
{
start = i;
}
}
/* Apply colors and alphas */
if (results[start].definition)
{
result = _getLayerColor(renderer, results[start]);
}
else
{
result = COLOR_GREEN;
}
for (i = start + 1; i <= nblayers; i++)
{
if (results[i].thickness)
{
if (results[i].definition)
{
color = _getLayerColor(renderer, results[i]);
color.a = results[i].thickness;
}
else
{
color = COLOR_GREEN;
}
colorMask(&result, &color);
}
}
return result;
}

View file

@ -1,56 +0,0 @@
#ifndef _PAYSAGES_TEXTURES_H_
#define _PAYSAGES_TEXTURES_H_
#include "tools/lighting.h"
#include "tools/color.h"
#include "tools/euclid.h"
#include "tools/pack.h"
#include "shared/types.h"
#include "layers.h"
#include "noise.h"
#include "zone.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
Zone* zone;
NoiseGenerator* bump_noise;
double bump_scaling;
double bump_height;
SurfaceMaterial material;
double thickness;
double slope_range;
double thickness_transparency;
} TextureLayerDefinition;
typedef struct
{
Layers* layers;
} TexturesDefinition;
TexturesDefinition texturesCreateDefinition();
void texturesDeleteDefinition(TexturesDefinition* definition);
void texturesCopyDefinition(TexturesDefinition* source, TexturesDefinition* destination);
void texturesValidateDefinition(TexturesDefinition* definition);
void texturesSave(PackStream* stream, TexturesDefinition* definition);
void texturesLoad(PackStream* stream, TexturesDefinition* definition);
TextureLayerDefinition* texturesLayerCreateDefinition();
void texturesLayerDeleteDefinition(TextureLayerDefinition* definition);
void texturesLayerCopyDefinition(TextureLayerDefinition* source, TextureLayerDefinition* destination);
void texturesLayerValidateDefinition(TextureLayerDefinition* definition);
LayerType texturesGetLayerType();
double texturesGetLayerCoverage(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail);
Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail);
Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, double x, double z, double detail);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,135 @@
#include "private.h"
#include <stdlib.h>
/******************** Global definition ********************/
static void _validateDefinition(TexturesDefinition* definition)
{
layersValidate(definition->layers);
}
static TexturesDefinition* _createDefinition()
{
TexturesDefinition* definition = malloc(sizeof(TexturesDefinition));
definition->layers = layersCreate(texturesGetLayerType(), TEXTURES_MAX_LAYERS);
return definition;
}
static void _deleteDefinition(TexturesDefinition* definition)
{
layersDelete(definition->layers);
free(definition);
}
static void _copyDefinition(TexturesDefinition* source, TexturesDefinition* destination)
{
layersCopy(source->layers, destination->layers);
}
static void _saveDefinition(PackStream* stream, TexturesDefinition* definition)
{
layersSave(stream, definition->layers);
}
static void _loadDefinition(PackStream* stream, TexturesDefinition* definition)
{
layersLoad(stream, definition->layers);
}
StandardDefinition TexturesDefinitionClass = {
(FuncObjectCreate)_createDefinition,
(FuncObjectDelete)_deleteDefinition,
(FuncObjectCopy)_copyDefinition,
(FuncObjectValidate)_validateDefinition,
(FuncObjectSave)_saveDefinition,
(FuncObjectLoad)_loadDefinition
};
/*** Layer definition ***/
static void _layerValidateDefinition(TexturesLayerDefinition* definition)
{
if (definition->displacement_scaling < 0.000001)
{
definition->displacement_scaling = 0.000001;
}
noiseClearLevels(definition->_displacement_noise);
noiseAddLevelsSimple(definition->_displacement_noise, 3, 1.0, -1.0, 1.0, 0.0);
noiseValidate(definition->_displacement_noise);
}
static TexturesLayerDefinition* _layerCreateDefinition()
{
TexturesLayerDefinition* result;
result = malloc(sizeof(TexturesLayerDefinition));
result->terrain_zone = zoneCreate();
result->displacement_scaling = 0.1;
result->displacement_height = 0.1;
result->displacement_offset = 0.0;
result->material.base = COLOR_WHITE;
result->material.reflection = 0.0;
result->material.shininess = 0.0;
result->_displacement_noise = noiseCreateGenerator();
return result;
}
static void _layerDeleteDefinition(TexturesLayerDefinition* definition)
{
zoneDelete(definition->terrain_zone);
noiseDeleteGenerator(definition->_displacement_noise);
free(definition);
}
static void _layerCopyDefinition(TexturesLayerDefinition* source, TexturesLayerDefinition* destination)
{
zoneCopy(source->terrain_zone, destination->terrain_zone);
destination->displacement_scaling = source->displacement_scaling;
destination->displacement_height = source->displacement_height;
destination->displacement_offset = source->displacement_offset;
destination->material = source->material;
noiseCopy(source->_displacement_noise, destination->_displacement_noise);
}
static void _layerSave(PackStream* stream, TexturesLayerDefinition* layer)
{
zoneSave(stream, layer->terrain_zone);
packWriteDouble(stream, &layer->displacement_scaling);
packWriteDouble(stream, &layer->displacement_height);
packWriteDouble(stream, &layer->displacement_offset);
materialSave(stream, &layer->material);
noiseSaveGenerator(stream, layer->_displacement_noise);
}
static void _layerLoad(PackStream* stream, TexturesLayerDefinition* layer)
{
zoneLoad(stream, layer->terrain_zone);
packReadDouble(stream, &layer->displacement_scaling);
packReadDouble(stream, &layer->displacement_height);
packReadDouble(stream, &layer->displacement_offset);
materialLoad(stream, &layer->material);
noiseLoadGenerator(stream, layer->_displacement_noise);
}
LayerType texturesGetLayerType()
{
LayerType result;
result.callback_create = (LayerCallbackCreate)_layerCreateDefinition;
result.callback_delete = (LayerCallbackDelete)_layerDeleteDefinition;
result.callback_copy = (LayerCallbackCopy)_layerCopyDefinition;
result.callback_validate = (LayerCallbackValidate)_layerValidateDefinition;
result.callback_save = (LayerCallbackSave)_layerSave;
result.callback_load = (LayerCallbackLoad)_layerLoad;
return result;
}

View file

@ -0,0 +1,94 @@
#include "private.h"
void texturesAutoPreset(TexturesDefinition* definition, TexturesPreset preset)
{
layersClear(definition->layers);
if (preset == TEXTURES_PRESET_IRELAND)
{
}
else if (preset == TEXTURES_PRESET_IRELAND)
{
}
else if (preset == TEXTURES_PRESET_IRELAND)
{
}
}
void texturesLayerAutoPreset(TexturesLayerDefinition* definition, TexturesLayerPreset preset)
{
noiseRandomizeOffsets(definition->_displacement_noise);
switch (preset)
{
case TEXTURES_LAYER_PRESET_ROCK:
break;
case TEXTURES_LAYER_PRESET_GRASS:
break;
case TEXTURES_LAYER_PRESET_SAND:
break;
case TEXTURES_LAYER_PRESET_SNOW:
break;
default:
break;
}
cloudsLayerValidateDefinition(definition);
}
#if 0
textures = texturesCreateDefinition();
layer = layersAddLayer(textures.layers, NULL);
layersSetName(textures.layers, layer, "Ground");
texture = layersGetLayer(textures.layers, layer);
noiseClearLevels(texture->bump_noise);
noiseRandomizeOffsets(texture->bump_noise);
noiseAddLevelsSimple(texture->bump_noise, 8, 1.0, -0.5, 0.5, 0.5);
texture->bump_height = 0.01;
texture->bump_scaling = 0.045;
texture->material.base.r = 0.6;
texture->material.base.g = 0.55;
texture->material.base.b = 0.57;
texture->material.reflection = 0.02;
texture->material.shininess = 3.0;
texture->thickness = 0.001;
texture->slope_range = 0.001;
texture->thickness_transparency = 0.0;
layer = layersAddLayer(textures.layers, NULL);
layersSetName(textures.layers, layer, "Grass");
texture = layersGetLayer(textures.layers, layer);
zoneAddHeightRangeQuick(texture->zone, 1.0, -6.0, -5.0, 3.0, 15.0);
zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.05, 0.4);
noiseClearLevels(texture->bump_noise);
noiseRandomizeOffsets(texture->bump_noise);
noiseAddLevelsSimple(texture->bump_noise, 5, 1.0, -0.2, 0.2, 0.5);
noiseAddLevelsSimple(texture->bump_noise, 2, 0.03, -0.04, 0.04, 0.5);
texture->bump_height = 0.002;
texture->bump_scaling = 0.03;
texture->material.base.r = 0.12;
texture->material.base.g = 0.19;
texture->material.base.b = 0.035;
texture->material.reflection = 0.003;
texture->material.shininess = 2.0;
texture->thickness = 0.02;
texture->slope_range = 0.03;
texture->thickness_transparency = 0.005;
/*texture = texturesGetLayer(&textures, texturesAddLayer(&textures));
zoneAddHeightRangeQuick(texture->zone, 1.0, 4.0, 5.0, 100.0, 100.0);
zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.2, 1.0);
noiseGenerateBaseNoise(texture->bump_noise, 102400);
noiseClearLevels(texture->bump_noise);
noiseAddLevelsSimple(texture->bump_noise, 6, 1.0, 1.0);
texture->bump_height = 0.002;
texture->bump_scaling = 0.03;
texture->material.base.r = 1.0;
texture->material.base.g = 1.0;
texture->material.base.b = 1.0;
texture->material.reflection = 0.25;
texture->material.shininess = 0.6;
texture->thickness = 0.05;
texture->slope_range = 0.3;
texture->thickness_transparency = 0.015;*/
scenerySetTextures(&textures);
texturesDeleteDefinition(&textures);
#endif

View file

@ -0,0 +1,2 @@
#include "private.h"

View file

@ -0,0 +1,21 @@
#ifndef _PAYSAGES_TEXTURES_PRIVATE_H_
#define _PAYSAGES_TEXTURES_PRIVATE_H_
#include "public.h"
/*
* Get the base presence factor of a layer, not accounting for other layers.
*/
double texturesGetLayerBasePresence(Renderer* renderer, TexturesLayerDefinition* layer, TerrainResult result);
/*
* Get triplanar noise value, depending on the normal direction.
*/
double texturesGetTriplanarNoise(NoiseGenerator* noise, Vector3 location, Vector3 normal);
/*
* Apply texture displacement on a terrain result.
*/
TerrainResult texturesApplyLayerDisplacement(Renderer* renderer, TexturesLayerDefinition* layer, TerrainResult initial, TerrainResult support, double presence, double cancel_factor);
#endif

View file

@ -0,0 +1,109 @@
#ifndef _PAYSAGES_TEXTURES_PUBLIC_H_
#define _PAYSAGES_TEXTURES_PUBLIC_H_
#include "../layers.h"
#include "../zone.h"
#include "../tools/lighting.h"
#include "../terrain/public.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TEXTURES_MAX_LAYERS 50
typedef enum
{
TEXTURES_PRESET_IRELAND,
TEXTURES_PRESET_ALPS,
TEXTURES_PRESET_CANYON
} TexturesPreset;
typedef enum
{
TEXTURES_LAYER_PRESET_ROCK,
TEXTURES_LAYER_PRESET_GRASS,
TEXTURES_LAYER_PRESET_SAND,
TEXTURES_LAYER_PRESET_SNOW
} TexturesLayerPreset;
typedef enum
{
TEXTURES_MERGE_FADE,
TEXTURES_MERGE_DISSOLVE,
TEXTURES_MERGE_DISPLACEMENT_VALUE
} TexturesMergeMode;
typedef struct
{
Zone* terrain_zone;
double displacement_scaling;
double displacement_height;
double displacement_offset;
/*double detail_scaling;
double detail_height;*/
SurfaceMaterial material;
/*double cancel_displacement_factor;
TexturesMergeMode merge_mode;*/
NoiseGenerator* _displacement_noise;
/*NoiseGenerator* _detail_noise;*/
/*Curve* _local_slope_condition;*/
} TexturesLayerDefinition;
typedef struct
{
Layers* layers;
} TexturesDefinition;
typedef struct
{
double global_presence;
double local_presence;
Vector3 displaced_location;
Vector3 displaced_normal;
Color color;
Color cancelled_color;
} TexturesLayerResult;
typedef struct
{
Vector3 base_location;
Vector3 base_normal;
int layer_count;
TexturesLayerResult layers[TEXTURES_MAX_LAYERS];
Vector3 final_location;
Color final_color;
} TexturesResult;
typedef TerrainResult (*FuncTexturesDisplaceTerrain)(Renderer* renderer, TerrainResult terrain);
typedef TexturesResult (*FuncTexturesApplyToTerrain)(Renderer* renderer, TerrainResult terrain);
typedef struct
{
TexturesDefinition* definition;
FuncTexturesDisplaceTerrain displaceTerrain;
FuncTexturesApplyToTerrain applyToTerrain;
} TexturesRenderer;
extern StandardDefinition TexturesDefinitionClass;
extern StandardRenderer TexturesRendererClass;
LayerType texturesGetLayerType();
void texturesAutoPreset(TexturesDefinition* definition, TexturesPreset preset);
void texturesLayerAutoPreset(TexturesLayerDefinition* definition, TexturesLayerPreset preset);
/*Renderer* cloudsCreatePreviewCoverageRenderer();
Color cloudsGetPreviewCoverage(Renderer* renderer, double x, double y, double scaling, int perspective);
Renderer* cloudsCreatePreviewColorRenderer();
Color cloudsGetPreviewColor(Renderer* renderer, double x, double y);*/
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,73 @@
#include "private.h"
#include <stdlib.h>
#include "../tools.h"
#include "../renderer.h"
/******************** Fake ********************/
static TerrainResult _fakeDisplaceTerrain(Renderer* renderer, TerrainResult terrain)
{
UNUSED(renderer);
return terrain;
}
static TexturesResult _fakeApplyToTerrain(Renderer* renderer, TerrainResult terrain)
{
TexturesResult result;
result.base_location = terrain.location;
result.base_normal = terrain.normal;
result.layer_count = 0;
result.final_location = terrain.location;
result.final_color = COLOR_WHITE;
return result;
}
/******************** Real ********************/
static TerrainResult _realDisplaceTerrain(Renderer* renderer, TerrainResult terrain)
{
/* TODO */
return _fakeDisplaceTerrain(renderer, terrain);
}
static TexturesResult _realApplyToTerrain(Renderer* renderer, TerrainResult terrain)
{
/* TODO */
return _fakeApplyToTerrain(renderer, terrain);
}
/******************** Renderer ********************/
static TexturesRenderer* _createRenderer()
{
TexturesRenderer* result;
result = malloc(sizeof(TexturesRenderer));
result->definition = TexturesDefinitionClass.create();
result->displaceTerrain = _fakeDisplaceTerrain;
result->applyToTerrain = _fakeApplyToTerrain;
return result;
}
static void _deleteRenderer(TexturesRenderer* renderer)
{
TexturesDefinitionClass.destroy(renderer->definition);
free(renderer);
}
static void _bindRenderer(Renderer* renderer, TexturesDefinition* definition)
{
TexturesDefinitionClass.copy(definition, renderer->textures->definition);
renderer->textures->displaceTerrain = _realDisplaceTerrain;
renderer->textures->applyToTerrain = _realApplyToTerrain;
}
StandardRenderer TexturesRendererClass = {
(FuncObjectCreate)_createRenderer,
(FuncObjectDelete)_deleteRenderer,
(FuncObjectBind)_bindRenderer
};