From 43431aae87ac5c94a3ce638caa8fec99a225c229 Mon Sep 17 00:00:00 2001 From: Michael Lemaire Date: Thu, 5 Jun 2014 17:12:49 +0200 Subject: [PATCH] New Canvas software rendering structure (WIP) --- src/interface/desktop/WidgetCanvas.cpp | 6 ++ src/interface/desktop/WidgetCanvas.h | 29 +++++++ src/interface/desktop/WidgetPreviewCanvas.cpp | 46 +++++++++++ src/interface/desktop/WidgetPreviewCanvas.h | 39 ++++++++++ src/interface/desktop/desktop.pro | 8 +- src/interface/desktop/desktop_global.h | 3 + src/interface/desktop/dialogrender.cpp | 9 +++ src/interface/desktop/dialogrender.h | 3 + src/render/software/Canvas.cpp | 76 +++++++++++++++++++ src/render/software/Canvas.h | 46 +++++++++++ src/render/software/CanvasFragment.cpp | 5 ++ src/render/software/CanvasFragment.h | 21 +++++ src/render/software/CanvasLiveClient.cpp | 17 +++++ src/render/software/CanvasLiveClient.h | 25 ++++++ src/render/software/CanvasPixel.cpp | 5 ++ src/render/software/CanvasPixel.h | 23 ++++++ src/render/software/CanvasPortion.cpp | 12 +++ src/render/software/CanvasPortion.h | 43 +++++++++++ src/render/software/Rasterizer.cpp | 5 ++ src/render/software/Rasterizer.h | 21 +++++ src/render/software/SkyRasterizer.h | 4 +- .../software/SoftwareCanvasRenderer.cpp | 51 +++++++++++++ src/render/software/SoftwareCanvasRenderer.h | 61 +++++++++++++++ src/render/software/SoftwareRenderer.cpp | 7 ++ src/render/software/SoftwareRenderer.h | 5 ++ src/render/software/TerrainRasterizer.h | 3 +- src/render/software/WaterRasterizer.h | 4 +- src/render/software/software.pro | 18 ++++- src/render/software/software_global.h | 8 ++ src/tests/Canvas_Test.cpp | 41 ++++++++++ src/tests/tests.pro | 3 +- 31 files changed, 639 insertions(+), 8 deletions(-) create mode 100644 src/interface/desktop/WidgetCanvas.cpp create mode 100644 src/interface/desktop/WidgetCanvas.h create mode 100644 src/interface/desktop/WidgetPreviewCanvas.cpp create mode 100644 src/interface/desktop/WidgetPreviewCanvas.h create mode 100644 src/render/software/Canvas.cpp create mode 100644 src/render/software/Canvas.h create mode 100644 src/render/software/CanvasFragment.cpp create mode 100644 src/render/software/CanvasFragment.h create mode 100644 src/render/software/CanvasLiveClient.cpp create mode 100644 src/render/software/CanvasLiveClient.h create mode 100644 src/render/software/CanvasPixel.cpp create mode 100644 src/render/software/CanvasPixel.h create mode 100644 src/render/software/CanvasPortion.cpp create mode 100644 src/render/software/CanvasPortion.h create mode 100644 src/render/software/Rasterizer.cpp create mode 100644 src/render/software/Rasterizer.h create mode 100644 src/render/software/SoftwareCanvasRenderer.cpp create mode 100644 src/render/software/SoftwareCanvasRenderer.h create mode 100644 src/tests/Canvas_Test.cpp diff --git a/src/interface/desktop/WidgetCanvas.cpp b/src/interface/desktop/WidgetCanvas.cpp new file mode 100644 index 0000000..a1a84b5 --- /dev/null +++ b/src/interface/desktop/WidgetCanvas.cpp @@ -0,0 +1,6 @@ +#include "WidgetCanvas.h" + +WidgetCanvas::WidgetCanvas(QWidget *parent) : + QWidget(parent) +{ +} diff --git a/src/interface/desktop/WidgetCanvas.h b/src/interface/desktop/WidgetCanvas.h new file mode 100644 index 0000000..ad74ae3 --- /dev/null +++ b/src/interface/desktop/WidgetCanvas.h @@ -0,0 +1,29 @@ +#ifndef WIDGETCANVAS_H +#define WIDGETCANVAS_H + +#include "desktop_global.h" + +#include + +namespace paysages { +namespace desktop { + +/*! + * \brief Widget to display the full content of a Canvas. + */ +class WidgetCanvas : public QWidget +{ + Q_OBJECT +public: + explicit WidgetCanvas(QWidget *parent = 0); + +signals: + +public slots: + +}; + +} +} + +#endif // WIDGETCANVAS_H diff --git a/src/interface/desktop/WidgetPreviewCanvas.cpp b/src/interface/desktop/WidgetPreviewCanvas.cpp new file mode 100644 index 0000000..3c104e2 --- /dev/null +++ b/src/interface/desktop/WidgetPreviewCanvas.cpp @@ -0,0 +1,46 @@ +#include "WidgetPreviewCanvas.h" + +#include "Canvas.h" + +WidgetPreviewCanvas::WidgetPreviewCanvas(QWidget *parent) : + QWidget(parent), canvas(NULL) +{ + startTimer(1000); +} + +void WidgetPreviewCanvas::setCanvas(const Canvas *canvas) +{ + this->canvas = canvas; +} + +void WidgetPreviewCanvas::canvasResized(int width, int height) +{ + // TODO +} + +void WidgetPreviewCanvas::canvasCleared(const Color &col) +{ + // TODO +} + +void WidgetPreviewCanvas::canvasPainted(int x, int y, const Color &col) +{ + // TODO +} + +void WidgetPreviewCanvas::timerEvent(QTimerEvent *) +{ + // Refresh the view + if (canvas) + { + int width = canvas->getPreviewWidth(); + int height = canvas->getPreviewHeight(); + + if (QSize(width, height) != this->size()) + { + setMaximumSize(width, height); + setMinimumSize(width, height); + resize(width, height); + } + } +} diff --git a/src/interface/desktop/WidgetPreviewCanvas.h b/src/interface/desktop/WidgetPreviewCanvas.h new file mode 100644 index 0000000..6aacafe --- /dev/null +++ b/src/interface/desktop/WidgetPreviewCanvas.h @@ -0,0 +1,39 @@ +#ifndef WIDGETPREVIEWCANVAS_H +#define WIDGETPREVIEWCANVAS_H + +#include "desktop_global.h" + +#include +#include "CanvasLiveClient.h" + +namespace paysages { +namespace desktop { + +/*! + * \brief Widget to display a live-updated preview of a Canvas software rendering. + */ +class WidgetPreviewCanvas : public QWidget, public CanvasLiveClient +{ + Q_OBJECT +public: + explicit WidgetPreviewCanvas(QWidget *parent = 0); + + /*! + * \brief Set the canvas to watch and display, null to stop watching. + */ + void setCanvas(const Canvas *canvas); + +protected: + virtual void canvasResized(int width, int height); + virtual void canvasCleared(const Color &col); + virtual void canvasPainted(int x, int y, const Color &col); + virtual void timerEvent(QTimerEvent *event); + +private: + const Canvas *canvas; +}; + +} +} + +#endif // WIDGETPREVIEWCANVAS_H diff --git a/src/interface/desktop/desktop.pro b/src/interface/desktop/desktop.pro index cb703cd..e6a47d2 100644 --- a/src/interface/desktop/desktop.pro +++ b/src/interface/desktop/desktop.pro @@ -52,7 +52,9 @@ HEADERS += \ lighting/SmallPreviewHues.h \ textures/DialogTexturesLayer.h \ desktop_global.h \ - DesktopScenery.h + DesktopScenery.h \ + WidgetCanvas.h \ + WidgetPreviewCanvas.h SOURCES += \ terrain/widgetheightmap.cpp \ @@ -96,7 +98,9 @@ SOURCES += \ lighting/SmallPreviewColor.cpp \ lighting/SmallPreviewHues.cpp \ textures/DialogTexturesLayer.cpp \ - DesktopScenery.cpp + DesktopScenery.cpp \ + WidgetCanvas.cpp \ + WidgetPreviewCanvas.cpp FORMS += \ terrain/dialogterrainpainting.ui \ diff --git a/src/interface/desktop/desktop_global.h b/src/interface/desktop/desktop_global.h index da63022..79c0d46 100644 --- a/src/interface/desktop/desktop_global.h +++ b/src/interface/desktop/desktop_global.h @@ -10,6 +10,9 @@ namespace paysages { namespace desktop { class BaseInput; class BaseForm; + + class WidgetCanvas; + class WidgetPreviewCanvas; } } diff --git a/src/interface/desktop/dialogrender.cpp b/src/interface/desktop/dialogrender.cpp index 1d979f0..59b6b70 100644 --- a/src/interface/desktop/dialogrender.cpp +++ b/src/interface/desktop/dialogrender.cpp @@ -21,6 +21,8 @@ #include "SoftwareRenderer.h" #include "Scenery.h" #include "ColorProfile.h" +#include "SoftwareCanvasRenderer.h" +#include "WidgetPreviewCanvas.h" static DialogRender* _current_dialog; @@ -103,6 +105,11 @@ DialogRender::DialogRender(QWidget *parent, SoftwareRenderer* renderer): _scroll->setWidget(area); layout()->addWidget(_scroll); + canvas_renderer = new SoftwareCanvasRenderer(); + canvas_preview = new WidgetPreviewCanvas(this); + canvas_preview->setCanvas(canvas_renderer->getCanvas()); + layout()->addWidget(canvas_preview); + // Status bar _info = new QWidget(this); _info->setLayout(new QHBoxLayout()); @@ -180,6 +187,8 @@ void DialogRender::startRender(RenderArea::RenderParams params) { _started = time(NULL); + canvas_renderer->setSize(params.width, params.height, params.antialias); + applyRenderSize(params.width, params.height); _renderer->setPreviewCallbacks(_renderStart, _renderDraw, _renderUpdate); diff --git a/src/interface/desktop/dialogrender.h b/src/interface/desktop/dialogrender.h index 80dbb05..62c6aa3 100644 --- a/src/interface/desktop/dialogrender.h +++ b/src/interface/desktop/dialogrender.h @@ -45,6 +45,9 @@ signals: void renderEnded(); private: + SoftwareCanvasRenderer* canvas_renderer; + WidgetPreviewCanvas* canvas_preview; + QScrollArea* _scroll; QWidget* _info; QWidget* _actions; diff --git a/src/render/software/Canvas.cpp b/src/render/software/Canvas.cpp new file mode 100644 index 0000000..09a890e --- /dev/null +++ b/src/render/software/Canvas.cpp @@ -0,0 +1,76 @@ +#include "Canvas.h" + +#include "CanvasPortion.h" +#include + +Canvas::Canvas() +{ + horizontal_portion_count = 1; + vertical_portion_count = 1; + width = 1; + height = 1; + preview_width = 1; + preview_height = 1; + portions.push_back(new CanvasPortion()); +} + +Canvas::~Canvas() +{ + for (auto portion: portions) + { + delete portion; + } +} + +void Canvas::setSize(int width, int height) +{ + horizontal_portion_count = 1 + width / 400; + vertical_portion_count = 1 + height / 400; + + int portion_width = width / horizontal_portion_count; + int portion_height = height / vertical_portion_count; + + for (auto portion: portions) + { + delete portion; + } + portions.clear(); + + int done_width = 0; + int done_height = 0; + + for (int y = 0; y < vertical_portion_count; y++) + { + done_width = 0; + for (int x = 0; x < horizontal_portion_count; x++) + { + CanvasPortion *portion = new CanvasPortion(); + + portion->setSize((x == horizontal_portion_count - 1) ? width - done_width : portion_width, + (y == vertical_portion_count - 1) ? height - done_height : portion_height); + + done_width += portion->getWidth(); + if (x == horizontal_portion_count - 1) + { + done_height += portion->getHeight(); + } + + portions.push_back(portion); + } + assert(done_width == width); + } + assert(done_height == height); + + this->width = width; + this->height = height; + this->preview_width = width; + this->preview_height = height; +} + +CanvasPortion *Canvas::at(int x, int y) const +{ + assert(x >= 0 && x < horizontal_portion_count); + assert(y >= 0 && y < vertical_portion_count); + + return portions[y * horizontal_portion_count + x]; +} diff --git a/src/render/software/Canvas.h b/src/render/software/Canvas.h new file mode 100644 index 0000000..4934e06 --- /dev/null +++ b/src/render/software/Canvas.h @@ -0,0 +1,46 @@ +#ifndef CANVAS_H +#define CANVAS_H + +#include "software_global.h" + +namespace paysages { +namespace software { + +/** + * @brief Graphics area to draw and do compositing. + * + * Software rendering is done in portions of Canvas (in CanvasPortion class). + * This splitting in portions allows to keep memory consumption low. + */ +class SOFTWARESHARED_EXPORT Canvas +{ +public: + Canvas(); + ~Canvas(); + + void setSize(int width, int height); + + inline int getHorizontalPortionCount() const {return horizontal_portion_count;} + inline int getVerticalPortionCount() const {return vertical_portion_count;} + + CanvasPortion *at(int x, int y) const; + + inline int getWidth() const {return width;} + inline int getHeight() const {return height;} + inline int getPreviewWidth() const {return preview_width;} + inline int getPreviewHeight() const {return preview_height;} + +private: + std::vector portions; + int horizontal_portion_count; + int vertical_portion_count; + int width; + int height; + int preview_width; + int preview_height; +}; + +} +} + +#endif // CANVAS_H diff --git a/src/render/software/CanvasFragment.cpp b/src/render/software/CanvasFragment.cpp new file mode 100644 index 0000000..2d105dd --- /dev/null +++ b/src/render/software/CanvasFragment.cpp @@ -0,0 +1,5 @@ +#include "CanvasFragment.h" + +CanvasFragment::CanvasFragment() +{ +} diff --git a/src/render/software/CanvasFragment.h b/src/render/software/CanvasFragment.h new file mode 100644 index 0000000..f1b3b5a --- /dev/null +++ b/src/render/software/CanvasFragment.h @@ -0,0 +1,21 @@ +#ifndef CANVASFRAGMENT_H +#define CANVASFRAGMENT_H + +#include "software_global.h" + +namespace paysages { +namespace software { + +/** + * @brief Representation of world coordinates projected in a canvas pixel. + */ +class SOFTWARESHARED_EXPORT CanvasFragment +{ +public: + CanvasFragment(); +}; + +} +} + +#endif // CANVASFRAGMENT_H diff --git a/src/render/software/CanvasLiveClient.cpp b/src/render/software/CanvasLiveClient.cpp new file mode 100644 index 0000000..3586fdd --- /dev/null +++ b/src/render/software/CanvasLiveClient.cpp @@ -0,0 +1,17 @@ +#include "CanvasLiveClient.h" + +CanvasLiveClient::CanvasLiveClient() +{ +} + +void CanvasLiveClient::canvasResized(int, int) +{ +} + +void CanvasLiveClient::canvasCleared(const Color &) +{ +} + +void CanvasLiveClient::canvasPainted(int, int, const Color &) +{ +} diff --git a/src/render/software/CanvasLiveClient.h b/src/render/software/CanvasLiveClient.h new file mode 100644 index 0000000..133e7cb --- /dev/null +++ b/src/render/software/CanvasLiveClient.h @@ -0,0 +1,25 @@ +#ifndef CANVASLIVECLIENT_H +#define CANVASLIVECLIENT_H + +#include "software_global.h" + +namespace paysages { +namespace software { + +/** + * @brief Abstract class to receive live modifications from canvas preview. + */ +class SOFTWARESHARED_EXPORT CanvasLiveClient +{ +public: + CanvasLiveClient(); + + virtual void canvasResized(int width, int height); + virtual void canvasCleared(const Color &col); + virtual void canvasPainted(int x, int y, const Color &col); +}; + +} +} + +#endif // CANVASLIVECLIENT_H diff --git a/src/render/software/CanvasPixel.cpp b/src/render/software/CanvasPixel.cpp new file mode 100644 index 0000000..c7c1b5c --- /dev/null +++ b/src/render/software/CanvasPixel.cpp @@ -0,0 +1,5 @@ +#include "CanvasPixel.h" + +CanvasPixel::CanvasPixel() +{ +} diff --git a/src/render/software/CanvasPixel.h b/src/render/software/CanvasPixel.h new file mode 100644 index 0000000..4a00c62 --- /dev/null +++ b/src/render/software/CanvasPixel.h @@ -0,0 +1,23 @@ +#ifndef CANVASPIXEL_H +#define CANVASPIXEL_H + +#include "software_global.h" + +namespace paysages { +namespace software { + +/** + * @brief One pixel of a Canvas. + * + * A pixel stores superimposed fragments (CanvasFragment), sorted by their distance to camera. + */ +class SOFTWARESHARED_EXPORT CanvasPixel +{ +public: + CanvasPixel(); +}; + +} +} + +#endif // CANVASPIXEL_H diff --git a/src/render/software/CanvasPortion.cpp b/src/render/software/CanvasPortion.cpp new file mode 100644 index 0000000..c44e15f --- /dev/null +++ b/src/render/software/CanvasPortion.cpp @@ -0,0 +1,12 @@ +#include "CanvasPortion.h" + +CanvasPortion::CanvasPortion() +{ +} + +void CanvasPortion::setSize(int width, int height) +{ + this->width = width; + this->height = height; + // TODO Resize and clear pixels +} diff --git a/src/render/software/CanvasPortion.h b/src/render/software/CanvasPortion.h new file mode 100644 index 0000000..274d645 --- /dev/null +++ b/src/render/software/CanvasPortion.h @@ -0,0 +1,43 @@ +#ifndef CANVASPORTION_H +#define CANVASPORTION_H + +#include "software_global.h" + +namespace paysages { +namespace software { + +typedef struct { + double red; + double green; + double blue; +} CanvasPreviewPixel; + +/** + * @brief Rectangular portion of a Canvas. + * + * Contains the pixels of a canvas region (CanvasPixel). + */ +class SOFTWARESHARED_EXPORT CanvasPortion +{ +public: + CanvasPortion(); + + inline int getWidth() const {return width;} + inline int getHeight() const {return height;} + + void setSize(int width, int height); + +private: + int width; + int height; + std::vector *pixels; + + int preview_width; + int preview_height; + std::vector *preview_pixels; +}; + +} +} + +#endif // CANVASPORTION_H diff --git a/src/render/software/Rasterizer.cpp b/src/render/software/Rasterizer.cpp new file mode 100644 index 0000000..2545ba1 --- /dev/null +++ b/src/render/software/Rasterizer.cpp @@ -0,0 +1,5 @@ +#include "Rasterizer.h" + +Rasterizer::Rasterizer() +{ +} diff --git a/src/render/software/Rasterizer.h b/src/render/software/Rasterizer.h new file mode 100644 index 0000000..422a8e2 --- /dev/null +++ b/src/render/software/Rasterizer.h @@ -0,0 +1,21 @@ +#ifndef RASTERIZER_H +#define RASTERIZER_H + +#include "software_global.h" + +namespace paysages { +namespace software { + +/** + * @brief Base abstract class for scenery pieces that can be rasterized to polygons. + */ +class SOFTWARESHARED_EXPORT Rasterizer +{ +public: + Rasterizer(); +}; + +} +} + +#endif // RASTERIZER_H diff --git a/src/render/software/SkyRasterizer.h b/src/render/software/SkyRasterizer.h index 1d03902..c6432fc 100644 --- a/src/render/software/SkyRasterizer.h +++ b/src/render/software/SkyRasterizer.h @@ -3,10 +3,12 @@ #include "software_global.h" +#include "Rasterizer.h" + namespace paysages { namespace software { -class SOFTWARESHARED_EXPORT SkyRasterizer +class SOFTWARESHARED_EXPORT SkyRasterizer: public Rasterizer { public: SkyRasterizer(SoftwareRenderer* renderer); diff --git a/src/render/software/SoftwareCanvasRenderer.cpp b/src/render/software/SoftwareCanvasRenderer.cpp new file mode 100644 index 0000000..f8c9742 --- /dev/null +++ b/src/render/software/SoftwareCanvasRenderer.cpp @@ -0,0 +1,51 @@ +#include "SoftwareCanvasRenderer.h" + +#include "Rasterizer.h" +#include "SoftwareRenderer.h" +#include "Canvas.h" + +SoftwareCanvasRenderer::SoftwareCanvasRenderer() +{ + started = false; + renderer = new SoftwareRenderer(); + canvas = new Canvas(); +} + +SoftwareCanvasRenderer::~SoftwareCanvasRenderer() +{ + delete renderer; + delete canvas; +} + +void SoftwareCanvasRenderer::setSize(int width, int height, int samples) +{ + if (not started) + { + canvas->setSize(width * samples, height * samples); + } +} + +void SoftwareCanvasRenderer::render() +{ + // TEMP + started = true; + CanvasPortion *portion = canvas->at(0, 0); + + rasterize(portion, true); + postProcess(portion, true); +} + +void SoftwareCanvasRenderer::rasterize(CanvasPortion *portion, bool threaded) +{ + std::vector rasterizers; + renderer->getRasterizers(&rasterizers); + + for (auto &rasterizer:rasterizers) + { + } +} + +void SoftwareCanvasRenderer::postProcess(CanvasPortion *portion, bool threaded) +{ + // TODO +} diff --git a/src/render/software/SoftwareCanvasRenderer.h b/src/render/software/SoftwareCanvasRenderer.h new file mode 100644 index 0000000..847fbd7 --- /dev/null +++ b/src/render/software/SoftwareCanvasRenderer.h @@ -0,0 +1,61 @@ +#ifndef SOFTWARECANVASRENDERER_H +#define SOFTWARECANVASRENDERER_H + +#include "software_global.h" + +namespace paysages { +namespace software { + +/** + * @brief Software rendering inside a Canvas surface. + * + * This class launches the rasterization process into canvas portions and + * redirects post processing to the software renderer. + * + * It tries to keep a canvas portion rasterized ahead of the post processing. + */ +class SOFTWARESHARED_EXPORT SoftwareCanvasRenderer +{ +public: + SoftwareCanvasRenderer(); + ~SoftwareCanvasRenderer(); + + inline const Canvas *getCanvas() const {return canvas;} + + /** + * @brief Set the rendering size in pixels. + * + * Set 'samples' to something bigger than 1 to allow for the multi-sampling of pixels. + */ + void setSize(int width, int height, int samples=1); + + /** + * @brief Start the two-pass render process. + */ + void render(); + +protected: + /** + * @brief Rasterize the scenery into a canvas portion. + * + * If 'threaded' is true, the rasterization will take advantage of multiple CPU cores. + */ + void rasterize(CanvasPortion* portion, bool threaded); + + /** + * @brief Apply post-processing to fragments stored in the CanvasPortion. + * + * If 'threaded' is true, the post-processing will take advantage of multiple CPU cores. + */ + void postProcess(CanvasPortion* portion, bool threaded=true); + +private: + SoftwareRenderer* renderer; + Canvas* canvas; + bool started; +}; + +} +} + +#endif // SOFTWARECANVASRENDERER_H diff --git a/src/render/software/SoftwareRenderer.cpp b/src/render/software/SoftwareRenderer.cpp index 1f88f17..12cdb64 100644 --- a/src/render/software/SoftwareRenderer.cpp +++ b/src/render/software/SoftwareRenderer.cpp @@ -108,6 +108,13 @@ void SoftwareRenderer::prepare() //fluid_medium->registerMedium(water_renderer); } +void SoftwareRenderer::getRasterizers(std::vector *array) +{ + array->push_back(TerrainRasterizer(this)); + array->push_back(WaterRasterizer(this)); + array->push_back(SkyRasterizer(this)); +} + void SoftwareRenderer::rasterize() { TerrainRasterizer terrain(this); diff --git a/src/render/software/SoftwareRenderer.h b/src/render/software/SoftwareRenderer.h index 9f269f3..08b2d76 100644 --- a/src/render/software/SoftwareRenderer.h +++ b/src/render/software/SoftwareRenderer.h @@ -59,6 +59,11 @@ public: */ virtual void prepare(); + /*! + * \brief Get the list of objects that can be rasterized to polygons on a canvas. + */ + virtual void getRasterizers(std::vector *array); + /*! * \brief Start the rasterization process. */ diff --git a/src/render/software/TerrainRasterizer.h b/src/render/software/TerrainRasterizer.h index 47b559e..83c9eaf 100644 --- a/src/render/software/TerrainRasterizer.h +++ b/src/render/software/TerrainRasterizer.h @@ -3,12 +3,13 @@ #include "software_global.h" +#include "Rasterizer.h" #include "Vector3.h" namespace paysages { namespace software { -class SOFTWARESHARED_EXPORT TerrainRasterizer +class SOFTWARESHARED_EXPORT TerrainRasterizer: public Rasterizer { public: typedef struct diff --git a/src/render/software/WaterRasterizer.h b/src/render/software/WaterRasterizer.h index 7d08798..031f937 100644 --- a/src/render/software/WaterRasterizer.h +++ b/src/render/software/WaterRasterizer.h @@ -3,10 +3,12 @@ #include "software_global.h" +#include "Rasterizer.h" + namespace paysages { namespace software { -class WaterRasterizer +class WaterRasterizer: public Rasterizer { public: WaterRasterizer(SoftwareRenderer* renderer); diff --git a/src/render/software/software.pro b/src/render/software/software.pro index ec32efa..8fbd61a 100644 --- a/src/render/software/software.pro +++ b/src/render/software/software.pro @@ -37,7 +37,14 @@ SOURCES += SoftwareRenderer.cpp \ RenderArea.cpp \ RayCastingManager.cpp \ NightSky.cpp \ - TerrainRayWalker.cpp + TerrainRayWalker.cpp \ + Canvas.cpp \ + CanvasPortion.cpp \ + CanvasPixel.cpp \ + CanvasFragment.cpp \ + SoftwareCanvasRenderer.cpp \ + Rasterizer.cpp \ + CanvasLiveClient.cpp HEADERS += SoftwareRenderer.h\ software_global.h \ @@ -64,7 +71,14 @@ HEADERS += SoftwareRenderer.h\ RenderArea.h \ RayCastingManager.h \ NightSky.h \ - TerrainRayWalker.h + TerrainRayWalker.h \ + Canvas.h \ + CanvasPortion.h \ + CanvasPixel.h \ + CanvasFragment.h \ + SoftwareCanvasRenderer.h \ + Rasterizer.h \ + CanvasLiveClient.h unix:!symbian { maemo5 { diff --git a/src/render/software/software_global.h b/src/render/software/software_global.h index 180bcca..432f108 100644 --- a/src/render/software/software_global.h +++ b/src/render/software/software_global.h @@ -14,6 +14,7 @@ namespace paysages { namespace software { class SoftwareRenderer; + class SoftwareCanvasRenderer; class RenderArea; class FluidMediumManager; @@ -33,6 +34,7 @@ namespace software { class TexturesRenderer; class WaterRenderer; + class Rasterizer; class SkyRasterizer; class TerrainRasterizer; @@ -44,6 +46,12 @@ namespace software { class NightSky; class TerrainRayWalker; + + class Canvas; + class CanvasPortion; + class CanvasPixel; + class CanvasFragment; + class CanvasLiveClient; } } diff --git a/src/tests/Canvas_Test.cpp b/src/tests/Canvas_Test.cpp new file mode 100644 index 0000000..7ae9551 --- /dev/null +++ b/src/tests/Canvas_Test.cpp @@ -0,0 +1,41 @@ +#include "BaseTestCase.h" + +#include "Canvas.h" +#include "CanvasPortion.h" + +static void checkPortion(Canvas &canvas, int x, int y, int width, int height) +{ + ASSERT_LT(x, canvas.getHorizontalPortionCount()); + ASSERT_LT(y, canvas.getVerticalPortionCount()); + + CanvasPortion* portion = canvas.at(x, y); + + EXPECT_EQ(width, portion->getWidth()); + EXPECT_EQ(height, portion->getHeight()); +} + +TEST(Canvas, SizingAndCutting) +{ + Canvas canvas; + + canvas.setSize(200, 100); + EXPECT_EQ(200, canvas.getWidth()); + EXPECT_EQ(100, canvas.getHeight()); + EXPECT_EQ(200, canvas.getPreviewWidth()); + EXPECT_EQ(100, canvas.getPreviewHeight()); + ASSERT_EQ(1, canvas.getHorizontalPortionCount()); + ASSERT_EQ(1, canvas.getVerticalPortionCount()); + checkPortion(canvas, 0, 0, 200, 100); + + canvas.setSize(600, 501); + EXPECT_EQ(600, canvas.getWidth()); + EXPECT_EQ(501, canvas.getHeight()); + EXPECT_EQ(600, canvas.getPreviewWidth()); + EXPECT_EQ(501, canvas.getPreviewHeight()); + ASSERT_EQ(2, canvas.getHorizontalPortionCount()); + ASSERT_EQ(2, canvas.getVerticalPortionCount()); + checkPortion(canvas, 0, 0, 300, 250); + checkPortion(canvas, 0, 1, 300, 251); + checkPortion(canvas, 1, 0, 300, 250); + checkPortion(canvas, 1, 1, 300, 251); +} diff --git a/src/tests/tests.pro b/src/tests/tests.pro index 378272f..3dd95e6 100644 --- a/src/tests/tests.pro +++ b/src/tests/tests.pro @@ -19,7 +19,8 @@ SOURCES += main.cpp \ Clouds_Test.cpp \ FluidMediumManager_Test.cpp \ VertexArray_Test.cpp \ - FractalNoise_Test.cpp + FractalNoise_Test.cpp \ + Canvas_Test.cpp HEADERS += \ BaseTestCase.h