paysages: Started heavy lighting refactoring (WIP - Broken).

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@230 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-01-22 18:39:42 +00:00 committed by ThunderK
parent 6b9b813753
commit e265be6105
20 changed files with 592 additions and 180 deletions

View file

@ -21,7 +21,7 @@ public:
_noise = noise;
_level = -1;
}
void setLevel(int row)
{
_level = row;
@ -76,7 +76,7 @@ DialogNoise::DialogNoise(QWidget *parent, NoiseGenerator* value):
QWidget* form;
QWidget* buttons;
QPushButton* button;
_base = value;
_current = noiseCreateGenerator();
@ -85,7 +85,7 @@ DialogNoise::DialogNoise(QWidget *parent, NoiseGenerator* value):
previews = new QWidget(this);
previews->setLayout(new QVBoxLayout());
layout()->addWidget(previews);
previewLevel = new PreviewLevel(previews, _current);
previews->layout()->addWidget(new QLabel("Level preview"));
previews->layout()->addWidget(previewLevel);
@ -98,16 +98,16 @@ DialogNoise::DialogNoise(QWidget *parent, NoiseGenerator* value):
form = new QWidget(this);
form->setLayout(new QVBoxLayout());
layout()->addWidget(form);
form->layout()->addWidget(new QLabel("Noise components"));
levels = new QListWidget(form);
form->layout()->addWidget(levels);
QObject::connect(levels, SIGNAL(currentRowChanged(int)), this, SLOT(levelChanged(int)));
buttons = new QWidget(form);
buttons->setLayout(new QHBoxLayout());
form->layout()->addWidget(buttons);
button = new QPushButton("Add component", buttons);
buttons->layout()->addWidget(button);
QObject::connect(button, SIGNAL(clicked()), this, SLOT(addLevel()));
@ -139,11 +139,11 @@ DialogNoise::DialogNoise(QWidget *parent, NoiseGenerator* value):
slider_scaling->setTickPosition(QSlider::TicksBelow);
form->layout()->addWidget(slider_scaling);
QObject::connect(slider_scaling, SIGNAL(valueChanged(int)), this, SLOT(scalingChanged(int)));
buttons = new QWidget(form);
buttons->setLayout(new QHBoxLayout());
form->layout()->addWidget(buttons);
button = new QPushButton("Validate", buttons);
buttons->layout()->addWidget(button);
QObject::connect(button, SIGNAL(clicked()), this, SLOT(accept()));
@ -157,7 +157,7 @@ DialogNoise::DialogNoise(QWidget *parent, NoiseGenerator* value):
QObject::connect(button, SIGNAL(clicked()), this, SLOT(reject()));
setWindowTitle("Paysages 3D - Noise editor");
revert();
}
@ -165,7 +165,7 @@ DialogNoise::~DialogNoise()
{
delete previewLevel;
delete previewTotal;
noiseDeleteGenerator(_current);
}
@ -202,14 +202,14 @@ void DialogNoise::revert()
void DialogNoise::revertToCurrent()
{
int i, n;
levels->clear();
n = noiseGetLevelCount(_current);
for (i = 0; i < n; i++)
{
levels->addItem("Level");
levels->addItem(QString("Component %1").arg(i + 1));
}
previewLevel->redraw();
previewTotal->redraw();
}
@ -217,20 +217,22 @@ void DialogNoise::revertToCurrent()
void DialogNoise::addLevel()
{
NoiseLevel level;
level.height = 0.1;
level.scaling = 0.1;
level.xoffset = 0.0;
level.yoffset = 0.0;
level.zoffset = 0.0;
noiseAddLevel(_current, level);
revertToCurrent();
}
void DialogNoise::removeLevel()
{
// TODO
noiseRemoveLevel(_current, _current_level);
revertToCurrent();
}
void DialogNoise::levelChanged(int row)
@ -239,7 +241,7 @@ void DialogNoise::levelChanged(int row)
{
_current_level = row;
((PreviewLevel*)previewLevel)->setLevel(row);
slider_height->setValue(_current_level_params.height * 1000.0);
slider_scaling->setValue(_current_level_params.scaling * 1000.0);
}

75
gui_qt/formterrain.cpp Normal file
View file

