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:
parent
324a01dca1
commit
22ed375111
17 changed files with 150 additions and 45 deletions
5
TODO
5
TODO
|
@ -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.
|
||||
|
|
|
@ -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)"));
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -76,5 +76,8 @@ void FormTerrain::configChangeEvent()
|
|||
|
||||
void FormTerrain::startPainting()
|
||||
{
|
||||
DialogHeightMap::editHeightMap(this, _definition);
|
||||
if (DialogHeightMap::editHeightMap(this, _definition))
|
||||
{
|
||||
configChangeEvent();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue