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:
parent
468b3628e5
commit
7f798cbf3d
10 changed files with 111 additions and 69 deletions
7
TODO
7
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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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'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'image %1 a été sauvegardée.</translation>
|
||||
</message>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in a new issue