@ -0,0 +1,75 @@
#include "formterrain.h"
#include "tools.h"
#include <QColor>
#include <QSlider>
#include <math.h>
#include "../lib_paysages/terrain.h"
#include "../lib_paysages/shared/functions.h"
#include "../lib_paysages/shared/constants.h"
static TerrainDefinition _definition;
/**************** Previews ****************/
class PreviewTerrainHeight:public Preview
{
public:
PreviewTerrainHeight(QWidget* parent):
Preview(parent)
{
}
protected:
QColor getColor(double x, double y)
{
double height;
height = terrainGetHeightNormalized(x, y);
return QColor((int)(255.0 * height), (int)(255.0 * height), (int)(255.0 * height));
}
};
class PreviewTerrainColor:public Preview
{
public:
PreviewTerrainColor(QWidget* parent):
Preview(parent)
{
_environment.toggle_fog = 0;
}
protected:
QColor getColor(double x, double y)
{
return colorToQColor(terrainGetColorCustom(x, y, scaling, &_definition, NULL, &_environment));
}
private:
TerrainEnvironment _environment;
};
/**************** Form ****************/
FormTerrain::FormTerrain(QWidget *parent):
BaseForm(parent)
{
_definition = terrainCreateDefinition();
previewHeight = new PreviewTerrainHeight(this);
previewColor = new PreviewTerrainColor(this);
addPreview(previewHeight, QString("Height preview"));
addPreview(previewColor, QString("Color preview"));
addInputNoise("Height", _definition.height_noise);
revertConfig();
}
void FormTerrain::revertConfig()
{
terrainCopyDefinition(terrainGetDefinition(), &_definition);
BaseForm::revertConfig();
}
void FormTerrain::applyConfig()
{
terrainSetDefinition(_definition);
BaseForm::applyConfig();
}

24
gui_qt/formterrain.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef _PAYSAGES_QT_FORMTERRAIN_H_
#define _PAYSAGES_QT_FORMTERRAIN_H_
#include <QWidget>
#include "preview.h"
#include "baseform.h"
class FormTerrain : public BaseForm
{
Q_OBJECT
public:
explicit FormTerrain(QWidget *parent = 0);
public slots:
virtual void revertConfig();
virtual void applyConfig();
private:
Preview* previewHeight;
Preview* previewColor;
};
#endif

View file

@ -13,10 +13,10 @@
static WaterDefinition _definition;
/**************** Previews ****************/
class PreviewCoverage:public Preview
class PreviewWaterCoverage:public Preview
{
public:
PreviewCoverage(QWidget* parent):
PreviewWaterCoverage(QWidget* parent):
Preview(parent)
{
}
@ -38,10 +38,10 @@ protected:
}
};
class PreviewColor:public Preview
class PreviewWaterColor:public Preview
{
public:
PreviewColor(QWidget* parent):
PreviewWaterColor(QWidget* parent):
Preview(parent)
{
}
@ -85,6 +85,7 @@ protected:
environment.toggle_fog = 0;
environment.toggle_shadows = 0;
quality.force_detail = 0.0001;
quality.detail_boost = 1.0;
result = waterGetColorCustom(location, look, &definition, &quality, &environment).final;
return colorToQColor(result);
@ -100,6 +101,7 @@ private:
if (direction.z < 0.0001)
{
result.hit_color = COLOR_WHITE;
result.hit_location = start;
}
else
{
@ -114,8 +116,10 @@ private:
{
result.hit_color = COLOR_GREY;
}
result.hit_location.x = x;
result.hit_location.y = y;
result.hit_location.z = 0.0;
}
/* TODO hit_location */
return result;
}
@ -127,8 +131,8 @@ FormWater::FormWater(QWidget *parent):
{
_definition = waterCreateDefinition();
previewCoverage = new PreviewCoverage(this);
previewColor = new PreviewColor(this);
previewCoverage = new PreviewWaterCoverage(this);
previewColor = new PreviewWaterColor(this);
addPreview(previewCoverage, QString("Coverage preview"));
addPreview(previewColor, QString("Color preview"));

View file

@ -4,6 +4,7 @@
#include <QMenuBar>
#include <QFileDialog>
#include "formterrain.h"
#include "formwater.h"
#include "formsky.h"
#include "formrender.h"
@ -30,7 +31,7 @@ MainWindow::MainWindow(QWidget *parent) :
QMenu* menu;
tabs = new QTabWidget(this);
tabs->addTab(new BaseForm(tabs), "Temp");
tabs->addTab(new FormTerrain(tabs), "Terrain");
tabs->addTab(new FormWater(tabs), "Water");
tabs->addTab(new FormSky(tabs), "Sky");
tabs->addTab(new FormRender(tabs), "Render");

View file

@ -14,34 +14,36 @@ win32:LIBS += ../libpaysages.a -lDevIL -lILU -lILUT -lglib-2.0 -lgthread-2.0
# Input
HEADERS += ../lib_paysages/shared/functions.h ../lib_paysages/shared/types.h \
mainwindow.h \
formwater.h \
preview.h \
baseform.h \
inputdouble.h \
baseinput.h \
inputcolor.h \
formrender.h \
inputint.h \
dialogrender.h \
dialognoise.h \
inputcolorgradation.h \
dialogrender.h \
formrender.h \
formsky.h \
formterrain.h \
formwater.h \
inputcolor.h \
inputcolorgradation.h \
inputdouble.h \
inputint.h \
inputnoise.h \
mainwindow.h \
preview.h \
tools.h
FORMS +=
SOURCES += \
mainwindow.cpp \
formwater.cpp \
preview.cpp \
baseform.cpp \
inputdouble.cpp \
baseinput.cpp \
inputcolor.cpp \
formrender.cpp \
inputint.cpp \
dialogrender.cpp \
dialognoise.cpp \
inputcolorgradation.cpp \
dialogrender.cpp \
formrender.cpp \
formsky.cpp \
inputnoise.cpp
formterrain.cpp \
formwater.cpp \
inputcolor.cpp \
inputcolorgradation.cpp \
inputdouble.cpp \
inputint.cpp \
inputnoise.cpp \
mainwindow.cpp \
preview.cpp

View file

@ -3,8 +3,6 @@
#include <QPainter>
#include <QTimer>
static QVector<Preview*> _previews;
class PreviewDrawer:public QThread
{
public:
@ -48,15 +46,18 @@ Preview::Preview(QWidget* parent) :
this->xoffset = 0.0;
this->yoffset = 0.0;
this->pixbuf = new QImage(this->size(), QImage::Format_ARGB32);
this->pixbuf->fill(0x00000000);
this->alive = true;
this->need_rerender = false;
this->need_render = false;
this->need_render = true;
this->setMinimumSize(256, 256);
this->setMaximumSize(256, 256);
this->resize(256, 256);
QObject::connect(this, SIGNAL(contentChange()), this, SLOT(update()));
this->updater = new PreviewDrawer(this);
this->updater->start();
}
@ -85,7 +86,7 @@ void Preview::doRender()
}
if (this->need_render)
{
this->need_render = 0;
this->need_render = false;
this->renderPixbuf();
}
}
@ -94,7 +95,7 @@ void Preview::doRender()
void Preview::redraw()
{
//lock->lock();
need_rerender = 1;
need_rerender = true;
//lock->unlock();
}
@ -110,12 +111,18 @@ void Preview::resizeEvent(QResizeEvent* event)
QImage* image;
this->lock->lock();
image = this->pixbuf;
this->pixbuf = new QImage(this->size(), QImage::Format_ARGB32);
delete image;
this->lock->unlock();
this->forceRender();
image = this->pixbuf;
this->pixbuf = new QImage(this->size(), QImage::Format_ARGB32);
this->pixbuf->fill(0x00000000);
this->need_rerender = false;
this->need_render = true;
delete image;
this->lock->unlock();
}
void Preview::paintEvent(QPaintEvent* event)
@ -128,8 +135,8 @@ void Preview::forceRender()
{
this->lock->lock();
this->pixbuf->fill(0x00000000);
this->need_rerender = 0;
this->need_render = 1;
this->need_rerender = false;
this->need_render = true;
this->lock->unlock();
}
@ -164,14 +171,12 @@ void Preview::renderPixbuf()
}
if (done && (x == w - 1 || x % 10 == 0))
{
this->update();
emit contentChange();
}
this->lock->unlock();
}
}
//static void _scrollPixbuf(SmallPreview* preview, int dx, int dy)
//{
// int xstart, ystart, xsize, ysize, y;

View file

@ -17,7 +17,7 @@ public:
static void startUpdater();
void doRender();
void redraw();
void setScaling(double scaling);
protected:
@ -50,8 +50,12 @@ protected:
bool alive;
bool need_rerender;
bool need_render;
private:
QThread* updater;
signals:
void contentChange();
};
#endif

View file

@ -15,6 +15,7 @@
#include "modifiers.h"
#include "terrain.h"
#include "textures.h"
#include "lighting.h"
#ifdef WIN32
#include <windows.h>
@ -47,47 +48,6 @@ void autoInit()
#ifdef _SC_NPROCESSORS_ONLN
_cpu_count = (int)sysconf(_SC_NPROCESSORS_ONLN);
#endif
renderSetBackgroundColor(&COLOR_BLACK);
terrainInit();
waterInit();
renderInit();
}
void autoSave(char* filepath)
{
FILE* f = fopen(filepath, "wb");
texturesSave(f);
cameraSave(f);
cloudsSave(f);
fogSave(f);
lightingSave(f);
renderSave(f);
skySave(f);
terrainSave(f);
waterSave(f);
fclose(f);
}
void autoLoad(char* filepath)
{
FILE* f = fopen(filepath, "rb");
texturesLoad(f);
cameraLoad(f);
cloudsLoad(f);
fogLoad(f);
lightingLoad(f);
renderLoad(f);
skyLoad(f);
terrainLoad(f);
waterLoad(f);
fclose(f);
}
void autoSetDaytime(int hour, int minute)
@ -98,8 +58,8 @@ void autoSetDaytime(int hour, int minute)
void autoSetDaytimeFraction(double daytime)
{
SkyDefinition sky;
ColorGradation grad_sun;
Color sun;
/*ColorGradation grad_sun;
Color sun;*/
daytime = fmod(daytime, 1.0);
if (daytime < 0.0)
@ -107,7 +67,7 @@ void autoSetDaytimeFraction(double daytime)
daytime += 1.0;
}
lightingSetSunAngle(0.0, (daytime + 0.25) * M_PI * 2.0);
/*lightingSetSunAngle(0.0, (daytime + 0.25) * M_PI * 2.0);
grad_sun = colorGradationCreate();
colorGradationAddRgba(&grad_sun, 0.2, 0.1, 0.1, 0.1, 1.0);
@ -118,7 +78,7 @@ void autoSetDaytimeFraction(double daytime)
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);
lightingSetSunColor(sun);*/
sky = skyGetDefinition();
sky.daytime = daytime;
@ -163,6 +123,7 @@ void autoGenRealisticLandscape(int seed)
CloudsDefinition cloud;
SkyDefinition sky;
TextureDefinition texture;
LightingDefinition lighting;
int layer;
HeightModifier* mod;
Zone* zone;
@ -249,6 +210,12 @@ void autoGenRealisticLandscape(int seed)
sky.sun_radius = 0.02;
skySetDefinition(sky);
/* Lighting */
lighting = lightingCreateDefinition();
lighting.autosetfromsky = 1;
lightingSetDefinition(lighting);
/* Terrain */
terrain = terrainCreateDefinition();
noiseGenerateBaseNoise(terrain.height_noise, 1048576);
noiseAddLevelsSimple(terrain.height_noise, 10, 10.0, 1.0);
@ -275,6 +242,7 @@ void autoGenRealisticLandscape(int seed)
terrainSetDefinition(terrain);
terrainDeleteDefinition(terrain);
/* Textures */
layer = texturesAddLayer();
texture = texturesCreateDefinition();
noiseGenerateBaseNoise(texture.bump_noise, 102400);
@ -308,6 +276,7 @@ void autoGenRealisticLandscape(int seed)
texturesSetDefinition(layer, texture);
texturesDeleteDefinition(texture);*/
/* Fog */
fogSetDistance(20.0, 100.0);
}

