[Broken WIP] Removed legacy Renderer and refactored RenderArea.
This commit is contained in:
parent
74634dfaf1
commit
ec444b7c26
79 changed files with 1252 additions and 1377 deletions
|
@ -4,20 +4,18 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "render.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "AtmosphereDefinition.h"
|
#include "AtmosphereDefinition.h"
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "RenderingScenery.h"
|
#include "RenderingScenery.h"
|
||||||
|
|
||||||
void startRender(Renderer* renderer, char* outputpath, RenderParams params)
|
void startRender(SoftwareRenderer* renderer, char* outputpath, RenderArea::RenderParams params)
|
||||||
{
|
{
|
||||||
printf("\rRendering %s ... \n", outputpath);
|
printf("\rRendering %s ... \n", outputpath);
|
||||||
rendererStart(renderer, params);
|
renderer->start(params);
|
||||||
printf("\rSaving %s ... \n", outputpath);
|
printf("\rSaving %s ... \n", outputpath);
|
||||||
remove(outputpath);
|
remove(outputpath);
|
||||||
renderSaveToFile(renderer->render_area, outputpath);
|
renderer->render_area->saveToFile(outputpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void displayHelp()
|
void displayHelp()
|
||||||
|
@ -48,7 +46,7 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
SoftwareRenderer* renderer;
|
SoftwareRenderer* renderer;
|
||||||
char* conf_file_path = NULL;
|
char* conf_file_path = NULL;
|
||||||
RenderParams conf_render_params = {800, 600, 1, 5};
|
RenderArea::RenderParams conf_render_params = {800, 600, 1, 5};
|
||||||
int conf_first_picture = 0;
|
int conf_first_picture = 0;
|
||||||
int conf_nb_pictures = 1;
|
int conf_nb_pictures = 1;
|
||||||
double conf_daytime_start = 0.4;
|
double conf_daytime_start = 0.4;
|
||||||
|
@ -177,7 +175,7 @@ int main(int argc, char** argv)
|
||||||
camera->setLocation(camera->getLocation().add(step));
|
camera->setLocation(camera->getLocation().add(step));
|
||||||
|
|
||||||
renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
||||||
rendererSetPreviewCallbacks(renderer, NULL, NULL, _previewUpdate);
|
renderer->setPreviewCallbacks(NULL, NULL, _previewUpdate);
|
||||||
|
|
||||||
if (outputcount >= conf_first_picture)
|
if (outputcount >= conf_first_picture)
|
||||||
{
|
{
|
||||||
|
|
|
@ -251,7 +251,7 @@ void FreeFormHelper::processRenderClicked()
|
||||||
emit needAlterRenderer(&renderer);
|
emit needAlterRenderer(&renderer);
|
||||||
|
|
||||||
DialogRender* dialog = new DialogRender(_form_widget, &renderer);
|
DialogRender* dialog = new DialogRender(_form_widget, &renderer);
|
||||||
RenderParams params = {400, 300, 1, 3};
|
RenderArea::RenderParams params = {400, 300, 1, 3};
|
||||||
dialog->startRender(params);
|
dialog->startRender(params);
|
||||||
|
|
||||||
delete dialog;
|
delete dialog;
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
class QSlider;
|
class QSlider;
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class Renderer;
|
|
||||||
|
|
||||||
class FreeFormHelper:public QObject
|
class FreeFormHelper:public QObject
|
||||||
{
|
{
|
||||||
|
@ -47,7 +46,7 @@ signals:
|
||||||
void needGlobalRefreshing();
|
void needGlobalRefreshing();
|
||||||
void needReverting();
|
void needReverting();
|
||||||
void needCommitting();
|
void needCommitting();
|
||||||
void needAlterRenderer(Renderer* renderer);
|
void needAlterRenderer(SoftwareRenderer* renderer);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void processDataChange();
|
void processDataChange();
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include "WidgetExplorer.h"
|
#include "WidgetExplorer.h"
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "renderer.h"
|
|
||||||
|
|
||||||
DialogExplorer::DialogExplorer(QWidget* parent, CameraDefinition* camera, bool camera_validable, SoftwareRenderer* renderer) : QDialog(parent)
|
DialogExplorer::DialogExplorer(QWidget* parent, CameraDefinition* camera, bool camera_validable, SoftwareRenderer* renderer) : QDialog(parent)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
|
#include "SoftwareRenderer.h"
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
#include "ColorProfile.h"
|
#include "ColorProfile.h"
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ static void _renderUpdate(double progress)
|
||||||
class RenderThread:public QThread
|
class RenderThread:public QThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RenderThread(DialogRender* dialog, Renderer* renderer, RenderParams params):QThread()
|
RenderThread(DialogRender* dialog, SoftwareRenderer* renderer, RenderArea::RenderParams params):QThread()
|
||||||
{
|
{
|
||||||
_dialog = dialog;
|
_dialog = dialog;
|
||||||
_renderer = renderer;
|
_renderer = renderer;
|
||||||
|
@ -56,13 +57,13 @@ public:
|
||||||
}
|
}
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
rendererStart(_renderer, _params);
|
_renderer->start(_params);
|
||||||
_dialog->tellRenderEnded();
|
_dialog->tellRenderEnded();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
DialogRender* _dialog;
|
DialogRender* _dialog;
|
||||||
Renderer* _renderer;
|
SoftwareRenderer* _renderer;
|
||||||
RenderParams _params;
|
RenderArea::RenderParams _params;
|
||||||
};
|
};
|
||||||
|
|
||||||
class _RenderArea:public QWidget
|
class _RenderArea:public QWidget
|
||||||
|
@ -83,7 +84,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DialogRender::DialogRender(QWidget *parent, Renderer* renderer):
|
DialogRender::DialogRender(QWidget *parent, SoftwareRenderer* renderer):
|
||||||
QDialog(parent, Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint)
|
QDialog(parent, Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint)
|
||||||
{
|
{
|
||||||
pixbuf_lock = new QMutex();
|
pixbuf_lock = new QMutex();
|
||||||
|
@ -151,7 +152,7 @@ DialogRender::~DialogRender()
|
||||||
{
|
{
|
||||||
if (_render_thread)
|
if (_render_thread)
|
||||||
{
|
{
|
||||||
rendererInterrupt(_renderer);
|
_renderer->interrupt();
|
||||||
_render_thread->wait();
|
_render_thread->wait();
|
||||||
|
|
||||||
delete _render_thread;
|
delete _render_thread;
|
||||||
|
@ -175,12 +176,12 @@ void DialogRender::tellRenderEnded()
|
||||||
emit renderEnded();
|
emit renderEnded();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogRender::startRender(RenderParams params)
|
void DialogRender::startRender(RenderArea::RenderParams params)
|
||||||
{
|
{
|
||||||
_started = time(NULL);
|
_started = time(NULL);
|
||||||
|
|
||||||
applyRenderSize(params.width, params.height);
|
applyRenderSize(params.width, params.height);
|
||||||
rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate);
|
_renderer->setPreviewCallbacks(_renderStart, _renderDraw, _renderUpdate);
|
||||||
|
|
||||||
_render_thread = new RenderThread(this, _renderer, params);
|
_render_thread = new RenderThread(this, _renderer, params);
|
||||||
_render_thread->start();
|
_render_thread->start();
|
||||||
|
@ -207,7 +208,8 @@ void DialogRender::saveRender()
|
||||||
{
|
{
|
||||||
filepath = filepath.append(".png");
|
filepath = filepath.append(".png");
|
||||||
}
|
}
|
||||||
if (renderSaveToFile(_renderer->render_area, (char*)filepath.toStdString().c_str()))
|
std::string filepathstr = filepath.toStdString();
|
||||||
|
if (_renderer->render_area->saveToFile((char*)filepathstr.c_str()))
|
||||||
{
|
{
|
||||||
QMessageBox::information(this, "Message", QString(tr("The picture %1 has been saved.")).arg(filepath));
|
QMessageBox::information(this, "Message", QString(tr("The picture %1 has been saved.")).arg(filepath));
|
||||||
}
|
}
|
||||||
|
@ -220,13 +222,14 @@ void DialogRender::saveRender()
|
||||||
|
|
||||||
void DialogRender::toneMappingChanged()
|
void DialogRender::toneMappingChanged()
|
||||||
{
|
{
|
||||||
renderSetToneMapping(_renderer->render_area, ColorProfile((ColorProfile::ToneMappingOperator)_tonemapping_control->currentIndex(), ((double)_exposure_control->value()) * 0.01));
|
ColorProfile profile((ColorProfile::ToneMappingOperator)_tonemapping_control->currentIndex(), ((double)_exposure_control->value()) * 0.01);
|
||||||
|
_renderer->render_area->setToneMapping(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogRender::loadLastRender()
|
void DialogRender::loadLastRender()
|
||||||
{
|
{
|
||||||
applyRenderSize(_renderer->render_width, _renderer->render_height);
|
applyRenderSize(_renderer->render_width, _renderer->render_height);
|
||||||
rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate);
|
_renderer->setPreviewCallbacks(_renderStart, _renderDraw, _renderUpdate);
|
||||||
renderEnded();
|
renderEnded();
|
||||||
toneMappingChanged();
|
toneMappingChanged();
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#ifndef _PAYSAGES_QT_DIALOGRENDER_H_
|
#ifndef _PAYSAGES_QT_DIALOGRENDER_H_
|
||||||
#define _PAYSAGES_QT_DIALOGRENDER_H_
|
#define _PAYSAGES_QT_DIALOGRENDER_H_
|
||||||
|
|
||||||
|
#include "desktop_global.h"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "renderer.h"
|
#include "RenderArea.h"
|
||||||
|
|
||||||
class QThread;
|
class QThread;
|
||||||
class QProgressBar;
|
class QProgressBar;
|
||||||
|
@ -17,13 +19,13 @@ class DialogRender : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit DialogRender(QWidget *parent, Renderer* renderer);
|
explicit DialogRender(QWidget *parent, SoftwareRenderer* renderer);
|
||||||
~DialogRender();
|
~DialogRender();
|
||||||
|
|
||||||
void tellRenderSize(int width, int height);
|
void tellRenderSize(int width, int height);
|
||||||
void tellProgressChange(double value);
|
void tellProgressChange(double value);
|
||||||
void tellRenderEnded();
|
void tellRenderEnded();
|
||||||
void startRender(RenderParams params);
|
void startRender(RenderArea::RenderParams params);
|
||||||
void loadLastRender();
|
void loadLastRender();
|
||||||
|
|
||||||
QImage* pixbuf;
|
QImage* pixbuf;
|
||||||
|
@ -51,7 +53,7 @@ private:
|
||||||
QPushButton* _save_button;
|
QPushButton* _save_button;
|
||||||
QThread* _render_thread;
|
QThread* _render_thread;
|
||||||
QLabel* _timer;
|
QLabel* _timer;
|
||||||
Renderer* _renderer;
|
SoftwareRenderer* _renderer;
|
||||||
QProgressBar* _progress;
|
QProgressBar* _progress;
|
||||||
time_t _started;
|
time_t _started;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "RenderingScenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "AtmosphereDefinition.h"
|
#include "AtmosphereDefinition.h"
|
||||||
#include "renderer.h"
|
|
||||||
|
|
||||||
static AtmosphereDefinition* _definition;
|
static AtmosphereDefinition* _definition;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include "RenderingScenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "renderer.h"
|
|
||||||
#include "CloudsDefinition.h"
|
#include "CloudsDefinition.h"
|
||||||
#include "CloudLayerDefinition.h"
|
#include "CloudLayerDefinition.h"
|
||||||
#include "CloudsCoveragePreviewRenderer.h"
|
#include "CloudsCoveragePreviewRenderer.h"
|
||||||
|
|
|
@ -5,10 +5,6 @@
|
||||||
#include "dialogrender.h"
|
#include "dialogrender.h"
|
||||||
#include "inputcamera.h"
|
#include "inputcamera.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "render.h"
|
|
||||||
#include "atmosphere/public.h"
|
|
||||||
#include "terrain/public.h"
|
|
||||||
#include "water/public.h"
|
|
||||||
#include "RenderingScenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
|
@ -57,7 +53,7 @@ FormRender::~FormRender()
|
||||||
delete _camera;
|
delete _camera;
|
||||||
if (_renderer_inited)
|
if (_renderer_inited)
|
||||||
{
|
{
|
||||||
rendererDelete(_renderer);
|
delete _renderer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,13 +101,13 @@ void FormRender::startQuickRender()
|
||||||
{
|
{
|
||||||
if (_renderer_inited)
|
if (_renderer_inited)
|
||||||
{
|
{
|
||||||
rendererDelete(_renderer);
|
delete _renderer;
|
||||||
}
|
}
|
||||||
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
||||||
_renderer_inited = true;
|
_renderer_inited = true;
|
||||||
|
|
||||||
DialogRender* dialog = new DialogRender(this, _renderer);
|
DialogRender* dialog = new DialogRender(this, _renderer);
|
||||||
RenderParams params = {400, 300, 1, 3};
|
RenderArea::RenderParams params = {400, 300, 1, 3};
|
||||||
dialog->startRender(params);
|
dialog->startRender(params);
|
||||||
|
|
||||||
delete dialog;
|
delete dialog;
|
||||||
|
@ -121,7 +117,7 @@ void FormRender::startRender()
|
||||||
{
|
{
|
||||||
if (_renderer_inited)
|
if (_renderer_inited)
|
||||||
{
|
{
|
||||||
rendererDelete(_renderer);
|
delete _renderer;
|
||||||
}
|
}
|
||||||
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
||||||
_renderer_inited = true;
|
_renderer_inited = true;
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#ifndef _PAYSAGES_QT_FORMRENDER_H_
|
#ifndef _PAYSAGES_QT_FORMRENDER_H_
|
||||||
#define _PAYSAGES_QT_FORMRENDER_H_
|
#define _PAYSAGES_QT_FORMRENDER_H_
|
||||||
|
|
||||||
|
#include "desktop_global.h"
|
||||||
|
|
||||||
#include "baseform.h"
|
#include "baseform.h"
|
||||||
#include "renderer.h"
|
|
||||||
#include "render.h"
|
#include "RenderArea.h"
|
||||||
|
|
||||||
class FormRender : public BaseForm
|
class FormRender : public BaseForm
|
||||||
{
|
{
|
||||||
|
@ -27,9 +29,9 @@ protected slots:
|
||||||
virtual void configChangeEvent();
|
virtual void configChangeEvent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RenderParams _params;
|
RenderArea::RenderParams _params;
|
||||||
CameraDefinition* _camera;
|
CameraDefinition* _camera;
|
||||||
Renderer* _renderer;
|
SoftwareRenderer* _renderer;
|
||||||
bool _renderer_inited;
|
bool _renderer_inited;
|
||||||
BasePreview* _preview_landscape;
|
BasePreview* _preview_landscape;
|
||||||
Base2dPreviewRenderer* _preview_landscape_renderer;
|
Base2dPreviewRenderer* _preview_landscape_renderer;
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
#include "RenderingScenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "renderer.h"
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "TexturesDefinition.h"
|
#include "TexturesDefinition.h"
|
||||||
#include "TextureLayerDefinition.h"
|
#include "TextureLayerDefinition.h"
|
||||||
#include "terrain/public.h"
|
#include "SoftwareRenderer.h"
|
||||||
|
#include "TerrainRenderer.h"
|
||||||
|
|
||||||
/**************** Previews ****************/
|
/**************** Previews ****************/
|
||||||
class PreviewTexturesCoverage : public BasePreview
|
class PreviewTexturesCoverage : public BasePreview
|
||||||
|
@ -16,11 +16,10 @@ public:
|
||||||
|
|
||||||
PreviewTexturesCoverage(QWidget* parent, TextureLayerDefinition* layer) : BasePreview(parent)
|
PreviewTexturesCoverage(QWidget* parent, TextureLayerDefinition* layer) : BasePreview(parent)
|
||||||
{
|
{
|
||||||
_renderer = rendererCreate();
|
_renderer = new SoftwareRenderer();
|
||||||
_renderer->render_quality = 3;
|
_renderer->render_quality = 3;
|
||||||
|
|
||||||
_original_layer = layer;
|
_original_layer = layer;
|
||||||
//_preview_definition = (TexturesDefinition*)TexturesDefinitionClass.create();
|
|
||||||
|
|
||||||
addOsd(QString("geolocation"));
|
addOsd(QString("geolocation"));
|
||||||
|
|
||||||
|
@ -30,7 +29,7 @@ public:
|
||||||
|
|
||||||
~PreviewTexturesCoverage()
|
~PreviewTexturesCoverage()
|
||||||
{
|
{
|
||||||
//TexturesDefinitionClass.destroy(_preview_layer);
|
delete _renderer;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -39,7 +38,7 @@ protected:
|
||||||
Vector3 location;
|
Vector3 location;
|
||||||
Color result;
|
Color result;
|
||||||
location.x = x;
|
location.x = x;
|
||||||
location.y = _renderer->terrain->getHeight(_renderer, x, y, 1);
|
location.y = _renderer->getTerrainRenderer()->getHeight(x, y, 1);
|
||||||
location.z = y;
|
location.z = y;
|
||||||
//result.r = result.g = result.b = texturesGetLayerCoverage(_preview_layer, _renderer, location, this->scaling);
|
//result.r = result.g = result.b = texturesGetLayerCoverage(_preview_layer, _renderer, location, this->scaling);
|
||||||
return result;
|
return result;
|
||||||
|
@ -47,15 +46,17 @@ protected:
|
||||||
|
|
||||||
void updateData()
|
void updateData()
|
||||||
{
|
{
|
||||||
TerrainRendererClass.bind(_renderer, RenderingScenery::getCurrent()->getTerrain());
|
TexturesDefinition* textures = _renderer->getScenery()->getTextures();
|
||||||
|
textures->clear();
|
||||||
|
textures->addLayer();
|
||||||
|
_original_layer->copy(textures->getLayer(0));
|
||||||
|
|
||||||
//TexturesDefinitionClass.copy(_original_layer, _preview_layer);
|
_renderer->prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Renderer* _renderer;
|
SoftwareRenderer* _renderer;
|
||||||
TextureLayerDefinition* _original_layer;
|
TextureLayerDefinition* _original_layer;
|
||||||
TexturesDefinition* _preview_definition;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PreviewTexturesColor : public BasePreview
|
class PreviewTexturesColor : public BasePreview
|
||||||
|
@ -65,9 +66,8 @@ public:
|
||||||
PreviewTexturesColor(QWidget* parent, TextureLayerDefinition* layer) : BasePreview(parent)
|
PreviewTexturesColor(QWidget* parent, TextureLayerDefinition* layer) : BasePreview(parent)
|
||||||
{
|
{
|
||||||
_original_layer = layer;
|
_original_layer = layer;
|
||||||
//_preview_layer = (TexturesLayerDefinition*)TexturesDefinitionClass.create();
|
|
||||||
|
|
||||||
_renderer = rendererCreate();
|
_renderer = new SoftwareRenderer();
|
||||||
_renderer->render_quality = 3;
|
_renderer->render_quality = 3;
|
||||||
|
|
||||||
_renderer->render_camera->setLocation(Vector3(0.0, 20.0, 0.0));
|
_renderer->render_camera->setLocation(Vector3(0.0, 20.0, 0.0));
|
||||||
|
@ -78,7 +78,7 @@ public:
|
||||||
|
|
||||||
~PreviewTexturesColor()
|
~PreviewTexturesColor()
|
||||||
{
|
{
|
||||||
//TexturesDefinitionClass.destroy(_preview_layer);
|
delete _renderer;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -94,12 +94,16 @@ protected:
|
||||||
|
|
||||||
void updateData()
|
void updateData()
|
||||||
{
|
{
|
||||||
//TexturesDefinitionClass.copy(_original_layer, _preview_layer);
|
TexturesDefinition* textures = _renderer->getScenery()->getTextures();
|
||||||
|
textures->clear();
|
||||||
|
textures->addLayer();
|
||||||
|
_original_layer->copy(textures->getLayer(0));
|
||||||
|
|
||||||
|
_renderer->prepare();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Renderer* _renderer;
|
SoftwareRenderer* _renderer;
|
||||||
TextureLayerDefinition* _original_layer;
|
TextureLayerDefinition* _original_layer;
|
||||||
TextureLayerDefinition* _preview_layer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**************** Form ****************/
|
/**************** Form ****************/
|
||||||
|
|
|
@ -4,11 +4,6 @@
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "tools/lighting.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
#include "water/public.h"
|
|
||||||
#include "terrain/public.h"
|
|
||||||
#include "atmosphere/public.h"
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "RenderingScenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include "baseinput.h"
|
#include "baseinput.h"
|
||||||
|
|
||||||
#include "tools/lighting.h"
|
|
||||||
|
|
||||||
class InputMaterial:public BaseInput
|
class InputMaterial:public BaseInput
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -69,6 +69,6 @@ void DialogMaterialEditor::commitLocalDataToScenery()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogMaterialEditor::alterRenderer(Renderer*)
|
void DialogMaterialEditor::alterRenderer(SoftwareRenderer*)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
#ifndef DIALOGMATERIALEDITOR_H
|
#ifndef DIALOGMATERIALEDITOR_H
|
||||||
#define DIALOGMATERIALEDITOR_H
|
#define DIALOGMATERIALEDITOR_H
|
||||||
|
|
||||||
|
#include "desktop_global.h"
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
#include "previewmaterial.h"
|
#include "previewmaterial.h"
|
||||||
|
|
||||||
#include "tools/lighting.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
#include "SurfaceMaterial.h"
|
#include "SurfaceMaterial.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -30,7 +29,7 @@ public slots:
|
||||||
void refreshFromFellowData();
|
void refreshFromFellowData();
|
||||||
void updateLocalDataFromScenery();
|
void updateLocalDataFromScenery();
|
||||||
void commitLocalDataToScenery();
|
void commitLocalDataToScenery();
|
||||||
void alterRenderer(Renderer* renderer);
|
void alterRenderer(SoftwareRenderer* renderer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::DialogMaterialEditor *ui;
|
Ui::DialogMaterialEditor *ui;
|
||||||
|
|
|
@ -7,20 +7,22 @@
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "ColorProfile.h"
|
#include "ColorProfile.h"
|
||||||
#include "tools/lighting.h"
|
#include "LightComponent.h"
|
||||||
|
#include "LightingManager.h"
|
||||||
|
|
||||||
/***** Shared renderer *****/
|
/***** Shared renderer *****/
|
||||||
MaterialPreviewRenderer::MaterialPreviewRenderer(SurfaceMaterial* material)
|
MaterialPreviewRenderer::MaterialPreviewRenderer(SurfaceMaterial* material)
|
||||||
{
|
{
|
||||||
_light.color.r = 3.0;
|
_light = new LightComponent;
|
||||||
_light.color.g = 3.0;
|
_light->color.r = 3.0;
|
||||||
_light.color.b = 3.0;
|
_light->color.g = 3.0;
|
||||||
_light.direction.x = -0.5;
|
_light->color.b = 3.0;
|
||||||
_light.direction.y = -0.5;
|
_light->direction.x = -0.5;
|
||||||
_light.direction.z = -0.5;
|
_light->direction.y = -0.5;
|
||||||
_light.direction = v3Normalize(_light.direction);
|
_light->direction.z = -0.5;
|
||||||
_light.altered = 0;
|
_light->direction = v3Normalize(_light->direction);
|
||||||
_light.reflection = 1.0;
|
_light->altered = 0;
|
||||||
|
_light->reflection = 1.0;
|
||||||
|
|
||||||
_material = material;
|
_material = material;
|
||||||
|
|
||||||
|
@ -33,6 +35,7 @@ MaterialPreviewRenderer::MaterialPreviewRenderer(SurfaceMaterial* material)
|
||||||
MaterialPreviewRenderer::~MaterialPreviewRenderer()
|
MaterialPreviewRenderer::~MaterialPreviewRenderer()
|
||||||
{
|
{
|
||||||
delete _color_profile;
|
delete _color_profile;
|
||||||
|
delete _light;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialPreviewRenderer::bindEvent(BasePreview* preview)
|
void MaterialPreviewRenderer::bindEvent(BasePreview* preview)
|
||||||
|
@ -64,7 +67,7 @@ Color MaterialPreviewRenderer::getColor2D(double x, double y, double)
|
||||||
}
|
}
|
||||||
|
|
||||||
point = v3Normalize(point);
|
point = v3Normalize(point);
|
||||||
color = lightingApplyOneLight(&_light, getCameraLocation(this, point), point, point, _material);
|
color = getLightingManager()->applyFinalComponent(*_light, getCameraLocation(point), point, point, *_material);
|
||||||
if (dist > 0.95)
|
if (dist > 0.95)
|
||||||
{
|
{
|
||||||
color.a = (1.0 - dist) / 0.05;
|
color.a = (1.0 - dist) / 0.05;
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
#include "Base2dPreviewRenderer.h"
|
#include "Base2dPreviewRenderer.h"
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "tools/lighting.h"
|
|
||||||
|
|
||||||
class MaterialPreviewRenderer:public Base2dPreviewRenderer {
|
class MaterialPreviewRenderer:public Base2dPreviewRenderer {
|
||||||
public:
|
public:
|
||||||
MaterialPreviewRenderer(SurfaceMaterial* material);
|
MaterialPreviewRenderer(SurfaceMaterial* material);
|
||||||
|
@ -18,7 +16,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SurfaceMaterial* _material;
|
SurfaceMaterial* _material;
|
||||||
LightDefinition _light;
|
LightComponent* _light;
|
||||||
ColorProfile* _color_profile;
|
ColorProfile* _color_profile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#ifndef DIALOGTERRAINPAINTING_H
|
#ifndef DIALOGTERRAINPAINTING_H
|
||||||
#define DIALOGTERRAINPAINTING_H
|
#define DIALOGTERRAINPAINTING_H
|
||||||
|
|
||||||
|
#include "desktop_global.h"
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "paintingbrush.h"
|
#include "paintingbrush.h"
|
||||||
#include "terrain/public.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class DialogTerrainPainting;
|
class DialogTerrainPainting;
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "RenderingScenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "TerrainDefinition.h"
|
#include "TerrainDefinition.h"
|
||||||
#include "TerrainHeightMap.h"
|
#include "TerrainHeightMap.h"
|
||||||
#include "textures/public.h"
|
|
||||||
|
|
||||||
MainTerrainForm::MainTerrainForm(QWidget *parent) :
|
MainTerrainForm::MainTerrainForm(QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
|
@ -71,7 +70,8 @@ void MainTerrainForm::refreshFromLocalData()
|
||||||
|
|
||||||
void MainTerrainForm::refreshFromFellowData()
|
void MainTerrainForm::refreshFromFellowData()
|
||||||
{
|
{
|
||||||
double disp = texturesGetMaximalDisplacement(RenderingScenery::getCurrent()->getTextures());
|
//double disp = texturesGetMaximalDisplacement(RenderingScenery::getCurrent()->getTextures());
|
||||||
|
double disp = -1000.0;
|
||||||
|
|
||||||
if (disp == 0.0)
|
if (disp == 0.0)
|
||||||
{
|
{
|
||||||
|
@ -93,9 +93,10 @@ void MainTerrainForm::commitLocalDataToScenery()
|
||||||
RenderingScenery::getCurrent()->setTerrain(_terrain);
|
RenderingScenery::getCurrent()->setTerrain(_terrain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTerrainForm::alterRenderer(Renderer* renderer)
|
void MainTerrainForm::alterRenderer(SoftwareRenderer* renderer)
|
||||||
{
|
{
|
||||||
TerrainRendererClass.bind(renderer, _terrain);
|
renderer->getScenery()->setTerrain(_terrain);
|
||||||
|
renderer->prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTerrainForm::buttonBaseNoisePressed()
|
void MainTerrainForm::buttonBaseNoisePressed()
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "terrain/public.h"
|
|
||||||
class FreeFormHelper;
|
class FreeFormHelper;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -27,7 +26,7 @@ public slots:
|
||||||
void refreshFromFellowData();
|
void refreshFromFellowData();
|
||||||
void updateLocalDataFromScenery();
|
void updateLocalDataFromScenery();
|
||||||
void commitLocalDataToScenery();
|
void commitLocalDataToScenery();
|
||||||
void alterRenderer(Renderer* renderer);
|
void alterRenderer(SoftwareRenderer* renderer);
|
||||||
|
|
||||||
void buttonBaseNoisePressed();
|
void buttonBaseNoisePressed();
|
||||||
void buttonPaintingPressed();
|
void buttonPaintingPressed();
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
#ifndef PAINTINGBRUSH_H
|
#ifndef PAINTINGBRUSH_H
|
||||||
#define PAINTINGBRUSH_H
|
#define PAINTINGBRUSH_H
|
||||||
|
|
||||||
#include "terrain/public.h"
|
#include "desktop_global.h"
|
||||||
|
|
||||||
namespace paysages {
|
|
||||||
namespace basics {
|
|
||||||
class NoiseGenerator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class QAbstractSlider;
|
class QAbstractSlider;
|
||||||
class QWidget;
|
class QWidget;
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,12 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <GL/glu.h>
|
#include <GL/glu.h>
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
#include "SoftwareRenderer.h"
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
#include "TerrainDefinition.h"
|
#include "TerrainDefinition.h"
|
||||||
#include "TerrainHeightMap.h"
|
#include "TerrainHeightMap.h"
|
||||||
#include "WaterDefinition.h"
|
#include "WaterDefinition.h"
|
||||||
|
#include "TerrainRenderer.h"
|
||||||
|
|
||||||
#define HEIGHTMAP_RESOLUTION 256
|
#define HEIGHTMAP_RESOLUTION 256
|
||||||
|
|
||||||
|
@ -23,7 +25,7 @@ QGLWidget(parent)
|
||||||
startTimer(100);
|
startTimer(100);
|
||||||
|
|
||||||
_terrain = NULL;
|
_terrain = NULL;
|
||||||
_renderer = rendererCreate();
|
_renderer = new SoftwareRenderer();
|
||||||
_vertices = new _VertexInfo[HEIGHTMAP_RESOLUTION * HEIGHTMAP_RESOLUTION];
|
_vertices = new _VertexInfo[HEIGHTMAP_RESOLUTION * HEIGHTMAP_RESOLUTION];
|
||||||
|
|
||||||
_dirty = true;
|
_dirty = true;
|
||||||
|
@ -66,15 +68,17 @@ WidgetHeightMap::~WidgetHeightMap()
|
||||||
delete _current_camera;
|
delete _current_camera;
|
||||||
delete _top_camera;
|
delete _top_camera;
|
||||||
delete _temp_camera;
|
delete _temp_camera;
|
||||||
rendererDelete(_renderer);
|
delete _renderer;
|
||||||
delete[] _vertices;
|
delete[] _vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidgetHeightMap::setTerrain(TerrainDefinition* terrain)
|
void WidgetHeightMap::setTerrain(TerrainDefinition* terrain)
|
||||||
{
|
{
|
||||||
_terrain = terrain;
|
_terrain = terrain;
|
||||||
TerrainRendererClass.bind(_renderer, _terrain);
|
|
||||||
_water_height = _renderer->terrain->getWaterHeight(_renderer) / _terrain->scaling;
|
_renderer->getScenery()->setTerrain(_terrain);
|
||||||
|
_renderer->prepare();
|
||||||
|
_water_height = _renderer->getTerrainRenderer()->getWaterHeight() / _terrain->scaling;
|
||||||
|
|
||||||
revert();
|
revert();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#ifndef _PAYSAGES_QT_WIDGETHEIGHTMAP_H_
|
#ifndef _PAYSAGES_QT_WIDGETHEIGHTMAP_H_
|
||||||
#define _PAYSAGES_QT_WIDGETHEIGHTMAP_H_
|
#define _PAYSAGES_QT_WIDGETHEIGHTMAP_H_
|
||||||
|
|
||||||
|
#include "desktop_global.h"
|
||||||
|
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include "terrain/paintingbrush.h"
|
#include "terrain/paintingbrush.h"
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "renderer.h"
|
|
||||||
#include "terrain/public.h"
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -55,7 +56,7 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TerrainDefinition* _terrain;
|
TerrainDefinition* _terrain;
|
||||||
Renderer* _renderer;
|
SoftwareRenderer* _renderer;
|
||||||
_VertexInfo* _vertices;
|
_VertexInfo* _vertices;
|
||||||
|
|
||||||
bool _dirty;
|
bool _dirty;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "textures/tex_preview.h"
|
|
||||||
|
|
||||||
void PreviewCumul::setTextures(TexturesDefinition* textures)
|
void PreviewCumul::setTextures(TexturesDefinition* textures)
|
||||||
{
|
{
|
||||||
|
@ -28,7 +27,7 @@ void PreviewCumul::updateEvent()
|
||||||
{
|
{
|
||||||
if (textures)
|
if (textures)
|
||||||
{
|
{
|
||||||
TexturesPreviewCumul_bind(this, textures);
|
//TexturesPreviewCumul_bind(this, textures);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +35,8 @@ Color PreviewCumul::getColor2D(double x, double y, double scaling)
|
||||||
{
|
{
|
||||||
if (textures)
|
if (textures)
|
||||||
{
|
{
|
||||||
return TexturesPreviewCumul_getColor(this, x, y, scaling, layer);
|
return COLOR_BLACK;
|
||||||
|
//return TexturesPreviewCumul_getColor(this, x, y, scaling, layer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "textures/tex_preview.h"
|
|
||||||
|
|
||||||
void PreviewLayerCoverage::setTextures(TexturesDefinition* textures)
|
void PreviewLayerCoverage::setTextures(TexturesDefinition* textures)
|
||||||
{
|
{
|
||||||
|
@ -26,7 +25,7 @@ void PreviewLayerCoverage::updateEvent()
|
||||||
{
|
{
|
||||||
if (textures)
|
if (textures)
|
||||||
{
|
{
|
||||||
TexturesPreviewLayerCoverage_bind(this, textures);
|
//TexturesPreviewLayerCoverage_bind(this, textures);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +33,8 @@ Color PreviewLayerCoverage::getColor2D(double x, double y, double scaling)
|
||||||
{
|
{
|
||||||
if (textures)
|
if (textures)
|
||||||
{
|
{
|
||||||
return TexturesPreviewLayerCoverage_getColor(this, x, y, scaling, layer);
|
return COLOR_BLACK;
|
||||||
|
//return TexturesPreviewLayerCoverage_getColor(this, x, y, scaling, layer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "textures/tex_preview.h"
|
|
||||||
|
|
||||||
void PreviewLayerLook::setTextures(TexturesDefinition* textures)
|
void PreviewLayerLook::setTextures(TexturesDefinition* textures)
|
||||||
{
|
{
|
||||||
|
@ -25,7 +24,7 @@ void PreviewLayerLook::updateEvent()
|
||||||
{
|
{
|
||||||
if (textures)
|
if (textures)
|
||||||
{
|
{
|
||||||
TexturesPreviewLayerLook_bind(this, textures);
|
//TexturesPreviewLayerLook_bind(this, textures);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +32,8 @@ Color PreviewLayerLook::getColor2D(double x, double y, double scaling)
|
||||||
{
|
{
|
||||||
if (textures)
|
if (textures)
|
||||||
{
|
{
|
||||||
return TexturesPreviewLayerLook_getColor(this, x, y, scaling, layer);
|
return COLOR_BLACK;
|
||||||
|
//return TexturesPreviewLayerLook_getColor(this, x, y, scaling, layer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include "textures/PreviewLayerLook.h"
|
#include "textures/PreviewLayerLook.h"
|
||||||
#include "textures/PreviewCumul.h"
|
#include "textures/PreviewCumul.h"
|
||||||
#include "textures/DialogTexturesLayer.h"
|
#include "textures/DialogTexturesLayer.h"
|
||||||
#include "textures/public.h"
|
|
||||||
|
|
||||||
MainTexturesForm::MainTexturesForm(QWidget *parent) : QWidget(parent), ui(new Ui::MainTexturesForm)
|
MainTexturesForm::MainTexturesForm(QWidget *parent) : QWidget(parent), ui(new Ui::MainTexturesForm)
|
||||||
{
|
{
|
||||||
|
@ -150,7 +149,8 @@ void MainTexturesForm::refreshFromFellowData()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTexturesForm::alterRenderer(Renderer* renderer)
|
void MainTexturesForm::alterRenderer(SoftwareRenderer* renderer)
|
||||||
{
|
{
|
||||||
TexturesRendererClass.bind(renderer, textures);
|
renderer->getScenery()->setTextures(textures);
|
||||||
|
renderer->prepare();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ class FreeLayerHelper;
|
||||||
class PreviewLayerCoverage;
|
class PreviewLayerCoverage;
|
||||||
class PreviewLayerLook;
|
class PreviewLayerLook;
|
||||||
class PreviewCumul;
|
class PreviewCumul;
|
||||||
class Renderer;
|
|
||||||
|
|
||||||
class MainTexturesForm : public QWidget
|
class MainTexturesForm : public QWidget
|
||||||
{
|
{
|
||||||
|
@ -29,7 +28,7 @@ public slots:
|
||||||
void commitLocalDataToScenery();
|
void commitLocalDataToScenery();
|
||||||
void refreshFromLocalData();
|
void refreshFromLocalData();
|
||||||
void refreshFromFellowData();
|
void refreshFromFellowData();
|
||||||
void alterRenderer(Renderer* renderer);
|
void alterRenderer(SoftwareRenderer* renderer);
|
||||||
|
|
||||||
void updateLayers();
|
void updateLayers();
|
||||||
void selectLayer(int layer);
|
void selectLayer(int layer);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#define GL_CLAMP_TO_EDGE 0x812F
|
#define GL_CLAMP_TO_EDGE 0x812F
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BaseExplorerChunk::BaseExplorerChunk(Renderer* renderer)
|
BaseExplorerChunk::BaseExplorerChunk(SoftwareRenderer* renderer)
|
||||||
{
|
{
|
||||||
_renderer = renderer;
|
_renderer = renderer;
|
||||||
_color_profile = new ColorProfile;
|
_color_profile = new ColorProfile;
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
class QImage;
|
class QImage;
|
||||||
class QGLWidget;
|
class QGLWidget;
|
||||||
class Renderer;
|
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace opengl {
|
namespace opengl {
|
||||||
|
@ -24,9 +23,9 @@ public:
|
||||||
|
|
||||||
double priority;
|
double priority;
|
||||||
protected:
|
protected:
|
||||||
BaseExplorerChunk(Renderer* renderer);
|
BaseExplorerChunk(SoftwareRenderer* renderer);
|
||||||
|
|
||||||
inline Renderer* renderer() {return _renderer;}
|
inline SoftwareRenderer* renderer() {return _renderer;}
|
||||||
|
|
||||||
void askReset();
|
void askReset();
|
||||||
void setMaxTextureSize(int size);
|
void setMaxTextureSize(int size);
|
||||||
|
@ -41,7 +40,7 @@ protected:
|
||||||
QMutex _lock_data;
|
QMutex _lock_data;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Renderer* _renderer;
|
SoftwareRenderer* _renderer;
|
||||||
ColorProfile* _color_profile;
|
ColorProfile* _color_profile;
|
||||||
|
|
||||||
bool _reset_needed;
|
bool _reset_needed;
|
||||||
|
|
|
@ -2,11 +2,12 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include "renderer.h"
|
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "atmosphere/public.h"
|
#include "SoftwareRenderer.h"
|
||||||
|
#include "AtmosphereRenderer.h"
|
||||||
|
#include "AtmosphereResult.h"
|
||||||
|
|
||||||
ExplorerChunkSky::ExplorerChunkSky(Renderer* renderer, double size, SkyboxOrientation orientation) : BaseExplorerChunk(renderer)
|
ExplorerChunkSky::ExplorerChunkSky(SoftwareRenderer* renderer, double size, SkyboxOrientation orientation) : BaseExplorerChunk(renderer)
|
||||||
{
|
{
|
||||||
_box_size = size;
|
_box_size = size;
|
||||||
_orientation = orientation;
|
_orientation = orientation;
|
||||||
|
@ -143,5 +144,5 @@ Color ExplorerChunkSky::getTextureColor(double x, double y)
|
||||||
{
|
{
|
||||||
location.y = 0.0;
|
location.y = 0.0;
|
||||||
}
|
}
|
||||||
return renderer()->atmosphere->getSkyColor(renderer(), location).final;
|
return renderer()->getAtmosphereRenderer()->getSkyColor(location).final;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ enum SkyboxOrientation
|
||||||
class OPENGLSHARED_EXPORT ExplorerChunkSky:public BaseExplorerChunk
|
class OPENGLSHARED_EXPORT ExplorerChunkSky:public BaseExplorerChunk
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExplorerChunkSky(Renderer* renderer, double size, SkyboxOrientation orientation);
|
ExplorerChunkSky(SoftwareRenderer* renderer, double size, SkyboxOrientation orientation);
|
||||||
|
|
||||||
void onCameraEvent(CameraDefinition* camera);
|
void onCameraEvent(CameraDefinition* camera);
|
||||||
void onRenderEvent(QGLWidget* widget);
|
void onRenderEvent(QGLWidget* widget);
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "renderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "terrain/public.h"
|
#include "TerrainRenderer.h"
|
||||||
|
|
||||||
ExplorerChunkTerrain::ExplorerChunkTerrain(Renderer* renderer, double x, double z, double size, int nbchunks, double water_height) : BaseExplorerChunk(renderer)
|
ExplorerChunkTerrain::ExplorerChunkTerrain(SoftwareRenderer* renderer, double x, double z, double size, int nbchunks, double water_height) : BaseExplorerChunk(renderer)
|
||||||
{
|
{
|
||||||
_startx = x;
|
_startx = x;
|
||||||
_startz = z;
|
_startz = z;
|
||||||
|
@ -43,7 +43,7 @@ void ExplorerChunkTerrain::onResetEvent()
|
||||||
|
|
||||||
bool ExplorerChunkTerrain::onMaintainEvent()
|
bool ExplorerChunkTerrain::onMaintainEvent()
|
||||||
{
|
{
|
||||||
Renderer* renderer = this->renderer();
|
SoftwareRenderer* renderer = this->renderer();
|
||||||
|
|
||||||
// Improve heightmap resolution
|
// Improve heightmap resolution
|
||||||
if (_tessellation_current_size < _tessellation_max_size)
|
if (_tessellation_current_size < _tessellation_max_size)
|
||||||
|
@ -57,7 +57,7 @@ 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->getTerrainRenderer()->getHeight(_startx + _tessellation_step * (double) i, _startz + _tessellation_step * (double) j, 1);
|
||||||
if (height >= _water_height)
|
if (height >= _water_height)
|
||||||
{
|
{
|
||||||
_overwater = true;
|
_overwater = true;
|
||||||
|
@ -170,7 +170,7 @@ double ExplorerChunkTerrain::getDisplayedSizeHint(CameraDefinition* camera)
|
||||||
Color ExplorerChunkTerrain::getTextureColor(double x, double y)
|
Color ExplorerChunkTerrain::getTextureColor(double x, double y)
|
||||||
{
|
{
|
||||||
Vector3 location = {_startx + x * _size, 0.0, _startz + y * _size};
|
Vector3 location = {_startx + x * _size, 0.0, _startz + y * _size};
|
||||||
return renderer()->terrain->getFinalColor(renderer(), location, 0.01);
|
return renderer()->getTerrainRenderer()->getFinalColor(location, 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 ExplorerChunkTerrain::getCenter()
|
Vector3 ExplorerChunkTerrain::getCenter()
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace opengl {
|
||||||
class OPENGLSHARED_EXPORT ExplorerChunkTerrain:public BaseExplorerChunk
|
class OPENGLSHARED_EXPORT ExplorerChunkTerrain:public BaseExplorerChunk
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExplorerChunkTerrain(Renderer* renderer, double x, double z, double size, int nbchunks, double water_height);
|
ExplorerChunkTerrain(SoftwareRenderer* renderer, double x, double z, double size, int nbchunks, double water_height);
|
||||||
~ExplorerChunkTerrain();
|
~ExplorerChunkTerrain();
|
||||||
|
|
||||||
void onCameraEvent(CameraDefinition* camera);
|
void onCameraEvent(CameraDefinition* camera);
|
||||||
|
|
|
@ -11,13 +11,11 @@
|
||||||
#include "OpenGLRenderer.h"
|
#include "OpenGLRenderer.h"
|
||||||
#include "WaterDefinition.h"
|
#include "WaterDefinition.h"
|
||||||
#include "SurfaceMaterial.h"
|
#include "SurfaceMaterial.h"
|
||||||
#include "renderer.h"
|
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "atmosphere/public.h"
|
|
||||||
#include "water/public.h"
|
|
||||||
#include "terrain/public.h"
|
|
||||||
#include "ExplorerChunkSky.h"
|
#include "ExplorerChunkSky.h"
|
||||||
#include "ExplorerChunkTerrain.h"
|
#include "ExplorerChunkTerrain.h"
|
||||||
|
#include "TerrainRenderer.h"
|
||||||
|
#include "WaterRenderer.h"
|
||||||
|
|
||||||
class ChunkMaintenanceThread : public QThread
|
class ChunkMaintenanceThread : public QThread
|
||||||
{
|
{
|
||||||
|
@ -57,7 +55,7 @@ private:
|
||||||
|
|
||||||
static QVector<ChunkMaintenanceThread*> _threads;
|
static QVector<ChunkMaintenanceThread*> _threads;
|
||||||
|
|
||||||
static Vector3 _getCameraLocation(Renderer* renderer, Vector3)
|
/*static Vector3 _getCameraLocation(Renderer* renderer, Vector3)
|
||||||
{
|
{
|
||||||
return ((CameraDefinition*)renderer->customData[2])->getLocation();
|
return ((CameraDefinition*)renderer->customData[2])->getLocation();
|
||||||
}
|
}
|
||||||
|
@ -70,7 +68,7 @@ static AtmosphereResult _applyAerialPerspective(Renderer*, Vector3, Color base)
|
||||||
result.final = base;
|
result.final = base;
|
||||||
atmosphereUpdateResult(&result);
|
atmosphereUpdateResult(&result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera, SoftwareRenderer* renderer) :
|
WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera, SoftwareRenderer* renderer) :
|
||||||
QGLWidget(parent)
|
QGLWidget(parent)
|
||||||
|
@ -95,10 +93,10 @@ QGLWidget(parent)
|
||||||
_opengl_renderer = new OpenGLRenderer(NULL);
|
_opengl_renderer = new OpenGLRenderer(NULL);
|
||||||
_renderer->prepare();
|
_renderer->prepare();
|
||||||
_renderer->render_quality = 3;
|
_renderer->render_quality = 3;
|
||||||
_renderer->customData[2] = _base_camera;
|
/*_renderer->customData[2] = _base_camera;
|
||||||
_renderer->getCameraLocation = _getCameraLocation;
|
_renderer->getCameraLocation = _getCameraLocation;
|
||||||
_renderer->atmosphere->applyAerialPerspective = _applyAerialPerspective;
|
_renderer->atmosphere->applyAerialPerspective = _applyAerialPerspective;
|
||||||
lightingManagerDisableSpecularity(_renderer->lighting);
|
lightingManagerDisableSpecularity(_renderer->lighting);*/
|
||||||
|
|
||||||
_inited = false;
|
_inited = false;
|
||||||
_updated = false;
|
_updated = false;
|
||||||
|
@ -123,7 +121,7 @@ WidgetExplorer::~WidgetExplorer()
|
||||||
|
|
||||||
if (_renderer_created)
|
if (_renderer_created)
|
||||||
{
|
{
|
||||||
rendererDelete(_renderer);
|
delete _renderer;
|
||||||
}
|
}
|
||||||
delete _opengl_renderer;
|
delete _opengl_renderer;
|
||||||
}
|
}
|
||||||
|
@ -135,7 +133,7 @@ void WidgetExplorer::startRendering()
|
||||||
double size = 400.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->water->getHeightInfo(_renderer).base_height;
|
double water_height = _renderer->getWaterRenderer()->getHeightInfo().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++)
|
||||||
|
@ -402,7 +400,7 @@ void WidgetExplorer::paintGL()
|
||||||
GLenum error_code;
|
GLenum error_code;
|
||||||
QTime start_time;
|
QTime start_time;
|
||||||
double frame_time;
|
double frame_time;
|
||||||
WaterDefinition* water = _renderer->water->definition;
|
WaterDefinition* water = _renderer->getScenery()->getWater();
|
||||||
|
|
||||||
// Don't do this at each frame, only on camera change
|
// Don't do this at each frame, only on camera change
|
||||||
_renderer->getScenery()->setCamera(_current_camera);
|
_renderer->getScenery()->setCamera(_current_camera);
|
||||||
|
@ -422,7 +420,7 @@ void WidgetExplorer::paintGL()
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
// Render water
|
// Render water
|
||||||
double water_height = _renderer->terrain->getWaterHeight(_renderer);
|
double water_height = _renderer->getTerrainRenderer()->getWaterHeight();
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
glColor3f(water->material->_rgb.r, water->material->_rgb.g, water->material->_rgb.b);
|
glColor3f(water->material->_rgb.r, water->material->_rgb.g, water->material->_rgb.b);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "LightComponent.h"
|
#include "LightComponent.h"
|
||||||
#include "AtmosphereResult.h"
|
#include "AtmosphereResult.h"
|
||||||
|
|
||||||
static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
|
/*static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
|
||||||
{
|
{
|
||||||
LightComponent light;
|
LightComponent light;
|
||||||
|
|
||||||
|
@ -45,17 +45,7 @@ static double _getDensity(Renderer*, CloudLayerDefinition* layer, Vector3 locati
|
||||||
{
|
{
|
||||||
return (1.0 - distance) / 0.2;
|
return (1.0 - distance) / 0.2;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
static AtmosphereResult _fakeApplyAerialPerspective(Renderer*, Vector3, Color base)
|
|
||||||
{
|
|
||||||
AtmosphereResult result;
|
|
||||||
|
|
||||||
result.base = base;
|
|
||||||
result.final = base;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloudsAspectPreviewRenderer::CloudsAspectPreviewRenderer(CloudLayerDefinition* layer):
|
CloudsAspectPreviewRenderer::CloudsAspectPreviewRenderer(CloudLayerDefinition* layer):
|
||||||
layer(layer)
|
layer(layer)
|
||||||
|
@ -82,9 +72,9 @@ void CloudsAspectPreviewRenderer::updateEvent()
|
||||||
|
|
||||||
prepare();
|
prepare();
|
||||||
|
|
||||||
|
//disableAerialPerspective();
|
||||||
//clouds->getLayerDensity = _getDensity;
|
//clouds->getLayerDensity = _getDensity;
|
||||||
//atmosphere->getLightingStatus = _getLightingStatus;
|
//atmosphere->getLightingStatus = _getLightingStatus;
|
||||||
//atmosphere->applyAerialPerspective = _fakeApplyAerialPerspective;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Color CloudsAspectPreviewRenderer::getColor2D(double x, double y, double)
|
Color CloudsAspectPreviewRenderer::getColor2D(double x, double y, double)
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
#include "CloudsDefinition.h"
|
#include "CloudsDefinition.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
|
#include "TerrainRenderer.h"
|
||||||
|
#include "WaterRenderer.h"
|
||||||
|
|
||||||
static Vector3 _getCameraLocation(Renderer*, Vector3 location)
|
/*static Vector3 _getCameraLocation(Renderer*, Vector3 location)
|
||||||
{
|
{
|
||||||
return v3Add(location, v3Scale(VECTOR_UP, 50.0));
|
return v3Add(location, v3Scale(VECTOR_UP, 50.0));
|
||||||
}
|
}
|
||||||
|
@ -17,7 +19,7 @@ static AtmosphereResult _applyAerialPerspective(Renderer*, Vector3, Color base)
|
||||||
result.final = base;
|
result.final = base;
|
||||||
atmosphereUpdateResult(&result);
|
atmosphereUpdateResult(&result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
SceneryTopDownPreviewRenderer::SceneryTopDownPreviewRenderer(Scenery* scenery):
|
SceneryTopDownPreviewRenderer::SceneryTopDownPreviewRenderer(Scenery* scenery):
|
||||||
scenery(scenery)
|
scenery(scenery)
|
||||||
|
@ -51,26 +53,26 @@ void SceneryTopDownPreviewRenderer::updateEvent()
|
||||||
|
|
||||||
prepare();
|
prepare();
|
||||||
|
|
||||||
getCameraLocation = _getCameraLocation;
|
/*getCameraLocation = _getCameraLocation;
|
||||||
lightingManagerDisableSpecularity(lighting);
|
lightingManagerDisableSpecularity(lighting);
|
||||||
atmosphere->applyAerialPerspective = _applyAerialPerspective;
|
atmosphere->applyAerialPerspective = _applyAerialPerspective;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
Color SceneryTopDownPreviewRenderer::getColor2D(double x, double y, double scaling)
|
Color SceneryTopDownPreviewRenderer::getColor2D(double x, double y, double scaling)
|
||||||
{
|
{
|
||||||
Vector3 location;
|
Vector3 location;
|
||||||
double height = terrain->getHeight(this, x, y, 1);
|
double height = getTerrainRenderer()->getHeight(x, y, 1);
|
||||||
|
|
||||||
if (height < water->getHeightInfo(this).max_height)
|
if (height < getWaterRenderer()->getHeightInfo().max_height)
|
||||||
{
|
{
|
||||||
return water->getResult(this, x, y).final;
|
return getWaterRenderer()->getResult(x, y).final;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
location.x = x;
|
location.x = x;
|
||||||
location.y = height;
|
location.y = height;
|
||||||
location.z = y;
|
location.z = y;
|
||||||
return terrain->getFinalColor(this, location, scaling);
|
return getTerrainRenderer()->getFinalColor(location, scaling);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,12 @@
|
||||||
#include "SurfaceMaterial.h"
|
#include "SurfaceMaterial.h"
|
||||||
#include "NoiseGenerator.h"
|
#include "NoiseGenerator.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
|
#include "Scenery.h"
|
||||||
#include "LightComponent.h"
|
#include "LightComponent.h"
|
||||||
#include "LightStatus.h"
|
#include "LightStatus.h"
|
||||||
|
#include "TerrainRenderer.h"
|
||||||
|
|
||||||
static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
|
/*static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
|
||||||
{
|
{
|
||||||
LightComponent light;
|
LightComponent light;
|
||||||
|
|
||||||
|
@ -42,32 +44,13 @@ static Vector3 _getCameraLocation(Renderer*, Vector3 location)
|
||||||
location.y += 15.0;
|
location.y += 15.0;
|
||||||
location.z += 10.0;
|
location.z += 10.0;
|
||||||
return location;
|
return location;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
static void _alterPreviewRenderer(Renderer* renderer)
|
|
||||||
{
|
|
||||||
renderer->render_quality = 3;
|
|
||||||
renderer->getCameraLocation = _getCameraLocation;
|
|
||||||
renderer->atmosphere->getLightingStatus = _getLightingStatus;
|
|
||||||
|
|
||||||
TexturesDefinition textures(NULL);
|
|
||||||
TextureLayerDefinition* layer = textures.getTextureLayer(textures.addLayer());
|
|
||||||
layer->terrain_zone->clear();
|
|
||||||
layer->displacement_height = 0.0;
|
|
||||||
layer->material->base = colorToHSL(COLOR_WHITE);
|
|
||||||
layer->material->reflection = 0.05;
|
|
||||||
layer->material->shininess = 2.0;
|
|
||||||
layer->validate();
|
|
||||||
layer->_detail_noise->clearLevels();
|
|
||||||
|
|
||||||
TexturesRendererClass.bind(renderer, &textures);
|
|
||||||
}
|
|
||||||
|
|
||||||
TerrainShapePreviewRenderer::TerrainShapePreviewRenderer(TerrainDefinition* terrain)
|
TerrainShapePreviewRenderer::TerrainShapePreviewRenderer(TerrainDefinition* terrain)
|
||||||
{
|
{
|
||||||
_terrain = terrain;
|
_terrain = terrain;
|
||||||
|
|
||||||
_alterPreviewRenderer(this);
|
render_quality = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerrainShapePreviewRenderer::bindEvent(BasePreview* preview)
|
void TerrainShapePreviewRenderer::bindEvent(BasePreview* preview)
|
||||||
|
@ -80,17 +63,31 @@ void TerrainShapePreviewRenderer::bindEvent(BasePreview* preview)
|
||||||
|
|
||||||
void TerrainShapePreviewRenderer::updateEvent()
|
void TerrainShapePreviewRenderer::updateEvent()
|
||||||
{
|
{
|
||||||
TerrainRendererClass.bind(this, _terrain);
|
getScenery()->setTerrain(_terrain);
|
||||||
|
|
||||||
|
prepare();
|
||||||
|
|
||||||
|
/*getCameraLocation = _getCameraLocation;
|
||||||
|
atmosphere->getLightingStatus = _getLightingStatus;*/
|
||||||
|
|
||||||
|
TextureLayerDefinition* layer = getScenery()->getTextures()->getTextureLayer(0);
|
||||||
|
layer->terrain_zone->clear();
|
||||||
|
layer->displacement_height = 0.0;
|
||||||
|
layer->material->base = colorToHSL(COLOR_WHITE);
|
||||||
|
layer->material->reflection = 0.05;
|
||||||
|
layer->material->shininess = 2.0;
|
||||||
|
layer->validate();
|
||||||
|
layer->_detail_noise->clearLevels();
|
||||||
}
|
}
|
||||||
|
|
||||||
Color TerrainShapePreviewRenderer::getColor2D(double x, double y, double scaling)
|
Color TerrainShapePreviewRenderer::getColor2D(double x, double y, double scaling)
|
||||||
{
|
{
|
||||||
double height;
|
double height;
|
||||||
|
|
||||||
height = terrain->getHeight(this, x, y, 1);
|
height = getTerrainRenderer()->getHeight(x, y, 1);
|
||||||
if (height > terrain->getWaterHeight(this))
|
if (height > getTerrainRenderer()->getWaterHeight())
|
||||||
{
|
{
|
||||||
return terrain->getFinalColor(this, Vector3(x, height, y), 0.000001);
|
return getTerrainRenderer()->getFinalColor(Vector3(x, height, y), 0.000001);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,64 +4,13 @@
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
#include "WaterDefinition.h"
|
#include "WaterDefinition.h"
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
|
#include "WaterRenderer.h"
|
||||||
|
|
||||||
static double _getWaterHeight(Renderer*)
|
/*static double _getWaterHeight(Renderer*)
|
||||||
{
|
{
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RayCastingResult _rayWalking(SoftwareRenderer* renderer, Vector3 location, Vector3 direction, int, int, int, int)
|
|
||||||
{
|
|
||||||
RayCastingResult result;
|
|
||||||
int background = *(int*)renderer->customData[1];
|
|
||||||
double x, y;
|
|
||||||
|
|
||||||
result.hit = 1;
|
|
||||||
if (direction.z < 0.0001)
|
|
||||||
{
|
|
||||||
result.hit_color = COLOR_WHITE;
|
|
||||||
result.hit_location = location;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
x = location.x + direction.x * (0.0 - location.z) / direction.z;
|
|
||||||
y = location.y + direction.y * (0.0 - location.z) / direction.z;
|
|
||||||
|
|
||||||
switch (background)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
result.hit_color = (((int) ceil(x * 0.2) % 2 == 0) ^ ((int) ceil(y * 0.2 - 0.5) % 2 == 0)) ? COLOR_WHITE : COLOR_BLACK;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
result.hit_color = (y * 0.1 > x * 0.03 + sin(x - M_PI_2)) ? COLOR_WHITE : COLOR_BLACK;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result.hit_color = COLOR_WHITE;
|
|
||||||
}
|
|
||||||
result.hit_location.x = x;
|
|
||||||
result.hit_location.y = y;
|
|
||||||
result.hit_location.z = 0.0;
|
|
||||||
|
|
||||||
if (result.hit_location.y < 0.0)
|
|
||||||
{
|
|
||||||
double lighting_depth = renderer->getScenery()->getWater()->lighting_depth;
|
|
||||||
if (result.hit_location.y < -lighting_depth)
|
|
||||||
{
|
|
||||||
result.hit_color = COLOR_BLACK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
double attenuation = -result.hit_location.y / lighting_depth;
|
|
||||||
result.hit_color.r *= 1.0 - attenuation;
|
|
||||||
result.hit_color.g *= 1.0 - attenuation;
|
|
||||||
result.hit_color.b *= 1.0 - attenuation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3, int)
|
static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3, int)
|
||||||
{
|
{
|
||||||
LightDefinition light;
|
LightDefinition light;
|
||||||
|
@ -85,7 +34,7 @@ static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3,
|
||||||
static double _getPrecision(Renderer*, Vector3)
|
static double _getPrecision(Renderer*, Vector3)
|
||||||
{
|
{
|
||||||
return 0.000001;
|
return 0.000001;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
WaterAspectPreviewRenderer::WaterAspectPreviewRenderer(WaterDefinition* definition):
|
WaterAspectPreviewRenderer::WaterAspectPreviewRenderer(WaterDefinition* definition):
|
||||||
definition(definition)
|
definition(definition)
|
||||||
|
@ -117,8 +66,7 @@ void WaterAspectPreviewRenderer::updateEvent()
|
||||||
|
|
||||||
//terrain->getWaterHeight = _getWaterHeight;
|
//terrain->getWaterHeight = _getWaterHeight;
|
||||||
//atmosphere->getLightingStatus = _getLightingStatus;
|
//atmosphere->getLightingStatus = _getLightingStatus;
|
||||||
//rayWalking = _rayWalking;
|
//getPrecision = _getPrecision;
|
||||||
getPrecision = _getPrecision;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterAspectPreviewRenderer::cameraEvent(double, double, double scaling)
|
void WaterAspectPreviewRenderer::cameraEvent(double, double, double scaling)
|
||||||
|
@ -138,7 +86,7 @@ Color WaterAspectPreviewRenderer::getColor2D(double x, double y, double scaling)
|
||||||
|
|
||||||
if (look.y > -0.0001)
|
if (look.y > -0.0001)
|
||||||
{
|
{
|
||||||
return _rayWalking(this, eye, look, 0, 0, 0, 0).hit_color;
|
return rayWalking(eye, look, 0, 0, 0, 0).hit_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
target_x = eye.x - look.x * eye.y / look.y;
|
target_x = eye.x - look.x * eye.y / look.y;
|
||||||
|
@ -146,10 +94,10 @@ Color WaterAspectPreviewRenderer::getColor2D(double x, double y, double scaling)
|
||||||
|
|
||||||
if (target_z > 0.0)
|
if (target_z > 0.0)
|
||||||
{
|
{
|
||||||
return _rayWalking(this, eye, look, 0, 0, 0, 0).hit_color;
|
return rayWalking(eye, look, 0, 0, 0, 0).hit_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
return water->getResult(this, target_x, target_z).final;
|
return getWaterRenderer()->getResult(target_x, target_z).final;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterAspectPreviewRenderer::toggleChangeEvent(const std::string &key, bool value)
|
void WaterAspectPreviewRenderer::toggleChangeEvent(const std::string &key, bool value)
|
||||||
|
@ -167,3 +115,54 @@ void WaterAspectPreviewRenderer::choiceChangeEvent(const std::string &key, int p
|
||||||
background = position;
|
background = position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RayCastingResult WaterAspectPreviewRenderer::rayWalking(const Vector3 &location, const Vector3 &direction, int, int, int, int)
|
||||||
|
{
|
||||||
|
RayCastingResult result;
|
||||||
|
double x, y;
|
||||||
|
|
||||||
|
result.hit = 1;
|
||||||
|
if (direction.z < 0.0001)
|
||||||
|
{
|
||||||
|
result.hit_color = COLOR_WHITE;
|
||||||
|
result.hit_location = location;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x = location.x + direction.x * (0.0 - location.z) / direction.z;
|
||||||
|
y = location.y + direction.y * (0.0 - location.z) / direction.z;
|
||||||
|
|
||||||
|
switch (background)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
result.hit_color = (((int) ceil(x * 0.2) % 2 == 0) ^ ((int) ceil(y * 0.2 - 0.5) % 2 == 0)) ? COLOR_WHITE : COLOR_BLACK;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result.hit_color = (y * 0.1 > x * 0.03 + sin(x - M_PI_2)) ? COLOR_WHITE : COLOR_BLACK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result.hit_color = COLOR_WHITE;
|
||||||
|
}
|
||||||
|
result.hit_location.x = x;
|
||||||
|
result.hit_location.y = y;
|
||||||
|
result.hit_location.z = 0.0;
|
||||||
|
|
||||||
|
if (result.hit_location.y < 0.0)
|
||||||
|
{
|
||||||
|
double lighting_depth = getScenery()->getWater()->lighting_depth;
|
||||||
|
if (result.hit_location.y < -lighting_depth)
|
||||||
|
{
|
||||||
|
result.hit_color = COLOR_BLACK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double attenuation = -result.hit_location.y / lighting_depth;
|
||||||
|
result.hit_color.r *= 1.0 - attenuation;
|
||||||
|
result.hit_color.g *= 1.0 - attenuation;
|
||||||
|
result.hit_color.b *= 1.0 - attenuation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ public:
|
||||||
virtual void toggleChangeEvent(const std::string &key, bool value) override;
|
virtual void toggleChangeEvent(const std::string &key, bool value) override;
|
||||||
virtual void choiceChangeEvent(const std::string &key, int position) override;
|
virtual void choiceChangeEvent(const std::string &key, int position) override;
|
||||||
|
|
||||||
|
virtual RayCastingResult rayWalking(const Vector3 &location, const Vector3 &direction, int terrain, int water, int sky, int clouds) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WaterDefinition* definition;
|
WaterDefinition* definition;
|
||||||
bool lighting;
|
bool lighting;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
|
#include "ParallelWork.h"
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
#include "AtmosphereDefinition.h"
|
#include "AtmosphereDefinition.h"
|
||||||
|
@ -20,8 +21,6 @@
|
||||||
#include "LightStatus.h"
|
#include "LightStatus.h"
|
||||||
#include "tools/cache.h"
|
#include "tools/cache.h"
|
||||||
#include "tools/texture.h"
|
#include "tools/texture.h"
|
||||||
#include "tools/parallel.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
|
|
||||||
/* Factor to convert software units to kilometers */
|
/* Factor to convert software units to kilometers */
|
||||||
// TODO This is copied in AtmosphereRenderer
|
// TODO This is copied in AtmosphereRenderer
|
||||||
|
@ -1088,9 +1087,9 @@ int brunetonInit()
|
||||||
/* computes single scattering texture deltaS (line 3 in algorithm 4.1)
|
/* computes single scattering texture deltaS (line 3 in algorithm 4.1)
|
||||||
* Rayleigh and Mie separated in deltaSR + deltaSM */
|
* Rayleigh and Mie separated in deltaSR + deltaSM */
|
||||||
Inscatter1Params params = {_deltaSRTexture, _deltaSMTexture};
|
Inscatter1Params params = {_deltaSRTexture, _deltaSMTexture};
|
||||||
work = parallelWorkCreate(_inscatter1Worker, RES_R, ¶ms);
|
work = new ParallelWork(_inscatter1Worker, RES_R, ¶ms);
|
||||||
parallelWorkPerform(work, -1);
|
work->perform();
|
||||||
parallelWorkDelete(work);
|
delete work;
|
||||||
_saveDebug4D(_deltaSRTexture, "deltaSR", 0);
|
_saveDebug4D(_deltaSRTexture, "deltaSR", 0);
|
||||||
_saveDebug4D(_deltaSMTexture, "deltaSM", 0);
|
_saveDebug4D(_deltaSMTexture, "deltaSM", 0);
|
||||||
|
|
||||||
|
@ -1122,9 +1121,9 @@ int brunetonInit()
|
||||||
{
|
{
|
||||||
/* computes deltaJ (line 7 in algorithm 4.1) */
|
/* computes deltaJ (line 7 in algorithm 4.1) */
|
||||||
jParams jparams = {_deltaJTexture, _deltaETexture, _deltaSRTexture, _deltaSMTexture, order == 2};
|
jParams jparams = {_deltaJTexture, _deltaETexture, _deltaSRTexture, _deltaSMTexture, order == 2};
|
||||||
work = parallelWorkCreate(_jWorker, RES_R, &jparams);
|
work = new ParallelWork(_jWorker, RES_R, &jparams);
|
||||||
parallelWorkPerform(work, -1);
|
work->perform();
|
||||||
parallelWorkDelete(work);
|
delete work;
|
||||||
_saveDebug4D(_deltaJTexture, "deltaJ", order);
|
_saveDebug4D(_deltaJTexture, "deltaJ", order);
|
||||||
|
|
||||||
/* computes deltaE (line 8 in algorithm 4.1) */
|
/* computes deltaE (line 8 in algorithm 4.1) */
|
||||||
|
@ -1133,10 +1132,9 @@ int brunetonInit()
|
||||||
|
|
||||||
/* computes deltaS (line 9 in algorithm 4.1) */
|
/* computes deltaS (line 9 in algorithm 4.1) */
|
||||||
InscatterNParams iparams = {_deltaSRTexture, _deltaJTexture};
|
InscatterNParams iparams = {_deltaSRTexture, _deltaJTexture};
|
||||||
work = parallelWorkCreate(_inscatterNWorker, RES_R, &iparams);
|
work = new ParallelWork(_inscatterNWorker, RES_R, &iparams);
|
||||||
parallelWorkPerform(work, -1);
|
work->perform();
|
||||||
parallelWorkDelete(work);
|
delete work;
|
||||||
_saveDebug4D(_deltaSRTexture, "deltaSR", order);
|
|
||||||
|
|
||||||
/* adds deltaE into irradiance texture E (line 10 in algorithm 4.1) */
|
/* adds deltaE into irradiance texture E (line 10 in algorithm 4.1) */
|
||||||
texture2DAdd(_deltaETexture, _irradianceTexture);
|
texture2DAdd(_deltaETexture, _irradianceTexture);
|
||||||
|
@ -1144,9 +1142,9 @@ int brunetonInit()
|
||||||
|
|
||||||
/* adds deltaS into inscatter texture S (line 11 in algorithm 4.1) */
|
/* adds deltaS into inscatter texture S (line 11 in algorithm 4.1) */
|
||||||
CopyInscatterNParams cparams = {_deltaSRTexture, _inscatterTexture};
|
CopyInscatterNParams cparams = {_deltaSRTexture, _inscatterTexture};
|
||||||
work = parallelWorkCreate(_copyInscatterNWorker, RES_R, &cparams);
|
work = new ParallelWork(_copyInscatterNWorker, RES_R, &cparams);
|
||||||
parallelWorkPerform(work, -1);
|
work->perform();
|
||||||
parallelWorkDelete(work);
|
delete work;
|
||||||
_saveDebug4D(_inscatterTexture, "inscatter", order);
|
_saveDebug4D(_inscatterTexture, "inscatter", order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1204,7 +1202,7 @@ AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3
|
||||||
|
|
||||||
AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 location, const Color &base)
|
AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 location, const Color &base)
|
||||||
{
|
{
|
||||||
Vector3 eye = parent->getCameraLocation(parent, location);
|
Vector3 eye = parent->getCameraLocation(location);
|
||||||
Vector3 sun_position = v3Scale(parent->getAtmosphereRenderer()->getSunDirection(), SUN_DISTANCE);
|
Vector3 sun_position = v3Scale(parent->getAtmosphereRenderer()->getSunDirection(), SUN_DISTANCE);
|
||||||
|
|
||||||
double yoffset = GROUND_OFFSET - parent->getWaterRenderer()->getHeightInfo().base_height;
|
double yoffset = GROUND_OFFSET - parent->getWaterRenderer()->getHeightInfo().base_height;
|
||||||
|
|
|
@ -69,7 +69,7 @@ static inline void _applyWeatherEffects(AtmosphereDefinition* definition, Atmosp
|
||||||
|
|
||||||
|
|
||||||
BaseAtmosphereRenderer::BaseAtmosphereRenderer(SoftwareRenderer* renderer):
|
BaseAtmosphereRenderer::BaseAtmosphereRenderer(SoftwareRenderer* renderer):
|
||||||
renderer(renderer)
|
parent(renderer)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -123,13 +123,13 @@ Vector3 BaseAtmosphereRenderer::getSunDirection()
|
||||||
|
|
||||||
AtmosphereDefinition* BaseAtmosphereRenderer::getDefinition()
|
AtmosphereDefinition* BaseAtmosphereRenderer::getDefinition()
|
||||||
{
|
{
|
||||||
return renderer->getScenery()->getAtmosphere();
|
return parent->getScenery()->getAtmosphere();
|
||||||
}
|
}
|
||||||
|
|
||||||
SoftwareBrunetonAtmosphereRenderer::SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer):
|
SoftwareBrunetonAtmosphereRenderer::SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer):
|
||||||
BaseAtmosphereRenderer(renderer)
|
BaseAtmosphereRenderer(renderer)
|
||||||
{
|
{
|
||||||
model = new AtmosphereModelBruneton(this);
|
model = new AtmosphereModelBruneton(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
SoftwareBrunetonAtmosphereRenderer::~SoftwareBrunetonAtmosphereRenderer()
|
SoftwareBrunetonAtmosphereRenderer::~SoftwareBrunetonAtmosphereRenderer()
|
||||||
|
@ -170,7 +170,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(Vector3 directi
|
||||||
Color base;
|
Color base;
|
||||||
|
|
||||||
definition = getDefinition();
|
definition = getDefinition();
|
||||||
camera_location = renderer->getCameraLocation(renderer, VECTOR_ZERO);
|
camera_location = parent->getCameraLocation(VECTOR_ZERO);
|
||||||
|
|
||||||
sun_direction = getSunDirection();
|
sun_direction = getSunDirection();
|
||||||
direction = v3Normalize(direction);
|
direction = v3Normalize(direction);
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace software {
|
||||||
class BaseAtmosphereRenderer
|
class BaseAtmosphereRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BaseAtmosphereRenderer(SoftwareRenderer* renderer);
|
BaseAtmosphereRenderer(SoftwareRenderer* parent);
|
||||||
virtual ~BaseAtmosphereRenderer() {}
|
virtual ~BaseAtmosphereRenderer() {}
|
||||||
|
|
||||||
virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque);
|
virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque);
|
||||||
|
@ -21,13 +21,13 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual AtmosphereDefinition* getDefinition();
|
virtual AtmosphereDefinition* getDefinition();
|
||||||
SoftwareRenderer* renderer;
|
SoftwareRenderer* parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SoftwareBrunetonAtmosphereRenderer: public BaseAtmosphereRenderer
|
class SoftwareBrunetonAtmosphereRenderer: public BaseAtmosphereRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer);
|
SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* parent);
|
||||||
virtual ~SoftwareBrunetonAtmosphereRenderer();
|
virtual ~SoftwareBrunetonAtmosphereRenderer();
|
||||||
|
|
||||||
virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque) override;
|
virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque) override;
|
||||||
|
|
|
@ -160,7 +160,7 @@ Color CloudBasicLayerRenderer::getColor(BaseCloudsModel *model, const Vector3 &e
|
||||||
direction = direction.normalize();
|
direction = direction.normalize();
|
||||||
result = COLOR_TRANSPARENT;
|
result = COLOR_TRANSPARENT;
|
||||||
|
|
||||||
detail = parent->getPrecision(parent, start) / layer->scaling;
|
detail = parent->getPrecision(start) / layer->scaling;
|
||||||
double transparency_depth = layer->scaling * 0.5;
|
double transparency_depth = layer->scaling * 0.5;
|
||||||
|
|
||||||
segment_count = _findSegments(model, parent, start, direction, detail, 20, transparency_depth, max_length, &inside_length, &total_length, segments);
|
segment_count = _findSegments(model, parent, start, direction, detail, 20, transparency_depth, max_length, &inside_length, &total_length, segments);
|
||||||
|
|
5
src/render/software/RayCastingManager.cpp
Normal file
5
src/render/software/RayCastingManager.cpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include "RayCastingManager.h"
|
||||||
|
|
||||||
|
RayCastingManager::RayCastingManager()
|
||||||
|
{
|
||||||
|
}
|
29
src/render/software/RayCastingManager.h
Normal file
29
src/render/software/RayCastingManager.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef RAYCASTINGMANAGER_H
|
||||||
|
#define RAYCASTINGMANAGER_H
|
||||||
|
|
||||||
|
#include "software_global.h"
|
||||||
|
|
||||||
|
#include "Color.h"
|
||||||
|
#include "Vector3.h"
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace software {
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int hit;
|
||||||
|
Color hit_color;
|
||||||
|
Vector3 hit_location;
|
||||||
|
} RayCastingResult;
|
||||||
|
typedef RayCastingResult (*FuncGeneralCastRay)(SoftwareRenderer* renderer, Vector3 start, Vector3 direction);
|
||||||
|
|
||||||
|
class SOFTWARESHARED_EXPORT RayCastingManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RayCastingManager();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // RAYCASTINGMANAGER_H
|
|
@ -1,17 +1,14 @@
|
||||||
#include "render.h"
|
#include "RenderArea.h"
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "renderer.h"
|
|
||||||
#include "CameraDefinition.h"
|
|
||||||
#include "PictureFile.h"
|
|
||||||
#include "Thread.h"
|
|
||||||
#include "Mutex.h"
|
|
||||||
#include "System.h"
|
|
||||||
#include "Vector3.h"
|
#include "Vector3.h"
|
||||||
#include "ColorProfile.h"
|
#include "ColorProfile.h"
|
||||||
|
#include "Mutex.h"
|
||||||
|
#include "CameraDefinition.h"
|
||||||
|
#include "SoftwareRenderer.h"
|
||||||
|
#include "Thread.h"
|
||||||
|
#include "PictureFile.h"
|
||||||
|
|
||||||
typedef struct
|
struct RenderFragment
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -33,7 +30,7 @@ typedef struct
|
||||||
} color;
|
} color;
|
||||||
} data;
|
} data;
|
||||||
double z;
|
double z;
|
||||||
} RenderFragment;
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -44,32 +41,10 @@ typedef struct
|
||||||
int callback;
|
int callback;
|
||||||
} ScanPoint;
|
} ScanPoint;
|
||||||
|
|
||||||
typedef struct
|
struct FragmentCallback
|
||||||
{
|
{
|
||||||
f_RenderFragmentCallback function;
|
RenderArea::f_RenderFragmentCallback function;
|
||||||
void* data;
|
void* data;
|
||||||
} FragmentCallback;
|
|
||||||
|
|
||||||
struct RenderArea
|
|
||||||
{
|
|
||||||
ColorProfile* hdr_mapping;
|
|
||||||
Renderer* renderer;
|
|
||||||
RenderParams params;
|
|
||||||
int pixel_count;
|
|
||||||
int pixel_done;
|
|
||||||
RenderFragment* pixels;
|
|
||||||
int fragment_callbacks_count;
|
|
||||||
FragmentCallback fragment_callbacks[64];
|
|
||||||
Color background_color;
|
|
||||||
volatile int dirty_left;
|
|
||||||
volatile int dirty_right;
|
|
||||||
volatile int dirty_up;
|
|
||||||
volatile int dirty_down;
|
|
||||||
volatile int dirty_count;
|
|
||||||
Mutex* lock;
|
|
||||||
RenderCallbackStart callback_start;
|
|
||||||
RenderCallbackDraw callback_draw;
|
|
||||||
RenderCallbackUpdate callback_update;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -97,122 +72,110 @@ static void _callbackStart(int, int, Color) {}
|
||||||
static void _callbackDraw(int, int, Color) {}
|
static void _callbackDraw(int, int, Color) {}
|
||||||
static void _callbackUpdate(double) {}
|
static void _callbackUpdate(double) {}
|
||||||
|
|
||||||
void renderInit()
|
RenderArea::RenderArea(SoftwareRenderer* renderer)
|
||||||
{
|
{
|
||||||
|
this->renderer = renderer;
|
||||||
|
this->hdr_mapping = new ColorProfile;
|
||||||
|
this->params.width = 1;
|
||||||
|
this->params.height = 1;
|
||||||
|
this->params.antialias = 1;
|
||||||
|
this->params.quality = 5;
|
||||||
|
this->pixel_count = 1;
|
||||||
|
this->pixels = new RenderFragment[1];
|
||||||
|
this->fragment_callbacks_count = 0;
|
||||||
|
this->fragment_callbacks = new FragmentCallback[64];
|
||||||
|
this->background_color = COLOR_TRANSPARENT;
|
||||||
|
this->dirty_left = 1;
|
||||||
|
this->dirty_right = -1;
|
||||||
|
this->dirty_down = 1;
|
||||||
|
this->dirty_up = -1;
|
||||||
|
this->dirty_count = 0;
|
||||||
|
this->lock = new Mutex();
|
||||||
|
this->callback_start = _callbackStart;
|
||||||
|
this->callback_draw = _callbackDraw;
|
||||||
|
this->callback_update = _callbackUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderQuit()
|
RenderArea::~RenderArea()
|
||||||
{
|
{
|
||||||
|
delete hdr_mapping;
|
||||||
|
delete lock;
|
||||||
|
delete[] fragment_callbacks;
|
||||||
|
delete[] pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderArea* renderCreateArea(Renderer* renderer)
|
void RenderArea::setAllDirty()
|
||||||
{
|
{
|
||||||
RenderArea* result;
|
dirty_left = 0;
|
||||||
|
dirty_right = params.width * params.antialias - 1;
|
||||||
result = new RenderArea;
|
dirty_down = 0;
|
||||||
result->renderer = renderer;
|
dirty_up = params.height * params.antialias - 1;
|
||||||
result->hdr_mapping = new ColorProfile;
|
|
||||||
result->params.width = 1;
|
|
||||||
result->params.height = 1;
|
|
||||||
result->params.antialias = 1;
|
|
||||||
result->params.quality = 5;
|
|
||||||
result->pixel_count = 1;
|
|
||||||
result->pixels = new RenderFragment[1];
|
|
||||||
result->fragment_callbacks_count = 0;
|
|
||||||
result->background_color = COLOR_TRANSPARENT;
|
|
||||||
result->dirty_left = 1;
|
|
||||||
result->dirty_right = -1;
|
|
||||||
result->dirty_down = 1;
|
|
||||||
result->dirty_up = -1;
|
|
||||||
result->dirty_count = 0;
|
|
||||||
result->lock = new Mutex();
|
|
||||||
result->callback_start = _callbackStart;
|
|
||||||
result->callback_draw = _callbackDraw;
|
|
||||||
result->callback_update = _callbackUpdate;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderDeleteArea(RenderArea* area)
|
void RenderArea::setParams(RenderParams params)
|
||||||
{
|
|
||||||
delete area->hdr_mapping;
|
|
||||||
delete area->lock;
|
|
||||||
free(area->pixels);
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
width = params.width * params.antialias;
|
width = params.width * params.antialias;
|
||||||
height = params.height * params.antialias;
|
height = params.height * params.antialias;
|
||||||
|
|
||||||
area->params = params;
|
params = params;
|
||||||
delete[] area->pixels;
|
delete[] pixels;
|
||||||
area->pixels = new RenderFragment[width * height];
|
pixels = new RenderFragment[width * height];
|
||||||
area->pixel_count = width * height;
|
pixel_count = width * height;
|
||||||
|
|
||||||
area->dirty_left = width;
|
dirty_left = width;
|
||||||
area->dirty_right = -1;
|
dirty_right = -1;
|
||||||
area->dirty_down = height;
|
dirty_down = height;
|
||||||
area->dirty_up = -1;
|
dirty_up = -1;
|
||||||
area->dirty_count = 0;
|
dirty_count = 0;
|
||||||
|
|
||||||
renderClear(area);
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSetToneMapping(RenderArea* area, const ColorProfile &profile)
|
void RenderArea::setToneMapping(const ColorProfile &profile)
|
||||||
{
|
{
|
||||||
profile.copy(area->hdr_mapping);
|
profile.copy(hdr_mapping);
|
||||||
_setAllDirty(area);
|
setAllDirty();
|
||||||
renderUpdate(area);
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSetBackgroundColor(RenderArea* area, const Color &col)
|
void RenderArea::setBackgroundColor(const Color &col)
|
||||||
{
|
{
|
||||||
area->background_color = col;
|
background_color = col;
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderClear(RenderArea* area)
|
void RenderArea::clear()
|
||||||
{
|
{
|
||||||
RenderFragment* pixel;
|
RenderFragment* pixel;
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
area->fragment_callbacks_count = 1;
|
fragment_callbacks_count = 1;
|
||||||
area->fragment_callbacks[0].function = NULL;
|
fragment_callbacks[0].function = NULL;
|
||||||
area->fragment_callbacks[0].data = NULL;
|
fragment_callbacks[0].data = NULL;
|
||||||
|
|
||||||
for (x = 0; x < area->params.width * area->params.antialias; x++)
|
for (x = 0; x < params.width * params.antialias; x++)
|
||||||
{
|
{
|
||||||
for (y = 0; y < area->params.height * area->params.antialias; y++)
|
for (y = 0; y < params.height * params.antialias; y++)
|
||||||
{
|
{
|
||||||
pixel = area->pixels + (y * area->params.width * area->params.antialias + x);
|
pixel = pixels + (y * params.width * params.antialias + x);
|
||||||
pixel->z = -100000000.0;
|
pixel->z = -100000000.0;
|
||||||
pixel->flags.dirty = 0;
|
pixel->flags.dirty = 0;
|
||||||
pixel->flags.callback = 0;
|
pixel->flags.callback = 0;
|
||||||
pixel->data.color.r = area->background_color.r;
|
pixel->data.color.r = background_color.r;
|
||||||
pixel->data.color.g = area->background_color.g;
|
pixel->data.color.g = background_color.g;
|
||||||
pixel->data.color.b = area->background_color.b;
|
pixel->data.color.b = background_color.b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
area->callback_start(area->params.width, area->params.height, area->background_color);
|
callback_start(params.width, params.height, background_color);
|
||||||
|
|
||||||
area->dirty_left = area->params.width * area->params.antialias;
|
dirty_left = params.width * params.antialias;
|
||||||
area->dirty_right = -1;
|
dirty_right = -1;
|
||||||
area->dirty_down = area->params.height * area->params.antialias;
|
dirty_down = params.height * params.antialias;
|
||||||
area->dirty_up = -1;
|
dirty_up = -1;
|
||||||
area->dirty_count = 0;
|
dirty_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _setDirtyPixel(RenderArea* area, int x, int y)
|
static inline void _setDirtyPixel(RenderArea* area, int x, int y)
|
||||||
|
@ -277,38 +240,38 @@ static inline Color _getFinalPixel(RenderArea* area, int x, int y)
|
||||||
return area->hdr_mapping->apply(result);
|
return area->hdr_mapping->apply(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _processDirtyPixels(RenderArea* area)
|
void RenderArea::processDirtyPixels()
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
int down, up, left, right;
|
int down, up, left, right;
|
||||||
|
|
||||||
down = area->dirty_down / area->params.antialias;
|
down = dirty_down / params.antialias;
|
||||||
up = area->dirty_up / area->params.antialias;
|
up = dirty_up / params.antialias;
|
||||||
left = area->dirty_left / area->params.antialias;
|
left = dirty_left / params.antialias;
|
||||||
right = area->dirty_right / area->params.antialias;
|
right = dirty_right / params.antialias;
|
||||||
|
|
||||||
for (y = down; y <= up; y++)
|
for (y = down; y <= up; y++)
|
||||||
{
|
{
|
||||||
for (x = left; x <= right; x++)
|
for (x = left; x <= right; x++)
|
||||||
{
|
{
|
||||||
area->callback_draw(x, y, _getFinalPixel(area, x, y));
|
callback_draw(x, y, _getFinalPixel(this, x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
area->callback_update(area->renderer->render_progress);
|
callback_update(renderer->render_progress);
|
||||||
|
|
||||||
area->dirty_left = area->params.width * area->params.antialias;
|
dirty_left = params.width * params.antialias;
|
||||||
area->dirty_right = -1;
|
dirty_right = -1;
|
||||||
area->dirty_down = area->params.height * area->params.antialias;
|
dirty_down = params.height * params.antialias;
|
||||||
area->dirty_up = -1;
|
dirty_up = -1;
|
||||||
area->dirty_count = 0;
|
dirty_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderUpdate(RenderArea* area)
|
void RenderArea::update()
|
||||||
{
|
{
|
||||||
area->lock->acquire();
|
lock->acquire();
|
||||||
_processDirtyPixels(area);
|
processDirtyPixels();
|
||||||
area->lock->release();
|
lock->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int _pushCallback(RenderArea* area, FragmentCallback callback)
|
static inline unsigned int _pushCallback(RenderArea* area, FragmentCallback callback)
|
||||||
|
@ -334,13 +297,13 @@ static inline unsigned int _pushCallback(RenderArea* area, FragmentCallback call
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _pushFragment(RenderArea* area, int x, int y, double z, int edge, Vector3 location, int callback)
|
void RenderArea::pushFragment(int x, int y, double z, int edge, Vector3 location, int callback)
|
||||||
{
|
{
|
||||||
RenderFragment* pixel_data;
|
RenderFragment* pixel_data;
|
||||||
|
|
||||||
if (x >= 0 && x < area->params.width * area->params.antialias && y >= 0 && y < area->params.height * area->params.antialias && z > 1.0)
|
if (x >= 0 && x < params.width * params.antialias && y >= 0 && y < params.height * params.antialias && z > 1.0)
|
||||||
{
|
{
|
||||||
pixel_data = area->pixels + (y * area->params.width * area->params.antialias + x);
|
pixel_data = pixels + (y * params.width * params.antialias + x);
|
||||||
|
|
||||||
if (z > pixel_data->z)
|
if (z > pixel_data->z)
|
||||||
{
|
{
|
||||||
|
@ -351,7 +314,7 @@ static void _pushFragment(RenderArea* area, int x, int y, double z, int edge, Ve
|
||||||
pixel_data->data.location.y = location.y;
|
pixel_data->data.location.y = location.y;
|
||||||
pixel_data->data.location.z = location.z;
|
pixel_data->data.location.z = location.z;
|
||||||
pixel_data->z = z;
|
pixel_data->z = z;
|
||||||
_setDirtyPixel(area, x, y);
|
_setDirtyPixel(this, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,18 +490,18 @@ static void _renderScanLines(RenderArea* area, RenderScanlines* scanlines)
|
||||||
current.y = cury;
|
current.y = cury;
|
||||||
_scanInterpolate(area->renderer->render_camera, &down, &diff, fy / dy, ¤t);
|
_scanInterpolate(area->renderer->render_camera, &down, &diff, fy / dy, ¤t);
|
||||||
|
|
||||||
_pushFragment(area, current.x, current.y, current.pixel.z, (cury == starty || cury == endy), current.location, current.callback);
|
area->pushFragment(current.x, current.y, current.pixel.z, (cury == starty || cury == endy), current.location, current.callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderPushTriangle(RenderArea* area, Vector3 pixel1, Vector3 pixel2, Vector3 pixel3, Vector3 location1, Vector3 location2, Vector3 location3, f_RenderFragmentCallback callback, void* callback_data)
|
void RenderArea::pushTriangle(Vector3 pixel1, Vector3 pixel2, Vector3 pixel3, Vector3 location1, Vector3 location2, Vector3 location3, f_RenderFragmentCallback callback, void* callback_data)
|
||||||
{
|
{
|
||||||
FragmentCallback fragment_callback = {callback, callback_data};
|
FragmentCallback fragment_callback = {callback, callback_data};
|
||||||
ScanPoint point1, point2, point3;
|
ScanPoint point1, point2, point3;
|
||||||
double limit_width = (double)(area->params.width * area->params.antialias - 1);
|
double limit_width = (double)(params.width * params.antialias - 1);
|
||||||
double limit_height = (double)(area->params.height * area->params.antialias - 1);
|
double limit_height = (double)(params.height * params.antialias - 1);
|
||||||
|
|
||||||
/* Filter if outside screen */
|
/* Filter if outside screen */
|
||||||
if (pixel1.z < 1.0 || pixel2.z < 1.0 || pixel3.z < 1.0 || (pixel1.x < 0.0 && pixel2.x < 0.0 && pixel3.x < 0.0) || (pixel1.y < 0.0 && pixel2.y < 0.0 && pixel3.y < 0.0) || (pixel1.x > limit_width && pixel2.x > limit_width && pixel3.x > limit_width) || (pixel1.y > limit_height && pixel2.y > limit_height && pixel3.y > limit_height))
|
if (pixel1.z < 1.0 || pixel2.z < 1.0 || pixel3.z < 1.0 || (pixel1.x < 0.0 && pixel2.x < 0.0 && pixel3.x < 0.0) || (pixel1.y < 0.0 && pixel2.y < 0.0 && pixel3.y < 0.0) || (pixel1.x > limit_width && pixel2.x > limit_width && pixel3.x > limit_width) || (pixel1.y > limit_height && pixel2.y > limit_height && pixel3.y > limit_height))
|
||||||
|
@ -547,9 +510,9 @@ void renderPushTriangle(RenderArea* area, Vector3 pixel1, Vector3 pixel2, Vector
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare fragment callback */
|
/* Prepare fragment callback */
|
||||||
area->lock->acquire();
|
lock->acquire();
|
||||||
point1.callback = _pushCallback(area, fragment_callback);
|
point1.callback = _pushCallback(this, fragment_callback);
|
||||||
area->lock->release();
|
lock->release();
|
||||||
|
|
||||||
/* Prepare vertices */
|
/* Prepare vertices */
|
||||||
point1.pixel = pixel1;
|
point1.pixel = pixel1;
|
||||||
|
@ -566,7 +529,7 @@ void renderPushTriangle(RenderArea* area, Vector3 pixel1, Vector3 pixel2, Vector
|
||||||
/* Prepare scanlines */
|
/* Prepare scanlines */
|
||||||
RenderScanlines scanlines;
|
RenderScanlines scanlines;
|
||||||
int x;
|
int x;
|
||||||
int width = area->params.width * area->params.antialias;
|
int width = params.width * params.antialias;
|
||||||
scanlines.left = width;
|
scanlines.left = width;
|
||||||
scanlines.right = -1;
|
scanlines.right = -1;
|
||||||
scanlines.up = new ScanPoint[width];
|
scanlines.up = new ScanPoint[width];
|
||||||
|
@ -575,31 +538,31 @@ void renderPushTriangle(RenderArea* area, Vector3 pixel1, Vector3 pixel2, Vector
|
||||||
{
|
{
|
||||||
/* TODO Do not initialize whole width each time, init only when needed on point push */
|
/* TODO Do not initialize whole width each time, init only when needed on point push */
|
||||||
scanlines.up[x].y = -1;
|
scanlines.up[x].y = -1;
|
||||||
scanlines.down[x].y = area->params.height * area->params.antialias;
|
scanlines.down[x].y = params.height * params.antialias;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Render edges in scanlines */
|
/* Render edges in scanlines */
|
||||||
_pushScanLineEdge(area, &scanlines, &point1, &point2);
|
_pushScanLineEdge(this, &scanlines, &point1, &point2);
|
||||||
_pushScanLineEdge(area, &scanlines, &point2, &point3);
|
_pushScanLineEdge(this, &scanlines, &point2, &point3);
|
||||||
_pushScanLineEdge(area, &scanlines, &point3, &point1);
|
_pushScanLineEdge(this, &scanlines, &point3, &point1);
|
||||||
|
|
||||||
/* Commit scanlines to area */
|
/* Commit scanlines to area */
|
||||||
area->lock->acquire();
|
lock->acquire();
|
||||||
_renderScanLines(area, &scanlines);
|
_renderScanLines(this, &scanlines);
|
||||||
area->lock->release();
|
lock->release();
|
||||||
|
|
||||||
/* Free scalines */
|
/* Free scalines */
|
||||||
free(scanlines.up);
|
free(scanlines.up);
|
||||||
free(scanlines.down);
|
free(scanlines.down);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color renderGetPixel(RenderArea* area, int x, int y)
|
Color RenderArea::getPixel(int x, int y)
|
||||||
{
|
{
|
||||||
Color result;
|
Color result;
|
||||||
|
|
||||||
area->lock->acquire();
|
lock->acquire();
|
||||||
result = _getFinalPixel(area, x, y);
|
result = _getFinalPixel(this, x, y);
|
||||||
area->lock->release();
|
lock->release();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -654,7 +617,7 @@ void* _renderPostProcessChunk(void* data)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_CHUNKS 8
|
#define MAX_CHUNKS 8
|
||||||
void renderPostProcess(RenderArea* area, int nbchunks)
|
void RenderArea::postProcess(int nbchunks)
|
||||||
{
|
{
|
||||||
volatile RenderChunk chunks[MAX_CHUNKS];
|
volatile RenderChunk chunks[MAX_CHUNKS];
|
||||||
int i;
|
int i;
|
||||||
|
@ -672,21 +635,21 @@ void renderPostProcess(RenderArea* area, int nbchunks)
|
||||||
|
|
||||||
nx = 10;
|
nx = 10;
|
||||||
ny = 10;
|
ny = 10;
|
||||||
dx = area->params.width * area->params.antialias / nx;
|
dx = params.width * params.antialias / nx;
|
||||||
dy = area->params.height * area->params.antialias / ny;
|
dy = params.height * params.antialias / ny;
|
||||||
x = 0;
|
x = 0;
|
||||||
y = 0;
|
y = 0;
|
||||||
area->pixel_done = 0;
|
pixel_done = 0;
|
||||||
|
|
||||||
for (i = 0; i < nbchunks; i++)
|
for (i = 0; i < nbchunks; i++)
|
||||||
{
|
{
|
||||||
chunks[i].thread = NULL;
|
chunks[i].thread = NULL;
|
||||||
chunks[i].area = area;
|
chunks[i].area = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
running = 0;
|
running = 0;
|
||||||
loops = 0;
|
loops = 0;
|
||||||
while ((x < nx && !area->renderer->render_interrupt) || running > 0)
|
while ((x < nx && !renderer->render_interrupt) || running > 0)
|
||||||
{
|
{
|
||||||
Thread::timeSleepMs(50);
|
Thread::timeSleepMs(50);
|
||||||
|
|
||||||
|
@ -701,22 +664,22 @@ void renderPostProcess(RenderArea* area, int nbchunks)
|
||||||
chunks[i].thread = NULL;
|
chunks[i].thread = NULL;
|
||||||
running--;
|
running--;
|
||||||
}
|
}
|
||||||
else if (area->renderer->render_interrupt)
|
else if (renderer->render_interrupt)
|
||||||
{
|
{
|
||||||
chunks[i].interrupt = 1;
|
chunks[i].interrupt = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
area->renderer->render_progress = 0.1 + ((double)area->pixel_done / (double)area->pixel_count) * 0.9;
|
renderer->render_progress = 0.1 + ((double)pixel_done / (double)pixel_count) * 0.9;
|
||||||
|
|
||||||
if (x < nx && !chunks[i].thread && !area->renderer->render_interrupt)
|
if (x < nx && !chunks[i].thread && !renderer->render_interrupt)
|
||||||
{
|
{
|
||||||
chunks[i].finished = 0;
|
chunks[i].finished = 0;
|
||||||
chunks[i].interrupt = 0;
|
chunks[i].interrupt = 0;
|
||||||
chunks[i].startx = x * dx;
|
chunks[i].startx = x * dx;
|
||||||
if (x == nx - 1)
|
if (x == nx - 1)
|
||||||
{
|
{
|
||||||
chunks[i].endx = area->params.width * area->params.antialias - 1;
|
chunks[i].endx = params.width * params.antialias - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -725,7 +688,7 @@ void renderPostProcess(RenderArea* area, int nbchunks)
|
||||||
chunks[i].starty = y * dy;
|
chunks[i].starty = y * dy;
|
||||||
if (y == ny - 1)
|
if (y == ny - 1)
|
||||||
{
|
{
|
||||||
chunks[i].endy = area->params.height * area->params.antialias - 1;
|
chunks[i].endy = params.height * params.antialias - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -746,16 +709,16 @@ void renderPostProcess(RenderArea* area, int nbchunks)
|
||||||
|
|
||||||
if (++loops >= 10)
|
if (++loops >= 10)
|
||||||
{
|
{
|
||||||
area->lock->acquire();
|
lock->acquire();
|
||||||
_processDirtyPixels(area);
|
processDirtyPixels();
|
||||||
area->lock->release();
|
lock->release();
|
||||||
|
|
||||||
loops = 0;
|
loops = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_processDirtyPixels(area);
|
processDirtyPixels();
|
||||||
area->callback_update(1.0);
|
callback_update(1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int _getPicturePixel(void* data, int x, int y)
|
static unsigned int _getPicturePixel(void* data, int x, int y)
|
||||||
|
@ -765,21 +728,21 @@ static unsigned int _getPicturePixel(void* data, int x, int y)
|
||||||
return result.to32BitBGRA();
|
return result.to32BitBGRA();
|
||||||
}
|
}
|
||||||
|
|
||||||
int renderSaveToFile(RenderArea* area, const char* path)
|
int RenderArea::saveToFile(const char* path)
|
||||||
{
|
{
|
||||||
return systemSavePictureFile(path, _getPicturePixel, area, area->params.width, area->params.height);
|
return systemSavePictureFile(path, _getPicturePixel, this, params.width, params.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSetPreviewCallbacks(RenderArea* area, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update)
|
void RenderArea::setPreviewCallbacks(RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update)
|
||||||
{
|
{
|
||||||
area->callback_start = start ? start : _callbackStart;
|
callback_start = start ? start : _callbackStart;
|
||||||
area->callback_draw = draw ? draw : _callbackDraw;
|
callback_draw = draw ? draw : _callbackDraw;
|
||||||
area->callback_update = update ? update : _callbackUpdate;
|
callback_update = update ? update : _callbackUpdate;
|
||||||
|
|
||||||
area->callback_start(area->params.width, area->params.height, area->background_color);
|
callback_start(params.width, params.height, background_color);
|
||||||
|
|
||||||
_setAllDirty(area);
|
setAllDirty();
|
||||||
_processDirtyPixels(area);
|
processDirtyPixels();
|
||||||
|
|
||||||
area->callback_update(0.0);
|
callback_update(0.0);
|
||||||
}
|
}
|
76
src/render/software/RenderArea.h
Normal file
76
src/render/software/RenderArea.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#ifndef RENDERAREA_H
|
||||||
|
#define RENDERAREA_H
|
||||||
|
|
||||||
|
#include "software_global.h"
|
||||||
|
|
||||||
|
#include "Color.h"
|
||||||
|
|
||||||
|
typedef struct RenderFragment RenderFragment;
|
||||||
|
typedef struct FragmentCallback FragmentCallback;
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace software {
|
||||||
|
|
||||||
|
class SOFTWARESHARED_EXPORT RenderArea
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int antialias;
|
||||||
|
int quality;
|
||||||
|
} RenderParams;
|
||||||
|
|
||||||
|
typedef Color (*f_RenderFragmentCallback)(SoftwareRenderer* renderer, Vector3 location, void* data);
|
||||||
|
typedef void (*RenderCallbackStart)(int width, int height, Color background);
|
||||||
|
typedef void (*RenderCallbackDraw)(int x, int y, Color col);
|
||||||
|
typedef void (*RenderCallbackUpdate)(double progress);
|
||||||
|
|
||||||
|
public:
|
||||||
|
RenderArea(SoftwareRenderer* parent);
|
||||||
|
~RenderArea();
|
||||||
|
|
||||||
|
void setParams(RenderParams params);
|
||||||
|
void setToneMapping(const ColorProfile &profile);
|
||||||
|
void setBackgroundColor(const Color& col);
|
||||||
|
void clear();
|
||||||
|
void update();
|
||||||
|
|
||||||
|
void pushTriangle(Vector3 pixel1, Vector3 pixel2, Vector3 pixel3, Vector3 location1, Vector3 location2, Vector3 location3, f_RenderFragmentCallback callback, void* callback_data);
|
||||||
|
|
||||||
|
Color getPixel(int x, int y);
|
||||||
|
|
||||||
|
void postProcess(int nbchunks);
|
||||||
|
int saveToFile(const char* path);
|
||||||
|
void setPreviewCallbacks(RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update);
|
||||||
|
|
||||||
|
void setAllDirty();
|
||||||
|
void processDirtyPixels();
|
||||||
|
void pushFragment(int x, int y, double z, int edge, Vector3 location, int callback);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ColorProfile* hdr_mapping;
|
||||||
|
SoftwareRenderer* renderer;
|
||||||
|
RenderParams params;
|
||||||
|
int pixel_count;
|
||||||
|
int pixel_done;
|
||||||
|
RenderFragment* pixels;
|
||||||
|
int fragment_callbacks_count;
|
||||||
|
FragmentCallback* fragment_callbacks;
|
||||||
|
Color background_color;
|
||||||
|
volatile int dirty_left;
|
||||||
|
volatile int dirty_right;
|
||||||
|
volatile int dirty_up;
|
||||||
|
volatile int dirty_down;
|
||||||
|
volatile int dirty_count;
|
||||||
|
Mutex* lock;
|
||||||
|
RenderCallbackStart callback_start;
|
||||||
|
RenderCallbackDraw callback_draw;
|
||||||
|
RenderCallbackUpdate callback_update;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // RENDERAREA_H
|
|
@ -19,7 +19,7 @@ static Color _postProcessFragment(SoftwareRenderer* renderer, Vector3 location,
|
||||||
Vector3 camera_location, direction;
|
Vector3 camera_location, direction;
|
||||||
Color result;
|
Color result;
|
||||||
|
|
||||||
camera_location = renderer->getCameraLocation(renderer, location);
|
camera_location = renderer->getCameraLocation(location);
|
||||||
direction = v3Sub(location, camera_location);
|
direction = v3Sub(location, camera_location);
|
||||||
|
|
||||||
/* TODO Don't compute result->color if it's fully covered by clouds */
|
/* TODO Don't compute result->color if it's fully covered by clouds */
|
||||||
|
@ -43,11 +43,11 @@ void SkyRasterizer::rasterize()
|
||||||
step_i = M_PI * 2.0 / (double)res_i;
|
step_i = M_PI * 2.0 / (double)res_i;
|
||||||
step_j = M_PI / (double)res_j;
|
step_j = M_PI / (double)res_j;
|
||||||
|
|
||||||
camera_location = renderer->getCameraLocation(renderer, VECTOR_ZERO);
|
camera_location = renderer->getCameraLocation(VECTOR_ZERO);
|
||||||
|
|
||||||
for (j = 0; j < res_j; j++)
|
for (j = 0; j < res_j; j++)
|
||||||
{
|
{
|
||||||
if (!renderer->addRenderProgress(renderer, 0.0))
|
if (!renderer->addRenderProgress(0.0))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ void SkyRasterizer::rasterize()
|
||||||
vertex4 = v3Add(camera_location, direction);
|
vertex4 = v3Add(camera_location, direction);
|
||||||
|
|
||||||
/* TODO Triangles at poles */
|
/* TODO Triangles at poles */
|
||||||
renderer->pushQuad(renderer, vertex1, vertex4, vertex3, vertex2, (f_RenderFragmentCallback)_postProcessFragment, NULL);
|
renderer->pushQuad(vertex1, vertex4, vertex3, vertex2, _postProcessFragment, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,23 +15,23 @@
|
||||||
#include "WaterRasterizer.h"
|
#include "WaterRasterizer.h"
|
||||||
#include "LightStatus.h"
|
#include "LightStatus.h"
|
||||||
#include "LightingManager.h"
|
#include "LightingManager.h"
|
||||||
|
#include "System.h"
|
||||||
|
#include "Thread.h"
|
||||||
// Legacy compatibility
|
|
||||||
#include "renderer.h"
|
|
||||||
static double _getPrecision(Renderer* renderer, Vector3 location)
|
|
||||||
{
|
|
||||||
Vector3 projected;
|
|
||||||
|
|
||||||
projected = renderer->render_camera->project(location);
|
|
||||||
projected.x += 1.0;
|
|
||||||
//projected.y += 1.0;
|
|
||||||
|
|
||||||
return v3Norm(v3Sub(renderer->render_camera->unproject(projected), location)); // / (double)render_quality;
|
|
||||||
}
|
|
||||||
|
|
||||||
SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
|
SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
|
||||||
{
|
{
|
||||||
|
RenderArea::RenderParams params = {1, 1, 1, 5};
|
||||||
|
|
||||||
|
render_quality = 5;
|
||||||
|
render_width = 1;
|
||||||
|
render_height = 1;
|
||||||
|
render_interrupt = 0;
|
||||||
|
render_progress = 0.0;
|
||||||
|
is_rendering = 0;
|
||||||
|
render_camera = new CameraDefinition;
|
||||||
|
render_area = new RenderArea(this);
|
||||||
|
render_area->setParams(params);
|
||||||
|
|
||||||
atmosphere_renderer = new BaseAtmosphereRenderer(this);
|
atmosphere_renderer = new BaseAtmosphereRenderer(this);
|
||||||
clouds_renderer = new CloudsRenderer(this);
|
clouds_renderer = new CloudsRenderer(this);
|
||||||
terrain_renderer = new TerrainRenderer(this);
|
terrain_renderer = new TerrainRenderer(this);
|
||||||
|
@ -39,6 +39,7 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
|
||||||
water_renderer = new WaterRenderer(this);
|
water_renderer = new WaterRenderer(this);
|
||||||
|
|
||||||
fluid_medium = new FluidMediumManager(this);
|
fluid_medium = new FluidMediumManager(this);
|
||||||
|
lighting = new LightingManager();
|
||||||
|
|
||||||
if (scenery)
|
if (scenery)
|
||||||
{
|
{
|
||||||
|
@ -54,6 +55,9 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
|
||||||
|
|
||||||
SoftwareRenderer::~SoftwareRenderer()
|
SoftwareRenderer::~SoftwareRenderer()
|
||||||
{
|
{
|
||||||
|
delete render_camera;
|
||||||
|
delete render_area;
|
||||||
|
|
||||||
delete atmosphere_renderer;
|
delete atmosphere_renderer;
|
||||||
delete clouds_renderer;
|
delete clouds_renderer;
|
||||||
delete terrain_renderer;
|
delete terrain_renderer;
|
||||||
|
@ -61,6 +65,7 @@ SoftwareRenderer::~SoftwareRenderer()
|
||||||
delete water_renderer;
|
delete water_renderer;
|
||||||
|
|
||||||
delete fluid_medium;
|
delete fluid_medium;
|
||||||
|
delete lighting;
|
||||||
|
|
||||||
if (own_scenery)
|
if (own_scenery)
|
||||||
{
|
{
|
||||||
|
@ -97,9 +102,6 @@ void SoftwareRenderer::prepare()
|
||||||
delete water_renderer;
|
delete water_renderer;
|
||||||
water_renderer = new WaterRenderer(this);
|
water_renderer = new WaterRenderer(this);
|
||||||
|
|
||||||
// Setup transitional renderers (for C-legacy subsystems)
|
|
||||||
getPrecision = _getPrecision;
|
|
||||||
|
|
||||||
// Prepare global tools
|
// Prepare global tools
|
||||||
fluid_medium->clearMedia();
|
fluid_medium->clearMedia();
|
||||||
//fluid_medium->registerMedium(water_renderer);
|
//fluid_medium->registerMedium(water_renderer);
|
||||||
|
@ -117,9 +119,71 @@ void SoftwareRenderer::rasterize()
|
||||||
sky.rasterize();
|
sky.rasterize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoftwareRenderer::setPreviewCallbacks(RenderArea::RenderCallbackStart start, RenderArea::RenderCallbackDraw draw, RenderArea::RenderCallbackUpdate update)
|
||||||
|
{
|
||||||
|
render_area->setPreviewCallbacks(start, draw, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* _renderFirstPass(void* data)
|
||||||
|
{
|
||||||
|
SoftwareRenderer* renderer = (SoftwareRenderer*)data;
|
||||||
|
renderer->rasterize();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareRenderer::start(RenderArea::RenderParams params)
|
||||||
|
{
|
||||||
|
Thread thread(_renderFirstPass);
|
||||||
|
int loops;
|
||||||
|
int core_count = System::getCoreCount();
|
||||||
|
|
||||||
|
params.antialias = (params.antialias < 1) ? 1 : params.antialias;
|
||||||
|
params.antialias = (params.antialias > 4) ? 4 : params.antialias;
|
||||||
|
|
||||||
|
render_quality = params.quality;
|
||||||
|
render_width = params.width * params.antialias;
|
||||||
|
render_height = params.height * params.antialias;
|
||||||
|
render_interrupt = 0;
|
||||||
|
render_progress = 0.0;
|
||||||
|
|
||||||
|
render_camera->setRenderSize(render_width, render_height);
|
||||||
|
|
||||||
|
render_area->setBackgroundColor(COLOR_BLACK);
|
||||||
|
render_area->setParams(params);
|
||||||
|
render_area->clear();
|
||||||
|
|
||||||
|
prepare();
|
||||||
|
|
||||||
|
is_rendering = 1;
|
||||||
|
thread.start(this);
|
||||||
|
loops = 0;
|
||||||
|
|
||||||
|
while (is_rendering)
|
||||||
|
{
|
||||||
|
Thread::timeSleepMs(100);
|
||||||
|
|
||||||
|
if (++loops >= 10)
|
||||||
|
{
|
||||||
|
|
||||||
|
render_area->update();
|
||||||
|
loops = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thread.join();
|
||||||
|
|
||||||
|
is_rendering = 1;
|
||||||
|
render_area->postProcess(core_count);
|
||||||
|
is_rendering = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareRenderer::interrupt()
|
||||||
|
{
|
||||||
|
render_interrupt = 1;
|
||||||
|
}
|
||||||
|
|
||||||
Color SoftwareRenderer::applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material)
|
Color SoftwareRenderer::applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material)
|
||||||
{
|
{
|
||||||
LightStatus status(lighting, location, getCameraLocation(this, location));
|
LightStatus status(lighting, location, getCameraLocation(location));
|
||||||
atmosphere_renderer->getLightingStatus(&status, normal, 0);
|
atmosphere_renderer->getLightingStatus(&status, normal, 0);
|
||||||
return status.apply(normal, material);
|
return status.apply(normal, material);
|
||||||
}
|
}
|
||||||
|
@ -127,7 +191,7 @@ Color SoftwareRenderer::applyLightingToSurface(const Vector3 &location, const Ve
|
||||||
Color SoftwareRenderer::applyMediumTraversal(Vector3 location, Color color)
|
Color SoftwareRenderer::applyMediumTraversal(Vector3 location, Color color)
|
||||||
{
|
{
|
||||||
color = atmosphere_renderer->applyAerialPerspective(location, color).final;
|
color = atmosphere_renderer->applyAerialPerspective(location, color).final;
|
||||||
color = clouds_renderer->getColor(getCameraLocation(this, location), location, color);
|
color = clouds_renderer->getColor(getCameraLocation(location), location, color);
|
||||||
return color;
|
return color;
|
||||||
|
|
||||||
/*Vector3 eye = cameraGetLocation(scenery->getCamera());
|
/*Vector3 eye = cameraGetLocation(scenery->getCamera());
|
||||||
|
@ -151,3 +215,73 @@ RayCastingResult SoftwareRenderer::rayWalking(const Vector3 &location, const Vec
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SoftwareRenderer::addRenderProgress(double)
|
||||||
|
{
|
||||||
|
return not render_interrupt;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 SoftwareRenderer::getCameraLocation(Vector3)
|
||||||
|
{
|
||||||
|
return render_camera->getLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 SoftwareRenderer::getCameraDirection(Vector3)
|
||||||
|
{
|
||||||
|
return render_camera->getDirectionNormalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
double SoftwareRenderer::getPrecision(Vector3 location)
|
||||||
|
{
|
||||||
|
Vector3 projected;
|
||||||
|
|
||||||
|
projected = render_camera->project(location);
|
||||||
|
projected.x += 1.0;
|
||||||
|
//projected.y += 1.0;
|
||||||
|
|
||||||
|
return v3Norm(v3Sub(render_camera->unproject(projected), location)); // / (double)render_quality;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 SoftwareRenderer::projectPoint(Vector3 point)
|
||||||
|
{
|
||||||
|
return render_camera->project(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 SoftwareRenderer::unprojectPoint(Vector3 point)
|
||||||
|
{
|
||||||
|
return render_camera->unproject(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareRenderer::pushTriangle(Vector3 v1, Vector3 v2, Vector3 v3, RenderArea::f_RenderFragmentCallback callback, void* callback_data)
|
||||||
|
{
|
||||||
|
Vector3 p1, p2, p3;
|
||||||
|
|
||||||
|
p1 = projectPoint(v1);
|
||||||
|
p2 = projectPoint(v2);
|
||||||
|
p3 = projectPoint(v3);
|
||||||
|
|
||||||
|
render_area->pushTriangle(p1, p2, p3, v1, v2, v3, callback, callback_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareRenderer::pushQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, RenderArea::f_RenderFragmentCallback callback, void* callback_data)
|
||||||
|
{
|
||||||
|
pushTriangle(v2, v3, v1, callback, callback_data);
|
||||||
|
pushTriangle(v4, v1, v3, callback, callback_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareRenderer::pushDisplacedTriangle(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 ov1, Vector3 ov2, Vector3 ov3, RenderArea::f_RenderFragmentCallback callback, void* callback_data)
|
||||||
|
{
|
||||||
|
Vector3 p1, p2, p3;
|
||||||
|
|
||||||
|
p1 = projectPoint(v1);
|
||||||
|
p2 = projectPoint(v2);
|
||||||
|
p3 = projectPoint(v3);
|
||||||
|
|
||||||
|
render_area->pushTriangle(p1, p2, p3, ov1, ov2, ov3, callback, callback_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareRenderer::pushDisplacedQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Vector3 ov1, Vector3 ov2, Vector3 ov3, Vector3 ov4, RenderArea::f_RenderFragmentCallback callback, void* callback_data)
|
||||||
|
{
|
||||||
|
pushDisplacedTriangle(v2, v3, v1, ov2, ov3, ov1, callback, callback_data);
|
||||||
|
pushDisplacedTriangle(v4, v1, v3, ov4, ov1, ov3, callback, callback_data);
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
#include "software_global.h"
|
#include "software_global.h"
|
||||||
|
|
||||||
#include "renderer.h"
|
#include "RenderArea.h"
|
||||||
|
#include "RayCastingManager.h"
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace software {
|
namespace software {
|
||||||
|
@ -11,19 +12,44 @@ namespace software {
|
||||||
/*!
|
/*!
|
||||||
* \brief This class renders a defined scenery in sotware mode (using only standard CPU computations).
|
* \brief This class renders a defined scenery in sotware mode (using only standard CPU computations).
|
||||||
*/
|
*/
|
||||||
class SOFTWARESHARED_EXPORT SoftwareRenderer: public Renderer
|
class SOFTWARESHARED_EXPORT SoftwareRenderer
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SoftwareRenderer(Scenery* scenery=0);
|
SoftwareRenderer(Scenery* scenery=0);
|
||||||
virtual ~SoftwareRenderer();
|
virtual ~SoftwareRenderer();
|
||||||
|
|
||||||
|
/* Render base configuration */
|
||||||
|
int render_quality;
|
||||||
|
int render_width;
|
||||||
|
int render_height;
|
||||||
|
CameraDefinition* render_camera;
|
||||||
|
|
||||||
|
/* Render related */
|
||||||
|
RenderArea* render_area;
|
||||||
|
double render_progress;
|
||||||
|
int render_interrupt;
|
||||||
|
int is_rendering;
|
||||||
|
|
||||||
|
void* customData[10];
|
||||||
|
|
||||||
|
virtual Vector3 getCameraLocation(Vector3 target);
|
||||||
|
virtual Vector3 getCameraDirection(Vector3 target);
|
||||||
|
virtual double getPrecision(Vector3 location);
|
||||||
|
virtual Vector3 projectPoint(Vector3 point);
|
||||||
|
virtual Vector3 unprojectPoint(Vector3 point);
|
||||||
|
virtual int addRenderProgress(double progress);
|
||||||
|
virtual void pushTriangle(Vector3 v1, Vector3 v2, Vector3 v3, RenderArea::f_RenderFragmentCallback callback, void* callback_data);
|
||||||
|
virtual void pushQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, RenderArea::f_RenderFragmentCallback callback, void* callback_data);
|
||||||
|
virtual void pushDisplacedTriangle(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 ov1, Vector3 ov2, Vector3 ov3, RenderArea::f_RenderFragmentCallback callback, void* callback_data);
|
||||||
|
virtual void pushDisplacedQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Vector3 ov1, Vector3 ov2, Vector3 ov3, Vector3 ov4, RenderArea::f_RenderFragmentCallback callback, void* callback_data);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Set the scenery to render.
|
* \brief Set the scenery to render.
|
||||||
*
|
*
|
||||||
* Don't call this after rendering has already started.
|
* Don't call this after rendering has already started.
|
||||||
*/
|
*/
|
||||||
virtual void setScenery(Scenery* scenery) override;
|
virtual void setScenery(Scenery* scenery);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Prepare the renderer sub-systems.
|
* \brief Prepare the renderer sub-systems.
|
||||||
|
@ -31,12 +57,16 @@ public:
|
||||||
* This will clear the caches and connect elements together.
|
* This will clear the caches and connect elements together.
|
||||||
* After this call, don't update the scenery when renderer is in use.
|
* After this call, don't update the scenery when renderer is in use.
|
||||||
*/
|
*/
|
||||||
virtual void prepare() override;
|
virtual void prepare();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Start the rasterization process.
|
* \brief Start the rasterization process.
|
||||||
*/
|
*/
|
||||||
virtual void rasterize() override;
|
virtual void rasterize();
|
||||||
|
|
||||||
|
void setPreviewCallbacks(RenderArea::RenderCallbackStart start, RenderArea::RenderCallbackDraw draw, RenderArea::RenderCallbackUpdate update);
|
||||||
|
void start(RenderArea::RenderParams params);
|
||||||
|
void interrupt();
|
||||||
|
|
||||||
inline Scenery* getScenery() const {return scenery;}
|
inline Scenery* getScenery() const {return scenery;}
|
||||||
|
|
||||||
|
@ -49,9 +79,9 @@ public:
|
||||||
inline FluidMediumManager* getFluidMediumManager() const {return fluid_medium;}
|
inline FluidMediumManager* getFluidMediumManager() const {return fluid_medium;}
|
||||||
inline LightingManager* getLightingManager() const {return lighting;}
|
inline LightingManager* getLightingManager() const {return lighting;}
|
||||||
|
|
||||||
virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material) override;
|
virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material);
|
||||||
virtual Color applyMediumTraversal(Vector3 location, Color color) override;
|
virtual Color applyMediumTraversal(Vector3 location, Color color);
|
||||||
virtual RayCastingResult rayWalking(const Vector3 &location, const Vector3 &direction, int terrain, int water, int sky, int clouds) override;
|
virtual RayCastingResult rayWalking(const Vector3 &location, const Vector3 &direction, int terrain, int water, int sky, int clouds);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Scenery* scenery;
|
Scenery* scenery;
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
#include "WaterRenderer.h"
|
#include "WaterRenderer.h"
|
||||||
#include "TexturesRenderer.h"
|
#include "TexturesRenderer.h"
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
|
#include "ParallelQueue.h"
|
||||||
#include "tools/parallel.h"
|
|
||||||
|
|
||||||
TerrainRasterizer::TerrainRasterizer(SoftwareRenderer* renderer):
|
TerrainRasterizer::TerrainRasterizer(SoftwareRenderer* renderer):
|
||||||
renderer(renderer)
|
renderer(renderer)
|
||||||
|
@ -26,14 +25,13 @@ static inline Vector3 _getPoint(SoftwareRenderer* renderer, double x, double z)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Color _postProcessFragment(Renderer* renderer_, Vector3 point, void*)
|
static Color _postProcessFragment(SoftwareRenderer* renderer, Vector3 point, void*)
|
||||||
{
|
{
|
||||||
double precision;
|
double precision;
|
||||||
SoftwareRenderer* renderer = (SoftwareRenderer*)renderer_;
|
|
||||||
|
|
||||||
point = _getPoint(renderer, point.x, point.z);
|
point = _getPoint(renderer, point.x, point.z);
|
||||||
|
|
||||||
precision = renderer->getPrecision(renderer, point);
|
precision = renderer->getPrecision(point);
|
||||||
return renderer->getTerrainRenderer()->getFinalColor(point, precision);
|
return renderer->getTerrainRenderer()->getFinalColor(point, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +60,7 @@ static void _renderQuad(SoftwareRenderer* renderer, double x, double z, double s
|
||||||
|
|
||||||
if (dv1.y > water_height || dv2.y > water_height || dv3.y > water_height || dv4.y > water_height)
|
if (dv1.y > water_height || dv2.y > water_height || dv3.y > water_height || dv4.y > water_height)
|
||||||
{
|
{
|
||||||
renderer->pushDisplacedQuad(renderer, dv1, dv2, dv3, dv4, ov1, ov2, ov3, ov4, _postProcessFragment, NULL);
|
renderer->pushDisplacedQuad(dv1, dv2, dv3, dv4, ov1, ov2, ov3, ov4, _postProcessFragment, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +144,7 @@ void TerrainRasterizer::getTessellationInfo(int displaced)
|
||||||
{
|
{
|
||||||
TerrainChunkInfo chunk;
|
TerrainChunkInfo chunk;
|
||||||
int chunk_factor, chunk_count, i;
|
int chunk_factor, chunk_count, i;
|
||||||
Vector3 cam = renderer->getCameraLocation(renderer, VECTOR_ZERO);
|
Vector3 cam = renderer->getCameraLocation(VECTOR_ZERO);
|
||||||
double progress;
|
double progress;
|
||||||
double radius_int, radius_ext;
|
double radius_int, radius_ext;
|
||||||
double base_chunk_size, chunk_size;
|
double base_chunk_size, chunk_size;
|
||||||
|
@ -231,7 +229,7 @@ int TerrainRasterizer::processChunk(TerrainChunkInfo* chunk, double progress)
|
||||||
info->rasterizer = this;
|
info->rasterizer = this;
|
||||||
info->chunk = *chunk;
|
info->chunk = *chunk;
|
||||||
|
|
||||||
if (!parallelQueueAddJob((ParallelQueue*)renderer->customData[0], _parallelJobCallback, info))
|
if (!((ParallelQueue*)renderer->customData[0])->addJob(_parallelJobCallback, info))
|
||||||
{
|
{
|
||||||
delete info;
|
delete info;
|
||||||
}
|
}
|
||||||
|
@ -242,16 +240,14 @@ int TerrainRasterizer::processChunk(TerrainChunkInfo* chunk, double progress)
|
||||||
|
|
||||||
void TerrainRasterizer::renderSurface()
|
void TerrainRasterizer::renderSurface()
|
||||||
{
|
{
|
||||||
ParallelQueue* queue;
|
ParallelQueue queue;
|
||||||
queue = parallelQueueCreate(0);
|
|
||||||
|
|
||||||
/* TODO Do not use custom data, it could already be used by another module */
|
/* TODO Do not use custom data, it could already be used by another module */
|
||||||
renderer->customData[0] = queue;
|
renderer->customData[0] = &queue;
|
||||||
|
|
||||||
renderer->render_progress = 0.0;
|
renderer->render_progress = 0.0;
|
||||||
getTessellationInfo(0);
|
getTessellationInfo(0);
|
||||||
renderer->render_progress = 0.05;
|
renderer->render_progress = 0.05;
|
||||||
|
|
||||||
parallelQueueWait(queue);
|
queue.wait();
|
||||||
parallelQueueDelete(queue);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ RayCastingResult TerrainRenderer::castRay(const Vector3 &start, const Vector3 &d
|
||||||
}
|
}
|
||||||
result.hit = 1;
|
result.hit = 1;
|
||||||
result.hit_location = cursor;
|
result.hit_location = cursor;
|
||||||
result.hit_color = getFinalColor(cursor, parent->getPrecision(parent, result.hit_location));
|
result.hit_color = getFinalColor(cursor, parent->getPrecision(result.hit_location));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
#include "software_global.h"
|
#include "software_global.h"
|
||||||
|
|
||||||
#include "shared/types.h"
|
#include "RayCastingManager.h"
|
||||||
|
#include "Color.h"
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace software {
|
namespace software {
|
||||||
|
|
|
@ -2,16 +2,15 @@
|
||||||
|
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "WaterRenderer.h"
|
#include "WaterRenderer.h"
|
||||||
#include "tools/parallel.h"
|
#include "ParallelQueue.h"
|
||||||
|
|
||||||
WaterRasterizer::WaterRasterizer(SoftwareRenderer* renderer):
|
WaterRasterizer::WaterRasterizer(SoftwareRenderer* renderer):
|
||||||
renderer(renderer)
|
renderer(renderer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static Color _postProcessFragment(Renderer* renderer_, Vector3 location, void*)
|
static Color _postProcessFragment(SoftwareRenderer* renderer, Vector3 location, void*)
|
||||||
{
|
{
|
||||||
SoftwareRenderer* renderer = (SoftwareRenderer*) renderer_;
|
|
||||||
return renderer->getWaterRenderer()->getResult(location.x, location.z).final;
|
return renderer->getWaterRenderer()->getResult(location.x, location.z).final;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +34,7 @@ static void _renderQuad(SoftwareRenderer* renderer, double x, double z, double s
|
||||||
v3 = _getFirstPassVertex(renderer, x + size, z + size);
|
v3 = _getFirstPassVertex(renderer, x + size, z + size);
|
||||||
v4 = _getFirstPassVertex(renderer, x + size, z);
|
v4 = _getFirstPassVertex(renderer, x + size, z);
|
||||||
|
|
||||||
renderer->pushQuad(renderer, v1, v2, v3, v4, _postProcessFragment, NULL);
|
renderer->pushQuad(v1, v2, v3, v4, _postProcessFragment, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -69,10 +68,10 @@ void WaterRasterizer::renderSurface()
|
||||||
{
|
{
|
||||||
ParallelRasterInfo* info;
|
ParallelRasterInfo* info;
|
||||||
ParallelQueue* queue;
|
ParallelQueue* queue;
|
||||||
queue = parallelQueueCreate(0);
|
queue = new ParallelQueue();
|
||||||
|
|
||||||
int chunk_factor, chunk_count, i;
|
int chunk_factor, chunk_count, i;
|
||||||
Vector3 cam = renderer->getCameraLocation(renderer, VECTOR_ZERO);
|
Vector3 cam = renderer->getCameraLocation(VECTOR_ZERO);
|
||||||
double radius_int, radius_ext, base_chunk_size, chunk_size;
|
double radius_int, radius_ext, base_chunk_size, chunk_size;
|
||||||
|
|
||||||
base_chunk_size = 2.0 / (double)renderer->render_quality;
|
base_chunk_size = 2.0 / (double)renderer->render_quality;
|
||||||
|
@ -92,7 +91,7 @@ void WaterRasterizer::renderSurface()
|
||||||
|
|
||||||
while (radius_int < 20000.0)
|
while (radius_int < 20000.0)
|
||||||
{
|
{
|
||||||
if (!renderer->addRenderProgress(renderer, 0.0))
|
if (!renderer->addRenderProgress(0.0))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +108,7 @@ void WaterRasterizer::renderSurface()
|
||||||
info->radius_ext = radius_ext;
|
info->radius_ext = radius_ext;
|
||||||
info->chunk_size = chunk_size;
|
info->chunk_size = chunk_size;
|
||||||
|
|
||||||
if (!parallelQueueAddJob(queue, _parallelJobCallback, info))
|
if (!queue->addJob(_parallelJobCallback, info))
|
||||||
{
|
{
|
||||||
delete info;
|
delete info;
|
||||||
}
|
}
|
||||||
|
@ -126,6 +125,6 @@ void WaterRasterizer::renderSurface()
|
||||||
radius_ext += chunk_size;
|
radius_ext += chunk_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
parallelQueueWait(queue);
|
queue->wait();
|
||||||
parallelQueueDelete(queue);
|
delete queue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,14 +207,14 @@ WaterRenderer::WaterResult WaterRenderer::getResult(double x, double z)
|
||||||
location.z = z;
|
location.z = z;
|
||||||
result.location = location;
|
result.location = location;
|
||||||
|
|
||||||
detail = parent->getPrecision(parent, location) * 0.1;
|
detail = parent->getPrecision(location) * 0.1;
|
||||||
if (detail < 0.00001)
|
if (detail < 0.00001)
|
||||||
{
|
{
|
||||||
detail = 0.00001;
|
detail = 0.00001;
|
||||||
}
|
}
|
||||||
|
|
||||||
normal = _getNormal(definition, base_height, location, detail);
|
normal = _getNormal(definition, base_height, location, detail);
|
||||||
look_direction = v3Normalize(v3Sub(location, parent->getCameraLocation(parent, location)));
|
look_direction = v3Normalize(v3Sub(location, parent->getCameraLocation(location)));
|
||||||
|
|
||||||
/* Reflection */
|
/* Reflection */
|
||||||
if (definition->reflection == 0.0)
|
if (definition->reflection == 0.0)
|
||||||
|
|
|
@ -33,7 +33,9 @@ SOURCES += SoftwareRenderer.cpp \
|
||||||
AtmosphereModelBruneton.cpp \
|
AtmosphereModelBruneton.cpp \
|
||||||
TerrainRenderer.cpp \
|
TerrainRenderer.cpp \
|
||||||
TexturesRenderer.cpp \
|
TexturesRenderer.cpp \
|
||||||
WaterRenderer.cpp
|
WaterRenderer.cpp \
|
||||||
|
RenderArea.cpp \
|
||||||
|
RayCastingManager.cpp
|
||||||
|
|
||||||
HEADERS += SoftwareRenderer.h\
|
HEADERS += SoftwareRenderer.h\
|
||||||
software_global.h \
|
software_global.h \
|
||||||
|
@ -56,7 +58,9 @@ HEADERS += SoftwareRenderer.h\
|
||||||
AtmosphereModelBruneton.h \
|
AtmosphereModelBruneton.h \
|
||||||
TerrainRenderer.h \
|
TerrainRenderer.h \
|
||||||
TexturesRenderer.h \
|
TexturesRenderer.h \
|
||||||
WaterRenderer.h
|
WaterRenderer.h \
|
||||||
|
RenderArea.h \
|
||||||
|
RayCastingManager.h
|
||||||
|
|
||||||
unix:!symbian {
|
unix:!symbian {
|
||||||
maemo5 {
|
maemo5 {
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace software {
|
namespace software {
|
||||||
class SoftwareRenderer;
|
class SoftwareRenderer;
|
||||||
|
class RenderArea;
|
||||||
|
|
||||||
class FluidMediumManager;
|
class FluidMediumManager;
|
||||||
class FluidMediumInterface;
|
class FluidMediumInterface;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "RenderingScenery.h"
|
#include "RenderingScenery.h"
|
||||||
|
|
||||||
#include "renderer.h"
|
|
||||||
|
|
||||||
static RenderingScenery _main_scenery;
|
static RenderingScenery _main_scenery;
|
||||||
|
|
||||||
RenderingScenery::RenderingScenery()
|
RenderingScenery::RenderingScenery()
|
||||||
|
@ -42,10 +40,3 @@ void RenderingScenery::load(PackStream* stream)
|
||||||
|
|
||||||
Scenery::load(stream);
|
Scenery::load(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderingScenery::bindToRenderer(Renderer* renderer)
|
|
||||||
{
|
|
||||||
renderer->setScenery(this);
|
|
||||||
renderer->prepare();
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
|
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
|
|
||||||
class Renderer;
|
|
||||||
|
|
||||||
typedef void (*SceneryCustomDataCallback)(PackStream* stream, void* data);
|
typedef void (*SceneryCustomDataCallback)(PackStream* stream, void* data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,8 +24,6 @@ public:
|
||||||
virtual void save(PackStream* stream) const override;
|
virtual void save(PackStream* stream) const override;
|
||||||
virtual void load(PackStream* stream) override;
|
virtual void load(PackStream* stream) override;
|
||||||
|
|
||||||
void bindToRenderer(Renderer* renderer);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SceneryCustomDataCallback _custom_save;
|
SceneryCustomDataCallback _custom_save;
|
||||||
SceneryCustomDataCallback _custom_load;
|
SceneryCustomDataCallback _custom_load;
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "RenderingScenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
#include "render.h"
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#define APP_HEADER 198632.125
|
#define APP_HEADER 198632.125
|
||||||
|
@ -18,13 +17,10 @@ void paysagesInit()
|
||||||
fprintf(stderr, "ERROR : Can't locate data files.\n");
|
fprintf(stderr, "ERROR : Can't locate data files.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderInit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void paysagesQuit()
|
void paysagesQuit()
|
||||||
{
|
{
|
||||||
renderQuit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileOperationResult paysagesSave(char* filepath)
|
FileOperationResult paysagesSave(char* filepath)
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
#ifndef _PAYSAGES_RENDER_H_
|
|
||||||
#define _PAYSAGES_RENDER_H_
|
|
||||||
|
|
||||||
#include "rendering_global.h"
|
|
||||||
#include "shared/types.h"
|
|
||||||
#include "Color.h"
|
|
||||||
|
|
||||||
typedef Color (*f_RenderFragmentCallback)(Renderer* renderer, Vector3 location, void* data);
|
|
||||||
|
|
||||||
typedef void (*RenderCallbackStart)(int width, int height, Color background);
|
|
||||||
typedef void (*RenderCallbackDraw)(int x, int y, Color col);
|
|
||||||
typedef void (*RenderCallbackUpdate)(double progress);
|
|
||||||
|
|
||||||
typedef struct RenderArea RenderArea;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int antialias;
|
|
||||||
int quality;
|
|
||||||
} RenderParams;
|
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT void renderInit();
|
|
||||||
RENDERINGSHARED_EXPORT void renderQuit();
|
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT RenderArea* renderCreateArea(Renderer* renderer);
|
|
||||||
RENDERINGSHARED_EXPORT void renderDeleteArea(RenderArea* area);
|
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT void renderSetParams(RenderArea* area, RenderParams params);
|
|
||||||
RENDERINGSHARED_EXPORT void renderSetToneMapping(RenderArea* area, const ColorProfile &profile);
|
|
||||||
RENDERINGSHARED_EXPORT void renderSetBackgroundColor(RenderArea* area, const Color& col);
|
|
||||||
RENDERINGSHARED_EXPORT void renderClear(RenderArea* area);
|
|
||||||
RENDERINGSHARED_EXPORT void renderUpdate(RenderArea* area);
|
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT void renderPushTriangle(RenderArea* area, Vector3 pixel1, Vector3 pixel2, Vector3 pixel3, Vector3 location1, Vector3 location2, Vector3 location3, f_RenderFragmentCallback callback, void* callback_data);
|
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT Color renderGetPixel(RenderArea* area, int x, int y);
|
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT void renderPostProcess(RenderArea* area, int nbchunks);
|
|
||||||
RENDERINGSHARED_EXPORT int renderSaveToFile(RenderArea* area, const char* path);
|
|
||||||
RENDERINGSHARED_EXPORT void renderSetPreviewCallbacks(RenderArea* area, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,211 +0,0 @@
|
||||||
#include "renderer.h"
|
|
||||||
|
|
||||||
#include "System.h"
|
|
||||||
#include "Thread.h"
|
|
||||||
#include "render.h"
|
|
||||||
#include "RenderingScenery.h"
|
|
||||||
#include "CameraDefinition.h"
|
|
||||||
#include "SurfaceMaterial.h"
|
|
||||||
|
|
||||||
static RayCastingResult _RAYCASTING_NULL = {0, {0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
|
|
||||||
|
|
||||||
static void* _renderFirstPass(void* data)
|
|
||||||
{
|
|
||||||
Renderer* renderer = (Renderer*)data;
|
|
||||||
|
|
||||||
renderer->rasterize();
|
|
||||||
renderer->is_rendering = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _addRenderProgress(Renderer* renderer, double)
|
|
||||||
{
|
|
||||||
return !renderer->render_interrupt;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Vector3 _getCameraLocation(Renderer* renderer, Vector3)
|
|
||||||
{
|
|
||||||
return renderer->render_camera->getLocation();
|
|
||||||
}
|
|
||||||
|
|
||||||
static Vector3 _getCameraDirection(Renderer* renderer, Vector3)
|
|
||||||
{
|
|
||||||
return renderer->render_camera->getDirectionNormalized();
|
|
||||||
}
|
|
||||||
|
|
||||||
static double _getPrecision(Renderer*, Vector3)
|
|
||||||
{
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Vector3 _projectPoint(Renderer* renderer, Vector3 point)
|
|
||||||
{
|
|
||||||
return renderer->render_camera->project(point);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Vector3 _unprojectPoint(Renderer* renderer, Vector3 point)
|
|
||||||
{
|
|
||||||
return renderer->render_camera->unproject(point);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _pushTriangle(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, f_RenderFragmentCallback callback, void* callback_data)
|
|
||||||
{
|
|
||||||
Vector3 p1, p2, p3;
|
|
||||||
|
|
||||||
p1 = renderer->projectPoint(renderer, v1);
|
|
||||||
p2 = renderer->projectPoint(renderer, v2);
|
|
||||||
p3 = renderer->projectPoint(renderer, v3);
|
|
||||||
|
|
||||||
renderPushTriangle(renderer->render_area, p1, p2, p3, v1, v2, v3, callback, callback_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _pushQuad(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, f_RenderFragmentCallback callback, void* callback_data)
|
|
||||||
{
|
|
||||||
renderer->pushTriangle(renderer, v2, v3, v1, callback, callback_data);
|
|
||||||
renderer->pushTriangle(renderer, v4, v1, v3, callback, callback_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _pushDisplacedTriangle(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 ov1, Vector3 ov2, Vector3 ov3, f_RenderFragmentCallback callback, void* callback_data)
|
|
||||||
{
|
|
||||||
Vector3 p1, p2, p3;
|
|
||||||
|
|
||||||
p1 = renderer->projectPoint(renderer, v1);
|
|
||||||
p2 = renderer->projectPoint(renderer, v2);
|
|
||||||
p3 = renderer->projectPoint(renderer, v3);
|
|
||||||
|
|
||||||
renderPushTriangle(renderer->render_area, p1, p2, p3, ov1, ov2, ov3, callback, callback_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _pushDisplacedQuad(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Vector3 ov1, Vector3 ov2, Vector3 ov3, Vector3 ov4, f_RenderFragmentCallback callback, void* callback_data)
|
|
||||||
{
|
|
||||||
renderer->pushDisplacedTriangle(renderer, v2, v3, v1, ov2, ov3, ov1, callback, callback_data);
|
|
||||||
renderer->pushDisplacedTriangle(renderer, v4, v1, v3, ov4, ov1, ov3, callback, callback_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Renderer::Renderer()
|
|
||||||
{
|
|
||||||
RenderParams params = {1, 1, 1, 5};
|
|
||||||
|
|
||||||
render_quality = 5;
|
|
||||||
render_width = 1;
|
|
||||||
render_height = 1;
|
|
||||||
render_interrupt = 0;
|
|
||||||
render_progress = 0.0;
|
|
||||||
is_rendering = 0;
|
|
||||||
render_camera = new CameraDefinition;
|
|
||||||
render_area = renderCreateArea(this);
|
|
||||||
|
|
||||||
renderSetParams(render_area, params);
|
|
||||||
|
|
||||||
addRenderProgress = _addRenderProgress;
|
|
||||||
getCameraLocation = _getCameraLocation;
|
|
||||||
getCameraDirection = _getCameraDirection;
|
|
||||||
getPrecision = _getPrecision;
|
|
||||||
projectPoint = _projectPoint;
|
|
||||||
unprojectPoint = _unprojectPoint;
|
|
||||||
pushTriangle = _pushTriangle;
|
|
||||||
pushQuad = _pushQuad;
|
|
||||||
pushDisplacedTriangle = _pushDisplacedTriangle;
|
|
||||||
pushDisplacedQuad = _pushDisplacedQuad;
|
|
||||||
}
|
|
||||||
|
|
||||||
Renderer::~Renderer()
|
|
||||||
{
|
|
||||||
delete render_camera;
|
|
||||||
|
|
||||||
renderDeleteArea(render_area);
|
|
||||||
}
|
|
||||||
|
|
||||||
Color Renderer::applyMediumTraversal(Vector3, Color color)
|
|
||||||
{
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color Renderer::applyLightingToSurface(const Vector3 &, const Vector3 &, const SurfaceMaterial &material)
|
|
||||||
{
|
|
||||||
return material._rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
RayCastingResult Renderer::rayWalking(const Vector3 &, const Vector3 &, int, int, int, int)
|
|
||||||
{
|
|
||||||
return _RAYCASTING_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Old API compat
|
|
||||||
|
|
||||||
Renderer* rendererCreate()
|
|
||||||
{
|
|
||||||
return new Renderer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void rendererDelete(Renderer* renderer)
|
|
||||||
{
|
|
||||||
delete renderer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rendererSetPreviewCallbacks(Renderer* renderer, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update)
|
|
||||||
{
|
|
||||||
renderSetPreviewCallbacks(renderer->render_area, start, draw, update);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rendererStart(Renderer* renderer, RenderParams params)
|
|
||||||
{
|
|
||||||
Thread thread(_renderFirstPass);
|
|
||||||
int loops;
|
|
||||||
int core_count = System::getCoreCount();
|
|
||||||
|
|
||||||
params.antialias = (params.antialias < 1) ? 1 : params.antialias;
|
|
||||||
params.antialias = (params.antialias > 4) ? 4 : params.antialias;
|
|
||||||
|
|
||||||
renderer->render_quality = params.quality;
|
|
||||||
renderer->render_width = params.width * params.antialias;
|
|
||||||
renderer->render_height = params.height * params.antialias;
|
|
||||||
renderer->render_interrupt = 0;
|
|
||||||
renderer->render_progress = 0.0;
|
|
||||||
|
|
||||||
renderer->render_camera->setRenderSize(renderer->render_width, renderer->render_height);
|
|
||||||
|
|
||||||
renderSetBackgroundColor(renderer->render_area, COLOR_BLACK);
|
|
||||||
renderSetParams(renderer->render_area, params);
|
|
||||||
renderClear(renderer->render_area);
|
|
||||||
|
|
||||||
renderer->prepare();
|
|
||||||
|
|
||||||
renderer->is_rendering = 1;
|
|
||||||
thread.start(renderer);
|
|
||||||
loops = 0;
|
|
||||||
|
|
||||||
while (renderer->is_rendering)
|
|
||||||
{
|
|
||||||
Thread::timeSleepMs(100);
|
|
||||||
|
|
||||||
if (++loops >= 10)
|
|
||||||
{
|
|
||||||
|
|
||||||
renderUpdate(renderer->render_area);
|
|
||||||
loops = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
thread.join();
|
|
||||||
|
|
||||||
renderer->is_rendering = 1;
|
|
||||||
renderPostProcess(renderer->render_area, core_count);
|
|
||||||
renderer->is_rendering = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rendererInterrupt(Renderer* renderer)
|
|
||||||
{
|
|
||||||
renderer->render_interrupt = 1;
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
#ifndef _PAYSAGES_RENDERER_H_
|
|
||||||
#define _PAYSAGES_RENDERER_H_
|
|
||||||
|
|
||||||
#include "rendering_global.h"
|
|
||||||
#include "shared/types.h"
|
|
||||||
#include "render.h"
|
|
||||||
|
|
||||||
class Renderer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Renderer();
|
|
||||||
virtual ~Renderer();
|
|
||||||
|
|
||||||
virtual void prepare() {}
|
|
||||||
virtual void rasterize() {}
|
|
||||||
virtual void setScenery(Scenery*) {}
|
|
||||||
|
|
||||||
/* Render base configuration */
|
|
||||||
int render_quality;
|
|
||||||
int render_width;
|
|
||||||
int render_height;
|
|
||||||
CameraDefinition* render_camera;
|
|
||||||
|
|
||||||
/* Render related */
|
|
||||||
RenderArea* render_area;
|
|
||||||
double render_progress;
|
|
||||||
int render_interrupt;
|
|
||||||
int is_rendering;
|
|
||||||
Vector3(*getCameraLocation)(Renderer* renderer, Vector3 target);
|
|
||||||
Vector3(*getCameraDirection)(Renderer* renderer, Vector3 target);
|
|
||||||
double (*getPrecision)(Renderer* renderer, Vector3 location);
|
|
||||||
Vector3(*projectPoint)(Renderer* renderer, Vector3 point);
|
|
||||||
Vector3(*unprojectPoint)(Renderer* renderer, Vector3 point);
|
|
||||||
int (*addRenderProgress)(Renderer* renderer, double progress);
|
|
||||||
void (*pushTriangle)(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, f_RenderFragmentCallback callback, void* callback_data);
|
|
||||||
void (*pushQuad)(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, f_RenderFragmentCallback callback, void* callback_data);
|
|
||||||
void (*pushDisplacedTriangle)(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 ov1, Vector3 ov2, Vector3 ov3, f_RenderFragmentCallback callback, void* callback_data);
|
|
||||||
void (*pushDisplacedQuad)(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Vector3 ov1, Vector3 ov2, Vector3 ov3, Vector3 ov4, f_RenderFragmentCallback callback, void* callback_data);
|
|
||||||
|
|
||||||
/* Shortcuts */
|
|
||||||
virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material);
|
|
||||||
virtual Color applyMediumTraversal(Vector3 location, Color color);
|
|
||||||
virtual RayCastingResult rayWalking(const Vector3 &location, const Vector3 &direction, int terrain, int water, int sky, int clouds);
|
|
||||||
|
|
||||||
/* Custom data */
|
|
||||||
void* customData[10];
|
|
||||||
};
|
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT Renderer* rendererCreate();
|
|
||||||
RENDERINGSHARED_EXPORT void rendererDelete(Renderer* renderer);
|
|
||||||
RENDERINGSHARED_EXPORT void rendererSetPreviewCallbacks(Renderer* renderer, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update);
|
|
||||||
RENDERINGSHARED_EXPORT void rendererStart(Renderer* renderer, RenderParams params);
|
|
||||||
RENDERINGSHARED_EXPORT void rendererInterrupt(Renderer* renderer);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -9,21 +9,15 @@ DEFINES += RENDERING_LIBRARY
|
||||||
include(../common.pri)
|
include(../common.pri)
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
renderer.cpp \
|
|
||||||
render.cpp \
|
|
||||||
tools/texture.cpp \
|
tools/texture.cpp \
|
||||||
tools/parallel.cpp \
|
|
||||||
tools/data.cpp \
|
tools/data.cpp \
|
||||||
tools/cache.cpp \
|
tools/cache.cpp \
|
||||||
RenderingScenery.cpp
|
RenderingScenery.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
renderer.h \
|
|
||||||
render.h \
|
|
||||||
main.h \
|
main.h \
|
||||||
shared/types.h \
|
shared/types.h \
|
||||||
tools/texture.h \
|
tools/texture.h \
|
||||||
tools/parallel.h \
|
|
||||||
tools/data.h \
|
tools/data.h \
|
||||||
tools/cache.h \
|
tools/cache.h \
|
||||||
rendering_global.h \
|
rendering_global.h \
|
||||||
|
|
|
@ -10,7 +10,4 @@
|
||||||
|
|
||||||
#include "definition_global.h"
|
#include "definition_global.h"
|
||||||
|
|
||||||
class Renderer; // TEMP
|
|
||||||
class RenderingScenery; // TEMP
|
|
||||||
|
|
||||||
#endif // RENDERING_GLOBAL_H
|
#endif // RENDERING_GLOBAL_H
|
||||||
|
|
|
@ -6,14 +6,6 @@
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
#include "Vector3.h"
|
#include "Vector3.h"
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int hit;
|
|
||||||
Color hit_color;
|
|
||||||
Vector3 hit_location;
|
|
||||||
} RayCastingResult;
|
|
||||||
typedef RayCastingResult (*FuncGeneralCastRay)(Renderer* renderer, Vector3 start, Vector3 direction);
|
|
||||||
|
|
||||||
typedef void* (*FuncObjectCreate)();
|
typedef void* (*FuncObjectCreate)();
|
||||||
typedef void (*FuncObjectDelete)(void* object);
|
typedef void (*FuncObjectDelete)(void* object);
|
||||||
typedef void (*FuncObjectBind)(void* base, void* sub);
|
typedef void (*FuncObjectBind)(void* base, void* sub);
|
||||||
|
|
|
@ -1,363 +0,0 @@
|
||||||
#include "parallel.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "System.h"
|
|
||||||
#include "Thread.h"
|
|
||||||
#include "Mutex.h"
|
|
||||||
|
|
||||||
#define PARALLEL_MAX_THREADS 20
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
PARALLEL_WORKER_STATUS_VOID,
|
|
||||||
PARALLEL_WORKER_STATUS_RUNNING,
|
|
||||||
PARALLEL_WORKER_STATUS_DONE
|
|
||||||
} ParallelWorkerStatus;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
Thread* thread;
|
|
||||||
ParallelWork* work;
|
|
||||||
ParallelWorkerStatus status;
|
|
||||||
int unit;
|
|
||||||
int result;
|
|
||||||
} ParallelWorker;
|
|
||||||
|
|
||||||
struct ParallelWork
|
|
||||||
{
|
|
||||||
int units;
|
|
||||||
int running;
|
|
||||||
ParallelUnitFunction unit_function;
|
|
||||||
ParallelWorker workers[PARALLEL_MAX_THREADS];
|
|
||||||
void* data;
|
|
||||||
};
|
|
||||||
|
|
||||||
ParallelWork* parallelWorkCreate(ParallelUnitFunction func, int units, void* data)
|
|
||||||
{
|
|
||||||
ParallelWork* result;
|
|
||||||
|
|
||||||
result = (ParallelWork*)malloc(sizeof(ParallelWork));
|
|
||||||
result->units = units;
|
|
||||||
result->running = 0;
|
|
||||||
result->unit_function = func;
|
|
||||||
result->data = data;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void parallelWorkDelete(ParallelWork* work)
|
|
||||||
{
|
|
||||||
assert(!work->running);
|
|
||||||
free(work);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* _workerThreadCallback(ParallelWorker* worker)
|
|
||||||
{
|
|
||||||
worker->result = worker->work->unit_function(worker->work, worker->unit, worker->work->data);
|
|
||||||
worker->status = PARALLEL_WORKER_STATUS_DONE;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _runNextWorker(ParallelWorker workers[], int worker_count, int unit)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
for (i = 0; i < worker_count; i++)
|
|
||||||
{
|
|
||||||
ParallelWorker* worker = workers + i;
|
|
||||||
if (worker->status == PARALLEL_WORKER_STATUS_VOID)
|
|
||||||
{
|
|
||||||
worker->status = PARALLEL_WORKER_STATUS_RUNNING;
|
|
||||||
worker->result = 0;
|
|
||||||
worker->unit = unit;
|
|
||||||
worker->thread = new Thread((ThreadFunction)_workerThreadCallback);
|
|
||||||
worker->thread->start(worker);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (worker->status == PARALLEL_WORKER_STATUS_DONE)
|
|
||||||
{
|
|
||||||
int result = worker->result;
|
|
||||||
|
|
||||||
worker->status = PARALLEL_WORKER_STATUS_RUNNING;
|
|
||||||
worker->result = 0;
|
|
||||||
worker->unit = unit;
|
|
||||||
worker->thread->join();
|
|
||||||
delete worker->thread;
|
|
||||||
worker->thread = new Thread((ThreadFunction)_workerThreadCallback);
|
|
||||||
worker->thread->start(worker);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Thread::timeSleepMs(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int parallelWorkPerform(ParallelWork* work, int workers)
|
|
||||||
{
|
|
||||||
int i, done, result;
|
|
||||||
assert(!work->running);
|
|
||||||
|
|
||||||
result = 0;
|
|
||||||
|
|
||||||
if (workers <= 0)
|
|
||||||
{
|
|
||||||
workers = System::getCoreCount();
|
|
||||||
}
|
|
||||||
if (workers > PARALLEL_MAX_THREADS)
|
|
||||||
{
|
|
||||||
workers = PARALLEL_MAX_THREADS;
|
|
||||||
}
|
|
||||||
work->running = 1;
|
|
||||||
|
|
||||||
/* Init workers */
|
|
||||||
for (i = 0; i < workers; i++)
|
|
||||||
{
|
|
||||||
work->workers[i].status = PARALLEL_WORKER_STATUS_VOID;
|
|
||||||
work->workers[i].work = work;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Perform run */
|
|
||||||
for (done = 0; done < work->units; done++)
|
|
||||||
{
|
|
||||||
if (_runNextWorker(work->workers, workers, done))
|
|
||||||
{
|
|
||||||
result++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait and clean up workers */
|
|
||||||
for (i = 0; i < workers; i++)
|
|
||||||
{
|
|
||||||
if (work->workers[i].status != PARALLEL_WORKER_STATUS_VOID)
|
|
||||||
{
|
|
||||||
work->workers[i].thread->join();
|
|
||||||
delete work->workers[i].thread;
|
|
||||||
if (work->workers[i].result)
|
|
||||||
{
|
|
||||||
result++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
work->running = 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define QUEUE_SIZE 1000
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
JOB_STATE_FREE,
|
|
||||||
JOB_STATE_PENDING,
|
|
||||||
JOB_STATE_PROCESSING,
|
|
||||||
JOB_STATE_TOCOLLECT
|
|
||||||
} EnumJobState;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
EnumJobState state;
|
|
||||||
int id;
|
|
||||||
FuncParallelJob process;
|
|
||||||
void* data;
|
|
||||||
} ParallelJob;
|
|
||||||
|
|
||||||
struct ParallelQueue
|
|
||||||
{
|
|
||||||
int collect;
|
|
||||||
volatile int stopping;
|
|
||||||
Mutex* lock;
|
|
||||||
|
|
||||||
int workers_count;
|
|
||||||
Thread** workers;
|
|
||||||
|
|
||||||
ParallelJob* jobs;
|
|
||||||
int jobs_count; /** Number of jobs in queue (all status except JOB_STATE_FREE) */
|
|
||||||
int jobs_index_free; /** Index of next free position */
|
|
||||||
int jobs_index_collect; /** Index of first job to collect */
|
|
||||||
int jobs_index_pending; /** Index of first pending job to process */
|
|
||||||
int jobs_next_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void* _queueThreadCallback(ParallelQueue* queue)
|
|
||||||
{
|
|
||||||
ParallelJob* job;
|
|
||||||
|
|
||||||
while (!queue->stopping)
|
|
||||||
{
|
|
||||||
/* Try to take a job */
|
|
||||||
queue->lock->acquire();
|
|
||||||
job = queue->jobs + queue->jobs_index_pending;
|
|
||||||
if (job->state == JOB_STATE_PENDING)
|
|
||||||
{
|
|
||||||
if (queue->jobs_index_pending >= QUEUE_SIZE - 1)
|
|
||||||
{
|
|
||||||
queue->jobs_index_pending = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
queue->jobs_index_pending++;
|
|
||||||
}
|
|
||||||
job->state = JOB_STATE_PROCESSING;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
job = NULL;
|
|
||||||
}
|
|
||||||
queue->lock->release();
|
|
||||||
|
|
||||||
if (job)
|
|
||||||
{
|
|
||||||
/* Process the job */
|
|
||||||
job->process(queue, job->id, job->data, 0);
|
|
||||||
|
|
||||||
queue->lock->acquire();
|
|
||||||
if (queue->collect)
|
|
||||||
{
|
|
||||||
job->state = JOB_STATE_TOCOLLECT;
|
|
||||||
/* TODO jobs_index_collect ? */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
job->state = JOB_STATE_FREE;
|
|
||||||
queue->jobs_count--;
|
|
||||||
}
|
|
||||||
queue->lock->release();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Thread::timeSleepMs(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ParallelQueue* parallelQueueCreate(int collect)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
assert(!collect); /* Not fully implemented yet ! */
|
|
||||||
|
|
||||||
ParallelQueue* queue = new ParallelQueue;
|
|
||||||
|
|
||||||
queue->collect = collect;
|
|
||||||
queue->stopping = 0;
|
|
||||||
queue->lock = new Mutex();
|
|
||||||
|
|
||||||
queue->jobs = new ParallelJob[QUEUE_SIZE];
|
|
||||||
for (i = 0; i < QUEUE_SIZE; i++)
|
|
||||||
{
|
|
||||||
queue->jobs[i].state = JOB_STATE_FREE;
|
|
||||||
}
|
|
||||||
queue->jobs_count = 0;
|
|
||||||
queue->jobs_index_free = 0;
|
|
||||||
queue->jobs_index_collect = 0;
|
|
||||||
queue->jobs_index_pending = 0;
|
|
||||||
queue->jobs_next_id = 1;
|
|
||||||
|
|
||||||
/* Start workers */
|
|
||||||
queue->workers_count = System::getCoreCount();
|
|
||||||
queue->workers = new Thread*[queue->workers_count];
|
|
||||||
for (i = 0; i < queue->workers_count; i++)
|
|
||||||
{
|
|
||||||
queue->workers[i] = new Thread((ThreadFunction)_queueThreadCallback);
|
|
||||||
queue->workers[i]->start(queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
return queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void parallelQueueDelete(ParallelQueue* queue)
|
|
||||||
{
|
|
||||||
parallelQueueInterrupt(queue);
|
|
||||||
|
|
||||||
assert(!queue->collect || queue->jobs[queue->jobs_index_collect].state != JOB_STATE_TOCOLLECT);
|
|
||||||
assert(queue->jobs_count == 0);
|
|
||||||
|
|
||||||
delete queue->lock;
|
|
||||||
delete[] queue->jobs;
|
|
||||||
delete[] queue->workers;
|
|
||||||
delete queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void parallelQueueInterrupt(ParallelQueue* queue)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!queue->stopping)
|
|
||||||
{
|
|
||||||
queue->stopping = 1;
|
|
||||||
|
|
||||||
for (i = 0; i < queue->workers_count; i++)
|
|
||||||
{
|
|
||||||
queue->workers[i]->join();
|
|
||||||
delete queue->workers[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void parallelQueueWait(ParallelQueue* queue)
|
|
||||||
{
|
|
||||||
while (queue->jobs_count > 0)
|
|
||||||
{
|
|
||||||
Thread::timeSleepMs(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int parallelQueueAddJob(ParallelQueue* queue, FuncParallelJob func_process, void* data)
|
|
||||||
{
|
|
||||||
if (queue->stopping)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait for a free slot */
|
|
||||||
while (queue->jobs[queue->jobs_index_free].state != JOB_STATE_FREE)
|
|
||||||
{
|
|
||||||
Thread::timeSleepMs(50);
|
|
||||||
if (queue->stopping)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare the job */
|
|
||||||
ParallelJob job;
|
|
||||||
job.state = JOB_STATE_PENDING;
|
|
||||||
job.id = queue->jobs_next_id++;
|
|
||||||
job.process = func_process;
|
|
||||||
job.data = data;
|
|
||||||
|
|
||||||
/* Add the job to the queue */
|
|
||||||
queue->lock->acquire();
|
|
||||||
if (queue->stopping)
|
|
||||||
{
|
|
||||||
queue->lock->release();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
queue->jobs[queue->jobs_index_free] = job;
|
|
||||||
if (queue->jobs_index_free >= QUEUE_SIZE - 1)
|
|
||||||
{
|
|
||||||
queue->jobs_index_free = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
queue->jobs_index_free++;
|
|
||||||
}
|
|
||||||
queue->jobs_count++;
|
|
||||||
assert(queue->jobs_count <= QUEUE_SIZE);
|
|
||||||
queue->lock->release();
|
|
||||||
|
|
||||||
return job.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
int parallelQueueCollectJobs(FuncParallelJob)
|
|
||||||
{
|
|
||||||
/* TODO */
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
#ifndef _PAYSAGES_TOOLS_PARALLEL_H_
|
|
||||||
#define _PAYSAGES_TOOLS_PARALLEL_H_
|
|
||||||
|
|
||||||
#include "../rendering_global.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parallel processing helpers.
|
|
||||||
*
|
|
||||||
* Several units of work can be accomplished by a given number of parallel workers.
|
|
||||||
* Workers are implemented by threads so thread-safety must be ensured while accessing
|
|
||||||
* shared data from unit functions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct ParallelWork ParallelWork;
|
|
||||||
typedef int (*ParallelUnitFunction)(ParallelWork* work, int unit, void* data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a parallel work handler.
|
|
||||||
*
|
|
||||||
* This will spawn an optimal number of threads to process a given number of work units.
|
|
||||||
* @param func The callback that will be called from threads to process one unit.
|
|
||||||
* @param units Number of units to handle.
|
|
||||||
* @param data Custom data that will be passed to the callback.
|
|
||||||
* @return The newly allocated handler.
|
|
||||||
*/
|
|
||||||
RENDERINGSHARED_EXPORT ParallelWork* parallelWorkCreate(ParallelUnitFunction func, int units, void* data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a parallel work handler.
|
|
||||||
*
|
|
||||||
* The work must be terminated or fully interrupted before calling this.
|
|
||||||
* @param work The handler to free.
|
|
||||||
*/
|
|
||||||
RENDERINGSHARED_EXPORT void parallelWorkDelete(ParallelWork* work);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start working on the units.
|
|
||||||
*
|
|
||||||
* @param work The handler.
|
|
||||||
* @param workers Number of threads to spaws, -1 for an optimal number.
|
|
||||||
*/
|
|
||||||
RENDERINGSHARED_EXPORT int parallelWorkPerform(ParallelWork* work, int workers);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct ParallelQueue ParallelQueue;
|
|
||||||
typedef int (*FuncParallelJob)(ParallelQueue* queue, int job_id, void* data, int stopping);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a parallel processing queue.
|
|
||||||
*
|
|
||||||
* This queue will use parallel workers to process jobs added to it.
|
|
||||||
* @param collect True to collect finished jobs and wait for a call to parallelQueueCollectJobs, False to discard finished jobs.
|
|
||||||
* @return The newly allocated queue.
|
|
||||||
*/
|
|
||||||
RENDERINGSHARED_EXPORT ParallelQueue* parallelQueueCreate(int collect);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a parallel queue.
|
|
||||||
*
|
|
||||||
* This will interrupt the queue.
|
|
||||||
* If the queue is in collect mode, you should call parallelQueueInterrupt, then parallelQueueCollectJobs, before calling this.
|
|
||||||
* @param queue The queue to free.
|
|
||||||
*/
|
|
||||||
RENDERINGSHARED_EXPORT void parallelQueueDelete(ParallelQueue* queue);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interrupt the queue processing.
|
|
||||||
*
|
|
||||||
* This will wait for running jobs to end, cancel pending jobs (still calling their callbacks with stopping=1) and
|
|
||||||
* refuse future jobs.
|
|
||||||
* @param queue The queue to interrupt.
|
|
||||||
*/
|
|
||||||
RENDERINGSHARED_EXPORT void parallelQueueInterrupt(ParallelQueue* queue);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait for all jobs to finish.
|
|
||||||
*
|
|
||||||
* This function will return as soon as there is no pending jobs. It is recommended to stop feeding the queue, or this
|
|
||||||
* function may never return.
|
|
||||||
*/
|
|
||||||
RENDERINGSHARED_EXPORT void parallelQueueWait(ParallelQueue* queue);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a job to the queue.
|
|
||||||
*
|
|
||||||
* Don't call this method concurrently from several threads.
|
|
||||||
* @param queue The queue.
|
|
||||||
* @param func_process The function that will be called for the job processing.
|
|
||||||
* @param data The data that will be passed to the callback.
|
|
||||||
* @return The job ID, 0 if the queue doesn't accept jobs.
|
|
||||||
*/
|
|
||||||
RENDERINGSHARED_EXPORT int parallelQueueAddJob(ParallelQueue* queue, FuncParallelJob func_process, void* data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collect finished jobs.
|
|
||||||
*
|
|
||||||
* The callback func_collect will be called sequentially for each finished job, from the caller thread (not parallel threads).
|
|
||||||
* Don't call this method concurrently from several threads.
|
|
||||||
* @param func_collect The callback for collect.
|
|
||||||
* @return The number of collected jobs.
|
|
||||||
*/
|
|
||||||
RENDERINGSHARED_EXPORT int parallelQueueCollectJobs(FuncParallelJob func_collect);
|
|
||||||
|
|
||||||
#endif
|
|
181
src/system/ParallelQueue.cpp
Normal file
181
src/system/ParallelQueue.cpp
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
#include "ParallelQueue.h"
|
||||||
|
|
||||||
|
#include "Mutex.h"
|
||||||
|
#include "Thread.h"
|
||||||
|
#include "System.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#define QUEUE_SIZE 1000
|
||||||
|
|
||||||
|
static void* _queueThreadCallback(ParallelQueue* queue)
|
||||||
|
{
|
||||||
|
ParallelQueue::ParallelJob* job;
|
||||||
|
|
||||||
|
while (!queue->stopping)
|
||||||
|
{
|
||||||
|
/* Try to take a job */
|
||||||
|
queue->lock->acquire();
|
||||||
|
job = queue->jobs + queue->jobs_index_pending;
|
||||||
|
if (job->state == ParallelQueue::JOB_STATE_PENDING)
|
||||||
|
{
|
||||||
|
if (queue->jobs_index_pending >= QUEUE_SIZE - 1)
|
||||||
|
{
|
||||||
|
queue->jobs_index_pending = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
queue->jobs_index_pending++;
|
||||||
|
}
|
||||||
|
job->state = ParallelQueue::JOB_STATE_PROCESSING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
job = NULL;
|
||||||
|
}
|
||||||
|
queue->lock->release();
|
||||||
|
|
||||||
|
if (job)
|
||||||
|
{
|
||||||
|
/* Process the job */
|
||||||
|
job->process(queue, job->id, job->data, 0);
|
||||||
|
|
||||||
|
queue->lock->acquire();
|
||||||
|
if (queue->collect)
|
||||||
|
{
|
||||||
|
job->state = ParallelQueue::JOB_STATE_TOCOLLECT;
|
||||||
|
/* TODO jobs_index_collect ? */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
job->state = ParallelQueue::JOB_STATE_FREE;
|
||||||
|
queue->jobs_count--;
|
||||||
|
}
|
||||||
|
queue->lock->release();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Thread::timeSleepMs(50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParallelQueue::ParallelQueue(int collect)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
assert(!collect); /* Not fully implemented yet ! */
|
||||||
|
|
||||||
|
this->collect = collect;
|
||||||
|
this->stopping = 0;
|
||||||
|
this->lock = new Mutex();
|
||||||
|
|
||||||
|
this->jobs = new ParallelJob[QUEUE_SIZE];
|
||||||
|
for (i = 0; i < QUEUE_SIZE; i++)
|
||||||
|
{
|
||||||
|
this->jobs[i].state = JOB_STATE_FREE;
|
||||||
|
}
|
||||||
|
this->jobs_count = 0;
|
||||||
|
this->jobs_index_free = 0;
|
||||||
|
this->jobs_index_collect = 0;
|
||||||
|
this->jobs_index_pending = 0;
|
||||||
|
this->jobs_next_id = 1;
|
||||||
|
|
||||||
|
/* Start workers */
|
||||||
|
this->workers_count = System::getCoreCount();
|
||||||
|
this->workers = new Thread*[this->workers_count];
|
||||||
|
for (i = 0; i < this->workers_count; i++)
|
||||||
|
{
|
||||||
|
this->workers[i] = new Thread((ThreadFunction)_queueThreadCallback);
|
||||||
|
this->workers[i]->start(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ParallelQueue::~ParallelQueue()
|
||||||
|
{
|
||||||
|
interrupt();
|
||||||
|
|
||||||
|
assert(not collect or jobs[jobs_index_collect].state != JOB_STATE_TOCOLLECT);
|
||||||
|
assert(jobs_count == 0);
|
||||||
|
|
||||||
|
delete lock;
|
||||||
|
delete[] jobs;
|
||||||
|
delete[] workers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParallelQueue::interrupt()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (not stopping)
|
||||||
|
{
|
||||||
|
stopping = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < workers_count; i++)
|
||||||
|
{
|
||||||
|
workers[i]->join();
|
||||||
|
delete workers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParallelQueue::wait()
|
||||||
|
{
|
||||||
|
while (jobs_count > 0)
|
||||||
|
{
|
||||||
|
Thread::timeSleepMs(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ParallelQueue::addJob(FuncParallelJob func_process, void* data)
|
||||||
|
{
|
||||||
|
if (stopping)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for a free slot */
|
||||||
|
while (jobs[jobs_index_free].state != JOB_STATE_FREE)
|
||||||
|
{
|
||||||
|
Thread::timeSleepMs(50);
|
||||||
|
if (stopping)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare the job */
|
||||||
|
ParallelJob job;
|
||||||
|
job.state = JOB_STATE_PENDING;
|
||||||
|
job.id = jobs_next_id++;
|
||||||
|
job.process = func_process;
|
||||||
|
job.data = data;
|
||||||
|
|
||||||
|
/* Add the job to the queue */
|
||||||
|
lock->acquire();
|
||||||
|
if (stopping)
|
||||||
|
{
|
||||||
|
lock->release();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
jobs[jobs_index_free] = job;
|
||||||
|
if (jobs_index_free >= QUEUE_SIZE - 1)
|
||||||
|
{
|
||||||
|
jobs_index_free = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jobs_index_free++;
|
||||||
|
}
|
||||||
|
jobs_count++;
|
||||||
|
assert(jobs_count <= QUEUE_SIZE);
|
||||||
|
lock->release();
|
||||||
|
|
||||||
|
return job.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ParallelQueue::collectJobs(FuncParallelJob)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
return 0;
|
||||||
|
}
|
94
src/system/ParallelQueue.h
Normal file
94
src/system/ParallelQueue.h
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
#ifndef PARALLELQUEUE_H
|
||||||
|
#define PARALLELQUEUE_H
|
||||||
|
|
||||||
|
#include "system_global.h"
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace system {
|
||||||
|
|
||||||
|
class SYSTEMSHARED_EXPORT ParallelQueue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef int (*FuncParallelJob)(ParallelQueue* queue, int job_id, void* data, int stopping);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
JOB_STATE_FREE,
|
||||||
|
JOB_STATE_PENDING,
|
||||||
|
JOB_STATE_PROCESSING,
|
||||||
|
JOB_STATE_TOCOLLECT
|
||||||
|
} EnumJobState;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
EnumJobState state;
|
||||||
|
int id;
|
||||||
|
FuncParallelJob process;
|
||||||
|
void* data;
|
||||||
|
} ParallelJob;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Create a parallel processing queue.
|
||||||
|
*
|
||||||
|
* This queue will use parallel workers to process jobs added to it.
|
||||||
|
* @param collect True to collect finished jobs and wait for a call to collectJobs, False to discard finished jobs.
|
||||||
|
* @return The newly allocated queue.
|
||||||
|
*/
|
||||||
|
ParallelQueue(int collect=0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a parallel queue.
|
||||||
|
*
|
||||||
|
* This will interrupt the queue.
|
||||||
|
* If the queue is in collect mode, you should call interrupt, then collectJobs, before calling this.
|
||||||
|
*/
|
||||||
|
~ParallelQueue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interrupt the queue processing.
|
||||||
|
*
|
||||||
|
* This will wait for running jobs to end, cancel pending jobs (still calling their callbacks with stopping=1) and
|
||||||
|
* refuse future jobs.
|
||||||
|
*/
|
||||||
|
void interrupt();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for all jobs to finish.
|
||||||
|
*
|
||||||
|
* This function will return as soon as there is no pending jobs. It is recommended to stop feeding the queue, or this
|
||||||
|
* function may never return.
|
||||||
|
*/
|
||||||
|
void wait();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a job to the queue.
|
||||||
|
*
|
||||||
|
* Don't call this method concurrently from several threads.
|
||||||
|
* @param func_process The function that will be called for the job processing.
|
||||||
|
* @param data The data that will be passed to the callback.
|
||||||
|
* @return The job ID, 0 if the queue doesn't accept jobs.
|
||||||
|
*/
|
||||||
|
int addJob(FuncParallelJob func_process, void* data);
|
||||||
|
|
||||||
|
int collectJobs(FuncParallelJob func_collect);
|
||||||
|
|
||||||
|
int collect;
|
||||||
|
volatile int stopping;
|
||||||
|
Mutex* lock;
|
||||||
|
|
||||||
|
int workers_count;
|
||||||
|
Thread** workers;
|
||||||
|
|
||||||
|
ParallelJob* jobs;
|
||||||
|
int jobs_count; /** Number of jobs in queue (all status except JOB_STATE_FREE) */
|
||||||
|
int jobs_index_free; /** Index of next free position */
|
||||||
|
int jobs_index_collect; /** Index of first job to collect */
|
||||||
|
int jobs_index_pending; /** Index of first pending job to process */
|
||||||
|
int jobs_next_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PARALLELQUEUE_H
|
114
src/system/ParallelWork.cpp
Normal file
114
src/system/ParallelWork.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#include "ParallelWork.h"
|
||||||
|
|
||||||
|
#include "Thread.h"
|
||||||
|
#include "System.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
ParallelWork::ParallelWork(ParallelUnitFunction func, int units, void* data)
|
||||||
|
{
|
||||||
|
this->units = units;
|
||||||
|
this->running = 0;
|
||||||
|
this->unit_function = func;
|
||||||
|
this->data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParallelWork::~ParallelWork()
|
||||||
|
{
|
||||||
|
assert(not running);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* _workerThreadCallback(ParallelWork::ParallelWorker* worker)
|
||||||
|
{
|
||||||
|
worker->result = worker->work->unit_function(worker->work, worker->unit, worker->work->data);
|
||||||
|
worker->status = ParallelWork::PARALLEL_WORKER_STATUS_DONE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _runNextWorker(ParallelWork::ParallelWorker workers[], int worker_count, int unit)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
for (i = 0; i < worker_count; i++)
|
||||||
|
{
|
||||||
|
ParallelWork::ParallelWorker* worker = workers + i;
|
||||||
|
if (worker->status == ParallelWork::PARALLEL_WORKER_STATUS_VOID)
|
||||||
|
{
|
||||||
|
worker->status = ParallelWork::PARALLEL_WORKER_STATUS_RUNNING;
|
||||||
|
worker->result = 0;
|
||||||
|
worker->unit = unit;
|
||||||
|
worker->thread = new Thread((ThreadFunction)_workerThreadCallback);
|
||||||
|
worker->thread->start(worker);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (worker->status == ParallelWork::PARALLEL_WORKER_STATUS_DONE)
|
||||||
|
{
|
||||||
|
int result = worker->result;
|
||||||
|
|
||||||
|
worker->status = ParallelWork::PARALLEL_WORKER_STATUS_RUNNING;
|
||||||
|
worker->result = 0;
|
||||||
|
worker->unit = unit;
|
||||||
|
worker->thread->join();
|
||||||
|
delete worker->thread;
|
||||||
|
worker->thread = new Thread((ThreadFunction)_workerThreadCallback);
|
||||||
|
worker->thread->start(worker);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Thread::timeSleepMs(50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ParallelWork::perform(int nbworkers)
|
||||||
|
{
|
||||||
|
int i, done, result;
|
||||||
|
assert(not running);
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
if (nbworkers <= 0)
|
||||||
|
{
|
||||||
|
nbworkers = System::getCoreCount();
|
||||||
|
}
|
||||||
|
if (nbworkers > PARALLEL_MAX_THREADS)
|
||||||
|
{
|
||||||
|
nbworkers = PARALLEL_MAX_THREADS;
|
||||||
|
}
|
||||||
|
running = 1;
|
||||||
|
|
||||||
|
/* Init workers */
|
||||||
|
for (i = 0; i < nbworkers; i++)
|
||||||
|
{
|
||||||
|
workers[i].status = PARALLEL_WORKER_STATUS_VOID;
|
||||||
|
workers[i].work = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform run */
|
||||||
|
for (done = 0; done < units; done++)
|
||||||
|
{
|
||||||
|
if (_runNextWorker(workers, nbworkers, done))
|
||||||
|
{
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait and clean up workers */
|
||||||
|
for (i = 0; i < nbworkers; i++)
|
||||||
|
{
|
||||||
|
if (workers[i].status != PARALLEL_WORKER_STATUS_VOID)
|
||||||
|
{
|
||||||
|
workers[i].thread->join();
|
||||||
|
delete workers[i].thread;
|
||||||
|
if (workers[i].result)
|
||||||
|
{
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
running = 0;
|
||||||
|
return result;
|
||||||
|
}
|
69
src/system/ParallelWork.h
Normal file
69
src/system/ParallelWork.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#ifndef PARALLELWORK_H
|
||||||
|
#define PARALLELWORK_H
|
||||||
|
|
||||||
|
#include "system_global.h"
|
||||||
|
|
||||||
|
#define PARALLEL_MAX_THREADS 20
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace system {
|
||||||
|
|
||||||
|
class SYSTEMSHARED_EXPORT ParallelWork
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef int (*ParallelUnitFunction)(ParallelWork* work, int unit, void* data);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PARALLEL_WORKER_STATUS_VOID,
|
||||||
|
PARALLEL_WORKER_STATUS_RUNNING,
|
||||||
|
PARALLEL_WORKER_STATUS_DONE
|
||||||
|
} ParallelWorkerStatus;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Thread* thread;
|
||||||
|
ParallelWork* work;
|
||||||
|
ParallelWorkerStatus status;
|
||||||
|
int unit;
|
||||||
|
int result;
|
||||||
|
} ParallelWorker;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Create a parallel work handler.
|
||||||
|
*
|
||||||
|
* This will spawn an optimal number of threads to process a given number of work units.
|
||||||
|
*
|
||||||
|
* @param func The callback that will be called from threads to process one unit.
|
||||||
|
* @param units Number of units to handle.
|
||||||
|
* @param data Custom data that will be passed to the callback.
|
||||||
|
* @return The newly allocated handler.
|
||||||
|
*/
|
||||||
|
ParallelWork(ParallelUnitFunction func, int units, void* data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a parallel work handler.
|
||||||
|
*
|
||||||
|
* The work must be terminated or fully interrupted before calling this.
|
||||||
|
*/
|
||||||
|
~ParallelWork();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start working on the units.
|
||||||
|
*
|
||||||
|
* @param workers Number of threads to spaws, -1 for an optimal number.
|
||||||
|
*/
|
||||||
|
int perform(int workers=-1);
|
||||||
|
|
||||||
|
int units;
|
||||||
|
int running;
|
||||||
|
ParallelUnitFunction unit_function;
|
||||||
|
ParallelWorker workers[PARALLEL_MAX_THREADS];
|
||||||
|
void* data;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PARALLELWORK_H
|
|
@ -1,7 +1,7 @@
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
|
|
||||||
Thread::Thread(ThreadFunction function):
|
Thread::Thread(ThreadFunction function):
|
||||||
function(function), data(0), result(0)
|
data(0), result(0), function(function)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
* The thread is not started automatically. A call to method start() needs to be done.
|
* The thread is not started automatically. A call to method start() needs to be done.
|
||||||
* \param function Function to call inside the thread once it is started
|
* \param function Function to call inside the thread once it is started
|
||||||
*/
|
*/
|
||||||
Thread(ThreadFunction function);
|
Thread(ThreadFunction function=0);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Start the thread
|
* \brief Start the thread
|
||||||
|
@ -40,12 +40,16 @@ public:
|
||||||
static inline void timeSleepMs(unsigned long ms){ QThread::msleep(ms); }
|
static inline void timeSleepMs(unsigned long ms){ QThread::msleep(ms); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/*!
|
||||||
|
* \brief Function to reimplement if no ThreadFunction has been passed to the constructor.
|
||||||
|
*/
|
||||||
virtual void run();
|
virtual void run();
|
||||||
|
|
||||||
|
void* data;
|
||||||
|
void* result;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ThreadFunction function;
|
ThreadFunction function;
|
||||||
void* data;
|
|
||||||
void* result;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,9 @@ SOURCES += \
|
||||||
System.cpp \
|
System.cpp \
|
||||||
PackStream.cpp \
|
PackStream.cpp \
|
||||||
RandomGenerator.cpp \
|
RandomGenerator.cpp \
|
||||||
Memory.cpp
|
Memory.cpp \
|
||||||
|
ParallelWork.cpp \
|
||||||
|
ParallelQueue.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
system_global.h \
|
system_global.h \
|
||||||
|
@ -30,7 +32,9 @@ HEADERS += \
|
||||||
System.h \
|
System.h \
|
||||||
PackStream.h \
|
PackStream.h \
|
||||||
RandomGenerator.h \
|
RandomGenerator.h \
|
||||||
Memory.h
|
Memory.h \
|
||||||
|
ParallelWork.h \
|
||||||
|
ParallelQueue.h
|
||||||
|
|
||||||
unix:!symbian {
|
unix:!symbian {
|
||||||
maemo5 {
|
maemo5 {
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace system {
|
namespace system {
|
||||||
class PackStream;
|
class PackStream;
|
||||||
|
class ParallelQueue;
|
||||||
|
class ParallelWork;
|
||||||
|
class Thread;
|
||||||
|
class Mutex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
using namespace paysages::system;
|
using namespace paysages::system;
|
||||||
|
|
|
@ -4,15 +4,16 @@
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "AtmosphereDefinition.h"
|
#include "AtmosphereDefinition.h"
|
||||||
#include "AtmosphereRenderer.h"
|
#include "AtmosphereRenderer.h"
|
||||||
|
#include "AtmosphereResult.h"
|
||||||
#include "RenderingScenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
|
|
||||||
#define OUTPUT_WIDTH 400
|
#define OUTPUT_WIDTH 400
|
||||||
#define OUTPUT_HEIGHT 300
|
#define OUTPUT_HEIGHT 300
|
||||||
|
|
||||||
static Color _postProcessFragment(Renderer* renderer, Vector3 location, void*)
|
static Color _postProcessFragment(SoftwareRenderer* renderer, Vector3 location, void*)
|
||||||
{
|
{
|
||||||
return renderer->atmosphere->applyAerialPerspective(renderer, location, COLOR_BLACK).final;
|
return renderer->getAtmosphereRenderer()->applyAerialPerspective(location, COLOR_BLACK).final;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Bruneton, AerialPerspective1)
|
TEST(Bruneton, AerialPerspective1)
|
||||||
|
@ -26,19 +27,19 @@ TEST(Bruneton, AerialPerspective1)
|
||||||
renderer.render_camera->setTarget(VECTOR_EAST);
|
renderer.render_camera->setTarget(VECTOR_EAST);
|
||||||
renderer.render_camera->setRenderSize(renderer.render_width, renderer.render_height);
|
renderer.render_camera->setRenderSize(renderer.render_width, renderer.render_height);
|
||||||
|
|
||||||
RenderParams params = {renderer.render_width, renderer.render_height, 1, 1};
|
RenderArea::RenderParams params = {renderer.render_width, renderer.render_height, 1, 1};
|
||||||
renderSetParams(renderer.render_area, params);
|
renderer.render_area->setParams(params);
|
||||||
renderSetBackgroundColor(renderer.render_area, COLOR_BLACK);
|
renderer.render_area->setBackgroundColor(COLOR_BLACK);
|
||||||
renderClear(renderer.render_area);
|
renderer.render_area->clear();
|
||||||
|
|
||||||
renderer.pushQuad(&renderer, v3(50.0, -10.0, -50.0), v3(1.0, -10.0, -50.0), v3(1.0, -10.0, 50.0), v3(50.0, -10.0, 50.0), _postProcessFragment, NULL);
|
renderer.pushQuad(v3(50.0, -10.0, -50.0), v3(1.0, -10.0, -50.0), v3(1.0, -10.0, 50.0), v3(50.0, -10.0, 50.0), _postProcessFragment, NULL);
|
||||||
renderer.pushQuad(&renderer, v3(10.0, -10.0, -10.0), v3(10.0, -10.0, -5.0), v3(10.0, 50.0, -5.0), v3(10.0, 50.0, -10.0), _postProcessFragment, NULL);
|
renderer.pushQuad(v3(10.0, -10.0, -10.0), v3(10.0, -10.0, -5.0), v3(10.0, 50.0, -5.0), v3(10.0, 50.0, -10.0), _postProcessFragment, NULL);
|
||||||
renderer.pushQuad(&renderer, v3(15.0, -10.0, -5.0), v3(15.0, -10.0, 0.0), v3(15.0, 50.0, 0.0), v3(15.0, 50.0, -5.0), _postProcessFragment, NULL);
|
renderer.pushQuad(v3(15.0, -10.0, -5.0), v3(15.0, -10.0, 0.0), v3(15.0, 50.0, 0.0), v3(15.0, 50.0, -5.0), _postProcessFragment, NULL);
|
||||||
renderer.pushQuad(&renderer, v3(20.0, -10.0, 5.0), v3(20.0, -10.0, 10.0), v3(20.0, 50.0, 10.0), v3(20.0, 50.0, 5.0), _postProcessFragment, NULL);
|
renderer.pushQuad(v3(20.0, -10.0, 5.0), v3(20.0, -10.0, 10.0), v3(20.0, 50.0, 10.0), v3(20.0, 50.0, 5.0), _postProcessFragment, NULL);
|
||||||
renderer.pushQuad(&renderer, v3(30.0, -10.0, 25.0), v3(30.0, -10.0, 30.0), v3(30.0, 50.0, 30.0), v3(30.0, 50.0, 25.0), _postProcessFragment, NULL);
|
renderer.pushQuad(v3(30.0, -10.0, 25.0), v3(30.0, -10.0, 30.0), v3(30.0, 50.0, 30.0), v3(30.0, 50.0, 25.0), _postProcessFragment, NULL);
|
||||||
renderPostProcess(renderer.render_area, System::getCoreCount());
|
renderer.render_area->postProcess(System::getCoreCount());
|
||||||
|
|
||||||
renderSaveToFile(renderer.render_area, "./output/test_bruneton_perspective.png");
|
renderer.render_area->saveToFile("./output/test_bruneton_perspective.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Bruneton, AerialPerspective2)
|
TEST(Bruneton, AerialPerspective2)
|
||||||
|
@ -48,7 +49,7 @@ TEST(Bruneton, AerialPerspective2)
|
||||||
atmo->minute = 30;
|
atmo->minute = 30;
|
||||||
atmo->validate();
|
atmo->validate();
|
||||||
|
|
||||||
Renderer renderer;
|
SoftwareRenderer renderer;
|
||||||
renderer.render_width = 800;
|
renderer.render_width = 800;
|
||||||
renderer.render_height = 600;
|
renderer.render_height = 600;
|
||||||
renderer.render_quality = 1;
|
renderer.render_quality = 1;
|
||||||
|
@ -57,17 +58,17 @@ TEST(Bruneton, AerialPerspective2)
|
||||||
renderer.render_camera->setTarget(VECTOR_EAST);
|
renderer.render_camera->setTarget(VECTOR_EAST);
|
||||||
renderer.render_camera->setRenderSize(renderer.render_width, renderer.render_height);
|
renderer.render_camera->setRenderSize(renderer.render_width, renderer.render_height);
|
||||||
|
|
||||||
RenderParams params = {renderer.render_width, renderer.render_height, 1, 1};
|
RenderArea::RenderParams params = {renderer.render_width, renderer.render_height, 1, 1};
|
||||||
renderSetParams(renderer.render_area, params);
|
renderer.render_area->setParams(params);
|
||||||
renderSetBackgroundColor(renderer.render_area, COLOR_BLACK);
|
renderer.render_area->setBackgroundColor(COLOR_BLACK);
|
||||||
renderClear(renderer.render_area);
|
renderer.render_area->clear();
|
||||||
|
|
||||||
renderer.pushQuad(&renderer, v3(50.0, -10.0, -50.0), v3(1.0, -10.0, -50.0), v3(1.0, -10.0, 50.0), v3(50.0, -10.0, 50.0), _postProcessFragment, NULL);
|
renderer.pushQuad(v3(50.0, -10.0, -50.0), v3(1.0, -10.0, -50.0), v3(1.0, -10.0, 50.0), v3(50.0, -10.0, 50.0), _postProcessFragment, NULL);
|
||||||
renderer.pushQuad(&renderer, v3(10.0, -10.0, -10.0), v3(10.0, -10.0, -5.0), v3(10.0, 50.0, -5.0), v3(10.0, 50.0, -10.0), _postProcessFragment, NULL);
|
renderer.pushQuad(v3(10.0, -10.0, -10.0), v3(10.0, -10.0, -5.0), v3(10.0, 50.0, -5.0), v3(10.0, 50.0, -10.0), _postProcessFragment, NULL);
|
||||||
renderer.pushQuad(&renderer, v3(15.0, -10.0, -5.0), v3(15.0, -10.0, 0.0), v3(15.0, 50.0, 0.0), v3(15.0, 50.0, -5.0), _postProcessFragment, NULL);
|
renderer.pushQuad(v3(15.0, -10.0, -5.0), v3(15.0, -10.0, 0.0), v3(15.0, 50.0, 0.0), v3(15.0, 50.0, -5.0), _postProcessFragment, NULL);
|
||||||
renderer.pushQuad(&renderer, v3(20.0, -10.0, 5.0), v3(20.0, -10.0, 10.0), v3(20.0, 50.0, 10.0), v3(20.0, 50.0, 5.0), _postProcessFragment, NULL);
|
renderer.pushQuad(v3(20.0, -10.0, 5.0), v3(20.0, -10.0, 10.0), v3(20.0, 50.0, 10.0), v3(20.0, 50.0, 5.0), _postProcessFragment, NULL);
|
||||||
renderer.pushQuad(&renderer, v3(30.0, -10.0, 25.0), v3(30.0, -10.0, 30.0), v3(30.0, 50.0, 30.0), v3(30.0, 50.0, 25.0), _postProcessFragment, NULL);
|
renderer.pushQuad(v3(30.0, -10.0, 25.0), v3(30.0, -10.0, 30.0), v3(30.0, 50.0, 30.0), v3(30.0, 50.0, 25.0), _postProcessFragment, NULL);
|
||||||
renderPostProcess(renderer.render_area, System::getCoreCount());
|
renderer.render_area->postProcess(System::getCoreCount());
|
||||||
|
|
||||||
renderSaveToFile(renderer.render_area, "./output/test_bruneton_perspective1.png");
|
renderer.render_area->saveToFile("./output/test_bruneton_perspective1.png");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#include "BaseTestCase.h"
|
#include "BaseTestCase.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "renderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "ColorProfile.h"
|
#include "ColorProfile.h"
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
|
|
||||||
static Color _postProcessFragment(Renderer*, Vector3 location, void*)
|
static Color _postProcessFragment(SoftwareRenderer*, Vector3 location, void*)
|
||||||
{
|
{
|
||||||
/* Checker-board */
|
/* Checker-board */
|
||||||
double x = fmod(location.x, 0.2);
|
double x = fmod(location.x, 0.2);
|
||||||
|
@ -32,36 +32,34 @@ static Color _postProcessFragment(Renderer*, Vector3 location, void*)
|
||||||
TEST(Render, quad)
|
TEST(Render, quad)
|
||||||
{
|
{
|
||||||
Color col;
|
Color col;
|
||||||
Renderer* renderer = rendererCreate();
|
SoftwareRenderer renderer;
|
||||||
|
|
||||||
renderer->render_width = 800;
|
renderer.render_width = 800;
|
||||||
renderer->render_height = 600;
|
renderer.render_height = 600;
|
||||||
renderer->render_quality = 1;
|
renderer.render_quality = 1;
|
||||||
renderSetToneMapping(renderer->render_area, ColorProfile(ColorProfile::TONE_MAPPING_CLAMP, 0.0));
|
renderer.render_area->setToneMapping(ColorProfile(ColorProfile::TONE_MAPPING_CLAMP, 0.0));
|
||||||
|
|
||||||
renderer->render_camera->setLocationCoords(0.0, 0.5, 2.0);
|
renderer.render_camera->setLocationCoords(0.0, 0.5, 2.0);
|
||||||
renderer->render_camera->setTargetCoords(0.0, 0.5, 0.0);
|
renderer.render_camera->setTargetCoords(0.0, 0.5, 0.0);
|
||||||
renderer->render_camera->setRenderSize(renderer->render_width, renderer->render_height);
|
renderer.render_camera->setRenderSize(renderer.render_width, renderer.render_height);
|
||||||
|
|
||||||
RenderParams params = {renderer->render_width, renderer->render_height, 1, 1};
|
RenderArea::RenderParams params = {renderer.render_width, renderer.render_height, 1, 1};
|
||||||
renderSetParams(renderer->render_area, params);
|
renderer.render_area->setParams(params);
|
||||||
|
|
||||||
renderSetBackgroundColor(renderer->render_area, COLOR_BLUE);
|
renderer.render_area->setBackgroundColor(COLOR_BLUE);
|
||||||
renderClear(renderer->render_area);
|
renderer.render_area->clear();
|
||||||
|
|
||||||
renderer->pushQuad(renderer, v3(-1.0, 0.0, 1.0), v3(-1.0, 0.0, -1.0), v3(1.0, 0.0, -1.0), v3(1.0, 0.0, 1.0), _postProcessFragment, NULL);
|
renderer.pushQuad(v3(-1.0, 0.0, 1.0), v3(-1.0, 0.0, -1.0), v3(1.0, 0.0, -1.0), v3(1.0, 0.0, 1.0), _postProcessFragment, NULL);
|
||||||
renderPostProcess(renderer->render_area, System::getCoreCount());
|
renderer.render_area->postProcess(System::getCoreCount());
|
||||||
|
|
||||||
col = renderGetPixel(renderer->render_area, 399, 599 - 435);
|
col = renderer.render_area->getPixel(399, 599 - 435);
|
||||||
ASSERT_COLOR_RGBA(col, 1.0, 1.0, 1.0, 1.0);
|
ASSERT_COLOR_RGBA(col, 1.0, 1.0, 1.0, 1.0);
|
||||||
col = renderGetPixel(renderer->render_area, 399, 599 - 436);
|
col = renderer.render_area->getPixel(399, 599 - 436);
|
||||||
ASSERT_COLOR_RGBA(col, 0.0, 0.0, 0.0, 1.0);
|
ASSERT_COLOR_RGBA(col, 0.0, 0.0, 0.0, 1.0);
|
||||||
col = renderGetPixel(renderer->render_area, 400, 599 - 435);
|
col = renderer.render_area->getPixel(400, 599 - 435);
|
||||||
ASSERT_COLOR_RGBA(col, 0.0, 0.0, 0.0, 1.0);
|
ASSERT_COLOR_RGBA(col, 0.0, 0.0, 0.0, 1.0);
|
||||||
col = renderGetPixel(renderer->render_area, 400, 599 - 436);
|
col = renderer.render_area->getPixel(400, 599 - 436);
|
||||||
ASSERT_COLOR_RGBA(col, 1.0, 1.0, 1.0, 1.0);
|
ASSERT_COLOR_RGBA(col, 1.0, 1.0, 1.0, 1.0);
|
||||||
|
|
||||||
renderSaveToFile(renderer->render_area, "./output/test_render_quad.png");
|
renderer.render_area->saveToFile("./output/test_render_quad.png");
|
||||||
|
|
||||||
rendererDelete(renderer);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue