paysages : Improved render file saving.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@319 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-05-06 10:13:34 +00:00 committed by ThunderK
parent 468b3628e5
commit 7f798cbf3d
10 changed files with 111 additions and 69 deletions

7
TODO
View file

@ -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.

View file

@ -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();

View file

@ -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));
}
}
}
}

View file

@ -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:

View file

@ -407,6 +407,11 @@ Maintenir Ctrl : Plus rapide</translation>
<source>Images (*.png *.jpg)</source>
<translation>Images (*.png *.jpg)</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="210"/>
<source>Can&apos;t write to file : %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Images (*.png, *.jpg)</source>
<translation type="obsolete">Images (*.png *.jpg)</translation>
@ -416,7 +421,7 @@ Maintenir Ctrl : Plus rapide</translation>
<translation type="obsolete">Choisissez un nom de fichier pour le rendu</translation>
</message>
<message>
<location filename="../gui_qt/formrender.cpp" line="205"/>
<location filename="../gui_qt/formrender.cpp" line="206"/>
<source>The picture %1 has been saved.</source>
<translation>L&apos;image %1 a é sauvegardée.</translation>
</message>

View file

@ -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);
}

View file

@ -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

View file

@ -1,6 +1,7 @@
#include "render.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#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)

View file

@ -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);

View file

@ -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];