View file

@ -1,11 +1,13 @@
#include "clouds.h"
#include <string.h>
#include <math.h>
#include "lighting.h"
#include "shared/types.h"
#include "shared/functions.h"
#include "shared/constants.h"
#include "shared/globals.h"
#include "clouds.h"
#define MAX_LAYERS 10
@ -378,22 +380,26 @@ static int _findSegments(CloudsDefinition* definition, CloudsQuality* quality, V
return segment_count;
}
static Color _applyLayerLighting(CloudsDefinition* definition, CloudsQuality* quality, Vector3 position, Color base, double detail)
typedef struct
{
CloudsDefinition* definition;
CloudsQuality* quality;
Color base;
double detail;
} LightFilterData;
static Color _lightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data)
{
Vector3 direction, normal;
double inside_depth, total_depth;
CloudSegment segments[20];
Color result;
LightFilterData data;
normal = _getNormal(definition, position, 0.5);
normal = v3Add(normal, _getNormal(definition, position, 0.2));
normal = v3Add(normal, _getNormal(definition, position, 0.1));
result = lightingApply(position, normal, 0.0, base, 0.3, 0.1);
data = *((LightFilterData*)custom_data);
data.detail = (data.detail < 0.1) ? 0.1 : data.detail;
direction = sun_direction_inv;
detail = (detail < 0.1) ? 0.1 : detail;
/* FIXME Dont hard-code max_total_length */
_findSegments(definition, quality, position, direction, detail, 20, 50.0, 300.0, &inside_depth, &total_depth, segments);
_findSegments(data.definition, data.quality, location, direction_to_light, data.detail, 20, 50.0, 300.0, &inside_depth, &total_depth, segments);
inside_depth *= 0.02;
if (inside_depth > 1.0)
@ -401,13 +407,40 @@ static Color _applyLayerLighting(CloudsDefinition* definition, CloudsQuality* qu
inside_depth = 1.0;
}
result.r = base.r * sun_color_lum * (0.9 - 0.2 * inside_depth) + result.r * (0.1 + 0.1 * inside_depth) + (0.1 - inside_depth * 0.1) * sun_color_lum;
result.g = base.g * sun_color_lum * (0.9 - 0.2 * inside_depth) + result.g * (0.1 + 0.1 * inside_depth) + (0.1 - inside_depth * 0.1) * sun_color_lum;
result.b = base.b * sun_color_lum * (0.9 - 0.2 * inside_depth) + result.b * (0.1 + 0.1 * inside_depth) + (0.1 - inside_depth * 0.1) * sun_color_lum;
result.r = data.base.r * sun_color_lum * (0.9 - 0.2 * inside_depth) + result.r * (0.1 + 0.1 * inside_depth) + (0.1 - inside_depth * 0.1) * sun_color_lum;
result.g = data.base.g * sun_color_lum * (0.9 - 0.2 * inside_depth) + result.g * (0.1 + 0.1 * inside_depth) + (0.1 - inside_depth * 0.1) * sun_color_lum;
result.b = data.base.b * sun_color_lum * (0.9 - 0.2 * inside_depth) + result.b * (0.1 + 0.1 * inside_depth) + (0.1 - inside_depth * 0.1) * sun_color_lum;
return result;
}
static Color _applyLayerLighting(CloudsDefinition* definition, CloudsQuality* quality, Vector3 position, Color base, double detail)
{
Vector3 normal;
ReceiverMaterial material;
LightingEnvironment lighting_environment;
LightFilterData data;
normal = _getNormal(definition, position, 0.5);
normal = v3Add(normal, _getNormal(definition, position, 0.2));
normal = v3Add(normal, _getNormal(definition, position, 0.1));
//normal = v3Normalize(normal);
data.definition = definition;
data.quality = quality;
data.detail = detail;
data.base = base;
lighting_environment.filter = _lightFilter;
lighting_environment.custom_data = &data;
material.base = base;
material.reflection = 0.3;
material.shininess = 0.1;
return lightingApplyCustom(position, normal, material, NULL, NULL, &lighting_environment);
}
Color cloudsGetColorCustom(Vector3 start, Vector3 end, CloudsDefinition* definition, CloudsQuality* quality, CloudsEnvironment* environment)
{
int i, segment_count;

View file

@ -1,25 +1,173 @@
#include "lighting.h"
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <string.h>
#include "shared/types.h"
#include "shared/functions.h"
#include "shared/constants.h"
#include "shared/globals.h"
static Color sun_color;
double sun_color_lum;
Vector3 sun_direction;
Vector3 sun_direction_inv;
static LightingDefinition _definition;
static LightingQuality _quality;
static LightingEnvironment _environment;
static LightDefinition _LIGHT_NULL;
static Color _standardFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data)
{
// TODO Find shadows
return light;
}
void lightingInit()
{
_definition = lightingCreateDefinition();
_environment.filter = _standardFilter;
_environment.custom_data = NULL;
_LIGHT_NULL.color = COLOR_BLACK;
_LIGHT_NULL.direction.x = 0.0;
_LIGHT_NULL.direction.y = 1.0;
_LIGHT_NULL.direction.z = 0.0;
}
void lightingSave(FILE* f)
{
// TODO
}
void lightingLoad(FILE* f)
{
// TODO
}
void lightingSetSunDirection(double x, double y, double z)
LightingDefinition lightingCreateDefinition()
{
LightingDefinition definition;
definition.autosetfromsky = 0;
definition.nblights = 0;
definition._nbautolights = 0;
return definition;
}
void lightingDeleteDefinition(LightingDefinition definition)
{
}
void lightingCopyDefinition(LightingDefinition source, LightingDefinition* destination)
{
*destination = source;
}
void lightingSetDefinition(LightingDefinition definition)
{
lightingCopyDefinition(definition, &_definition);
}
LightingDefinition lightingGetDefinition()
{
return _definition;
}
void lightingValidateDefinition(LightingDefinition* definition)
{
if (!definition)
{
lightingValidateDefinition(&_definition);
}
if (definition->autosetfromsky)
{
// TODO Get lights from sky
}
else
{
definition->_nbautolights = 0;
}
}
int lightingGetLightCount(LightingDefinition* definition)
{
return definition->nblights;
}
LightDefinition lightingGetLight(LightingDefinition* definition, int light)
{
if (light >= 0 && light < definition->nblights)
{
return definition->lights[light];
}
else
{
return _LIGHT_NULL;
}
}
int lightingAddLight(LightingDefinition* definition, LightDefinition light)
{
if (definition->nblights < MAX_LIGHTS)
{
definition->lights[definition->nblights] = light;
return definition->nblights++;
}
else
{
return -1;
}
}
void lightingDeleteLight(LightingDefinition* definition, int light)
{
if (light >= 0 && light < definition->nblights)
{
if (definition->nblights > 1 && light < definition->nblights - 1)
{
memmove(definition->lights + light, definition->lights + light + 1, sizeof(LightDefinition) * definition->nblights - light - 1);
}
definition->nblights--;
}
}
void lightingSetQuality(LightingQuality quality)
{
_quality = quality;
}
LightingQuality lightingGetQuality()
{
return _quality;
}
Color lightingApplyCustom(Vector3 location, Vector3 normal, ReceiverMaterial material, LightingDefinition* definition, LightingQuality* quality, LightingEnvironment* environment)
{
if (!definition)
{
definition = &_definition;
}
if (!quality)
{
quality = &_quality;
}
if (!environment)
{
environment = &_environment;
}
return COLOR_RED;
}
Color lightingApply(Vector3 location, Vector3 normal, ReceiverMaterial material)
{
return lightingApplyCustom(location, normal, material, &_definition, &_quality, &_environment);
}
/*void lightingSetSunDirection(double x, double y, double z)
{
sun_direction.x = x;
sun_direction.y = y;
@ -44,15 +192,15 @@ Color lightingApply(Vector3 location, Vector3 normal, double shadowing, Color ba
Color result, light;
double ambient, diffuse, specular;
Vector3 view, reflect;
light.r = sun_color.r * (1.0 - 0.4 * shadowing);
light.g = sun_color.g * (1.0 - 0.4 * shadowing);
light.b = sun_color.b * (1.0 - 0.4 * shadowing);
normal = v3Normalize(normal);
view = v3Normalize(v3Sub(location, camera_location));
reflect = v3Sub(v3Scale(normal, 2.0 * v3Dot(sun_direction_inv, normal)), sun_direction_inv);
ambient = 0.2;
diffuse = v3Dot(sun_direction_inv, normal);
diffuse = pow(diffuse * 0.5 + 0.5, 2.0) * (1.0 - shadowing) + (diffuse * 0.5 + 0.3) * shadowing;
@ -77,6 +225,6 @@ Color lightingApply(Vector3 location, Vector3 normal, double shadowing, Color ba
result.g = base.g * ambient + base.g * diffuse * light.g + base.g * specular * light.g;
result.b = base.b * ambient + base.b * diffuse * light.b + base.b * specular * light.b;
result.a = base.a;
return result;
}
}*/

