[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 "main.h"
#include "render.h"
#include "renderer.h"
#include "CameraDefinition.h"
#include "AtmosphereDefinition.h"
#include "SoftwareRenderer.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);
rendererStart(renderer, params);
renderer->start(params);
printf("\rSaving %s ... \n", outputpath);
remove(outputpath);
renderSaveToFile(renderer->render_area, outputpath);
renderer->render_area->saveToFile(outputpath);
}
void displayHelp()
@ -48,7 +46,7 @@ int main(int argc, char** argv)
{
SoftwareRenderer* renderer;
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_nb_pictures = 1;
double conf_daytime_start = 0.4;
@ -177,7 +175,7 @@ int main(int argc, char** argv)
camera->setLocation(camera->getLocation().add(step));
renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
rendererSetPreviewCallbacks(renderer, NULL, NULL, _previewUpdate);
renderer->setPreviewCallbacks(NULL, NULL, _previewUpdate);
if (outputcount >= conf_first_picture)
{

View file

@ -251,7 +251,7 @@ void FreeFormHelper::processRenderClicked()
emit needAlterRenderer(&renderer);
DialogRender* dialog = new DialogRender(_form_widget, &renderer);
RenderParams params = {400, 300, 1, 3};
RenderArea::RenderParams params = {400, 300, 1, 3};
dialog->startRender(params);
delete dialog;

View file

@ -11,7 +11,6 @@
class QSlider;
class QPushButton;
class QLabel;
class Renderer;
class FreeFormHelper:public QObject
{
@ -47,7 +46,7 @@ signals:
void needGlobalRefreshing();
void needReverting();
void needCommitting();
void needAlterRenderer(Renderer* renderer);
void needAlterRenderer(SoftwareRenderer* renderer);
public slots:
void processDataChange();

View file

@ -6,7 +6,6 @@
#include <QLabel>
#include "WidgetExplorer.h"
#include "CameraDefinition.h"
#include "renderer.h"
DialogExplorer::DialogExplorer(QWidget* parent, CameraDefinition* camera, bool camera_validable, SoftwareRenderer* renderer) : QDialog(parent)
{

View file

@ -18,6 +18,7 @@
#include <QComboBox>
#include "tools.h"
#include "SoftwareRenderer.h"
#include "Scenery.h"
#include "ColorProfile.h"
@ -48,7 +49,7 @@ static void _renderUpdate(double progress)
class RenderThread:public QThread
{
public:
RenderThread(DialogRender* dialog, Renderer* renderer, RenderParams params):QThread()
RenderThread(DialogRender* dialog, SoftwareRenderer* renderer, RenderArea::RenderParams params):QThread()
{
_dialog = dialog;
_renderer = renderer;
@ -56,13 +57,13 @@ public:
}
void run()
{
rendererStart(_renderer, _params);
_renderer->start(_params);
_dialog->tellRenderEnded();
}
private:
DialogRender* _dialog;
Renderer* _renderer;
RenderParams _params;
SoftwareRenderer* _renderer;
RenderArea::RenderParams _params;
};
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)
{
pixbuf_lock = new QMutex();
@ -151,7 +152,7 @@ DialogRender::~DialogRender()
{
if (_render_thread)
{
rendererInterrupt(_renderer);
_renderer->interrupt();
_render_thread->wait();
delete _render_thread;
@ -175,12 +176,12 @@ void DialogRender::tellRenderEnded()
emit renderEnded();
}
void DialogRender::startRender(RenderParams params)
void DialogRender::startRender(RenderArea::RenderParams params)
{
_started = time(NULL);
applyRenderSize(params.width, params.height);
rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate);
_renderer->setPreviewCallbacks(_renderStart, _renderDraw, _renderUpdate);
_render_thread = new RenderThread(this, _renderer, params);
_render_thread->start();
@ -207,7 +208,8 @@ void DialogRender::saveRender()
{
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));
}
@ -220,13 +222,14 @@ void DialogRender::saveRender()
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()
{
applyRenderSize(_renderer->render_width, _renderer->render_height);
rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate);
_renderer->setPreviewCallbacks(_renderStart, _renderDraw, _renderUpdate);
renderEnded();
toneMappingChanged();

View file

@ -1,9 +1,11 @@
#ifndef _PAYSAGES_QT_DIALOGRENDER_H_
#define _PAYSAGES_QT_DIALOGRENDER_H_
#include "desktop_global.h"
#include <ctime>
#include <QDialog>
#include "renderer.h"
#include "RenderArea.h"
class QThread;
class QProgressBar;
@ -17,13 +19,13 @@ class DialogRender : public QDialog
{
Q_OBJECT
public:
explicit DialogRender(QWidget *parent, Renderer* renderer);
explicit DialogRender(QWidget *parent, SoftwareRenderer* renderer);
~DialogRender();
void tellRenderSize(int width, int height);
void tellProgressChange(double value);
void tellRenderEnded();
void startRender(RenderParams params);
void startRender(RenderArea::RenderParams params);
void loadLastRender();
QImage* pixbuf;
@ -51,7 +53,7 @@ private:
QPushButton* _save_button;
QThread* _render_thread;
QLabel* _timer;
Renderer* _renderer;
SoftwareRenderer* _renderer;
QProgressBar* _progress;
time_t _started;
};

View file

@ -10,7 +10,6 @@
#include "RenderingScenery.h"
#include "BasePreview.h"
#include "AtmosphereDefinition.h"
#include "renderer.h"
static AtmosphereDefinition* _definition;

View file

@ -2,7 +2,6 @@
#include "RenderingScenery.h"
#include "BasePreview.h"
#include "renderer.h"
#include "CloudsDefinition.h"
#include "CloudLayerDefinition.h"
#include "CloudsCoveragePreviewRenderer.h"

View file

@ -5,10 +5,6 @@
#include "dialogrender.h"
#include "inputcamera.h"
#include "tools.h"
#include "render.h"
#include "atmosphere/public.h"
#include "terrain/public.h"
#include "water/public.h"
#include "RenderingScenery.h"
#include "PackStream.h"
#include "SoftwareRenderer.h"
@ -57,7 +53,7 @@ FormRender::~FormRender()
delete _camera;
if (_renderer_inited)
{
rendererDelete(_renderer);
delete _renderer;
}
}
@ -105,13 +101,13 @@ void FormRender::startQuickRender()
{
if (_renderer_inited)
{
rendererDelete(_renderer);
delete _renderer;
}
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
_renderer_inited = true;
DialogRender* dialog = new DialogRender(this, _renderer);
RenderParams params = {400, 300, 1, 3};
RenderArea::RenderParams params = {400, 300, 1, 3};
dialog->startRender(params);
delete dialog;
@ -121,7 +117,7 @@ void FormRender::startRender()
{
if (_renderer_inited)
{
rendererDelete(_renderer);
delete _renderer;
}
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
_renderer_inited = true;

View file

@ -1,9 +1,11 @@
#ifndef _PAYSAGES_QT_FORMRENDER_H_
#define _PAYSAGES_QT_FORMRENDER_H_
#include "desktop_global.h"
#include "baseform.h"
#include "renderer.h"
#include "render.h"
#include "RenderArea.h"
class FormRender : public BaseForm
{
@ -27,9 +29,9 @@ protected slots:
virtual void configChangeEvent();
private:
RenderParams _params;
RenderArea::RenderParams _params;
CameraDefinition* _camera;
Renderer* _renderer;
SoftwareRenderer* _renderer;
bool _renderer_inited;
BasePreview* _preview_landscape;
Base2dPreviewRenderer* _preview_landscape_renderer;

View file

@ -2,12 +2,12 @@
#include "RenderingScenery.h"
#include "BasePreview.h"
#include "renderer.h"
#include "tools.h"
#include "CameraDefinition.h"
#include "TexturesDefinition.h"
#include "TextureLayerDefinition.h"
#include "terrain/public.h"
#include "SoftwareRenderer.h"
#include "TerrainRenderer.h"
/**************** Previews ****************/
class PreviewTexturesCoverage : public BasePreview
@ -16,11 +16,10 @@ public:
PreviewTexturesCoverage(QWidget* parent, TextureLayerDefinition* layer) : BasePreview(parent)
{
_renderer = rendererCreate();
_renderer = new SoftwareRenderer();
_renderer->render_quality = 3;
_original_layer = layer;
//_preview_definition = (TexturesDefinition*)TexturesDefinitionClass.create();
addOsd(QString("geolocation"));
@ -30,7 +29,7 @@ public:
~PreviewTexturesCoverage()
{
//TexturesDefinitionClass.destroy(_preview_layer);
delete _renderer;
}
protected:
@ -39,7 +38,7 @@ protected:
Vector3 location;
Color result;
location.x = x;
location.y = _renderer->terrain->getHeight(_renderer, x, y, 1);
location.y = _renderer->getTerrainRenderer()->getHeight(x, y, 1);
location.z = y;
//result.r = result.g = result.b = texturesGetLayerCoverage(_preview_layer, _renderer, location, this->scaling);
return result;
@ -47,15 +46,17 @@ protected:
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:
Renderer* _renderer;
SoftwareRenderer* _renderer;
TextureLayerDefinition* _original_layer;
TexturesDefinition* _preview_definition;
};
class PreviewTexturesColor : public BasePreview
@ -65,9 +66,8 @@ public:
PreviewTexturesColor(QWidget* parent, TextureLayerDefinition* layer) : BasePreview(parent)
{
_original_layer = layer;
//_preview_layer = (TexturesLayerDefinition*)TexturesDefinitionClass.create();
_renderer = rendererCreate();
_renderer = new SoftwareRenderer();
_renderer->render_quality = 3;
_renderer->render_camera->setLocation(Vector3(0.0, 20.0, 0.0));
@ -78,7 +78,7 @@ public:
~PreviewTexturesColor()
{
//TexturesDefinitionClass.destroy(_preview_layer);
delete _renderer;
}
protected:
@ -94,12 +94,16 @@ protected:
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:
Renderer* _renderer;
SoftwareRenderer* _renderer;
TextureLayerDefinition* _original_layer;
TextureLayerDefinition* _preview_layer;
};
/**************** Form ****************/

View file

@ -4,11 +4,6 @@
#include <QSlider>
#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 "RenderingScenery.h"
#include "BasePreview.h"

View file

@ -4,8 +4,6 @@
#include <QWidget>
#include "baseinput.h"
#include "tools/lighting.h"
class InputMaterial:public BaseInput
{
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
#define DIALOGMATERIALEDITOR_H
#include "desktop_global.h"
#include <QDialog>
#include "previewmaterial.h"
#include "tools/lighting.h"
#include "renderer.h"
#include "SurfaceMaterial.h"
namespace Ui {
@ -30,7 +29,7 @@ public slots:
void refreshFromFellowData();
void updateLocalDataFromScenery();
void commitLocalDataToScenery();
void alterRenderer(Renderer* renderer);
void alterRenderer(SoftwareRenderer* renderer);
private:
Ui::DialogMaterialEditor *ui;

View file

@ -7,20 +7,22 @@
#include "BasePreview.h"
#include "CameraDefinition.h"
#include "ColorProfile.h"
#include "tools/lighting.h"
#include "LightComponent.h"
#include "LightingManager.h"
/***** Shared renderer *****/
MaterialPreviewRenderer::MaterialPreviewRenderer(SurfaceMaterial* material)
{
_light.color.r = 3.0;
_light.color.g = 3.0;
_light.color.b = 3.0;
_light.direction.x = -0.5;
_light.direction.y = -0.5;
_light.direction.z = -0.5;
_light.direction = v3Normalize(_light.direction);
_light.altered = 0;
_light.reflection = 1.0;
_light = new LightComponent;
_light->color.r = 3.0;
_light->color.g = 3.0;
_light->color.b = 3.0;
_light->direction.x = -0.5;
_light->direction.y = -0.5;
_light->direction.z = -0.5;
_light->direction = v3Normalize(_light->direction);
_light->altered = 0;
_light->reflection = 1.0;
_material = material;
@ -33,6 +35,7 @@ MaterialPreviewRenderer::MaterialPreviewRenderer(SurfaceMaterial* material)
MaterialPreviewRenderer::~MaterialPreviewRenderer()
{
delete _color_profile;
delete _light;
}
void MaterialPreviewRenderer::bindEvent(BasePreview* preview)
@ -64,7 +67,7 @@ Color MaterialPreviewRenderer::getColor2D(double x, double y, double)
}
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)
{
color.a = (1.0 - dist) / 0.05;

View file

@ -6,8 +6,6 @@
#include "Base2dPreviewRenderer.h"
#include <QWidget>
#include "tools/lighting.h"
class MaterialPreviewRenderer:public Base2dPreviewRenderer {
public:
MaterialPreviewRenderer(SurfaceMaterial* material);
@ -18,7 +16,7 @@ public:
private:
SurfaceMaterial* _material;
LightDefinition _light;
LightComponent* _light;
ColorProfile* _color_profile;
};

View file

@ -1,9 +1,10 @@
#ifndef DIALOGTERRAINPAINTING_H
#define DIALOGTERRAINPAINTING_H
#include "desktop_global.h"
#include <QDialog>
#include "paintingbrush.h"
#include "terrain/public.h"
namespace Ui {
class DialogTerrainPainting;

View file

@ -10,7 +10,6 @@
#include "RenderingScenery.h"
#include "TerrainDefinition.h"
#include "TerrainHeightMap.h"
#include "textures/public.h"
MainTerrainForm::MainTerrainForm(QWidget *parent) :
QWidget(parent),
@ -71,7 +70,8 @@ void MainTerrainForm::refreshFromLocalData()
void MainTerrainForm::refreshFromFellowData()
{
double disp = texturesGetMaximalDisplacement(RenderingScenery::getCurrent()->getTextures());
//double disp = texturesGetMaximalDisplacement(RenderingScenery::getCurrent()->getTextures());
double disp = -1000.0;
if (disp == 0.0)
{
@ -93,9 +93,10 @@ void MainTerrainForm::commitLocalDataToScenery()
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()

View file

@ -5,7 +5,6 @@
#include <QWidget>
#include "terrain/public.h"
class FreeFormHelper;
namespace Ui {
@ -27,7 +26,7 @@ public slots:
void refreshFromFellowData();
void updateLocalDataFromScenery();
void commitLocalDataToScenery();
void alterRenderer(Renderer* renderer);
void alterRenderer(SoftwareRenderer* renderer);
void buttonBaseNoisePressed();
void buttonPaintingPressed();

View file

@ -1,13 +1,8 @@
#ifndef PAINTINGBRUSH_H
#define PAINTINGBRUSH_H
#include "terrain/public.h"
#include "desktop_global.h"
namespace paysages {
namespace basics {
class NoiseGenerator;
}
}
class QAbstractSlider;
class QWidget;

View file

@ -6,10 +6,12 @@
#include <math.h>
#include <GL/glu.h>
#include "tools.h"
#include "SoftwareRenderer.h"
#include "Scenery.h"
#include "TerrainDefinition.h"
#include "TerrainHeightMap.h"
#include "WaterDefinition.h"
#include "TerrainRenderer.h"
#define HEIGHTMAP_RESOLUTION 256
@ -23,7 +25,7 @@ QGLWidget(parent)
startTimer(100);
_terrain = NULL;
_renderer = rendererCreate();
_renderer = new SoftwareRenderer();
_vertices = new _VertexInfo[HEIGHTMAP_RESOLUTION * HEIGHTMAP_RESOLUTION];
_dirty = true;
@ -66,15 +68,17 @@ WidgetHeightMap::~WidgetHeightMap()
delete _current_camera;
delete _top_camera;
delete _temp_camera;
rendererDelete(_renderer);
delete _renderer;
delete[] _vertices;
}
void WidgetHeightMap::setTerrain(TerrainDefinition* 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();
}

View file

@ -1,12 +1,13 @@
#ifndef _PAYSAGES_QT_WIDGETHEIGHTMAP_H_
#define _PAYSAGES_QT_WIDGETHEIGHTMAP_H_
#include "desktop_global.h"
#include <QGLWidget>
#include <QDateTime>
#include "terrain/paintingbrush.h"
#include "CameraDefinition.h"
#include "renderer.h"
#include "terrain/public.h"
typedef struct
{
@ -55,7 +56,7 @@ private:
private:
TerrainDefinition* _terrain;
Renderer* _renderer;
SoftwareRenderer* _renderer;
_VertexInfo* _vertices;
bool _dirty;

View file

@ -2,7 +2,6 @@
#include "SoftwareRenderer.h"
#include "BasePreview.h"
#include "textures/tex_preview.h"
void PreviewCumul::setTextures(TexturesDefinition* textures)
{
@ -28,7 +27,7 @@ void PreviewCumul::updateEvent()
{
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)
{
return TexturesPreviewCumul_getColor(this, x, y, scaling, layer);
return COLOR_BLACK;
//return TexturesPreviewCumul_getColor(this, x, y, scaling, layer);
}
else
{

View file

@ -2,7 +2,6 @@
#include "SoftwareRenderer.h"
#include "BasePreview.h"
#include "textures/tex_preview.h"
void PreviewLayerCoverage::setTextures(TexturesDefinition* textures)
{
@ -26,7 +25,7 @@ void PreviewLayerCoverage::updateEvent()
{
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)
{
return TexturesPreviewLayerCoverage_getColor(this, x, y, scaling, layer);
return COLOR_BLACK;
//return TexturesPreviewLayerCoverage_getColor(this, x, y, scaling, layer);
}
else
{

View file

@ -2,7 +2,6 @@
#include "SoftwareRenderer.h"
#include "BasePreview.h"
#include "textures/tex_preview.h"
void PreviewLayerLook::setTextures(TexturesDefinition* textures)
{
@ -25,7 +24,7 @@ void PreviewLayerLook::updateEvent()
{
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)
{
return TexturesPreviewLayerLook_getColor(this, x, y, scaling, layer);
return COLOR_BLACK;
//return TexturesPreviewLayerLook_getColor(this, x, y, scaling, layer);
}
else
{

View file

@ -11,7 +11,6 @@
#include "textures/PreviewLayerLook.h"
#include "textures/PreviewCumul.h"
#include "textures/DialogTexturesLayer.h"
#include "textures/public.h"
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 PreviewLayerLook;
class PreviewCumul;
class Renderer;
class MainTexturesForm : public QWidget
{
@ -29,7 +28,7 @@ public slots:
void commitLocalDataToScenery();
void refreshFromLocalData();
void refreshFromFellowData();
void alterRenderer(Renderer* renderer);
void alterRenderer(SoftwareRenderer* renderer);
void updateLayers();
void selectLayer(int layer);

View file

@ -8,7 +8,7 @@
#define GL_CLAMP_TO_EDGE 0x812F
#endif
BaseExplorerChunk::BaseExplorerChunk(Renderer* renderer)
BaseExplorerChunk::BaseExplorerChunk(SoftwareRenderer* renderer)
{
_renderer = renderer;
_color_profile = new ColorProfile;

View file

@ -8,7 +8,6 @@
class QImage;
class QGLWidget;
class Renderer;
namespace paysages {
namespace opengl {
@ -24,9 +23,9 @@ public:
double priority;
protected:
BaseExplorerChunk(Renderer* renderer);
BaseExplorerChunk(SoftwareRenderer* renderer);
inline Renderer* renderer() {return _renderer;}
inline SoftwareRenderer* renderer() {return _renderer;}
void askReset();
void setMaxTextureSize(int size);
@ -41,7 +40,7 @@ protected:
QMutex _lock_data;
private:
Renderer* _renderer;
SoftwareRenderer* _renderer;
ColorProfile* _color_profile;
bool _reset_needed;

View file

@ -2,11 +2,12 @@
#include <cmath>
#include <GL/gl.h>
#include "renderer.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;
_orientation = orientation;
@ -143,5 +144,5 @@ Color ExplorerChunkSky::getTextureColor(double x, double y)
{
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
{
public:
ExplorerChunkSky(Renderer* renderer, double size, SkyboxOrientation orientation);
ExplorerChunkSky(SoftwareRenderer* renderer, double size, SkyboxOrientation orientation);
void onCameraEvent(CameraDefinition* camera);
void onRenderEvent(QGLWidget* widget);

View file

@ -3,10 +3,10 @@
#include <cmath>
#include <GL/gl.h>
#include "CameraDefinition.h"
#include "renderer.h"
#include "terrain/public.h"
#include "SoftwareRenderer.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;
_startz = z;
@ -43,7 +43,7 @@ void ExplorerChunkTerrain::onResetEvent()
bool ExplorerChunkTerrain::onMaintainEvent()
{
Renderer* renderer = this->renderer();
SoftwareRenderer* renderer = this->renderer();
// Improve heightmap resolution
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)
{
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)
{
_overwater = true;
@ -170,7 +170,7 @@ double ExplorerChunkTerrain::getDisplayedSizeHint(CameraDefinition* camera)
Color ExplorerChunkTerrain::getTextureColor(double x, double y)
{
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()

View file

@ -11,7 +11,7 @@ namespace opengl {
class OPENGLSHARED_EXPORT ExplorerChunkTerrain:public BaseExplorerChunk
{
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();
void onCameraEvent(CameraDefinition* camera);

View file

@ -11,13 +11,11 @@
#include "OpenGLRenderer.h"
#include "WaterDefinition.h"
#include "SurfaceMaterial.h"
#include "renderer.h"
#include "CameraDefinition.h"
#include "atmosphere/public.h"
#include "water/public.h"
#include "terrain/public.h"
#include "ExplorerChunkSky.h"
#include "ExplorerChunkTerrain.h"
#include "TerrainRenderer.h"
#include "WaterRenderer.h"
class ChunkMaintenanceThread : public QThread
{
@ -57,7 +55,7 @@ private:
static QVector<ChunkMaintenanceThread*> _threads;
static Vector3 _getCameraLocation(Renderer* renderer, Vector3)
/*static Vector3 _getCameraLocation(Renderer* renderer, Vector3)
{
return ((CameraDefinition*)renderer->customData[2])->getLocation();
}
@ -70,7 +68,7 @@ static AtmosphereResult _applyAerialPerspective(Renderer*, Vector3, Color base)
result.final = base;
atmosphereUpdateResult(&result);
return result;
}
}*/
WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera, SoftwareRenderer* renderer) :
QGLWidget(parent)
@ -95,10 +93,10 @@ QGLWidget(parent)
_opengl_renderer = new OpenGLRenderer(NULL);
_renderer->prepare();
_renderer->render_quality = 3;
_renderer->customData[2] = _base_camera;
/*_renderer->customData[2] = _base_camera;
_renderer->getCameraLocation = _getCameraLocation;
_renderer->atmosphere->applyAerialPerspective = _applyAerialPerspective;
lightingManagerDisableSpecularity(_renderer->lighting);
lightingManagerDisableSpecularity(_renderer->lighting);*/
_inited = false;
_updated = false;
@ -123,7 +121,7 @@ WidgetExplorer::~WidgetExplorer()
if (_renderer_created)
{
rendererDelete(_renderer);
delete _renderer;
}
delete _opengl_renderer;
}
@ -135,7 +133,7 @@ void WidgetExplorer::startRendering()
double size = 400.0;
double chunksize = size / (double) chunks;
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 j = 0; j < chunks; j++)
@ -402,7 +400,7 @@ void WidgetExplorer::paintGL()
GLenum error_code;
QTime start_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
_renderer->getScenery()->setCamera(_current_camera);
@ -422,7 +420,7 @@ void WidgetExplorer::paintGL()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Render water
double water_height = _renderer->terrain->getWaterHeight(_renderer);
double water_height = _renderer->getTerrainRenderer()->getWaterHeight();
glDisable(GL_TEXTURE_2D);
glColor3f(water->material->_rgb.r, water->material->_rgb.g, water->material->_rgb.b);
glBegin(GL_QUADS);

View file

@ -9,7 +9,7 @@
#include "LightComponent.h"
#include "AtmosphereResult.h"
static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
/*static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
{
LightComponent light;
@ -45,17 +45,7 @@ static double _getDensity(Renderer*, CloudLayerDefinition* layer, Vector3 locati
{
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):
layer(layer)
@ -82,9 +72,9 @@ void CloudsAspectPreviewRenderer::updateEvent()
prepare();
//disableAerialPerspective();
//clouds->getLayerDensity = _getDensity;
//atmosphere->getLightingStatus = _getLightingStatus;
//atmosphere->applyAerialPerspective = _fakeApplyAerialPerspective;
}
Color CloudsAspectPreviewRenderer::getColor2D(double x, double y, double)

View file

@ -3,8 +3,10 @@
#include "CloudsDefinition.h"
#include "BasePreview.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));
}
@ -17,7 +19,7 @@ static AtmosphereResult _applyAerialPerspective(Renderer*, Vector3, Color base)
result.final = base;
atmosphereUpdateResult(&result);
return result;
}
}*/
SceneryTopDownPreviewRenderer::SceneryTopDownPreviewRenderer(Scenery* scenery):
scenery(scenery)
@ -51,26 +53,26 @@ void SceneryTopDownPreviewRenderer::updateEvent()
prepare();
getCameraLocation = _getCameraLocation;
/*getCameraLocation = _getCameraLocation;
lightingManagerDisableSpecularity(lighting);
atmosphere->applyAerialPerspective = _applyAerialPerspective;
atmosphere->applyAerialPerspective = _applyAerialPerspective;*/
}
Color SceneryTopDownPreviewRenderer::getColor2D(double x, double y, double scaling)
{
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
{
location.x = x;
location.y = height;
location.z = y;
return terrain->getFinalColor(this, location, scaling);
return getTerrainRenderer()->getFinalColor(location, scaling);
}
}

View file

@ -6,10 +6,12 @@
#include "SurfaceMaterial.h"
#include "NoiseGenerator.h"
#include "BasePreview.h"
#include "Scenery.h"
#include "LightComponent.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;
@ -42,32 +44,13 @@ static Vector3 _getCameraLocation(Renderer*, Vector3 location)
location.y += 15.0;
location.z += 10.0;
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)
{
_terrain = terrain;
_alterPreviewRenderer(this);
render_quality = 3;
}
void TerrainShapePreviewRenderer::bindEvent(BasePreview* preview)
@ -80,17 +63,31 @@ void TerrainShapePreviewRenderer::bindEvent(BasePreview* preview)
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)
{
double height;
height = terrain->getHeight(this, x, y, 1);
if (height > terrain->getWaterHeight(this))
height = getTerrainRenderer()->getHeight(x, y, 1);
if (height > getTerrainRenderer()->getWaterHeight())
{
return terrain->getFinalColor(this, Vector3(x, height, y), 0.000001);
return getTerrainRenderer()->getFinalColor(Vector3(x, height, y), 0.000001);
}
else
{

View file

@ -4,64 +4,13 @@
#include "Scenery.h"
#include "WaterDefinition.h"
#include "CameraDefinition.h"
#include "WaterRenderer.h"
static double _getWaterHeight(Renderer*)
/*static double _getWaterHeight(Renderer*)
{
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)
{
LightDefinition light;
@ -85,7 +34,7 @@ static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3,
static double _getPrecision(Renderer*, Vector3)
{
return 0.000001;
}
}*/
WaterAspectPreviewRenderer::WaterAspectPreviewRenderer(WaterDefinition* definition):
definition(definition)
@ -117,8 +66,7 @@ void WaterAspectPreviewRenderer::updateEvent()
//terrain->getWaterHeight = _getWaterHeight;
//atmosphere->getLightingStatus = _getLightingStatus;
//rayWalking = _rayWalking;
getPrecision = _getPrecision;
//getPrecision = _getPrecision;
}
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)
{
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;
@ -146,10 +94,10 @@ Color WaterAspectPreviewRenderer::getColor2D(double x, double y, double scaling)
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)
@ -167,3 +115,54 @@ void WaterAspectPreviewRenderer::choiceChangeEvent(const std::string &key, int p
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 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:
WaterDefinition* definition;
bool lighting;

View file

@ -10,6 +10,7 @@
#include <cstdio>
#include <cstdlib>
#include "System.h"
#include "ParallelWork.h"
#include "PackStream.h"
#include "Scenery.h"
#include "AtmosphereDefinition.h"
@ -20,8 +21,6 @@
#include "LightStatus.h"
#include "tools/cache.h"
#include "tools/texture.h"
#include "tools/parallel.h"
#include "renderer.h"
/* Factor to convert software units to kilometers */
// TODO This is copied in AtmosphereRenderer
@ -1088,9 +1087,9 @@ int brunetonInit()
/* computes single scattering texture deltaS (line 3 in algorithm 4.1)
* Rayleigh and Mie separated in deltaSR + deltaSM */
Inscatter1Params params = {_deltaSRTexture, _deltaSMTexture};
work = parallelWorkCreate(_inscatter1Worker, RES_R, &params);
parallelWorkPerform(work, -1);
parallelWorkDelete(work);
work = new ParallelWork(_inscatter1Worker, RES_R, &params);
work->perform();
delete work;
_saveDebug4D(_deltaSRTexture, "deltaSR", 0);
_saveDebug4D(_deltaSMTexture, "deltaSM", 0);
@ -1122,9 +1121,9 @@ int brunetonInit()
{
/* computes deltaJ (line 7 in algorithm 4.1) */
jParams jparams = {_deltaJTexture, _deltaETexture, _deltaSRTexture, _deltaSMTexture, order == 2};
work = parallelWorkCreate(_jWorker, RES_R, &jparams);
parallelWorkPerform(work, -1);
parallelWorkDelete(work);
work = new ParallelWork(_jWorker, RES_R, &jparams);
work->perform();
delete work;
_saveDebug4D(_deltaJTexture, "deltaJ", order);
/* computes deltaE (line 8 in algorithm 4.1) */
@ -1133,10 +1132,9 @@ int brunetonInit()
/* computes deltaS (line 9 in algorithm 4.1) */
InscatterNParams iparams = {_deltaSRTexture, _deltaJTexture};
work = parallelWorkCreate(_inscatterNWorker, RES_R, &iparams);
parallelWorkPerform(work, -1);
parallelWorkDelete(work);
_saveDebug4D(_deltaSRTexture, "deltaSR", order);
work = new ParallelWork(_inscatterNWorker, RES_R, &iparams);
work->perform();
delete work;
/* adds deltaE into irradiance texture E (line 10 in algorithm 4.1) */
texture2DAdd(_deltaETexture, _irradianceTexture);
@ -1144,9 +1142,9 @@ int brunetonInit()
/* adds deltaS into inscatter texture S (line 11 in algorithm 4.1) */
CopyInscatterNParams cparams = {_deltaSRTexture, _inscatterTexture};
work = parallelWorkCreate(_copyInscatterNWorker, RES_R, &cparams);
parallelWorkPerform(work, -1);
parallelWorkDelete(work);
work = new ParallelWork(_copyInscatterNWorker, RES_R, &cparams);
work->perform();
delete work;
_saveDebug4D(_inscatterTexture, "inscatter", order);
}
@ -1204,7 +1202,7 @@ AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3
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);
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):
renderer(renderer)
parent(renderer)
{
}
@ -123,13 +123,13 @@ Vector3 BaseAtmosphereRenderer::getSunDirection()
AtmosphereDefinition* BaseAtmosphereRenderer::getDefinition()
{
return renderer->getScenery()->getAtmosphere();
return parent->getScenery()->getAtmosphere();
}
SoftwareBrunetonAtmosphereRenderer::SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer):
BaseAtmosphereRenderer(renderer)
{
model = new AtmosphereModelBruneton(this);
model = new AtmosphereModelBruneton(parent);
}
SoftwareBrunetonAtmosphereRenderer::~SoftwareBrunetonAtmosphereRenderer()
@ -170,7 +170,7 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(Vector3 directi
Color base;
definition = getDefinition();
camera_location = renderer->getCameraLocation(renderer, VECTOR_ZERO);
camera_location = parent->getCameraLocation(VECTOR_ZERO);
sun_direction = getSunDirection();
direction = v3Normalize(direction);

View file

@ -11,7 +11,7 @@ namespace software {
class BaseAtmosphereRenderer
{
public:
BaseAtmosphereRenderer(SoftwareRenderer* renderer);
BaseAtmosphereRenderer(SoftwareRenderer* parent);
virtual ~BaseAtmosphereRenderer() {}
virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque);
@ -21,13 +21,13 @@ public:
protected:
virtual AtmosphereDefinition* getDefinition();
SoftwareRenderer* renderer;
SoftwareRenderer* parent;
};
class SoftwareBrunetonAtmosphereRenderer: public BaseAtmosphereRenderer
{
public:
SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* renderer);
SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* parent);
virtual ~SoftwareBrunetonAtmosphereRenderer();
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();
result = COLOR_TRANSPARENT;
detail = parent->getPrecision(parent, start) / layer->scaling;
detail = parent->getPrecision(start) / layer->scaling;
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);

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 "ColorProfile.h"
#include "Mutex.h"
#include "CameraDefinition.h"
#include "SoftwareRenderer.h"
#include "Thread.h"
#include "PictureFile.h"
typedef struct
struct RenderFragment
{
struct
{
@ -33,7 +30,7 @@ typedef struct
} color;
} data;
double z;
} RenderFragment;
};
typedef struct
{
@ -44,32 +41,10 @@ typedef struct
int callback;
} ScanPoint;
typedef struct
struct FragmentCallback
{
f_RenderFragmentCallback function;
RenderArea::f_RenderFragmentCallback function;
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
@ -97,122 +72,110 @@ static void _callbackStart(int, int, Color) {}
static void _callbackDraw(int, int, Color) {}
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;
result = new RenderArea;
result->renderer = renderer;
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;
dirty_left = 0;
dirty_right = params.width * params.antialias - 1;
dirty_down = 0;
dirty_up = params.height * params.antialias - 1;
}
void renderDeleteArea(RenderArea* area)
{
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)
void RenderArea::setParams(RenderParams params)
{
int width, height;
width = params.width * params.antialias;
height = params.height * params.antialias;
area->params = params;
delete[] area->pixels;
area->pixels = new RenderFragment[width * height];
area->pixel_count = width * height;
params = params;
delete[] pixels;
pixels = new RenderFragment[width * height];
pixel_count = width * height;
area->dirty_left = width;
area->dirty_right = -1;
area->dirty_down = height;
area->dirty_up = -1;
area->dirty_count = 0;
dirty_left = width;
dirty_right = -1;
dirty_down = height;
dirty_up = -1;
dirty_count = 0;
renderClear(area);
clear();
}
void renderSetToneMapping(RenderArea* area, const ColorProfile &profile)
void RenderArea::setToneMapping(const ColorProfile &profile)
{
profile.copy(area->hdr_mapping);
_setAllDirty(area);
renderUpdate(area);
profile.copy(hdr_mapping);
setAllDirty();
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;
int x;
int y;
area->fragment_callbacks_count = 1;
area->fragment_callbacks[0].function = NULL;
area->fragment_callbacks[0].data = NULL;
fragment_callbacks_count = 1;
fragment_callbacks[0].function = 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->flags.dirty = 0;
pixel->flags.callback = 0;
pixel->data.color.r = area->background_color.r;
pixel->data.color.g = area->background_color.g;
pixel->data.color.b = area->background_color.b;
pixel->data.color.r = background_color.r;
pixel->data.color.g = background_color.g;
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;
area->dirty_right = -1;
area->dirty_down = area->params.height * area->params.antialias;
area->dirty_up = -1;
area->dirty_count = 0;
dirty_left = params.width * params.antialias;
dirty_right = -1;
dirty_down = params.height * params.antialias;
dirty_up = -1;
dirty_count = 0;
}
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);
}
static void _processDirtyPixels(RenderArea* area)
void RenderArea::processDirtyPixels()
{
int x, y;
int down, up, left, right;
down = area->dirty_down / area->params.antialias;
up = area->dirty_up / area->params.antialias;
left = area->dirty_left / area->params.antialias;
right = area->dirty_right / area->params.antialias;
down = dirty_down / params.antialias;
up = dirty_up / params.antialias;
left = dirty_left / params.antialias;
right = dirty_right / params.antialias;
for (y = down; y <= up; y++)
{
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;
area->dirty_right = -1;
area->dirty_down = area->params.height * area->params.antialias;
area->dirty_up = -1;
area->dirty_count = 0;
dirty_left = params.width * params.antialias;
dirty_right = -1;
dirty_down = params.height * params.antialias;
dirty_up = -1;
dirty_count = 0;
}
void renderUpdate(RenderArea* area)
void RenderArea::update()
{
area->lock->acquire();
_processDirtyPixels(area);
area->lock->release();
lock->acquire();
processDirtyPixels();
lock->release();
}
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;
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)
{
@ -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.z = location.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;
_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};
ScanPoint point1, point2, point3;
double limit_width = (double)(area->params.width * area->params.antialias - 1);
double limit_height = (double)(area->params.height * area->params.antialias - 1);
double limit_width = (double)(params.width * params.antialias - 1);
double limit_height = (double)(params.height * params.antialias - 1);
/* 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))
@ -547,9 +510,9 @@ void renderPushTriangle(RenderArea* area, Vector3 pixel1, Vector3 pixel2, Vector
}
/* Prepare fragment callback */
area->lock->acquire();
point1.callback = _pushCallback(area, fragment_callback);
area->lock->release();
lock->acquire();
point1.callback = _pushCallback(this, fragment_callback);
lock->release();
/* Prepare vertices */
point1.pixel = pixel1;
@ -566,7 +529,7 @@ void renderPushTriangle(RenderArea* area, Vector3 pixel1, Vector3 pixel2, Vector
/* Prepare scanlines */
RenderScanlines scanlines;
int x;
int width = area->params.width * area->params.antialias;
int width = params.width * params.antialias;
scanlines.left = width;
scanlines.right = -1;
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 */
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 */
_pushScanLineEdge(area, &scanlines, &point1, &point2);
_pushScanLineEdge(area, &scanlines, &point2, &point3);
_pushScanLineEdge(area, &scanlines, &point3, &point1);
_pushScanLineEdge(this, &scanlines, &point1, &point2);
_pushScanLineEdge(this, &scanlines, &point2, &point3);
_pushScanLineEdge(this, &scanlines, &point3, &point1);
/* Commit scanlines to area */
area->lock->acquire();
_renderScanLines(area, &scanlines);
area->lock->release();
lock->acquire();
_renderScanLines(this, &scanlines);
lock->release();
/* Free scalines */
free(scanlines.up);
free(scanlines.down);
}
Color renderGetPixel(RenderArea* area, int x, int y)
Color RenderArea::getPixel(int x, int y)
{
Color result;
area->lock->acquire();
result = _getFinalPixel(area, x, y);
area->lock->release();
lock->acquire();
result = _getFinalPixel(this, x, y);
lock->release();
return result;
}
@ -654,7 +617,7 @@ void* _renderPostProcessChunk(void* data)
}
#define MAX_CHUNKS 8
void renderPostProcess(RenderArea* area, int nbchunks)
void RenderArea::postProcess(int nbchunks)
{
volatile RenderChunk chunks[MAX_CHUNKS];
int i;
@ -672,21 +635,21 @@ void renderPostProcess(RenderArea* area, int nbchunks)
nx = 10;
ny = 10;
dx = area->params.width * area->params.antialias / nx;
dy = area->params.height * area->params.antialias / ny;
dx = params.width * params.antialias / nx;
dy = params.height * params.antialias / ny;
x = 0;
y = 0;
area->pixel_done = 0;
pixel_done = 0;
for (i = 0; i < nbchunks; i++)
{
chunks[i].thread = NULL;
chunks[i].area = area;
chunks[i].area = this;
}
running = 0;
loops = 0;
while ((x < nx && !area->renderer->render_interrupt) || running > 0)
while ((x < nx && !renderer->render_interrupt) || running > 0)
{
Thread::timeSleepMs(50);
@ -701,22 +664,22 @@ void renderPostProcess(RenderArea* area, int nbchunks)
chunks[i].thread = NULL;
running--;
}
else if (area->renderer->render_interrupt)
else if (renderer->render_interrupt)
{
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].interrupt = 0;
chunks[i].startx = x * dx;
if (x == nx - 1)
{
chunks[i].endx = area->params.width * area->params.antialias - 1;
chunks[i].endx = params.width * params.antialias - 1;
}
else
{
@ -725,7 +688,7 @@ void renderPostProcess(RenderArea* area, int nbchunks)
chunks[i].starty = y * dy;
if (y == ny - 1)
{
chunks[i].endy = area->params.height * area->params.antialias - 1;
chunks[i].endy = params.height * params.antialias - 1;
}
else
{
@ -746,16 +709,16 @@ void renderPostProcess(RenderArea* area, int nbchunks)
if (++loops >= 10)
{
area->lock->acquire();
_processDirtyPixels(area);
area->lock->release();
lock->acquire();
processDirtyPixels();
lock->release();
loops = 0;
}
}
_processDirtyPixels(area);
area->callback_update(1.0);
processDirtyPixels();
callback_update(1.0);
}
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();
}
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;
area->callback_draw = draw ? draw : _callbackDraw;
area->callback_update = update ? update : _callbackUpdate;
callback_start = start ? start : _callbackStart;
callback_draw = draw ? draw : _callbackDraw;
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);
_processDirtyPixels(area);
setAllDirty();
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;
Color result;
camera_location = renderer->getCameraLocation(renderer, location);
camera_location = renderer->getCameraLocation(location);
direction = v3Sub(location, camera_location);
/* 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_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++)
{
if (!renderer->addRenderProgress(renderer, 0.0))
if (!renderer->addRenderProgress(0.0))
{
return;
}
@ -79,7 +79,7 @@ void SkyRasterizer::rasterize()
vertex4 = v3Add(camera_location, direction);
/* 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 "LightStatus.h"
#include "LightingManager.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;
}
#include "System.h"
#include "Thread.h"
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);
clouds_renderer = new CloudsRenderer(this);
terrain_renderer = new TerrainRenderer(this);
@ -39,6 +39,7 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
water_renderer = new WaterRenderer(this);
fluid_medium = new FluidMediumManager(this);
lighting = new LightingManager();
if (scenery)
{
@ -54,6 +55,9 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
SoftwareRenderer::~SoftwareRenderer()
{
delete render_camera;
delete render_area;
delete atmosphere_renderer;
delete clouds_renderer;
delete terrain_renderer;
@ -61,6 +65,7 @@ SoftwareRenderer::~SoftwareRenderer()
delete water_renderer;
delete fluid_medium;
delete lighting;
if (own_scenery)
{
@ -97,9 +102,6 @@ void SoftwareRenderer::prepare()
delete water_renderer;
water_renderer = new WaterRenderer(this);
// Setup transitional renderers (for C-legacy subsystems)
getPrecision = _getPrecision;
// Prepare global tools
fluid_medium->clearMedia();
//fluid_medium->registerMedium(water_renderer);
@ -117,9 +119,71 @@ void SoftwareRenderer::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)
{
LightStatus status(lighting, location, getCameraLocation(this, location));
LightStatus status(lighting, location, getCameraLocation(location));
atmosphere_renderer->getLightingStatus(&status, normal, 0);
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 = 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;
/*Vector3 eye = cameraGetLocation(scenery->getCamera());
@ -151,3 +215,73 @@ RayCastingResult SoftwareRenderer::rayWalking(const Vector3 &location, const Vec
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 "renderer.h"
#include "RenderArea.h"
#include "RayCastingManager.h"
namespace paysages {
namespace software {
@ -11,19 +12,44 @@ namespace software {
/*!
* \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:
SoftwareRenderer(Scenery* scenery=0);
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.
*
* 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.
@ -31,12 +57,16 @@ public:
* This will clear the caches and connect elements together.
* 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.
*/
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;}
@ -49,9 +79,9 @@ public:
inline FluidMediumManager* getFluidMediumManager() const {return fluid_medium;}
inline LightingManager* getLightingManager() const {return lighting;}
virtual Color applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material) override;
virtual Color applyMediumTraversal(Vector3 location, Color color) override;
virtual RayCastingResult rayWalking(const Vector3 &location, const Vector3 &direction, int terrain, int water, int sky, int clouds) override;
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);
private:
Scenery* scenery;

View file

@ -7,8 +7,7 @@
#include "WaterRenderer.h"
#include "TexturesRenderer.h"
#include "Scenery.h"
#include "tools/parallel.h"
#include "ParallelQueue.h"
TerrainRasterizer::TerrainRasterizer(SoftwareRenderer* renderer):
renderer(renderer)
@ -26,14 +25,13 @@ static inline Vector3 _getPoint(SoftwareRenderer* renderer, double x, double z)
return result;
}
static Color _postProcessFragment(Renderer* renderer_, Vector3 point, void*)
static Color _postProcessFragment(SoftwareRenderer* renderer, Vector3 point, void*)
{
double precision;
SoftwareRenderer* renderer = (SoftwareRenderer*)renderer_;
point = _getPoint(renderer, point.x, point.z);
precision = renderer->getPrecision(renderer, point);
precision = renderer->getPrecision(point);
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)
{
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;
int chunk_factor, chunk_count, i;
Vector3 cam = renderer->getCameraLocation(renderer, VECTOR_ZERO);
Vector3 cam = renderer->getCameraLocation(VECTOR_ZERO);
double progress;
double radius_int, radius_ext;
double base_chunk_size, chunk_size;
@ -231,7 +229,7 @@ int TerrainRasterizer::processChunk(TerrainChunkInfo* chunk, double progress)
info->rasterizer = this;
info->chunk = *chunk;
if (!parallelQueueAddJob((ParallelQueue*)renderer->customData[0], _parallelJobCallback, info))
if (!((ParallelQueue*)renderer->customData[0])->addJob(_parallelJobCallback, info))
{
delete info;
}
@ -242,16 +240,14 @@ int TerrainRasterizer::processChunk(TerrainChunkInfo* chunk, double progress)
void TerrainRasterizer::renderSurface()
{
ParallelQueue* queue;
queue = parallelQueueCreate(0);
ParallelQueue queue;
/* 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;
getTessellationInfo(0);
renderer->render_progress = 0.05;
parallelQueueWait(queue);
parallelQueueDelete(queue);
queue.wait();
}

View file

@ -158,7 +158,7 @@ RayCastingResult TerrainRenderer::castRay(const Vector3 &start, const Vector3 &d
}
result.hit = 1;
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;
}

View file

@ -3,7 +3,8 @@
#include "software_global.h"
#include "shared/types.h"
#include "RayCastingManager.h"
#include "Color.h"
namespace paysages {
namespace software {

View file

@ -2,16 +2,15 @@
#include "SoftwareRenderer.h"
#include "WaterRenderer.h"
#include "tools/parallel.h"
#include "ParallelQueue.h"
WaterRasterizer::WaterRasterizer(SoftwareRenderer* 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;
}
@ -35,7 +34,7 @@ static void _renderQuad(SoftwareRenderer* renderer, double x, double z, double s
v3 = _getFirstPassVertex(renderer, x + size, z + size);
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
@ -69,10 +68,10 @@ void WaterRasterizer::renderSurface()
{
ParallelRasterInfo* info;
ParallelQueue* queue;
queue = parallelQueueCreate(0);
queue = new ParallelQueue();
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;
base_chunk_size = 2.0 / (double)renderer->render_quality;
@ -92,7 +91,7 @@ void WaterRasterizer::renderSurface()
while (radius_int < 20000.0)
{
if (!renderer->addRenderProgress(renderer, 0.0))
if (!renderer->addRenderProgress(0.0))
{
return;
}
@ -109,7 +108,7 @@ void WaterRasterizer::renderSurface()
info->radius_ext = radius_ext;
info->chunk_size = chunk_size;
if (!parallelQueueAddJob(queue, _parallelJobCallback, info))
if (!queue->addJob(_parallelJobCallback, info))
{
delete info;
}
@ -126,6 +125,6 @@ void WaterRasterizer::renderSurface()
radius_ext += chunk_size;
}
parallelQueueWait(queue);
parallelQueueDelete(queue);
queue->wait();
delete queue;
}

View file

@ -207,14 +207,14 @@ WaterRenderer::WaterResult WaterRenderer::getResult(double x, double z)
location.z = z;
result.location = location;
detail = parent->getPrecision(parent, location) * 0.1;
detail = parent->getPrecision(location) * 0.1;
if (detail < 0.00001)
{
detail = 0.00001;
}
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 */
if (definition->reflection == 0.0)

View file

@ -33,7 +33,9 @@ SOURCES += SoftwareRenderer.cpp \
AtmosphereModelBruneton.cpp \
TerrainRenderer.cpp \
TexturesRenderer.cpp \
WaterRenderer.cpp
WaterRenderer.cpp \
RenderArea.cpp \
RayCastingManager.cpp
HEADERS += SoftwareRenderer.h\
software_global.h \
@ -56,7 +58,9 @@ HEADERS += SoftwareRenderer.h\
AtmosphereModelBruneton.h \
TerrainRenderer.h \
TexturesRenderer.h \
WaterRenderer.h
WaterRenderer.h \
RenderArea.h \
RayCastingManager.h
unix:!symbian {
maemo5 {

View file

@ -14,6 +14,7 @@
namespace paysages {
namespace software {
class SoftwareRenderer;
class RenderArea;
class FluidMediumManager;
class FluidMediumInterface;

View file

@ -1,7 +1,5 @@
#include "RenderingScenery.h"
#include "renderer.h"
static RenderingScenery _main_scenery;
RenderingScenery::RenderingScenery()
@ -42,10 +40,3 @@ void RenderingScenery::load(PackStream* stream)
Scenery::load(stream);
}
void RenderingScenery::bindToRenderer(Renderer* renderer)
{
renderer->setScenery(this);
renderer->prepare();
}

View file

@ -5,8 +5,6 @@
#include "Scenery.h"
class Renderer;
typedef void (*SceneryCustomDataCallback)(PackStream* stream, void* data);
/**
@ -26,8 +24,6 @@ public:
virtual void save(PackStream* stream) const override;
virtual void load(PackStream* stream) override;
void bindToRenderer(Renderer* renderer);
private:
SceneryCustomDataCallback _custom_save;
SceneryCustomDataCallback _custom_load;

View file

@ -5,7 +5,6 @@
#include "RenderingScenery.h"
#include "Scenery.h"
#include "PackStream.h"
#include "render.h"
#include "main.h"
#define APP_HEADER 198632.125
@ -18,13 +17,10 @@ void paysagesInit()
fprintf(stderr, "ERROR : Can't locate data files.\n");
exit(1);
}
renderInit();
}
void paysagesQuit()
{
renderQuit();
}
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)
SOURCES += main.cpp \
renderer.cpp \
render.cpp \
tools/texture.cpp \
tools/parallel.cpp \
tools/data.cpp \
tools/cache.cpp \
RenderingScenery.cpp
HEADERS += \
renderer.h \
render.h \
main.h \
shared/types.h \
tools/texture.h \
tools/parallel.h \
tools/data.h \
tools/cache.h \
rendering_global.h \

View file

@ -10,7 +10,4 @@
#include "definition_global.h"
class Renderer; // TEMP
class RenderingScenery; // TEMP
#endif // RENDERING_GLOBAL_H

View file

@ -6,14 +6,6 @@
#include "Color.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 (*FuncObjectDelete)(void* object);
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"
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.
* \param function Function to call inside the thread once it is started
*/
Thread(ThreadFunction function);
Thread(ThreadFunction function=0);
/*!
* \brief Start the thread
@ -40,12 +40,16 @@ public:
static inline void timeSleepMs(unsigned long ms){ QThread::msleep(ms); }
protected:
/*!
* \brief Function to reimplement if no ThreadFunction has been passed to the constructor.
*/
virtual void run();
void* data;
void* result;
private:
ThreadFunction function;
void* data;
void* result;
};
}

View file

@ -20,7 +20,9 @@ SOURCES += \
System.cpp \
PackStream.cpp \
RandomGenerator.cpp \
Memory.cpp
Memory.cpp \
ParallelWork.cpp \
ParallelQueue.cpp
HEADERS += \
system_global.h \
@ -30,7 +32,9 @@ HEADERS += \
System.h \
PackStream.h \
RandomGenerator.h \
Memory.h
Memory.h \
ParallelWork.h \
ParallelQueue.h
unix:!symbian {
maemo5 {

View file

@ -13,6 +13,10 @@
namespace paysages {
namespace system {
class PackStream;
class ParallelQueue;
class ParallelWork;
class Thread;
class Mutex;
}
}
using namespace paysages::system;

View file

@ -4,15 +4,16 @@
#include "SoftwareRenderer.h"
#include "AtmosphereDefinition.h"
#include "AtmosphereRenderer.h"
#include "AtmosphereResult.h"
#include "RenderingScenery.h"
#include "System.h"
#define OUTPUT_WIDTH 400
#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)
@ -26,19 +27,19 @@ TEST(Bruneton, AerialPerspective1)
renderer.render_camera->setTarget(VECTOR_EAST);
renderer.render_camera->setRenderSize(renderer.render_width, renderer.render_height);
RenderParams params = {renderer.render_width, renderer.render_height, 1, 1};
renderSetParams(renderer.render_area, params);
renderSetBackgroundColor(renderer.render_area, COLOR_BLACK);
renderClear(renderer.render_area);
RenderArea::RenderParams params = {renderer.render_width, renderer.render_height, 1, 1};
renderer.render_area->setParams(params);
renderer.render_area->setBackgroundColor(COLOR_BLACK);
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(&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(&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(&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(&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);
renderPostProcess(renderer.render_area, System::getCoreCount());
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(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(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(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(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.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)
@ -48,7 +49,7 @@ TEST(Bruneton, AerialPerspective2)
atmo->minute = 30;
atmo->validate();
Renderer renderer;
SoftwareRenderer renderer;
renderer.render_width = 800;
renderer.render_height = 600;
renderer.render_quality = 1;
@ -57,17 +58,17 @@ TEST(Bruneton, AerialPerspective2)
renderer.render_camera->setTarget(VECTOR_EAST);
renderer.render_camera->setRenderSize(renderer.render_width, renderer.render_height);
RenderParams params = {renderer.render_width, renderer.render_height, 1, 1};
renderSetParams(renderer.render_area, params);
renderSetBackgroundColor(renderer.render_area, COLOR_BLACK);
renderClear(renderer.render_area);
RenderArea::RenderParams params = {renderer.render_width, renderer.render_height, 1, 1};
renderer.render_area->setParams(params);
renderer.render_area->setBackgroundColor(COLOR_BLACK);
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(&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(&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(&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(&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);
renderPostProcess(renderer.render_area, System::getCoreCount());
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(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(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(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(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.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 <cmath>
#include "renderer.h"
#include "SoftwareRenderer.h"
#include "CameraDefinition.h"
#include "ColorProfile.h"
#include "System.h"
static Color _postProcessFragment(Renderer*, Vector3 location, void*)
static Color _postProcessFragment(SoftwareRenderer*, Vector3 location, void*)
{
/* Checker-board */
double x = fmod(location.x, 0.2);
@ -32,36 +32,34 @@ static Color _postProcessFragment(Renderer*, Vector3 location, void*)
TEST(Render, quad)
{
Color col;
Renderer* renderer = rendererCreate();
SoftwareRenderer renderer;
renderer->render_width = 800;
renderer->render_height = 600;
renderer->render_quality = 1;
renderSetToneMapping(renderer->render_area, ColorProfile(ColorProfile::TONE_MAPPING_CLAMP, 0.0));
renderer.render_width = 800;
renderer.render_height = 600;
renderer.render_quality = 1;
renderer.render_area->setToneMapping(ColorProfile(ColorProfile::TONE_MAPPING_CLAMP, 0.0));
renderer->render_camera->setLocationCoords(0.0, 0.5, 2.0);
renderer->render_camera->setTargetCoords(0.0, 0.5, 0.0);
renderer->render_camera->setRenderSize(renderer->render_width, renderer->render_height);
renderer.render_camera->setLocationCoords(0.0, 0.5, 2.0);
renderer.render_camera->setTargetCoords(0.0, 0.5, 0.0);
renderer.render_camera->setRenderSize(renderer.render_width, renderer.render_height);
RenderParams params = {renderer->render_width, renderer->render_height, 1, 1};
renderSetParams(renderer->render_area, params);
RenderArea::RenderParams params = {renderer.render_width, renderer.render_height, 1, 1};
renderer.render_area->setParams(params);
renderSetBackgroundColor(renderer->render_area, COLOR_BLUE);
renderClear(renderer->render_area);
renderer.render_area->setBackgroundColor(COLOR_BLUE);
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);
renderPostProcess(renderer->render_area, System::getCoreCount());
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);
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);
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);
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);
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);
renderSaveToFile(renderer->render_area, "./output/test_render_quad.png");
rendererDelete(renderer);
renderer.render_area->saveToFile("./output/test_render_quad.png");
}