[Broken WIP] Removed legacy Renderer and refactored RenderArea.

This commit is contained in:
Michaël Lemaire 2013-12-09 11:59:57 +01:00 committed by Michael Lemaire
parent 74634dfaf1
commit ec444b7c26
79 changed files with 1252 additions and 1377 deletions

View file

@ -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)
{ {

View file

@ -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;

View file

@ -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();

View file

@ -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)
{ {

View file

@ -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();

View file

@ -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;
}; };

View file

@ -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;

View file

@ -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"

View file

@ -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;

View file

@ -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;

View file

@ -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 ****************/

View file

@ -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"

View file

@ -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

View file

@ -69,6 +69,6 @@ void DialogMaterialEditor::commitLocalDataToScenery()
{ {
} }
void DialogMaterialEditor::alterRenderer(Renderer*) void DialogMaterialEditor::alterRenderer(SoftwareRenderer*)
{ {
} }

View file

@ -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;

View file

@ -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;

View file

@ -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;
}; };

View file

@ -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;

View file

@ -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()

View file

@ -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();

View file

@ -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;

View file

@ -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();
} }

View file

@ -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;

View file

@ -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
{ {

View file

@ -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
{ {

View file

@ -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
{ {

View file

@ -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();
} }

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;
} }

View file

@ -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);

View file

@ -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()

View file

@ -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);

View file

@ -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);

View file

@ -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)

View file

@ -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);
} }
} }

View file

@ -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
{ {

View file

@ -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;
}

View file

@ -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;

View file

@ -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, &params); work = new ParallelWork(_inscatter1Worker, RES_R, &params);
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;

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -0,0 +1,5 @@
#include "RayCastingManager.h"
RayCastingManager::RayCastingManager()
{
}

View 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

View file

@ -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, &current); _scanInterpolate(area->renderer->render_camera, &down, &diff, fy / dy, &current);
_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);
} }

View 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

View file

@ -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);
} }
} }
} }

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
} }

View file

@ -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;
} }

View file

@ -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 {

View file

@ -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;
} }

View file

@ -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)

View file

@ -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 {

View file

@ -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;

View file

@ -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();
}

View file

@ -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;

View file

@ -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)

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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 \

View file

@ -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

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View 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;
}

View 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
View 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
View 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

View file

@ -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)
{ {
} }

View file

@ -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;
}; };
} }

View file

@ -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 {

View file

@ -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;

View file

@ -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");
} }

View file

@ -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);
} }