75
lib_paysages/lighting.h Normal file
View file

@ -0,0 +1,75 @@
#ifndef _PAYSAGES_LIGHTING_H_
#define _PAYSAGES_LIGHTING_H_
#include "shared/types.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_LIGHTS 10
typedef struct
{
Vector3 direction;
Color color;
double maxshadow;
} LightDefinition;
typedef struct
{
int autosetfromsky;
int nblights;
LightDefinition lights[MAX_LIGHTS];
int _nbautolights;
LightDefinition _autolights[MAX_LIGHTS];
} LightingDefinition;
typedef struct
{
int unused;
} LightingQuality;
typedef Color (*LightFilter)(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data);
typedef struct
{
LightFilter filter;
void* custom_data;
} LightingEnvironment;
typedef struct
{
Color base;
double reflection;
double shininess;
} ReceiverMaterial;
void lightingInit();
void lightingSave(FILE* f);
void lightingLoad(FILE* f);
LightingDefinition lightingCreateDefinition();
void lightingDeleteDefinition(LightingDefinition definition);
void lightingCopyDefinition(LightingDefinition source, LightingDefinition* destination);
void lightingSetDefinition(LightingDefinition definition);
LightingDefinition lightingGetDefinition();
void lightingValidateDefinition(LightingDefinition* definition);
int lightingGetLightCount(LightingDefinition* definition);
LightDefinition lightingGetLight(LightingDefinition* definition, int light);
int lightingAddLight(LightingDefinition* definition, LightDefinition light);
void lightingDeleteLight(LightingDefinition* definition, int light);
void lightingSetQuality(LightingQuality quality);
LightingQuality lightingGetQuality();
Color lightingApplyCustom(Vector3 location, Vector3 normal, ReceiverMaterial material, LightingDefinition* definition, LightingQuality* quality, LightingEnvironment* environment);
Color lightingApply(Vector3 location, Vector3 normal, ReceiverMaterial material);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,8 +1,5 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include "IL/il.h"
#include "IL/ilu.h"
@ -12,7 +9,13 @@
#include "shared/functions.h"
#include "shared/globals.h"
#include "shared/system.h"
#include "terrain.h"
#include "water.h"
#include "lighting.h"
#include "textures.h"
#include "sky.h"
#include "clouds.h"
void paysagesInit()
{
@ -24,11 +27,17 @@ void paysagesInit()
cameraSetTarget(0.0, 5.0, 0.0);
autoInit();
skyInit();
terrainInit();
texturesInit();
waterInit();
lightingInit();
renderInit();
autoSetRenderQuality(5);
autoGenRealisticLandscape(0);
autoSetDaytime(8, 30);
// DEBUG
/*double last_height, height, x;
last_height = height = 0.0;
@ -42,3 +51,39 @@ void paysagesInit()
cameraSetLocation(x - 2.0, height, 0.0);
cameraSetTarget(x - 1.0, height, 0.0);*/
}
void paysagesSave(char* filepath)
{
FILE* f = fopen(filepath, "wb");
cameraSave(f);
cloudsSave(f);
fogSave(f);
renderSave(f);
skySave(f);
terrainSave(f);
texturesSave(f);
waterSave(f);
lightingSave(f);
fclose(f);
}
void paysagesLoad(char* filepath)
{
FILE* f = fopen(filepath, "rb");
cameraLoad(f);
cloudsLoad(f);
fogLoad(f);
renderLoad(f);
skyLoad(f);
terrainLoad(f);
texturesLoad(f);
waterLoad(f);
lightingLoad(f);
fclose(f);
}

