diff --git a/TODO b/TODO
index 1d60719..55a1aa5 100644
--- a/TODO
+++ b/TODO
@@ -1,10 +1,9 @@
Technology Preview 2 :
-- Replace zone ranges with curves.
-- Interface for textures thickness, slope_range and thickness_transparency.
+- Replace zone ranges with curves (with curve input and curve dialog).
+- Interface for textures thickness, slope_range and thickness_transparency (and correct slider ranges).
- Render tab previews should not rerender when changing render options.
- Compute shadows only once for all textures at a same location.
=> Add an intermediary light status (two pass lighting).
-- Don't change opacity when scrolling previews.
- Add layer sorting/naming.
- Save GUI config (views, render params).
- Add an OSD ability on previews and use it for camera location and user landmarks.
@@ -12,6 +11,7 @@ Technology Preview 2 :
- Add a zone editor dialog for localized textures.
- Add a terrain modifier dialog with zones.
- Add a noise filler (and maybe noise intervals ?).
+- Fix the sun appearance.
- Improve curve editor.
=> Add curve modes
=> Improve curve rendering
@@ -19,7 +19,6 @@ Technology Preview 2 :
- Water and terrain LOD moves with the camera, fix it like in the wanderer.
- Pause previews drawing of main window when a dialog is opened.
- Interrupt preview chunk renderings that will be discarded at commit, or that are no more visible.
-- Can't overwrite picture files (ILError).
- Fix "RGB parameters out of range" (and segfault) on preview while moving render params fast in render tab.
=> May need to change the updateData system.
=> Previews need to be paused while updating data.
diff --git a/gui_qt/basepreview.cpp b/gui_qt/basepreview.cpp
index 605519a..bb7420a 100644
--- a/gui_qt/basepreview.cpp
+++ b/gui_qt/basepreview.cpp
@@ -519,8 +519,8 @@ void BasePreview::mouseMoveEvent(QMouseEvent* event)
}
QImage part = pixbuf->copy(xstart, ystart, xsize, ysize);
- QPainter painter(pixbuf);
pixbuf->fill(0x00000000);
+ QPainter painter(pixbuf);
painter.drawImage(xstart + ndx, ystart + ndy, part);
updateChunks();
@@ -597,8 +597,8 @@ void BasePreview::wheelEvent(QWheelEvent* event)
new_width = (int) floor(((double) width) * scaling / old_scaling);
new_height = (int) floor(((double) height) * scaling / old_scaling);
QImage part = pixbuf->copy((width - new_width) / 2, (height - new_height) / 2, new_width, new_height).scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- QPainter painter(pixbuf);
pixbuf->fill(0x00000000);
+ QPainter painter(pixbuf);
painter.drawImage(0, 0, part);
invalidatePixbuf(254);
lock_drawing->unlock();
@@ -609,8 +609,8 @@ void BasePreview::wheelEvent(QWheelEvent* event)
{
lock_drawing->lock();
QImage part = pixbuf->scaled((int) floor(((double) width) * old_scaling / scaling), (int) floor(((double) height) * old_scaling / scaling), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- QPainter painter(pixbuf);
pixbuf->fill(0x00000000);
+ QPainter painter(pixbuf);
painter.drawImage((width - part.width()) / 2, (height - part.height()) / 2, part);
invalidatePixbuf(254);
lock_drawing->unlock();
diff --git a/gui_qt/formrender.cpp b/gui_qt/formrender.cpp
index 48e3247..5b1cd88 100644
--- a/gui_qt/formrender.cpp
+++ b/gui_qt/formrender.cpp
@@ -201,8 +201,14 @@ void FormRender::saveRender()
{
filepath = filepath.append(".png");
}
- renderSaveToFile(_renderer.render_area, (char*)filepath.toStdString().c_str());
- QMessageBox::information(this, "Message", QString(tr("The picture %1 has been saved.")).arg(filepath));
+ if (renderSaveToFile(_renderer.render_area, (char*)filepath.toStdString().c_str()))
+ {
+ QMessageBox::information(this, "Message", QString(tr("The picture %1 has been saved.")).arg(filepath));
+ }
+ else
+ {
+ QMessageBox::critical(this, "Message", QString(tr("Can't write to file : %1")).arg(filepath));
+ }
}
}
}
diff --git a/gui_qt/formtextures.cpp b/gui_qt/formtextures.cpp
index f700156..89cc5ad 100644
--- a/gui_qt/formtextures.cpp
+++ b/gui_qt/formtextures.cpp
@@ -97,7 +97,7 @@ public:
_zone = zoneCreate();
- configScaling(0.1, 10.0, 0.1, 1.0);
+ configScaling(0.01, 1.0, 0.01, 0.1);
configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0);
}
protected:
diff --git a/i18n/paysages_fr.ts b/i18n/paysages_fr.ts
index 6338424..d6bd209 100644
--- a/i18n/paysages_fr.ts
+++ b/i18n/paysages_fr.ts
@@ -407,6 +407,11 @@ Maintenir Ctrl : Plus rapide
Images (*.png *.jpg)
Images (*.png *.jpg)
+
+
+ Can't write to file : %1
+
+
Images (*.png, *.jpg)
Images (*.png *.jpg)
@@ -416,7 +421,7 @@ Maintenir Ctrl : Plus rapide
Choisissez un nom de fichier pour le rendu
-
+
The picture %1 has been saved.
L'image %1 a été sauvegardée.
diff --git a/lib_paysages/lighting.c b/lib_paysages/lighting.c
index 80b5337..f185010 100644
--- a/lib_paysages/lighting.c
+++ b/lib_paysages/lighting.c
@@ -149,17 +149,46 @@ void lightingDeleteLight(LightingDefinition* definition, int light)
}
}
-static Color _applyLightCustom(LightDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
+static int _getLightStatus(LightDefinition* definition, Renderer* renderer, Vector3 location, LightDefinition* result)
+{
+ Color light;
+ Vector3 direction_inv;
+
+ light = definition->color;
+ direction_inv = v3Scale(definition->direction, -1.0);
+ 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);
+ }
+
+ if (light.r > 0.0 || light.g > 0.0 || light.b > 0.0)
+ {
+ *result = *definition;
+ result->color = light;
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static Color _applyDirectLight(LightDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
{
Color result, light;
double diffuse, specular, normal_norm;
Vector3 view, reflect, direction_inv;
light = definition->color;
+ direction_inv = v3Scale(definition->direction, -1.0);
if (definition->amplitude > 0.0)
{
- // TODO Sampling around light direction
+ /* TODO Sampling around light direction */
int xsamples, ysamples, samples, x, y;
double xstep, ystep, factor;
LightDefinition sublight;
@@ -178,7 +207,7 @@ static Color _applyLightCustom(LightDefinition* definition, Renderer* renderer,
sublight.color.g *= factor;
sublight.color.b *= factor;
- result = _applyLightCustom(&sublight, renderer, location, normal, material);
+ result = _applyDirectLight(&sublight, renderer, location, normal, material);
for (x = 0; x < xsamples; x++)
{
for (y = 0; y < ysamples; y++)
@@ -186,7 +215,7 @@ static Color _applyLightCustom(LightDefinition* definition, Renderer* renderer,
sublight.direction.x = cos(x * xstep) * cos(y * ystep);
sublight.direction.y = -sin(y * ystep);
sublight.direction.z = sin(x * xstep) * cos(y * ystep);
- light = _applyLightCustom(&sublight, renderer, location, normal, material);
+ light = _applyDirectLight(&sublight, renderer, location, normal, material);
result.r += light.r;
result.g += light.g;
result.b += light.b;
@@ -195,16 +224,6 @@ static Color _applyLightCustom(LightDefinition* definition, Renderer* renderer,
return result;
}
- direction_inv = v3Scale(definition->direction, -1.0);
- 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)
{
@@ -213,7 +232,7 @@ static Color _applyLightCustom(LightDefinition* definition, Renderer* renderer,
normal = v3Normalize(normal);
diffuse = v3Dot(direction_inv, normal);
- //diffuse = pow(diffuse * 0.5 + 0.5, 2.0);
+ /*diffuse = pow(diffuse * 0.5 + 0.5, 2.0);*/
diffuse = diffuse * 0.5 + 0.5;
if (diffuse > 0.0)
{
@@ -255,28 +274,51 @@ static Color _applyLightCustom(LightDefinition* definition, Renderer* renderer,
return result;
}
-Color lightingApplyToSurface(LightingDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
+void lightingGetStatus(LightingDefinition* definition, Renderer* renderer, Vector3 location, LightStatus* result)
+{
+ int i;
+
+ result->nblights = 0;
+
+ for (i = 0; i < definition->nblights; i++)
+ {
+ if (_getLightStatus(definition->lights + i, renderer, location, result->lights + result->nblights))
+ {
+ result->nblights++;
+ }
+ }
+ for (i = 0; i < definition->_nbautolights; i++)
+ {
+ if (_getLightStatus(definition->_autolights + i, renderer, location, result->lights + result->nblights))
+ {
+ result->nblights++;
+ }
+ }
+}
+
+Color lightingApplyStatusToSurface(Renderer* renderer, LightStatus* status, Vector3 location, Vector3 normal, SurfaceMaterial material)
{
Color result, lighted;
int i;
result = COLOR_BLACK;
result.a = material.base.a;
-
- for (i = 0; i < definition->nblights; i++)
+
+ for (i = 0; i < status->nblights; i++)
{
- lighted = _applyLightCustom(definition->lights + i, renderer, location, normal, material);
+ lighted = _applyDirectLight(status->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++)
- {
- lighted = _applyLightCustom(definition->_autolights + i, renderer, location, normal, material);
- result.r += lighted.r;
- result.g += lighted.g;
- result.b += lighted.b;
- }
-
+
return result;
}
+
+Color lightingApplyToSurface(LightingDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
+{
+ LightStatus status;
+
+ lightingGetStatus(definition, renderer, location, &status);
+ return lightingApplyStatusToSurface(renderer, &status, location, normal, material);
+}
diff --git a/lib_paysages/lighting.h b/lib_paysages/lighting.h
index 310165c..a56e7b8 100644
--- a/lib_paysages/lighting.h
+++ b/lib_paysages/lighting.h
@@ -30,6 +30,12 @@ typedef struct
LightDefinition _autolights[LIGHTING_MAX_LIGHTS];
} LightingDefinition;
+typedef struct
+{
+ int nblights;
+ LightDefinition lights[LIGHTING_MAX_LIGHTS * 2];
+} LightStatus;
+
void lightingInit();
void lightingQuit();
void lightingSave(PackStream* stream, LightingDefinition* definition);
@@ -45,6 +51,8 @@ LightDefinition lightingGetLight(LightingDefinition* definition, int light);
int lightingAddLight(LightingDefinition* definition, LightDefinition light);
void lightingDeleteLight(LightingDefinition* definition, int light);
+void lightingGetStatus(LightingDefinition* definition, Renderer* renderer, Vector3 location, LightStatus* result);
+Color lightingApplyStatusToSurface(Renderer* renderer, LightStatus* status, Vector3 location, Vector3 normal, SurfaceMaterial material);
Color lightingApplyToSurface(LightingDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material);
#ifdef __cplusplus
diff --git a/lib_paysages/render.c b/lib_paysages/render.c
index 6cf535c..b9fbf3b 100644
--- a/lib_paysages/render.c
+++ b/lib_paysages/render.c
@@ -1,6 +1,7 @@
#include "render.h"
#include
+#include
#include
#include "IL/il.h"
#include "IL/ilu.h"
@@ -745,7 +746,7 @@ void renderPostProcess(RenderArea* area, Renderer* renderer, int nbchunks)
_processDirtyPixels(area);
}
-void renderSaveToFile(RenderArea* area, const char* path)
+int renderSaveToFile(RenderArea* area, const char* path)
{
ILuint image_id;
ilGenImages(1, &image_id);
@@ -756,6 +757,7 @@ void renderSaveToFile(RenderArea* area, const char* path)
ILuint data[area->height * area->width];
ILenum error;
Array* pixel_data;
+ int error_count;
for (y = 0; y < area->height; y++)
{
@@ -769,14 +771,18 @@ void renderSaveToFile(RenderArea* area, const char* path)
}
ilTexImage((ILuint)area->width, (ILuint)area->height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, data);
+ remove(path);
ilSaveImage(path);
ilDeleteImages(1, &image_id);
+ error_count = 0;
while ((error=ilGetError()) != IL_NO_ERROR)
{
fprintf(stderr, "IL ERROR : %s\n", iluErrorString(error));
+ error_count++;
}
+ return !error_count;
}
void renderSetPreviewCallbacks(RenderArea* area, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update)
diff --git a/lib_paysages/render.h b/lib_paysages/render.h
index 9a566b5..ea27706 100644
--- a/lib_paysages/render.h
+++ b/lib_paysages/render.h
@@ -25,7 +25,7 @@ void renderPushFragment(RenderArea* area, int x, int y, double z, Vertex* vertex
void renderPushTriangle(RenderArea* area, Vertex* v1, Vertex* v2, Vertex* v3, Vector3 p1, Vector3 p2, Vector3 p3);
void renderPostProcess(RenderArea* area, Renderer* renderer, int nbchunks);
-void renderSaveToFile(RenderArea* area, const char* path);
+int renderSaveToFile(RenderArea* area, const char* path);
void renderSetPreviewCallbacks(RenderArea* area, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update);
diff --git a/lib_paysages/textures.c b/lib_paysages/textures.c
index aabfdf4..effc7a6 100644
--- a/lib_paysages/textures.c
+++ b/lib_paysages/textures.c
@@ -216,35 +216,6 @@ void texturesDeleteLayer(TexturesDefinition* definition, int layer)
}
}
-Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail)
-{
- Color result;
- Vector3 normal;
- double coverage, noise;
-
- result = COLOR_TRANSPARENT;
- /*normal = _getPreNormal(definition, renderer, location, detail * 0.1);
-
- coverage = zoneGetValue(definition->zone, location, normal);
- if (coverage > 0.0)
- {
- if (coverage < 1.0)
- {
- noise = noiseGet2DTotal(definition->border_noise, location.x * 1000.0, location.z * 1000.0);
- coverage = -1.0 + 2.0 * coverage + noise * (1.0 - coverage);
- }
- if (coverage > 0.0)
- {
- normal = _getPostNormal(definition, renderer, location, normal, detail * 0.1);
- result = renderer->applyLightingToSurface(renderer, location, normal, definition->material);
- result.a = coverage < 0.1 ? coverage / 0.1 : 1.0;
- }
- }*/
- return result;
-}
-
-
-
static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west)
{
Vector3 dnorth, deast, dsouth, dwest, normal;
@@ -369,6 +340,11 @@ double texturesGetLayerCoverage(TextureLayerDefinition* definition, Renderer* re
return zoneGetValue(definition->zone, base.location, base.normal);
}
+Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail)
+{
+ return _getLayerResult(definition, renderer, location.x, location.z, detail).color;
+}
+
Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, double x, double z, double detail)
{
TextureResult results[TEXTURES_MAX_LAYERS + 1];