paysages : WIP on several parts.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@515 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2013-02-03 21:18:32 +00:00 committed by ThunderK
parent 324a01dca1
commit 22ed375111
17 changed files with 150 additions and 45 deletions

5
TODO
View file

@ -12,9 +12,7 @@ Technology Preview 2 :
=> Restore water filtering
=> Restore cloud lighting
=> Restore and improve skydome lighting
- Apply Preetham's model usage
=> Convert to HDR rendering.
=> Apply model's aerial perspective.
- Hide Preetham's model.
- Find a proper model for night sky (maybe Shirley).
- Improve textures (current model is greatly incorrect).
=> Separate models (basic texture and covering texture).
@ -29,6 +27,7 @@ Technology Preview 2 :
Technlogy Preview 3 :
- Fully move layer management from BaseForm to BaseFormLayer.
- Start vegetation system.
- Add tone-mapping and exposure control to final image.
- Allow render saving in HDR compatible format.
- Add clouds to explorer with 3d textures.
- Add fresnel effect to specular lighting.

View file

@ -55,6 +55,8 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, TerrainDefinition* terrain) :
// Viewer layout (3d display + sliders)
_3dview = new WidgetHeightMap(viewer, _value_modified);
viewer_layout->addWidget(_3dview, 0, 0);
connect(_3dview, SIGNAL(heightmapChanged()), this, SLOT(heightmapChanged()));
slider = new QSlider(Qt::Horizontal, viewer);
slider->setRange(0, 1000);
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(angleHChanged(int)));
@ -65,6 +67,9 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, TerrainDefinition* terrain) :
viewer_layout->addWidget(slider, 0, 1);
// Panel layout
_info_memory = new QLabel(panel);
panel->layout()->addWidget(_info_memory);
/*button = new QPushButton(tr("Load from picture file"), panel);
connect(button, SIGNAL(clicked()), this, SLOT(loadFromFile()));
panel->layout()->addWidget(button);*/
@ -175,6 +180,11 @@ void DialogHeightMap::brushStrengthChanged(int value)
_3dview->setBrushStrength((double)value / 2000.0);
}
void DialogHeightMap::heightmapChanged()
{
_info_memory->setText(tr("Memory used: %1").arg(_3dview->getMemoryStats()));
}
/*void DialogHeightMap::loadFromFile()
{
QString filepath = QFileDialog::getOpenFileName(this, tr("Paysages 3D - Choose a picture to load"), QString(), tr("Images (*.jpg *.jpeg *.bmp *.png)"));

View file

@ -24,11 +24,13 @@ private slots:
void brushSizeChanged(int value);
void brushSmoothingChanged(int value);
void brushStrengthChanged(int value);
void heightmapChanged();
//void loadFromFile();
private:
TerrainDefinition* _value_original;
TerrainDefinition* _value_modified;
QLabel* _info_memory;
WidgetHeightMap* _3dview;
};

View file

@ -80,7 +80,7 @@ private:
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
}
static Vector3 _getCameraLocation(Renderer* renderer, Vector3 location)
static Vector3 _getCameraLocation(Renderer*, Vector3 location)
{
return v3Add(location, v3Scale(VECTOR_UP, 50.0));
}

View file

@ -76,5 +76,8 @@ void FormTerrain::configChangeEvent()
void FormTerrain::startPainting()
{
DialogHeightMap::editHeightMap(this, _definition);
if (DialogHeightMap::editHeightMap(this, _definition))
{
configChangeEvent();
}
}

View file

@ -17,6 +17,8 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, TerrainDefinition* terrain):
setCursor(Qt::CrossCursor);
startTimer(100);
_memory_stats = terrainGetMemoryStats(terrain);
_terrain = terrain;
_renderer = rendererCreate();
TerrainRendererClass.bind(_renderer, _terrain);
@ -98,6 +100,36 @@ void WidgetHeightMap::setBrushStrength(double strength)
updateGL();
}
QString WidgetHeightMap::getMemoryStats()
{
qint64 memused = _memory_stats;
if (memused >= 1024)
{
memused /= 1024;
if (memused >= 1024)
{
memused /= 1024;
if (memused >= 1024)
{
memused /= 1024;
return tr("%1 GB").arg(memused);
}
else
{
return tr("%1 MB").arg(memused);
}
}
else
{
return tr("%1 kB").arg(memused);
}
}
else
{
return tr("%1 B").arg(memused);
}
}
void WidgetHeightMap::revert()
{
_dirty = true;
@ -121,6 +153,7 @@ void WidgetHeightMap::mousePressEvent(QMouseEvent* event)
void WidgetHeightMap::mouseReleaseEvent(QMouseEvent*)
{
_last_brush_action = 0;
terrainEndBrushStroke(_terrain->height_map);
}
void WidgetHeightMap::mouseMoveEvent(QMouseEvent* event)
@ -244,6 +277,7 @@ void WidgetHeightMap::paintGL()
if (_dirty)
{
updateVertexInfo();
emit heightmapChanged();
_dirty = false;
}
@ -359,6 +393,8 @@ void WidgetHeightMap::updateVertexInfo()
_vertices = new _VertexInfo[rx * rz];
delete[] old_vertices;
_memory_stats = terrainGetMemoryStats(_terrain);
// Update positions
for (int x = 0; x < rx; x++)
{

View file

@ -33,9 +33,14 @@ public:
void setBrushSmoothing(double smoothing);
void setBrushStrength(double smoothing);
QString getMemoryStats();
public slots:
void revert();
signals:
void heightmapChanged();
protected:
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
@ -56,6 +61,7 @@ private:
_VertexInfo* _vertices;
bool _dirty;
qint64 _memory_stats;
double _average_frame_time;

View file

@ -26,7 +26,7 @@ static const double exposure = 0.4;
static const double ISun = 100.0;
static const double AVERAGE_GROUND_REFLECTANCE = 0.1;
#if 1
#if 0
#define RES_MU 128
#define RES_MU_S 32
#define RES_R 32

View file

@ -144,33 +144,32 @@ static Color _getSkyColor(Renderer* renderer, Vector3 direction)
}
/* Get sun shape */
double sun_radius = definition->sun_radius * SUN_RADIUS_SCALED;
Vector3 hit1, hit2;
int hits = euclidRayIntersectSphere(camera_location, direction, sun_position, sun_radius, &hit1, &hit2);
if (hits > 1)
if (v3Dot(sun_direction, direction) >= 0)
{
double dist = v3Norm(v3Sub(hit2, hit1)) / sun_radius; /* distance between intersection points (relative to radius) */
sun_color = definition->sun_color;
sun_color.r *= 100.0;
sun_color.g *= 100.0;
sun_color.b *= 100.0;
if (dist > 0.05)
double sun_radius = definition->sun_radius * SUN_RADIUS_SCALED * 5.0; /* FIXME Why should we multiply by 5 ? */
Vector3 hit1, hit2;
int hits = euclidRayIntersectSphere(camera_location, direction, sun_position, sun_radius, &hit1, &hit2);
if (hits > 1)
{
return sun_color;
}
else
{
sun_color.a = 1.0 - dist / 0.05;
colorMask(&sky_color, &sun_color);
return sky_color;
double dist = v3Norm(v3Sub(hit2, hit1)) / sun_radius; /* distance between intersection points (relative to radius) */
sun_color = definition->sun_color;
sun_color.r *= 100.0;
sun_color.g *= 100.0;
sun_color.b *= 100.0;
if (dist > 0.05)
{
return sun_color;
}
else
{
sun_color.a = 1.0 - dist / 0.05;
colorMask(&sky_color, &sun_color);
}
}
}
else
{
return sky_color;
}
return sky_color;
}
static Vector3 _getSunDirection(Renderer* renderer)

