paysages: Made multi-light working.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@236 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
1e922ccbce
commit
a2307c4746
14 changed files with 117 additions and 47 deletions
2
TODO
2
TODO
|
@ -1,5 +1,3 @@
|
|||
- Refactor fog in a new 'atmosphere' module.
|
||||
- Make multi-lights work, to restore lighting from skydome.
|
||||
- In GUI, revertConfig should lock the previews while reverting.
|
||||
- All Save and Load methods should have same signature : void ...Save(FILE*, ...*)
|
||||
- All noises should use the same entropy pool (saved separately), and avoid reallocs.
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <QPainter>
|
||||
|
||||
#include "../lib_paysages/render.h"
|
||||
#include "../lib_paysages/renderer.h"
|
||||
#include "../lib_paysages/scenery.h"
|
||||
#include "../lib_paysages/auto.h"
|
||||
#include "../lib_paysages/shared/functions.h"
|
||||
|
@ -97,10 +96,22 @@ DialogRender::DialogRender(QWidget *parent):
|
|||
progress_value = 0;
|
||||
}
|
||||
|
||||
DialogRender::~DialogRender()
|
||||
{
|
||||
if (render_thread)
|
||||
{
|
||||
renderInterrupt();
|
||||
render_thread->wait();
|
||||
|
||||
renderSetPreviewCallbacks(NULL, NULL, NULL, NULL);
|
||||
|
||||
delete render_thread;
|
||||
}
|
||||
delete pixbuf;
|
||||
}
|
||||
|
||||
void DialogRender::startRender(int quality, int width, int height)
|
||||
{
|
||||
Renderer renderer;
|
||||
|
||||
renderer = sceneryGetStandardRenderer(quality);
|
||||
renderSetSize(width, height);
|
||||
renderSetPreviewCallbacks(_renderResize, _renderClear, _renderDraw, _renderUpdate);
|
||||
|
@ -118,17 +129,3 @@ void DialogRender::loadLastRender()
|
|||
|
||||
exec();
|
||||
}
|
||||
|
||||
DialogRender::~DialogRender()
|
||||
{
|
||||
if (render_thread)
|
||||
{
|
||||
renderInterrupt();
|
||||
render_thread->wait();
|
||||
|
||||
renderSetPreviewCallbacks(NULL, NULL, NULL, NULL);
|
||||
|
||||
delete render_thread;
|
||||
}
|
||||
delete pixbuf;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <QThread>
|
||||
#include <QProgressBar>
|
||||
#include <QScrollArea>
|
||||
#include "../lib_paysages/renderer.h"
|
||||
|
||||
class DialogRender : public QDialog
|
||||
{
|
||||
|
@ -12,10 +13,10 @@ class DialogRender : public QDialog
|
|||
public:
|
||||
explicit DialogRender(QWidget *parent);
|
||||
~DialogRender();
|
||||
|
||||
|
||||
void startRender(int quality, int width, int height);
|
||||
void loadLastRender();
|
||||
|
||||
|
||||
QImage* pixbuf;
|
||||
QWidget* area;
|
||||
QScrollArea* scroll;
|
||||
|
@ -24,6 +25,7 @@ public:
|
|||
|
||||
private:
|
||||
QThread* render_thread;
|
||||
Renderer renderer;
|
||||
};
|
||||
|
||||
#endif // _PAYSAGES_QT_DIALOGRENDER_H_
|
||||
|
|
|
@ -117,7 +117,7 @@ void Preview::resizeEvent(QResizeEvent* event)
|
|||
this->pixbuf = new QImage(this->size(), QImage::Format_ARGB32);
|
||||
|
||||
this->pixbuf->fill(0x00000000);
|
||||
this->need_rerender = false;
|
||||
this->need_rerender = true;
|
||||
this->need_render = true;
|
||||
|
||||
delete image;
|
||||
|
|
|
@ -85,8 +85,10 @@ void autoGenRealisticLandscape(int seed)
|
|||
cloud->ymin = 10.0;
|
||||
cloud->ycenter = 40.0;
|
||||
cloud->ymax = 100.0;
|
||||
cloud->color = COLOR_WHITE;
|
||||
cloud->color.a = 0.1;
|
||||
cloud->color.r = 0.7;
|
||||
cloud->color.g = 0.7;
|
||||
cloud->color.b = 0.7;
|
||||
cloud->color.a = 0.05;
|
||||
cloud->scaling = 50.0;
|
||||
cloud->coverage = 0.5;
|
||||
noiseGenerateBaseNoise(cloud->noise, 262144);
|
||||
|
|
|
@ -19,10 +19,13 @@ static LightDefinition _LIGHT_NULL;
|
|||
|
||||
void lightingInit()
|
||||
{
|
||||
_LIGHT_NULL.color = COLOR_BLACK;
|
||||
_LIGHT_NULL.direction.x = 0.0;
|
||||
_LIGHT_NULL.direction.y = 1.0;
|
||||
_LIGHT_NULL.direction.z = 0.0;
|
||||
_LIGHT_NULL.color = COLOR_BLACK;
|
||||
_LIGHT_NULL.filtered = 0;
|
||||
_LIGHT_NULL.masked = 0;
|
||||
_LIGHT_NULL.amplitude = 0.0;
|
||||
}
|
||||
|
||||
void lightingSave(FILE* f, LightingDefinition* definition)
|
||||
|
@ -33,9 +36,11 @@ void lightingSave(FILE* f, LightingDefinition* definition)
|
|||
toolsSaveInt(f, definition->nblights);
|
||||
for (i = 0; i < definition->nblights; i++)
|
||||
{
|
||||
colorSave(definition->lights[i].color, f);
|
||||
v3Save(definition->lights[i].direction, f);
|
||||
toolsSaveDouble(f, definition->lights[i].maxshadow);
|
||||
colorSave(definition->lights[i].color, f);
|
||||
toolsSaveInt(f, definition->lights[i].filtered);
|
||||
toolsSaveInt(f, definition->lights[i].masked);
|
||||
toolsSaveDouble(f, definition->lights[i].amplitude);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,9 +52,11 @@ void lightingLoad(FILE* f, LightingDefinition* definition)
|
|||
definition->nblights = toolsLoadInt(f);
|
||||
for (i = 0; i < definition->nblights; i++)
|
||||
{
|
||||
definition->lights[i].color = colorLoad(f);
|
||||
definition->lights[i].direction = v3Load(f);
|
||||
definition->lights[i].maxshadow = toolsLoadDouble(f);
|
||||
definition->lights[i].color = colorLoad(f);
|
||||
definition->lights[i].filtered = toolsLoadInt(f);
|
||||
definition->lights[i].masked = toolsLoadInt(f);
|
||||
definition->lights[i].amplitude = toolsLoadDouble(f);
|
||||
}
|
||||
|
||||
lightingValidateDefinition(definition);
|
||||
|
@ -143,7 +150,14 @@ static Color _applyLightCustom(LightDefinition* definition, Renderer* renderer,
|
|||
light = definition->color;
|
||||
|
||||
direction_inv = v3Scale(definition->direction, -1.0);
|
||||
light = renderer->filterLight(renderer, light, location, v3Add(location, v3Scale(direction_inv, 1000.0)), direction_inv);
|
||||
if (definition->masked)
|
||||
{
|
||||
light = renderer->maskLight(renderer, light, location, v3Add(location, v3Scale(direction_inv, 1000.0)), direction_inv);
|
||||
}
|
||||
if (definition->filtered)
|
||||
{
|
||||
light = renderer->filterLight(renderer, light, location, v3Add(location, v3Scale(direction_inv, 1000.0)), direction_inv);
|
||||
}
|
||||
|
||||
normal_norm = v3Norm(normal);
|
||||
if (normal_norm > 1.0)
|
||||
|
@ -156,13 +170,21 @@ static Color _applyLightCustom(LightDefinition* definition, Renderer* renderer,
|
|||
reflect = v3Sub(v3Scale(normal, 2.0 * v3Dot(direction_inv, normal)), direction_inv);
|
||||
|
||||
diffuse = v3Dot(direction_inv, normal);
|
||||
//diffuse = pow(diffuse * 0.5 + 0.5, 2.0);
|
||||
diffuse = (diffuse * 0.5 + 0.5);
|
||||
diffuse = pow(diffuse * 0.5 + 0.5, 2.0);
|
||||
//diffuse = (diffuse * 0.5 + 0.5);
|
||||
if (diffuse > 0.0)
|
||||
{
|
||||
if (material.shininess > 0.0)
|
||||
{
|
||||
specular = pow(v3Dot(reflect, view) * material.reflection, material.shininess * 10.0 + 1.0);
|
||||
specular = v3Dot(reflect, view) * material.reflection;
|
||||
if (specular > 0.0)
|
||||
{
|
||||
specular = pow(specular, material.shininess * 10.0 + 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
specular = 0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -188,18 +210,26 @@ static Color _applyLightCustom(LightDefinition* definition, Renderer* renderer,
|
|||
|
||||
Color lightingApplyToSurface(LightingDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
|
||||
{
|
||||
Color result;
|
||||
Color result, lighted;
|
||||
int i;
|
||||
|
||||
/* TODO Merge lights */
|
||||
result = material.base;
|
||||
result = COLOR_BLACK;
|
||||
result.a = material.base.a;
|
||||
|
||||
for (i = 0; i < definition->nblights; i++)
|
||||
{
|
||||
result = _applyLightCustom(definition->lights + i, renderer, location, normal, material);
|
||||
lighted = _applyLightCustom(definition->lights + i, renderer, location, normal, material);
|
||||
result.r += lighted.r;
|
||||
result.g += lighted.g;
|
||||
result.b += lighted.b;
|
||||
}
|
||||
for (i = 0; i < definition->_nbautolights; i++)
|
||||
{
|
||||
result = _applyLightCustom(definition->_autolights + i, renderer, location, normal, material);
|
||||
lighted = _applyLightCustom(definition->_autolights + i, renderer, location, normal, material);
|
||||
result.r += lighted.r;
|
||||
result.g += lighted.g;
|
||||
result.b += lighted.b;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -13,9 +13,11 @@ extern "C" {
|
|||
|
||||
typedef struct
|
||||
{
|
||||
Vector3 direction;
|
||||
Color color;
|
||||
double maxshadow;
|
||||
Vector3 direction; /* Global direction of the light */
|
||||
Color color; /* Main color of the light */
|
||||
int filtered; /* Should the light be filtered (by atmosphere, water...) */
|
||||
int masked; /* Should the light be masked (cast shadows..) */
|
||||
double amplitude; /* Angle amplitude of the light source (for multi-sampling, pi / 2.0 for skydome) */
|
||||
} LightDefinition;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -34,7 +34,7 @@ static volatile double _progress = 0.0;
|
|||
static volatile double _progress_step_start = 0.0;
|
||||
static volatile double _progress_step_length = 1.0;
|
||||
|
||||
#define RENDER_INVERSE 1
|
||||
/*#define RENDER_INVERSE 1*/
|
||||
#define RENDER_WIREFRAME 1
|
||||
|
||||
static void _previewResize(int width, int height) {}
|
||||
|
|
|
@ -9,6 +9,11 @@ static Color _filterLight(Renderer* renderer, Color light_color, Vector3 at_loca
|
|||
return light_color;
|
||||
}
|
||||
|
||||
static Color _maskLight(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light)
|
||||
{
|
||||
return light_color;
|
||||
}
|
||||
|
||||
static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
|
||||
{
|
||||
return material.base;
|
||||
|
@ -62,6 +67,7 @@ Renderer rendererGetFake()
|
|||
result.camera_location = VECTOR_ZERO;
|
||||
|
||||
result.filterLight = _filterLight;
|
||||
result.maskLight = _maskLight;
|
||||
result.applyLightingToSurface = _applyLightingToSurface;
|
||||
result.rayWalking = _rayWalking;
|
||||
result.getTerrainHeight = _getTerrainHeight;
|
||||
|
|
|
@ -29,6 +29,7 @@ struct Renderer
|
|||
|
||||
/* Lighting related */
|
||||
Color (*filterLight)(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light);
|
||||
Color (*maskLight)(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light);
|
||||
Color (*applyLightingToSurface)(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material);
|
||||
|
||||
/* Custom data */
|
||||
|
|
|
@ -210,9 +210,15 @@ void sceneryRenderSecondPass(Renderer* renderer)
|
|||
/******* Standard renderer *********/
|
||||
static Color _filterLight(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light)
|
||||
{
|
||||
light_color = waterLightFilter(&_water, renderer, light_color, at_location, light_location, direction_to_light);
|
||||
light_color = terrainLightFilter(&_terrain, renderer, light_color, at_location, light_location, direction_to_light);
|
||||
// TODO atmosphere filter
|
||||
light_color = waterLightFilter(&_water, renderer, light_color, at_location, light_location, direction_to_light);
|
||||
|
||||
return light_color;
|
||||
}
|
||||
|
||||
static Color _maskLight(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light)
|
||||
{
|
||||
light_color = terrainLightFilter(&_terrain, renderer, light_color, at_location, light_location, direction_to_light);
|
||||
light_color = cloudsFilterLight(&_clouds, renderer, light_color, at_location, light_location, direction_to_light);
|
||||
|
||||
return light_color;
|
||||
|
@ -294,6 +300,7 @@ Renderer sceneryGetStandardRenderer(int quality)
|
|||
result.render_quality = quality;
|
||||
|
||||
result.filterLight = _filterLight;
|
||||
result.maskLight = _maskLight;
|
||||
result.applyLightingToSurface = _applyLightingToSurface;
|
||||
result.rayWalking = _rayWalking;
|
||||
result.getTerrainHeight = _getTerrainHeight;
|
||||
|
|
|
@ -92,12 +92,32 @@ int skyGetLights(SkyDefinition* sky, LightDefinition* lights, int max_lights)
|
|||
sun_direction.y = sin(sun_angle);
|
||||
sun_direction.z = 0.0;
|
||||
|
||||
/* TODO Night lights */
|
||||
|
||||
if (max_lights > 0)
|
||||
{
|
||||
lights[0].color = colorGradationGet(&sky->sun_color, sky->daytime);
|
||||
/* Light from the sun */
|
||||
lights[0].direction = v3Scale(sun_direction, -1.0);
|
||||
lights[0].maxshadow = 1.0;
|
||||
lights[0].color = colorGradationGet(&sky->sun_color, sky->daytime);
|
||||
lights[0].filtered = 1;
|
||||
lights[0].masked = 1;
|
||||
lights[0].amplitude = 0.0;
|
||||
nblights = 1;
|
||||
if (max_lights > 1)
|
||||
{
|
||||
/* Skydome lighting */
|
||||
lights[1].direction.x = 0.0;
|
||||
lights[1].direction.y = -1.0;
|
||||
lights[1].direction.z = 0.0;
|
||||
lights[1].color = colorGradationGet(&sky->zenith_color, sky->daytime);
|
||||
lights[1].color.r *= 0.4;
|
||||
lights[1].color.g *= 0.4;
|
||||
lights[1].color.b *= 0.4;
|
||||
lights[1].filtered = 1;
|
||||
lights[1].masked = 0;
|
||||
lights[1].amplitude = M_PI / 2.0;
|
||||
nblights = 2;
|
||||
}
|
||||
}
|
||||
|
||||
return nblights;
|
||||
|
|
|
@ -171,6 +171,11 @@ Color terrainLightFilter(TerrainDefinition* definition, Renderer* renderer, Colo
|
|||
double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length;
|
||||
|
||||
direction_to_light = v3Normalize(direction_to_light);
|
||||
if (fabs(direction_to_light.x) < 0.0001 && fabs(direction_to_light.z) < 0.0001)
|
||||
{
|
||||
return light;
|
||||
}
|
||||
|
||||
inc_factor = (double)renderer->render_quality;
|
||||
inc_base = 1.0;
|
||||
inc_value = inc_base / inc_factor;
|
||||
|
|
|
@ -137,7 +137,7 @@ Color waterLightFilter(WaterDefinition* definition, Renderer* renderer, Color li
|
|||
{
|
||||
if (direction_to_light.y > 0.00001)
|
||||
{
|
||||
factor = (definition->height - location.y) / (direction_to_light.y * 5.0); // TODO Configurable
|
||||
factor = (definition->height - location.y) / (direction_to_light.y * 3.0); // TODO Configurable
|
||||
if (factor > 1.0)
|
||||
{
|
||||
factor = 1.0;
|
||||
|
|
Loading…
Reference in a new issue