paysages : WIP on several parts.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@516 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
22ed375111
commit
47ebc90552
20 changed files with 273 additions and 94 deletions
|
@ -64,7 +64,7 @@ bool BaseExplorerChunk::maintain()
|
||||||
_texture_changed = true;
|
_texture_changed = true;
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
|
|
||||||
if (_texture_current_size < 8 && _texture_current_size < _texture_max_size)
|
if (_texture_current_size < 4 && _texture_current_size < _texture_max_size)
|
||||||
{
|
{
|
||||||
maintain();
|
maintain();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QPushButton>
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#include "../lib_paysages/scenery.h"
|
#include "../lib_paysages/scenery.h"
|
||||||
|
@ -26,7 +30,6 @@ static void _renderStart(int width, int height, Color background)
|
||||||
|
|
||||||
static void _renderDraw(int x, int y, Color col)
|
static void _renderDraw(int x, int y, Color col)
|
||||||
{
|
{
|
||||||
col = colorProfileApply(_current_dialog->_hdr_profile, col);
|
|
||||||
_current_dialog->pixbuf->setPixel(x, _current_dialog->pixbuf->height() - 1 - y, colorToQColor(col).rgb());
|
_current_dialog->pixbuf->setPixel(x, _current_dialog->pixbuf->height() - 1 - y, colorToQColor(col).rgb());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,8 +83,6 @@ DialogRender::DialogRender(QWidget *parent, Renderer* renderer):
|
||||||
_render_thread = NULL;
|
_render_thread = NULL;
|
||||||
_renderer = renderer;
|
_renderer = renderer;
|
||||||
|
|
||||||
_hdr_profile = colorProfileCreate();
|
|
||||||
|
|
||||||
setModal(true);
|
setModal(true);
|
||||||
setWindowTitle(tr("Paysages 3D - Render"));
|
setWindowTitle(tr("Paysages 3D - Render"));
|
||||||
setLayout(new QVBoxLayout());
|
setLayout(new QVBoxLayout());
|
||||||
|
@ -92,6 +93,7 @@ DialogRender::DialogRender(QWidget *parent, Renderer* renderer):
|
||||||
_scroll->setWidget(area);
|
_scroll->setWidget(area);
|
||||||
layout()->addWidget(_scroll);
|
layout()->addWidget(_scroll);
|
||||||
|
|
||||||
|
// Status bar
|
||||||
_info = new QWidget(this);
|
_info = new QWidget(this);
|
||||||
_info->setLayout(new QHBoxLayout());
|
_info->setLayout(new QHBoxLayout());
|
||||||
layout()->addWidget(_info);
|
layout()->addWidget(_info);
|
||||||
|
@ -106,8 +108,31 @@ DialogRender::DialogRender(QWidget *parent, Renderer* renderer):
|
||||||
_progress->setValue(0);
|
_progress->setValue(0);
|
||||||
_info->layout()->addWidget(_progress);
|
_info->layout()->addWidget(_progress);
|
||||||
|
|
||||||
|
// Action bar
|
||||||
|
_actions = new QWidget(this);
|
||||||
|
_actions->setLayout(new QHBoxLayout());
|
||||||
|
layout()->addWidget(_actions);
|
||||||
|
|
||||||
|
_actions->layout()->addWidget(new QLabel(tr("Tone-mapping: "), _actions));
|
||||||
|
_tonemapping_control = new QComboBox(_actions);
|
||||||
|
_tonemapping_control->addItems(QStringList(tr("Uncharted")) << tr("Reinhard"));
|
||||||
|
_actions->layout()->addWidget(_tonemapping_control);
|
||||||
|
|
||||||
|
_actions->layout()->addWidget(new QLabel(tr("Exposure: "), _actions));
|
||||||
|
_exposure_control = new QSlider(Qt::Horizontal, _actions);
|
||||||
|
_exposure_control->setRange(0, 1000);
|
||||||
|
_exposure_control->setValue(200);
|
||||||
|
_actions->layout()->addWidget(_exposure_control);
|
||||||
|
|
||||||
|
_save_button = new QPushButton(QIcon("images/save.png"), tr("Save picture"), _actions);
|
||||||
|
_actions->layout()->addWidget(_save_button);
|
||||||
|
|
||||||
|
// Connections
|
||||||
connect(this, SIGNAL(renderSizeChanged(int, int)), this, SLOT(applyRenderSize(int, int)));
|
connect(this, SIGNAL(renderSizeChanged(int, int)), this, SLOT(applyRenderSize(int, int)));
|
||||||
connect(this, SIGNAL(progressChanged(double)), this, SLOT(applyProgress(double)));
|
connect(this, SIGNAL(progressChanged(double)), this, SLOT(applyProgress(double)));
|
||||||
|
connect(_save_button, SIGNAL(clicked()), this, SLOT(saveRender()));
|
||||||
|
connect(_tonemapping_control, SIGNAL(currentIndexChanged(int)), this, SLOT(toneMappingChanged()));
|
||||||
|
connect(_exposure_control, SIGNAL(valueChanged(int)), this, SLOT(toneMappingChanged()));
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogRender::~DialogRender()
|
DialogRender::~DialogRender()
|
||||||
|
@ -119,7 +144,6 @@ DialogRender::~DialogRender()
|
||||||
|
|
||||||
delete _render_thread;
|
delete _render_thread;
|
||||||
}
|
}
|
||||||
colorProfileDelete(_hdr_profile);
|
|
||||||
delete pixbuf;
|
delete pixbuf;
|
||||||
delete pixbuf_lock;
|
delete pixbuf_lock;
|
||||||
}
|
}
|
||||||
|
@ -147,6 +171,33 @@ void DialogRender::startRender(RenderParams params)
|
||||||
exec();
|
exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogRender::saveRender()
|
||||||
|
{
|
||||||
|
QString filepath;
|
||||||
|
|
||||||
|
filepath = QFileDialog::getSaveFileName(this, tr("Paysages 3D - Choose a filename to save the last render"), QString(), tr("Images (*.png *.jpg)"));
|
||||||
|
if (!filepath.isNull())
|
||||||
|
{
|
||||||
|
if (!filepath.toLower().endsWith(".jpg") && !filepath.toLower().endsWith(".jpeg") && !filepath.toLower().endsWith(".png"))
|
||||||
|
{
|
||||||
|
filepath = filepath.append(".png");
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogRender::toneMappingChanged()
|
||||||
|
{
|
||||||
|
renderSetToneMapping(_renderer->render_area, (ToneMappingOperator)_tonemapping_control->currentIndex(), ((double)_exposure_control->value()) * 0.01);
|
||||||
|
}
|
||||||
|
|
||||||
void DialogRender::loadLastRender()
|
void DialogRender::loadLastRender()
|
||||||
{
|
{
|
||||||
//applyRenderSize(_renderer->render_width, _renderer->render_height);
|
//applyRenderSize(_renderer->render_width, _renderer->render_height);
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QProgressBar>
|
#include <QProgressBar>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
|
#include <QSlider>
|
||||||
|
#include <QComboBox>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include "../lib_paysages/renderer.h"
|
#include "../lib_paysages/renderer.h"
|
||||||
|
@ -26,11 +28,12 @@ public:
|
||||||
QImage* pixbuf;
|
QImage* pixbuf;
|
||||||
QMutex* pixbuf_lock;
|
QMutex* pixbuf_lock;
|
||||||
QWidget* area;
|
QWidget* area;
|
||||||
ColorProfile* _hdr_profile;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void applyRenderSize(int width, int height);
|
void applyRenderSize(int width, int height);
|
||||||
void applyProgress(double value);
|
void applyProgress(double value);
|
||||||
|
void saveRender();
|
||||||
|
void toneMappingChanged();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void renderSizeChanged(int width, int height);
|
void renderSizeChanged(int width, int height);
|
||||||
|
@ -39,6 +42,10 @@ signals:
|
||||||
private:
|
private:
|
||||||
QScrollArea* _scroll;
|
QScrollArea* _scroll;
|
||||||
QWidget* _info;
|
QWidget* _info;
|
||||||
|
QWidget* _actions;
|
||||||
|
QComboBox* _tonemapping_control;
|
||||||
|
QSlider* _exposure_control;
|
||||||
|
QPushButton* _save_button;
|
||||||
QThread* _render_thread;
|
QThread* _render_thread;
|
||||||
QLabel* _timer;
|
QLabel* _timer;
|
||||||
Renderer* _renderer;
|
Renderer* _renderer;
|
||||||
|
|
|
@ -8,15 +8,21 @@ ExplorerChunkSky::ExplorerChunkSky(Renderer* renderer, double size, SkyboxOrient
|
||||||
{
|
{
|
||||||
_box_size = size;
|
_box_size = size;
|
||||||
_orientation = orientation;
|
_orientation = orientation;
|
||||||
|
_center = VECTOR_ZERO;
|
||||||
|
|
||||||
setMaxTextureSize(256);
|
setMaxTextureSize(256);
|
||||||
maintain();
|
maintain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExplorerChunkSky::onCameraEvent(CameraDefinition* camera)
|
||||||
|
{
|
||||||
|
_center = camera->location;
|
||||||
|
}
|
||||||
|
|
||||||
void ExplorerChunkSky::onRenderEvent(QGLWidget*)
|
void ExplorerChunkSky::onRenderEvent(QGLWidget*)
|
||||||
{
|
{
|
||||||
double size = _box_size;
|
double size = _box_size;
|
||||||
Vector3 camera = renderer()->getCameraLocation(renderer(), VECTOR_ZERO);
|
Vector3 camera = _center;
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
switch(_orientation)
|
switch(_orientation)
|
||||||
|
@ -72,14 +78,14 @@ void ExplorerChunkSky::onRenderEvent(QGLWidget*)
|
||||||
glVertex3d(camera.x + size, camera.y + size, camera.z + size);
|
glVertex3d(camera.x + size, camera.y + size, camera.z + size);
|
||||||
break;
|
break;
|
||||||
case SKYBOX_BOTTOM:
|
case SKYBOX_BOTTOM:
|
||||||
glTexCoord2d(0.0, 0.0);
|
/*glTexCoord2d(0.0, 0.0);
|
||||||
glVertex3d(camera.x - size, camera.y - size, camera.z - size);
|
glVertex3d(camera.x - size, camera.y - size, camera.z - size);
|
||||||
glTexCoord2d(0.0, 1.0);
|
glTexCoord2d(0.0, 1.0);
|
||||||
glVertex3d(camera.x - size, camera.y - size, camera.z + size);
|
glVertex3d(camera.x - size, camera.y - size, camera.z + size);
|
||||||
glTexCoord2d(1.0, 1.0);
|
glTexCoord2d(1.0, 1.0);
|
||||||
glVertex3d(camera.x + size, camera.y - size, camera.z + size);
|
glVertex3d(camera.x + size, camera.y - size, camera.z + size);
|
||||||
glTexCoord2d(1.0, 0.0);
|
glTexCoord2d(1.0, 0.0);
|
||||||
glVertex3d(camera.x + size, camera.y - size, camera.z - size);
|
glVertex3d(camera.x + size, camera.y - size, camera.z - size);*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
|
@ -20,6 +20,7 @@ class ExplorerChunkSky:public BaseExplorerChunk
|
||||||
public:
|
public:
|
||||||
ExplorerChunkSky(Renderer* renderer, double size, SkyboxOrientation orientation);
|
ExplorerChunkSky(Renderer* renderer, double size, SkyboxOrientation orientation);
|
||||||
|
|
||||||
|
void onCameraEvent(CameraDefinition* camera);
|
||||||
void onRenderEvent(QGLWidget* widget);
|
void onRenderEvent(QGLWidget* widget);
|
||||||
double getDisplayedSizeHint(CameraDefinition* camera);
|
double getDisplayedSizeHint(CameraDefinition* camera);
|
||||||
Color getTextureColor(double x, double y);
|
Color getTextureColor(double x, double y);
|
||||||
|
@ -27,7 +28,7 @@ public:
|
||||||
private:
|
private:
|
||||||
SkyboxOrientation _orientation;
|
SkyboxOrientation _orientation;
|
||||||
double _box_size;
|
double _box_size;
|
||||||
|
Vector3 _center;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,13 +4,18 @@
|
||||||
#include "baseexplorerchunk.h"
|
#include "baseexplorerchunk.h"
|
||||||
#include "../lib_paysages/camera.h"
|
#include "../lib_paysages/camera.h"
|
||||||
|
|
||||||
ExplorerChunkTerrain::ExplorerChunkTerrain(Renderer* renderer, double x, double z, double size, int nbchunks) : BaseExplorerChunk(renderer)
|
ExplorerChunkTerrain::ExplorerChunkTerrain(Renderer* renderer, double x, double z, double size, int nbchunks, double water_height) : BaseExplorerChunk(renderer)
|
||||||
{
|
{
|
||||||
_startx = x;
|
_startx = x;
|
||||||
_startz = z;
|
_startz = z;
|
||||||
_size = size;
|
_size = size;
|
||||||
_overall_step = size * (double)nbchunks;
|
_overall_step = size * (double)nbchunks;
|
||||||
|
|
||||||
|
_distance_to_camera = 0.0;
|
||||||
|
|
||||||
|
_water_height = water_height;
|
||||||
|
_overwater = false;
|
||||||
|
|
||||||
_tessellation_max_size = 32;
|
_tessellation_max_size = 32;
|
||||||
_tessellation = new double[(_tessellation_max_size + 1) * (_tessellation_max_size + 1)];
|
_tessellation = new double[(_tessellation_max_size + 1) * (_tessellation_max_size + 1)];
|
||||||
_tessellation_current_size = 0;
|
_tessellation_current_size = 0;
|
||||||
|
@ -31,6 +36,7 @@ ExplorerChunkTerrain::~ExplorerChunkTerrain()
|
||||||
void ExplorerChunkTerrain::onResetEvent()
|
void ExplorerChunkTerrain::onResetEvent()
|
||||||
{
|
{
|
||||||
_tessellation_current_size = 0;
|
_tessellation_current_size = 0;
|
||||||
|
_overwater = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExplorerChunkTerrain::onMaintainEvent()
|
bool ExplorerChunkTerrain::onMaintainEvent()
|
||||||
|
@ -50,6 +56,10 @@ bool ExplorerChunkTerrain::onMaintainEvent()
|
||||||
if (_tessellation_current_size == 0 || i % old_tessellation_inc != 0 || j % old_tessellation_inc != 0)
|
if (_tessellation_current_size == 0 || i % old_tessellation_inc != 0 || j % old_tessellation_inc != 0)
|
||||||
{
|
{
|
||||||
double height = renderer->terrain->getHeight(renderer, _startx + _tessellation_step * (double)i, _startz + _tessellation_step * (double)j, 1);
|
double height = renderer->terrain->getHeight(renderer, _startx + _tessellation_step * (double)i, _startz + _tessellation_step * (double)j, 1);
|
||||||
|
if (height >= _water_height)
|
||||||
|
{
|
||||||
|
_overwater = true;
|
||||||
|
}
|
||||||
_tessellation[j * (_tessellation_max_size + 1) + i] = height;
|
_tessellation[j * (_tessellation_max_size + 1) + i] = height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +69,7 @@ bool ExplorerChunkTerrain::onMaintainEvent()
|
||||||
_tessellation_current_size = new_tessellation_size;
|
_tessellation_current_size = new_tessellation_size;
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
|
|
||||||
if (_tessellation_current_size < 8 && _tessellation_current_size < _tessellation_max_size)
|
if (_tessellation_current_size < 4 && _tessellation_current_size < _tessellation_max_size)
|
||||||
{
|
{
|
||||||
onMaintainEvent();
|
onMaintainEvent();
|
||||||
}
|
}
|
||||||
|
@ -96,6 +106,9 @@ void ExplorerChunkTerrain::onCameraEvent(CameraDefinition* camera)
|
||||||
_startz -= _overall_step;
|
_startz -= _overall_step;
|
||||||
askReset();
|
askReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_distance_to_camera = v3Norm(v3Sub(getCenter(), camera->location));
|
||||||
|
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +119,7 @@ void ExplorerChunkTerrain::onRenderEvent(QGLWidget*)
|
||||||
double tsize = 1.0 / (double)_tessellation_max_size;
|
double tsize = 1.0 / (double)_tessellation_max_size;
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
|
|
||||||
if (tessellation_size <= 1)
|
if (tessellation_size <= 1 or not _overwater)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -131,11 +144,16 @@ double ExplorerChunkTerrain::getDisplayedSizeHint(CameraDefinition* camera)
|
||||||
double distance;
|
double distance;
|
||||||
Vector3 center;
|
Vector3 center;
|
||||||
|
|
||||||
|
if (not _overwater)
|
||||||
|
{
|
||||||
|
return -1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
center = getCenter();
|
center = getCenter();
|
||||||
|
|
||||||
if (cameraIsBoxInView(camera, center, _size, 40.0, _size))
|
if (cameraIsBoxInView(camera, center, _size, 40.0, _size))
|
||||||
{
|
{
|
||||||
distance = v3Norm(v3Sub(camera->location, center));
|
distance = _distance_to_camera;
|
||||||
distance = distance < 0.1 ? 0.1 : distance;
|
distance = distance < 0.1 ? 0.1 : distance;
|
||||||
return (int)ceil(120.0 - distance / 1.5);
|
return (int)ceil(120.0 - distance / 1.5);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
class ExplorerChunkTerrain:public BaseExplorerChunk
|
class ExplorerChunkTerrain:public BaseExplorerChunk
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExplorerChunkTerrain(Renderer* renderer, double x, double z, double size, int nbchunks);
|
ExplorerChunkTerrain(Renderer* renderer, double x, double z, double size, int nbchunks, double water_height);
|
||||||
~ExplorerChunkTerrain();
|
~ExplorerChunkTerrain();
|
||||||
|
|
||||||
void onCameraEvent(CameraDefinition* camera);
|
void onCameraEvent(CameraDefinition* camera);
|
||||||
|
@ -26,6 +26,10 @@ private:
|
||||||
double _size;
|
double _size;
|
||||||
double _overall_step;
|
double _overall_step;
|
||||||
|
|
||||||
|
double _distance_to_camera;
|
||||||
|
double _water_height;
|
||||||
|
bool _overwater;
|
||||||
|
|
||||||
double* _tessellation;
|
double* _tessellation;
|
||||||
int _tessellation_max_size;
|
int _tessellation_max_size;
|
||||||
int _tessellation_current_size;
|
int _tessellation_current_size;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "formrender.h"
|
#include "formrender.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include "dialogrender.h"
|
#include "dialogrender.h"
|
||||||
#include "inputcamera.h"
|
#include "inputcamera.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
@ -120,8 +118,6 @@ FormRender::FormRender(QWidget *parent) :
|
||||||
connect(button, SIGNAL(clicked()), this, SLOT(startRender()));
|
connect(button, SIGNAL(clicked()), this, SLOT(startRender()));
|
||||||
button = addButton(tr("Show last render"));
|
button = addButton(tr("Show last render"));
|
||||||
connect(button, SIGNAL(clicked()), this, SLOT(showRender()));
|
connect(button, SIGNAL(clicked()), this, SLOT(showRender()));
|
||||||
button = addButton(tr("Save last render"));
|
|
||||||
connect(button, SIGNAL(clicked()), this, SLOT(saveRender()));
|
|
||||||
|
|
||||||
revertConfig();
|
revertConfig();
|
||||||
}
|
}
|
||||||
|
@ -215,28 +211,3 @@ void FormRender::showRender()
|
||||||
delete dialog;
|
delete dialog;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormRender::saveRender()
|
|
||||||
{
|
|
||||||
if (_renderer_inited)
|
|
||||||
{
|
|
||||||
QString filepath;
|
|
||||||
|
|
||||||
filepath = QFileDialog::getSaveFileName(this, tr("Paysages 3D - Choose a filename to save the last render"), QString(), tr("Images (*.png *.jpg)"));
|
|
||||||
if (!filepath.isNull())
|
|
||||||
{
|
|
||||||
if (!filepath.toLower().endsWith(".jpg") && !filepath.toLower().endsWith(".jpeg") && !filepath.toLower().endsWith(".png"))
|
|
||||||
{
|
|
||||||
filepath = filepath.append(".png");
|
|
||||||
}
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ protected slots:
|
||||||
private slots:
|
private slots:
|
||||||
void startRender();
|
void startRender();
|
||||||
void showRender();
|
void showRender();
|
||||||
void saveRender();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RenderParams _params;
|
RenderParams _params;
|
||||||
|
|
|
@ -238,7 +238,7 @@ FormWater::FormWater(QWidget *parent):
|
||||||
addPreview(previewCoverage, tr("Coverage preview"));
|
addPreview(previewCoverage, tr("Coverage preview"));
|
||||||
addPreview(previewColor, tr("Rendered preview"));
|
addPreview(previewColor, tr("Rendered preview"));
|
||||||
|
|
||||||
addInputDouble(tr("Height"), &_definition.height, -10.0, 10.0, 0.1, 1.0);
|
addInputDouble(tr("Height"), &_definition.height, -15.0, 15.0, 0.1, 1.0);
|
||||||
addInputMaterial(tr("Surface material"), &_definition.material);
|
addInputMaterial(tr("Surface material"), &_definition.material);
|
||||||
addInputColor(tr("Depth color"), &_definition.depth_color);
|
addInputColor(tr("Depth color"), &_definition.depth_color);
|
||||||
addInputDouble(tr("Transparency"), &_definition.transparency, 0.0, 1.0, 0.001, 0.1);
|
addInputDouble(tr("Transparency"), &_definition.transparency, 0.0, 1.0, 0.001, 0.1);
|
||||||
|
|
|
@ -53,6 +53,11 @@ static Color _applyTextures(Renderer* renderer, Vector3 location, double precisi
|
||||||
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Vector3 _getCameraLocation(Renderer* renderer, Vector3)
|
||||||
|
{
|
||||||
|
return ((CameraDefinition*)renderer->customData[2])->location;
|
||||||
|
}
|
||||||
|
|
||||||
WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
||||||
QGLWidget(parent)
|
QGLWidget(parent)
|
||||||
{
|
{
|
||||||
|
@ -70,8 +75,10 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
||||||
_renderer = sceneryCreateStandardRenderer();
|
_renderer = sceneryCreateStandardRenderer();
|
||||||
_renderer->render_quality = 3;
|
_renderer->render_quality = 3;
|
||||||
_renderer->customData[1] = &_textures;
|
_renderer->customData[1] = &_textures;
|
||||||
|
_renderer->customData[2] = _base_camera;
|
||||||
_renderer->customData[3] = &_water;
|
_renderer->customData[3] = &_water;
|
||||||
_renderer->applyTextures = _applyTextures;
|
_renderer->applyTextures = _applyTextures;
|
||||||
|
_renderer->getCameraLocation = _getCameraLocation;
|
||||||
|
|
||||||
_inited = false;
|
_inited = false;
|
||||||
_updated = false;
|
_updated = false;
|
||||||
|
@ -100,14 +107,15 @@ void WidgetExplorer::startRendering()
|
||||||
{
|
{
|
||||||
// Add terrain
|
// Add terrain
|
||||||
int chunks = 20;
|
int chunks = 20;
|
||||||
double size = 200.0;
|
double size = 400.0;
|
||||||
double chunksize = size / (double)chunks;
|
double chunksize = size / (double)chunks;
|
||||||
double start = -size / 2.0;
|
double start = -size / 2.0;
|
||||||
|
double water_height = _renderer->getWaterHeightInfo(_renderer).base_height;
|
||||||
for (int i = 0; i < chunks; i++)
|
for (int i = 0; i < chunks; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < chunks; j++)
|
for (int j = 0; j < chunks; j++)
|
||||||
{
|
{
|
||||||
ExplorerChunkTerrain* chunk = new ExplorerChunkTerrain(_renderer, start + chunksize * (double)i, start + chunksize * (double)j, chunksize, chunks);
|
ExplorerChunkTerrain* chunk = new ExplorerChunkTerrain(_renderer, start + chunksize * (double)i, start + chunksize * (double)j, chunksize, chunks, water_height);
|
||||||
_chunks.append(chunk);
|
_chunks.append(chunk);
|
||||||
_updateQueue.append(chunk);
|
_updateQueue.append(chunk);
|
||||||
}
|
}
|
||||||
|
@ -326,7 +334,6 @@ void WidgetExplorer::wheelEvent(QWheelEvent* event)
|
||||||
{
|
{
|
||||||
cameraStrafeForward(&_current_camera, (double)event->delta() * factor);
|
cameraStrafeForward(&_current_camera, (double)event->delta() * factor);
|
||||||
updateGL();
|
updateGL();
|
||||||
|
|
||||||
}
|
}
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
@ -396,6 +403,7 @@ void WidgetExplorer::paintGL()
|
||||||
QTime start_time;
|
QTime start_time;
|
||||||
double frame_time;
|
double frame_time;
|
||||||
|
|
||||||
|
cameraCopyDefinition(&_current_camera, &_renderer->render_camera);
|
||||||
cameraValidateDefinition(&_current_camera, 1);
|
cameraValidateDefinition(&_current_camera, 1);
|
||||||
|
|
||||||
start_time = QTime::currentTime();
|
start_time = QTime::currentTime();
|
||||||
|
|
|
@ -65,7 +65,8 @@ void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition)
|
||||||
noiseClearLevels(definition->_edge_noise);
|
noiseClearLevels(definition->_edge_noise);
|
||||||
noiseClearLevels(definition->_coverage_noise);
|
noiseClearLevels(definition->_coverage_noise);
|
||||||
|
|
||||||
noiseAddLevelsSimple(definition->_coverage_noise, 3, 1.0, 0.0, 1.0, 0.0);
|
noiseAddLevelsSimple(definition->_coverage_noise, 2, 10.0, 0.0, 1.0, 0.0);
|
||||||
|
noiseAddLevelsSimple(definition->_coverage_noise, 2, 1.0, 0.0, 1.0, 0.0);
|
||||||
noiseSetFunctionParams(definition->_coverage_noise, NOISE_FUNCTION_NAIVE, 0.0, 0.0);
|
noiseSetFunctionParams(definition->_coverage_noise, NOISE_FUNCTION_NAIVE, 0.0, 0.0);
|
||||||
switch (definition->type)
|
switch (definition->type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,6 +44,7 @@ typedef struct
|
||||||
|
|
||||||
struct RenderArea
|
struct RenderArea
|
||||||
{
|
{
|
||||||
|
ColorProfile* hdr_mapping;
|
||||||
RenderParams params;
|
RenderParams params;
|
||||||
int pixel_count;
|
int pixel_count;
|
||||||
RenderFragment* pixels;
|
RenderFragment* pixels;
|
||||||
|
@ -96,6 +97,7 @@ RenderArea* renderCreateArea()
|
||||||
RenderArea* result;
|
RenderArea* result;
|
||||||
|
|
||||||
result = malloc(sizeof(RenderArea));
|
result = malloc(sizeof(RenderArea));
|
||||||
|
result->hdr_mapping = colorProfileCreate();
|
||||||
result->params.width = 1;
|
result->params.width = 1;
|
||||||
result->params.height = 1;
|
result->params.height = 1;
|
||||||
result->params.antialias = 1;
|
result->params.antialias = 1;
|
||||||
|
@ -123,6 +125,7 @@ RenderArea* renderCreateArea()
|
||||||
|
|
||||||
void renderDeleteArea(RenderArea* area)
|
void renderDeleteArea(RenderArea* area)
|
||||||
{
|
{
|
||||||
|
colorProfileDelete(area->hdr_mapping);
|
||||||
mutexDestroy(area->lock);
|
mutexDestroy(area->lock);
|
||||||
free(area->pixels);
|
free(area->pixels);
|
||||||
free(area->scanline_up);
|
free(area->scanline_up);
|
||||||
|
@ -130,6 +133,14 @@ void renderDeleteArea(RenderArea* area)
|
||||||
free(area);
|
free(area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _setAllDirty(RenderArea* area)
|
||||||
|
{
|
||||||
|
area->dirty_left = 0;
|
||||||
|
area->dirty_right = area->params.width * area->params.antialias - 1;
|
||||||
|
area->dirty_down = 0;
|
||||||
|
area->dirty_up = area->params.height * area->params.antialias - 1;
|
||||||
|
}
|
||||||
|
|
||||||
void renderSetParams(RenderArea* area, RenderParams params)
|
void renderSetParams(RenderArea* area, RenderParams params)
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
|
@ -155,6 +166,13 @@ void renderSetParams(RenderArea* area, RenderParams params)
|
||||||
renderClear(area);
|
renderClear(area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderSetToneMapping(RenderArea* area, ToneMappingOperator tonemapper, double exposure)
|
||||||
|
{
|
||||||
|
colorProfileSetToneMapping(area->hdr_mapping, tonemapper, exposure);
|
||||||
|
_setAllDirty(area);
|
||||||
|
renderUpdate(area);
|
||||||
|
}
|
||||||
|
|
||||||
void renderSetBackgroundColor(RenderArea* area, Color* col)
|
void renderSetBackgroundColor(RenderArea* area, Color* col)
|
||||||
{
|
{
|
||||||
area->background_color = *col;
|
area->background_color = *col;
|
||||||
|
@ -264,6 +282,8 @@ static inline Color _getFinalPixel(RenderArea* area, int x, int y)
|
||||||
result.r += col.r / (double)(area->params.antialias * area->params.antialias);
|
result.r += col.r / (double)(area->params.antialias * area->params.antialias);
|
||||||
result.g += col.g / (double)(area->params.antialias * area->params.antialias);
|
result.g += col.g / (double)(area->params.antialias * area->params.antialias);
|
||||||
result.b += col.b / (double)(area->params.antialias * area->params.antialias);
|
result.b += col.b / (double)(area->params.antialias * area->params.antialias);
|
||||||
|
|
||||||
|
result = colorProfileApply(area->hdr_mapping, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,14 +324,6 @@ void renderUpdate(RenderArea* area)
|
||||||
mutexRelease(area->lock);
|
mutexRelease(area->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _setAllDirty(RenderArea* area)
|
|
||||||
{
|
|
||||||
area->dirty_left = 0;
|
|
||||||
area->dirty_right = area->params.width * area->params.antialias - 1;
|
|
||||||
area->dirty_down = 0;
|
|
||||||
area->dirty_up = area->params.height * area->params.antialias - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned int _pushCallback(RenderArea* area, FragmentCallback callback)
|
static inline unsigned int _pushCallback(RenderArea* area, FragmentCallback callback)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -32,6 +32,7 @@ RenderArea* renderCreateArea();
|
||||||
void renderDeleteArea(RenderArea* area);
|
void renderDeleteArea(RenderArea* area);
|
||||||
|
|
||||||
void renderSetParams(RenderArea* area, RenderParams params);
|
void renderSetParams(RenderArea* area, RenderParams params);
|
||||||
|
void renderSetToneMapping(RenderArea* area, ToneMappingOperator tonemapper, double exposure);
|
||||||
void renderSetBackgroundColor(RenderArea* area, Color* col);
|
void renderSetBackgroundColor(RenderArea* area, Color* col);
|
||||||
void renderClear(RenderArea* area);
|
void renderClear(RenderArea* area);
|
||||||
void renderUpdate(RenderArea* area);
|
void renderUpdate(RenderArea* area);
|
||||||
|
|
|
@ -83,6 +83,7 @@ int systemSavePictureFile(const char* filepath, PictureCallbackSavePixel callbac
|
||||||
for (x = 0; x < width; x++)
|
for (x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
result = callback_pixel(data, x, y);
|
result = callback_pixel(data, x, y);
|
||||||
|
colorNormalize(&result);
|
||||||
rgba = colorTo32BitRGBA(&result);
|
rgba = colorTo32BitRGBA(&result);
|
||||||
pixels[y * width + x] = rgba;
|
pixels[y * width + x] = rgba;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "../tools/memory.h"
|
#include "../tools/memory.h"
|
||||||
|
#include "../tools.h"
|
||||||
|
|
||||||
TerrainHeightMap* terrainHeightMapCreate(TerrainDefinition* terrain)
|
TerrainHeightMap* terrainHeightMapCreate(TerrainDefinition* terrain)
|
||||||
{
|
{
|
||||||
|
@ -143,10 +144,35 @@ void terrainHeightmapLoad(PackStream* stream, TerrainHeightMap* heightmap)
|
||||||
|
|
||||||
static inline int _checkDataHit(TerrainHeightMapChunk* chunk, double x, double z, double* result)
|
static inline int _checkDataHit(TerrainHeightMapChunk* chunk, double x, double z, double* result)
|
||||||
{
|
{
|
||||||
if (x > (double)chunk->rect.xstart && x < (double)chunk->rect.xend && z > (double)chunk->rect.zstart && z < (double)chunk->rect.zend)
|
if (x >= (double)chunk->rect.xstart && x <= (double)chunk->rect.xend && z >= (double)chunk->rect.zstart && z <= (double)chunk->rect.zend)
|
||||||
{
|
{
|
||||||
/* TODO Get interpolated value */
|
double stencil[16];
|
||||||
*result = 0.0;
|
int ix, iz, cx, cz;
|
||||||
|
int xmax = chunk->rect.xsize - 1;
|
||||||
|
int zmax = chunk->rect.zsize - 1;
|
||||||
|
int xlow;
|
||||||
|
int zlow;
|
||||||
|
|
||||||
|
x -= chunk->rect.xstart;
|
||||||
|
z -= chunk->rect.zstart;
|
||||||
|
|
||||||
|
xlow = floor(x);
|
||||||
|
zlow = floor(z);
|
||||||
|
|
||||||
|
for (ix = xlow - 1; ix <= xlow + 2; ix++)
|
||||||
|
{
|
||||||
|
for (iz = zlow - 1; iz <= zlow + 2; iz++)
|
||||||
|
{
|
||||||
|
cx = ix < 0 ? 0 : ix;
|
||||||
|
cx = cx > xmax ? xmax : cx;
|
||||||
|
cz = iz < 0 ? 0 : iz;
|
||||||
|
cz = cz > zmax ? zmax : cz;
|
||||||
|
stencil[(iz - (zlow - 1)) * 4 + ix - (xlow - 1)] = chunk->data[cz * chunk->rect.xsize + cx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*result = toolsBicubicInterpolate(stencil, x - (double)xlow, z - (double)zlow);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -240,7 +266,7 @@ static void _prepareBrushStroke(TerrainHeightMap* heightmap, TerrainBrush* brush
|
||||||
new_size = sizeof(double) * heightmap->floating_data.rect.xsize * heightmap->floating_data.rect.zsize;
|
new_size = sizeof(double) * heightmap->floating_data.rect.xsize * heightmap->floating_data.rect.zsize;
|
||||||
heightmap->floating_data.data = realloc(heightmap->floating_data.data, new_size);
|
heightmap->floating_data.data = realloc(heightmap->floating_data.data, new_size);
|
||||||
|
|
||||||
_resetRect(heightmap, 0, 0, heightmap->floating_data.rect.xsize - 1, heightmap->floating_data.rect.zsize - 1);
|
_resetRect(heightmap, 0, heightmap->floating_data.rect.xsize - 1, 0, heightmap->floating_data.rect.zsize - 1);
|
||||||
|
|
||||||
heightmap->floating_used = 1;
|
heightmap->floating_used = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,9 @@ void terrainAutoPreset(TerrainDefinition* definition, TerrainPreset preset)
|
||||||
case TERRAIN_PRESET_STANDARD:
|
case TERRAIN_PRESET_STANDARD:
|
||||||
noiseRandomizeOffsets(definition->_height_noise);
|
noiseRandomizeOffsets(definition->_height_noise);
|
||||||
noiseClearLevels(definition->_height_noise);
|
noiseClearLevels(definition->_height_noise);
|
||||||
noiseAddLevelsSimple(definition->_height_noise, resolution, pow(2.0, resolution - 1), -12.5, 12.5, 0.5);
|
noiseAddLevelSimple(definition->_height_noise, pow(2.0, resolution + 1), -15.0, 15.0);
|
||||||
|
noiseAddLevelsSimple(definition->_height_noise, resolution - 2, pow(2.0, resolution - 1), -10.0, 10.0, 0.5);
|
||||||
|
noiseNormalizeAmplitude(definition->_height_noise, -15.0, 15.0, 0);
|
||||||
noiseSetFunctionParams(definition->_height_noise, NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
|
noiseSetFunctionParams(definition->_height_noise, NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
|
||||||
definition->scaling = 1.0;
|
definition->scaling = 1.0;
|
||||||
definition->height = 1.0;
|
definition->height = 1.0;
|
||||||
|
|
|
@ -184,6 +184,8 @@ struct ColorProfile
|
||||||
{
|
{
|
||||||
double minvalue;
|
double minvalue;
|
||||||
double maxvalue;
|
double maxvalue;
|
||||||
|
Color (*mapper)(Color col, double exposure);
|
||||||
|
double exposure;
|
||||||
};
|
};
|
||||||
|
|
||||||
ColorProfile* colorProfileCreate()
|
ColorProfile* colorProfileCreate()
|
||||||
|
@ -192,6 +194,7 @@ ColorProfile* colorProfileCreate()
|
||||||
|
|
||||||
profile = malloc(sizeof(ColorProfile));
|
profile = malloc(sizeof(ColorProfile));
|
||||||
|
|
||||||
|
colorProfileSetToneMapping(profile, TONE_MAPPING_UNCHARTED, 2.0);
|
||||||
colorProfileClear(profile);
|
colorProfileClear(profile);
|
||||||
|
|
||||||
return profile;
|
return profile;
|
||||||
|
@ -202,6 +205,52 @@ void colorProfileDelete(ColorProfile* profile)
|
||||||
free(profile);
|
free(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline double _uncharted2Tonemap(double x)
|
||||||
|
{
|
||||||
|
double A = 0.15;
|
||||||
|
double B = 0.50;
|
||||||
|
double C = 0.10;
|
||||||
|
double D = 0.20;
|
||||||
|
double E = 0.02;
|
||||||
|
double F = 0.30;
|
||||||
|
|
||||||
|
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color _toneMappingUncharted(Color pixel, double exposure)
|
||||||
|
{
|
||||||
|
double W = 11.2;
|
||||||
|
double white_scale = 1.0 / _uncharted2Tonemap(W);
|
||||||
|
|
||||||
|
pixel.r = pow(_uncharted2Tonemap(pixel.r * exposure) * white_scale, 1.0 / 2.2);
|
||||||
|
pixel.g = pow(_uncharted2Tonemap(pixel.g * exposure) * white_scale, 1.0 / 2.2);
|
||||||
|
pixel.b = pow(_uncharted2Tonemap(pixel.b * exposure) * white_scale, 1.0 / 2.2);
|
||||||
|
|
||||||
|
return pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color _toneMappingReinhard(Color pixel, double exposure)
|
||||||
|
{
|
||||||
|
pixel.r = (pixel.r * exposure) / (1.0 + pixel.r * exposure);
|
||||||
|
pixel.g = (pixel.g * exposure) / (1.0 + pixel.g * exposure);
|
||||||
|
pixel.b = (pixel.b * exposure) / (1.0 + pixel.b * exposure);
|
||||||
|
|
||||||
|
return pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void colorProfileSetToneMapping(ColorProfile* profile, ToneMappingOperator tonemapper, double exposure)
|
||||||
|
{
|
||||||
|
if (tonemapper == TONE_MAPPING_REIHNARD)
|
||||||
|
{
|
||||||
|
profile->mapper = _toneMappingReinhard;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
profile->mapper = _toneMappingUncharted;
|
||||||
|
}
|
||||||
|
profile->exposure = exposure;
|
||||||
|
}
|
||||||
|
|
||||||
void colorProfileSave(PackStream* stream, ColorProfile* profile)
|
void colorProfileSave(PackStream* stream, ColorProfile* profile)
|
||||||
{
|
{
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
@ -236,37 +285,9 @@ int colorProfileCollect(ColorProfile* profile, Color pixel)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double _uncharted2Tonemap(double x)
|
|
||||||
{
|
|
||||||
double A = 0.15;
|
|
||||||
double B = 0.50;
|
|
||||||
double C = 0.10;
|
|
||||||
double D = 0.20;
|
|
||||||
double E = 0.02;
|
|
||||||
double F = 0.30;
|
|
||||||
|
|
||||||
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color colorProfileApply(ColorProfile* profile, Color pixel)
|
Color colorProfileApply(ColorProfile* profile, Color pixel)
|
||||||
{
|
{
|
||||||
/*pixel.r *= 0.4;
|
return profile->mapper(pixel, profile->exposure);
|
||||||
pixel.g *= 0.4;
|
|
||||||
pixel.b *= 0.4;
|
|
||||||
pixel.r = pixel.r < 1.413 ? pow(pixel.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-pixel.r);
|
|
||||||
pixel.g = pixel.g < 1.413 ? pow(pixel.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-pixel.g);
|
|
||||||
pixel.b = pixel.b < 1.413 ? pow(pixel.b * 0.38317, 1.0 / 2.2) : 1.0 - exp(-pixel.b);
|
|
||||||
return pixel;*/
|
|
||||||
|
|
||||||
double exposure_bias = 2.0;
|
|
||||||
double W = 11.2;
|
|
||||||
double white_scale = 1.0 / _uncharted2Tonemap(W);
|
|
||||||
|
|
||||||
pixel.r = pow(_uncharted2Tonemap(pixel.r * exposure_bias) * white_scale, 1.0 / 2.2);
|
|
||||||
pixel.g = pow(_uncharted2Tonemap(pixel.g * exposure_bias) * white_scale, 1.0 / 2.2);
|
|
||||||
pixel.b = pow(_uncharted2Tonemap(pixel.b * exposure_bias) * white_scale, 1.0 / 2.2);
|
|
||||||
|
|
||||||
return pixel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************** ColorGradation ********************************/
|
/******************************** ColorGradation ********************************/
|
||||||
|
|
|
@ -44,10 +44,17 @@ double colorGetValue(Color* col);
|
||||||
|
|
||||||
/* HDR profile for tone-mapping */
|
/* HDR profile for tone-mapping */
|
||||||
typedef struct ColorProfile ColorProfile;
|
typedef struct ColorProfile ColorProfile;
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TONE_MAPPING_UNCHARTED,
|
||||||
|
TONE_MAPPING_REIHNARD
|
||||||
|
} ToneMappingOperator;
|
||||||
|
|
||||||
ColorProfile* colorProfileCreate();
|
ColorProfile* colorProfileCreate();
|
||||||
void colorProfileDelete(ColorProfile* profile);
|
void colorProfileDelete(ColorProfile* profile);
|
||||||
|
|
||||||
|
void colorProfileSetToneMapping(ColorProfile* profile, ToneMappingOperator tonemapper, double exposure);
|
||||||
|
|
||||||
void colorProfileSave(PackStream* stream, ColorProfile* profile);
|
void colorProfileSave(PackStream* stream, ColorProfile* profile);
|
||||||
void colorProfileLoad(PackStream* stream, ColorProfile* profile);
|
void colorProfileLoad(PackStream* stream, ColorProfile* profile);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,54 @@
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
void* memory2dRealloc(void* data, int datasize, int oldxsize, int oldysize, int newxsize, int newysize, int xoffset, int yoffset)
|
void* memory2dRealloc(void* data, int datasize, int oldxsize, int oldysize, int newxsize, int newysize, int xoffset, int yoffset)
|
||||||
{
|
{
|
||||||
/* TODO Move remaining part*/
|
int xstart, xend, xlen;
|
||||||
return realloc(data, datasize * newxsize * newysize);
|
int ystart, yend, y;
|
||||||
|
void* result = malloc(datasize * newxsize * newysize);
|
||||||
|
|
||||||
|
/* Move remaining part*/
|
||||||
|
ystart = yoffset;
|
||||||
|
yend = yoffset + oldysize;
|
||||||
|
if (yend >= 0 && ystart < newysize)
|
||||||
|
{
|
||||||
|
if (ystart < 0)
|
||||||
|
{
|
||||||
|
ystart = 0;
|
||||||
|
}
|
||||||
|
if (yend > newysize - 1)
|
||||||
|
{
|
||||||
|
yend = newysize - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
xstart = xoffset;
|
||||||
|
xend = xoffset + oldxsize;
|
||||||
|
if (xend >= 0 && xstart < newxsize)
|
||||||
|
{
|
||||||
|
if (xstart < 0)
|
||||||
|
{
|
||||||
|
xstart = 0;
|
||||||
|
}
|
||||||
|
if (xend > newxsize - 1)
|
||||||
|
{
|
||||||
|
xend = newxsize - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
xlen = xend - xstart + 1;
|
||||||
|
if (xlen > 0)
|
||||||
|
{
|
||||||
|
for (y = ystart; y <= yend; y++)
|
||||||
|
{
|
||||||
|
memcpy(result + (y * newxsize + xstart) * datasize, data + ((y - ystart) * oldxsize) * datasize, xlen * datasize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory2dScrolling(void* data, int datasize, int xsize, int ysize, int xoffset, int yoffset)
|
void memory2dScrolling(void* data, int datasize, int xsize, int ysize, int xoffset, int yoffset)
|
||||||
|
|
Loading…
Reference in a new issue