paysages : Terrain canvas - Height map painting (WIP).

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@389 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-07-13 21:24:19 +00:00 committed by ThunderK
parent a52321fd45
commit 82181ed5b0
9 changed files with 118 additions and 5 deletions

View file

@ -48,8 +48,10 @@ QStringList BaseFormLayer::getLayers()
void BaseFormLayer::layerAddedEvent()
{
if (layersAddLayer(_layers_modified, NULL) >= 0)
int layer = layersAddLayer(_layers_modified, NULL);
if (layer >= 0)
{
layersSetName(_layers_modified, layer, tr("Unnamed").toUtf8().data());
BaseForm::layerAddedEvent();
}
}

View file

@ -1,10 +1,11 @@
#include "dialogheightmap.h"
#include "widgetheightmap.h"
#include <QBoxLayout>
#include <QGridLayout>
#include <QPushButton>
#include <QSlider>
#include <math.h>
#include "widgetheightmap.h"
/**************** Dialog form ****************/
DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap) : DialogWithPreview(parent)
@ -47,12 +48,17 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap) : Dialog
_3dview = new WidgetHeightMap(viewer, &_value_modified);
viewer_layout->addWidget(_3dview, 0, 0);
slider = new QSlider(Qt::Horizontal, viewer);
slider->setRange(0, 1000);
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(angleHChanged(int)));
viewer_layout->addWidget(slider, 1, 0);
slider = new QSlider(Qt::Vertical, viewer);
slider->setRange(-300, 700);
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(angleVChanged(int)));
viewer_layout->addWidget(slider, 0, 1);
// Panel layout
button = new QPushButton(tr("Reset to terrain height"), buttons);
connect(button, SIGNAL(clicked()), _3dview, SLOT(resetToTerrain()));
panel->layout()->addWidget(button);
// Buttons layout
@ -91,3 +97,13 @@ void DialogHeightMap::accept()
void DialogHeightMap::revert()
{
}
void DialogHeightMap::angleHChanged(int value)
{
_3dview->setHorizontalViewAngle(M_PI * ((double)value) / 500.0);
}
void DialogHeightMap::angleVChanged(int value)
{
_3dview->setVerticalViewAngle(M_PI_2 * ((double)value) / 1000.0);
}

View file

@ -16,6 +16,10 @@ public slots:
virtual void accept();
void revert();
private slots:
void angleHChanged(int value);
void angleVChanged(int value);
private:
HeightMap* _value_original;
HeightMap _value_modified;

View file

@ -4,6 +4,8 @@
#include <math.h>
#include <GL/glu.h>
#include "tools.h"
#include "../lib_paysages/terrain.h"
#include "../lib_paysages/scenery.h"
WidgetHeightMap::WidgetHeightMap(QWidget *parent, HeightMap* heightmap):
QGLWidget(parent)
@ -11,15 +13,55 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, HeightMap* heightmap):
setMinimumSize(500, 500);
setFocusPolicy(Qt::StrongFocus);
_heightmap = heightmap;
_average_frame_time = 0.0;
_last_mouse_x = 0;
_last_mouse_y = 0;
_angle_h = 0.0;
_angle_v = 0.3;
}
WidgetHeightMap::~WidgetHeightMap()
{
}
void WidgetHeightMap::setHorizontalViewAngle(double angle_h)
{
_angle_h = angle_h;
updateGL();
}
void WidgetHeightMap::setVerticalViewAngle(double angle_v)
{
_angle_v = angle_v;
updateGL();
}
void WidgetHeightMap::resetToTerrain()
{
TerrainDefinition terrain;
terrain = terrainCreateDefinition();
sceneryGetTerrain(&terrain);
// TODO Apply geoarea
int rx = _heightmap->resolution_x;
int rz = _heightmap->resolution_z;
for (int x = 0; x < rx; x++)
{
for (int z = 0; z < rz; z++)
{
_heightmap->data[z * rx + x] = terrainGetHeight(&terrain, 80.0 * (double)x / (double)(rx - 1) - 40.0, 80.0 * (double)z / (double)(rz - 1) - 40.0);
}
}
terrainDeleteDefinition(&terrain);
updateGL();
}
void WidgetHeightMap::keyPressEvent(QKeyEvent* event)
{
}
@ -65,7 +107,7 @@ void WidgetHeightMap::resizeGL(int w, int h)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(_current_camera.yfov * 180.0 / M_PI, _current_camera.xratio, _current_camera.znear, _current_camera.zfar);
gluPerspective(1.57 * 180.0 / M_PI, 1.0, 1.0, 1000.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
@ -75,17 +117,31 @@ void WidgetHeightMap::paintGL()
GLenum error_code;
QTime start_time;
double frame_time;
int rx, rz;
start_time = QTime::currentTime();
// Place camera
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(_current_camera.location.x, _current_camera.location.y, _current_camera.location.z, _current_camera.target.x, _current_camera.target.y, _current_camera.target.z, _current_camera.up.x, _current_camera.up.y, _current_camera.up.z);
gluLookAt(50.0 * cos(_angle_h) * cos(_angle_v), 50.0 * sin(_angle_v), -50.0 * sin(_angle_h) * cos(_angle_v), 0.0, 0.0, 0.0, -cos(_angle_h) * sin(_angle_v), cos(_angle_v), sin(_angle_h) * sin(_angle_v));
// Background
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_POINTS);
glColor3d(1.0, 0.0, 0.0);
rx = _heightmap->resolution_x;
rz = _heightmap->resolution_z;
for (int x = 0; x < rx; x++)
{
for (int z = 0; z < rz; z++)
{
glVertex3d(80.0 * (double)x / (double)(rx - 1) - 40.0, _heightmap->data[z * rx + x], 80.0 * (double)z / (double)(rz - 1) - 40.0);
}
}
glEnd();
// Time stats
frame_time = 0.001 * (double)start_time.msecsTo(QTime::currentTime());
_average_frame_time = _average_frame_time * 0.8 + frame_time * 0.2;

View file

@ -11,6 +11,12 @@ public:
WidgetHeightMap(QWidget* parent, HeightMap* heightmap);
~WidgetHeightMap();
void setHorizontalViewAngle(double angle_h);
void setVerticalViewAngle(double angle_v);
public slots:
void resetToTerrain();
protected:
void keyPressEvent(QKeyEvent* event);
void mousePressEvent(QMouseEvent* event);
@ -22,9 +28,15 @@ protected:
void paintGL();
private:
HeightMap* _heightmap;
double _average_frame_time;
int _last_mouse_x;
int _last_mouse_y;
double _angle_h;
double _angle_v;
};
#endif

View file

@ -54,3 +54,17 @@ void heightmapLoad(PackStream* stream, HeightMap* heightmap)
packReadDouble(stream, &heightmap->data[i]);
}
}
void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z)
{
int i;
heightmap->resolution_x = resolution_x;
heightmap->resolution_z = resolution_z;
heightmap->data = realloc(heightmap->data, sizeof(double) * heightmap->resolution_x * heightmap->resolution_z);
for (i = 0; i < heightmap->resolution_x * heightmap->resolution_z; i++)
{
heightmap->data[i] = 0.0;
}
}

View file

@ -24,6 +24,8 @@ void heightmapValidate(HeightMap* heightmap);
void heightmapSave(PackStream* stream, HeightMap* heightmap);
void heightmapLoad(PackStream* stream, HeightMap* heightmap);
void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z);
#ifdef __cplusplus
}
#endif

View file

@ -57,7 +57,12 @@ void layersCopy(Layers* source, Layers* destination)
{
int i;
assert(source->type == destination->type);
assert(source->type.callback_copy == destination->type.callback_copy);
assert(source->type.callback_create == destination->type.callback_create);
assert(source->type.callback_delete == destination->type.callback_delete);
assert(source->type.callback_load == destination->type.callback_load);
assert(source->type.callback_save == destination->type.callback_save);
assert(source->type.callback_validate == destination->type.callback_validate);
assert(source->max_count == destination->max_count);
/* TODO Optimize by reusing common layers */
@ -157,6 +162,7 @@ int layersAddLayer(Layers* layers, void* definition)
layers->count++;
layersSetName(layers, layers->count - 1, "unnamed");
return layers->count - 1;
}
else
{

View file

@ -14,6 +14,7 @@ TerrainCanvas* terrainCanvasCreate()
result->area.size_z = 1.0;
result->offset_z = 0.0;
result->height_map = heightmapCreate();
heightmapChangeResolution(&result->height_map, 256, 256);
result->height_factor = 1.0;
result->detail_noise = noiseCreateGenerator();
result->detail_height_factor = 0.1;