View file

@ -180,13 +180,13 @@ void noiseAddLevel(NoiseGenerator* generator, NoiseLevel level)
void noiseAddLevelSimple(NoiseGenerator* generator, double scaling, double height)
{
NoiseLevel level;
level.scaling = scaling;
level.height = height;
level.xoffset = toolsRandom();
level.yoffset = toolsRandom();
level.zoffset = toolsRandom();
noiseAddLevel(generator, level);
}
@ -211,12 +211,24 @@ void noiseAddLevels(NoiseGenerator* generator, int level_count, NoiseLevel start
void noiseAddLevelsSimple(NoiseGenerator* generator, int level_count, double scaling, double height)
{
NoiseLevel level;
level.scaling = scaling;
level.height = height;
noiseAddLevels(generator, level_count, level, 0.5, 0.5, 1);
}
void noiseRemoveLevel(NoiseGenerator* generator, int level)
{
if (level >= 0 && level < generator->level_count)
{
if (generator->level_count > 1 && level < generator->level_count - 1)
{
memmove(generator->levels + level, generator->levels + level + 1, sizeof(NoiseLevel) * (generator->level_count - level - 1));
}
generator->level_count--;
}
}
int noiseGetLevel(NoiseGenerator* generator, int level, NoiseLevel* params)
{
if (level >= 0 && level < generator->level_count)
@ -241,13 +253,13 @@ void noiseSetLevel(NoiseGenerator* generator, int level, NoiseLevel params)
void noiseSetLevelSimple(NoiseGenerator* generator, int level, double scaling, double height)
{
NoiseLevel params;
params.scaling = scaling;
params.height = height;
params.xoffset = toolsRandom();
params.yoffset = toolsRandom();
params.zoffset = toolsRandom();
noiseSetLevel(generator, level, params);
}

View file

@ -56,6 +56,7 @@ void renderLoad(FILE* f)
void renderInit()
{
_lock = mutexCreate();
renderSetBackgroundColor(&COLOR_BLACK);
}
void renderSetSize(int width, int height)
@ -263,12 +264,12 @@ static void _processDirtyPixels()
static void _setAllDirty()
{
int x, y;
_dirty_left = 0;
_dirty_right = render_width - 1;
_dirty_down = 0;
_dirty_up = render_height - 1;
for (y = _dirty_down; y <= _dirty_up; y++)
{
for (x = _dirty_left; x <= _dirty_right; x++)
@ -799,10 +800,10 @@ void renderSetPreviewCallbacks(PreviewCallbackResize resize, PreviewCallbackClea
_cb_preview_clear = clear ? clear : _previewClear;
_cb_preview_draw = draw ? draw : _previewDraw;
_cb_preview_update = update ? update : _previewUpdate;
_cb_preview_resize(render_width, render_height);
_cb_preview_clear(background_color);
_setAllDirty();
_processDirtyPixels();

View file

@ -9,6 +9,8 @@ extern "C" {
#include <stdio.h>
void paysagesInit();
void paysagesSave(char* filepath);
void paysagesLoad(char* filepath);
/* array.c */
void arrayCreate(Array* array, int item_size);
@ -21,8 +23,6 @@ void arrayClear(Array* array);
/* auto.c */
void autoInit();
void autoSave(char* filepath);
void autoLoad(char* filepath);
void autoSetDaytime(int hour, int minute);
void autoSetDaytimeFraction(double daytime);
void autoSetRenderQuality(int quality);
@ -97,14 +97,6 @@ void fogSetColor(Color col);
void fogSetDistance(double near, double far);
Color fogApplyToLocation(Vector3 location, Color base);
/* lighting.c */
void lightingSave(FILE* f);
void lightingLoad(FILE* f);
void lightingSetSunDirection(double x, double y, double z);
void lightingSetSunAngle(double hor, double ver);
void lightingSetSunColor(Color col);
Color lightingApply(Vector3 location, Vector3 normal, double shadowing, Color base, double reflection, double shininess);
/* noise.c */
NoiseGenerator* noiseCreateGenerator();
void noiseDeleteGenerator(NoiseGenerator* generator);
@ -120,6 +112,7 @@ void noiseAddLevel(NoiseGenerator* generator, NoiseLevel level);
void noiseAddLevelSimple(NoiseGenerator* generator, double scaling, double height);
void noiseAddLevels(NoiseGenerator* generator, int level_count, NoiseLevel start_level, double scaling_factor, double height_factor, int randomize_offset);
void noiseAddLevelsSimple(NoiseGenerator* generator, int level_count, double scaling, double height);
void noiseRemoveLevel(NoiseGenerator* generator, int level);
int noiseGetLevel(NoiseGenerator* generator, int level, NoiseLevel* params);
void noiseSetLevel(NoiseGenerator* generator, int level, NoiseLevel params);
void noiseSetLevelSimple(NoiseGenerator* generator, int level, double scaling, double height);

View file

@ -20,12 +20,14 @@ void terrainInit()
{
_definition = terrainCreateDefinition();
_max_height = noiseGetMaxValue(_definition.height_noise);
_environment.toggle_fog = 1;
}
void terrainSave(FILE* f)
{
int i;
noiseSave(_definition.height_noise, f);
toolsSaveInt(f, _definition.height_modifiers_count);
for (i = 0; i < _definition.height_modifiers_count; i++)
@ -37,7 +39,7 @@ void terrainSave(FILE* f)
void terrainLoad(FILE* f)
{
int i;
noiseLoad(_definition.height_noise, f);
_max_height = noiseGetMaxValue(_definition.height_noise);
@ -56,17 +58,17 @@ void terrainLoad(FILE* f)
TerrainDefinition terrainCreateDefinition()
{
TerrainDefinition definition;
definition.height_noise = noiseCreateGenerator();
definition.height_modifiers_count = 0;
return definition;
}
void terrainDeleteDefinition(TerrainDefinition definition)
{
int i;
noiseDeleteGenerator(definition.height_noise);
for (i = 0; i < definition.height_modifiers_count; i++)
{
@ -77,9 +79,9 @@ void terrainDeleteDefinition(TerrainDefinition definition)
void terrainCopyDefinition(TerrainDefinition source, TerrainDefinition* destination)
{
int i;
noiseCopy(source.height_noise, destination->height_noise);
for (i = 0; i < destination->height_modifiers_count; i++)
{
modifierDelete(destination->height_modifiers[i]);
@ -138,16 +140,16 @@ static inline double _getHeight(TerrainDefinition* definition, double x, double
{
Vector3 location;
int i;
location.x = x;
location.y = noiseGet2DDetail(definition->height_noise, x, z, detail);
location.z = z;
for (i = 0; i < definition->height_modifiers_count; i++)
{
location = modifierApply(definition->height_modifiers[i], location);
}
return location.y;
}
@ -214,13 +216,15 @@ double terrainGetShadow(Vector3 start, Vector3 direction)
}
}
static Color _getColor(TerrainDefinition* definition, Vector3 point, double precision)
static Color _getColor(TerrainDefinition* definition, TerrainEnvironment* environment, Vector3 point, double precision)
{
Color color;
/* FIXME Environment for textures should be customized */
color = texturesGetColor(point);
color = fogApplyToLocation(point, color);
if (environment->toggle_fog)
{
color = fogApplyToLocation(point, color);
}
//color = cloudsApplySegmentResult(color, camera_location, point);
return color;
@ -248,7 +252,7 @@ int terrainProjectRay(Vector3 start, Vector3 direction, Vector3* hit_point, Colo
{
start.y = height;
*hit_point = start;
*hit_color = _getColor(&_definition, start, inc_value);
*hit_color = _getColor(&_definition, &_environment, start, inc_value);
return 1;
}
@ -279,7 +283,7 @@ static int _postProcessFragment(RenderFragment* fragment)
point = _getPoint(&_definition, point.x, point.z, precision);
fragment->vertex.color = _getColor(&_definition, point, precision);
fragment->vertex.color = _getColor(&_definition, &_environment, point, precision);
return 1;
}
@ -324,7 +328,20 @@ double terrainGetHeightNormalized(double x, double z)
Color terrainGetColorCustom(double x, double z, double detail, TerrainDefinition* definition, TerrainQuality* quality, TerrainEnvironment* environment)
{
return _getColor(definition, _getPoint(definition, x, z, detail), detail);
if (!definition)
{
definition = &_definition;
}
if (!quality)
{
quality = &_quality;
}
if (!environment)
{
environment = &_environment;
}
return _getColor(definition, environment, _getPoint(definition, x, z, detail), detail);
}
Color terrainGetColor(double x, double z, double detail)
@ -351,7 +368,7 @@ void terrainRender(RenderProgressCallback callback)
{
return;
}
for (i = 0; i < chunk_count - 1; i++)
{
_renderQuad(cx - radius_ext + chunk_size * i, cz - radius_ext, chunk_size);

View file

@ -26,7 +26,7 @@ typedef struct
typedef struct
{
int unused;
int toggle_fog;
} TerrainEnvironment;
void terrainInit();

View file

@ -5,6 +5,7 @@
#include "water.h"
#include "terrain.h"
#include "lighting.h"
#include <math.h>
@ -80,6 +81,9 @@ WaterDefinition waterCreateDefinition()
result.main_color = COLOR_BLACK;
result.depth_color = COLOR_BLACK;
result.height = -1000.0;
result.reflection = 0.0;
result.transparency = 0.0;
result.transparency_depth = 0.0;
result.waves_noise = noiseCreateGenerator();
result.waves_noise_height = 0.02;
result.waves_noise_scale = 0.2;
@ -181,7 +185,8 @@ WaterResult waterGetColorCustom(Vector3 location, Vector3 look, WaterDefinition*
RayCastingResult refracted;
Vector3 normal;
Color color;
double shadowed, detail, depth;
ReceiverMaterial material;
double detail, depth;
if (definition == NULL)
{
@ -231,15 +236,10 @@ WaterResult waterGetColorCustom(Vector3 location, Vector3 look, WaterDefinition*
color.b = definition->main_color.b * (1.0 - definition->transparency) + result.reflected.b * definition->reflection + result.refracted.b * definition->transparency;
color.a = 1.0;
if (environment->toggle_shadows)
{
shadowed = terrainGetShadow(location, sun_direction_inv);
}
else
{
shadowed = 0.0;
}
color = lightingApply(location, normal, shadowed, color, 0.8, 0.6);
material.base = color;
material.reflection = 0.8;
material.shininess = 0.6;
color = lightingApplyCustom(location, normal, material, environment->lighting_definition, NULL, environment->lighting_environment);
if (environment->toggle_fog)
{
color = fogApplyToLocation(location, color);

View file

@ -2,6 +2,7 @@
#define _PAYSAGES_WATER_H_
#include "shared/types.h"
#include "lighting.h"
#include <stdio.h>
#ifdef __cplusplus
@ -32,7 +33,8 @@ typedef struct
RayCastingFunction reflection_function;
RayCastingFunction refraction_function;
int toggle_fog;
int toggle_shadows;
LightingDefinition* lighting_definition;
LightingEnvironment* lighting_environment;
} WaterEnvironment;
typedef struct