View file

@ -36,7 +36,7 @@ Color cloudsGetPreviewCoverage(Renderer* renderer, double x, double y, double sc
eye.y = scaling;
eye.z = -10.0 * scaling;
look.x = x * 0.01 / scaling;
look.y = -y * 0.01 / scaling - 0.3;
look.y = -(y * 0.01 - 0.3) / scaling;
look.z = 1.0;
look = v3Normalize(look);

View file

@ -289,6 +289,8 @@ Color cloudsApplyLayer(CloudsLayerDefinition* definition, Color base, Renderer*
col.a = inside_length / definition->transparencydepth;
}
col = renderer->atmosphere->applyAerialPerspective(renderer, start, col);
colorMask(&base, &col);
return base;

View file

@ -89,7 +89,7 @@ static Color _applyTextures(Renderer* renderer, Vector3 location, double precisi
return COLOR_TRANSPARENT;
}
Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial* material)
static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial* material)
{
LightStatus* light = lightingCreateStatus(renderer->lighting, location, renderer->getCameraLocation(renderer, location));
renderer->atmosphere->getLightingStatus(renderer, light, normal, 0);
@ -98,6 +98,13 @@ Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 norm
return result;
}
static Color _applyMediumTraversal(Renderer* renderer, Vector3 location, Color color)
{
color = renderer->atmosphere->applyAerialPerspective(renderer, location, color);
color = renderer->clouds->getColor(renderer, color, renderer->getCameraLocation(renderer, location), location);
return color;
}
Renderer* rendererCreate()
{
Renderer* result = malloc(sizeof(Renderer));
@ -128,6 +135,7 @@ Renderer* rendererCreate()
result->applyTextures = _applyTextures;
result->applyLightingToSurface = _applyLightingToSurface;
result->applyMediumTraversal = _applyMediumTraversal;
result->lighting = lightingManagerCreate();

View file

@ -35,6 +35,7 @@ struct Renderer
/* Shortcuts */
Color (*applyLightingToSurface)(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial* material);
Color (*applyMediumTraversal)(Renderer* renderer, Vector3 location, Color color);
/* Scenery related */
RayCastingResult (*rayWalking)(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds);

View file

@ -121,10 +121,7 @@ static Color _getFinalColor(Renderer* renderer, Vector3 location, double precisi
Color color;
color = renderer->applyTextures(renderer, location, precision);
/* TODO Factorize this in scenery renderer */
color = renderer->atmosphere->applyAerialPerspective(renderer, location, color);
color = renderer->clouds->getColor(renderer, color, renderer->getCameraLocation(renderer, location), location);
color = renderer->applyMediumTraversal(renderer, location, color);
return color;
}

View file

@ -74,14 +74,16 @@ void terrainHeightmapCopy(TerrainHeightMap* source, TerrainHeightMap* destinatio
for (i = 0; i < destination->fixed_count; i++)
{
TerrainHeightMapChunk* chunk = destination->fixed_data + i;
TerrainHeightMapChunk* chunk_source = source->fixed_data + i;
TerrainHeightMapChunk* chunk_destination = destination->fixed_data + i;
size_t mapsize = sizeof(double) * chunk_source->rect.xsize * chunk_source->rect.zsize;
chunk->rect = chunk->rect;
if (chunk->rect.xsize * chunk->rect.zsize > 0)
chunk_destination->rect = chunk_source->rect;
if (chunk_source->rect.xsize * chunk_source->rect.zsize > 0)
{
chunk->data = realloc(chunk->data, sizeof(double) * chunk->rect.xsize * chunk->rect.zsize);
chunk_destination->data = realloc(chunk_destination->data, mapsize);
memcpy(chunk_destination->data, chunk_source->data, mapsize);
}
memcpy(chunk->data, chunk->data, sizeof(double) * chunk->rect.xsize * chunk->rect.zsize);
}
destination->floating_used = 0;
@ -219,9 +221,9 @@ static void _prepareBrushStroke(TerrainHeightMap* heightmap, TerrainBrush* brush
heightmap->floating_data.rect.zsize += gz1 + gz2;
_resetRect(heightmap, 0, new_width - 1, 0, gz1 - 1);
_resetRect(heightmap, 0, new_width - 1, new_height - gz2 + 1, new_height - 1);
_resetRect(heightmap, 0, gx1 - 1, gz1, new_height - gz2);
_resetRect(heightmap, new_width - gx2 + 1, new_width - 1, gz1, new_height - gz2);
_resetRect(heightmap, 0, new_width - 1, new_height - gz2, new_height - 1);
_resetRect(heightmap, 0, gx1 - 1, gz1, new_height - 1 - gz2);
_resetRect(heightmap, new_width - gx2, new_width - 1, gz1, new_height - 1 - gz2);
}
}
else
@ -244,6 +246,24 @@ static void _prepareBrushStroke(TerrainHeightMap* heightmap, TerrainBrush* brush
}
}
size_t terrainGetMemoryStats(TerrainDefinition* definition)
{
TerrainHeightMap* heightmap = definition->height_map;
size_t result = 0;
int i;
if (heightmap->floating_used)
{
result += sizeof(double) * heightmap->floating_data.rect.xsize * heightmap->floating_data.rect.zsize;
}
for (i = 0; i < heightmap->fixed_count; i++)
{
result += sizeof(double) * heightmap->fixed_data[i].rect.xsize * heightmap->fixed_data[i].rect.zsize;
}
return result;
}
void terrainBrushElevation(TerrainHeightMap* heightmap, TerrainBrush* brush, double value)
{
_prepareBrushStroke(heightmap, brush);
@ -263,6 +283,25 @@ void terrainBrushReset(TerrainHeightMap* heightmap, TerrainBrush* brush, double
{
}
void terrainEndBrushStroke(TerrainHeightMap* heightmap)
{
/* Commit floating data to fixed */
if (heightmap->floating_used)
{
/* TODO Find overlapping data and merge with them */
size_t mapsize = sizeof(double) * heightmap->floating_data.rect.xsize * heightmap->floating_data.rect.zsize;
heightmap->fixed_data = realloc(heightmap->fixed_data, sizeof(TerrainHeightMapChunk) * (heightmap->fixed_count + 1));
heightmap->fixed_data[heightmap->fixed_count].rect = heightmap->floating_data.rect;
heightmap->fixed_data[heightmap->fixed_count].data = malloc(mapsize);
memcpy(heightmap->fixed_data[heightmap->fixed_count].data, heightmap->floating_data.data, mapsize);
heightmap->fixed_count++;
heightmap->floating_used = 0;
heightmap->floating_data.data = realloc(heightmap->floating_data.data, sizeof(double));
}
}
#if 0
static void _loadFromFilePixel(HeightMap* heightmap, int x, int y, Color col)
{

View file

@ -1,6 +1,7 @@
#ifndef _PAYSAGES_TERRAIN_PUBLIC_H_
#define _PAYSAGES_TERRAIN_PUBLIC_H_
#include <stdlib.h>
#include "../shared/types.h"
#include "../tools/color.h"
#include "../tools/euclid.h"
@ -51,6 +52,7 @@ extern StandardRenderer TerrainRendererClass;
void terrainAutoPreset(TerrainDefinition* definition, TerrainPreset preset);
void terrainRenderSurface(Renderer* renderer);
double terrainGetGridHeight(TerrainDefinition* definition, int x, int z, int with_painting);
size_t terrainGetMemoryStats(TerrainDefinition* definition);
Renderer* terrainCreatePreviewRenderer();
Color terrainGetPreviewColor(Renderer* renderer, double x, double z, double detail);
@ -64,10 +66,12 @@ typedef struct
double total_radius;
} TerrainBrush;
/* Heightmap manipulation */
void terrainBrushElevation(TerrainHeightMap* heightmap, TerrainBrush* brush, double value);
void terrainBrushSmooth(TerrainHeightMap* heightmap, TerrainBrush* brush, double value);
void terrainBrushAddNoise(TerrainHeightMap* heightmap, TerrainBrush* brush, NoiseGenerator* generator, double value);
void terrainBrushReset(TerrainHeightMap* heightmap, TerrainBrush* brush, double value);
void terrainEndBrushStroke(TerrainHeightMap* heightmap);
#ifdef __cplusplus
}

View file

@ -355,8 +355,7 @@ WaterResult waterGetColorDetail(WaterDefinition* definition, Renderer* renderer,
_applyFoam(definition, location, normal, detail, &material);
color = renderer->applyLightingToSurface(renderer, location, normal, &material);
color = renderer->atmosphere->applyAerialPerspective(renderer, location, color);
color = renderer->clouds->getColor(renderer, color, renderer->getCameraLocation(renderer, location), location);
color = renderer->applyMediumTraversal(renderer, location, color);
result.base = definition->material.base;
result.final = color;