diff --git a/src/interface/desktop/formrender.cpp b/src/interface/desktop/formrender.cpp index cbc6157..489e7bb 100644 --- a/src/interface/desktop/formrender.cpp +++ b/src/interface/desktop/formrender.cpp @@ -36,8 +36,8 @@ BaseForm(parent, true) addInput(new InputCamera(this, tr("Camera"), _camera)); addInputInt(tr("Quality"), &_params.quality, 1, 10, 1, 1); - addInputInt(tr("Image width"), &_params.width, 100, 2000, 10, 100); - addInputInt(tr("Image height"), &_params.height, 100, 1200, 10, 100); + addInputInt(tr("Image width"), &_params.width, 100, 4000, 10, 100); + addInputInt(tr("Image height"), &_params.height, 100, 3000, 10, 100); addInputInt(tr("Anti aliasing"), &_params.antialias, 1, 4, 1, 1); button = addButton(tr("Start new render")); diff --git a/src/render/software/Canvas.cpp b/src/render/software/Canvas.cpp index 809b170..875b8fc 100644 --- a/src/render/software/Canvas.cpp +++ b/src/render/software/Canvas.cpp @@ -67,8 +67,13 @@ void Canvas::setSize(int width, int height) this->width = width; this->height = height; - // TODO Smaller preview - preview->setSize(width, height, width, height); + // Smaller preview + while (width > 800 and height > 800) + { + width = width / 2; + height = height / 2; + } + preview->setSize(this->width, this->height, width, height); } CanvasPortion *Canvas::at(int x, int y) const diff --git a/src/render/software/CanvasPortion.cpp b/src/render/software/CanvasPortion.cpp index 93acae0..ff0b15e 100644 --- a/src/render/software/CanvasPortion.cpp +++ b/src/render/software/CanvasPortion.cpp @@ -8,19 +8,23 @@ #define CHECK_COORDINATES() assert(x >= 0); \ assert(x < width); \ assert(y >= 0); \ - assert(y < height) + assert(y < height); \ + assert(pixels != NULL) CanvasPortion::CanvasPortion(CanvasPreview* preview): preview(preview) { width = 1; height = 1; - pixels = new CanvasPixel[1]; + pixels = NULL; } CanvasPortion::~CanvasPortion() { - delete[] pixels; + if (pixels) + { + delete[] pixels; + } } int CanvasPortion::getFragmentCount(int x, int y) const @@ -50,9 +54,16 @@ void CanvasPortion::setSize(int width, int height) { this->width = width; this->height = height; +} - delete[] pixels; +void CanvasPortion::preparePixels() +{ + if (pixels) + { + delete[] pixels; + } pixels = new CanvasPixel[width * height]; + clear(); } void CanvasPortion::pushFragment(int x, int y, const CanvasFragment &fragment) diff --git a/src/render/software/CanvasPortion.h b/src/render/software/CanvasPortion.h index 49d88d4..9d45f42 100644 --- a/src/render/software/CanvasPortion.h +++ b/src/render/software/CanvasPortion.h @@ -10,6 +10,8 @@ namespace software { * Rectangular portion of a Canvas. * * Contains the pixels of a canvas region (CanvasPixel). + * + * Pixels are not allocated until preparePixels is called. */ class SOFTWARESHARED_EXPORT CanvasPortion { @@ -25,6 +27,11 @@ public: void clear(); void setSize(int width, int height); + /** + * Prepare (allocate in memory) the pixels area. + */ + void preparePixels(); + /** * Add a fragment to the pixel located at (x, y). * diff --git a/src/render/software/CanvasPreview.cpp b/src/render/software/CanvasPreview.cpp index e37b41d..cb63c03 100644 --- a/src/render/software/CanvasPreview.cpp +++ b/src/render/software/CanvasPreview.cpp @@ -18,6 +18,11 @@ CanvasPreview::CanvasPreview() dirty_down = 1; dirty_up = -1; + scaled = false; + factor = 1.0; + factor_x = 1.0; + factor_y = 1.0; + lock = new Mutex(); profile = new ColorProfile(); } @@ -44,6 +49,11 @@ void CanvasPreview::setSize(int real_width, int real_height, int preview_width, dirty_down = height; dirty_up = -1; + scaled = (real_width != preview_height or real_height != preview_height); + factor_x = (double)real_width / (double)preview_width; + factor_y = (double)real_height / (double)preview_height; + factor = factor_x * factor_y; + lock->release(); reset(); @@ -94,17 +104,26 @@ void CanvasPreview::updateLive(CanvasLiveClient *client) void CanvasPreview::pushPixel(int real_x, int real_y, const Color &old_color, const Color &new_color) { + int x, y; + lock->acquire(); - // TODO Assert-check and transform coordinates - int x = real_x; - int y = real_y; - double fact = 1.0; + // TODO Assert-check + if (scaled) + { + x = round(real_x / factor_x); + y = round(real_y / factor_y); + } + else + { + x = real_x; + y = real_y; + } - Color* pixel = pixels + (real_y * width + real_x); - pixel->r = pixel->r - old_color.r * fact + new_color.r * fact; - pixel->g = pixel->g - old_color.g * fact + new_color.g * fact; - pixel->b = pixel->b - old_color.b * fact + new_color.b * fact; + Color* pixel = pixels + (y * width + x); + pixel->r = pixel->r - old_color.r / factor + new_color.r / factor; + pixel->g = pixel->g - old_color.g / factor + new_color.g / factor; + pixel->b = pixel->b - old_color.b / factor + new_color.b / factor; // Set pixel dirty if (x < dirty_left) diff --git a/src/render/software/CanvasPreview.h b/src/render/software/CanvasPreview.h index 35ef00a..f67cc39 100644 --- a/src/render/software/CanvasPreview.h +++ b/src/render/software/CanvasPreview.h @@ -42,6 +42,11 @@ private: int dirty_right; int dirty_down; int dirty_up; + + bool scaled; + double factor; + double factor_x; + double factor_y; }; } diff --git a/src/render/software/SoftwareCanvasRenderer.cpp b/src/render/software/SoftwareCanvasRenderer.cpp index a70ba88..fde61ee 100644 --- a/src/render/software/SoftwareCanvasRenderer.cpp +++ b/src/render/software/SoftwareCanvasRenderer.cpp @@ -43,7 +43,6 @@ void SoftwareCanvasRenderer::render() { // TEMP started = true; - CanvasPortion *portion = canvas->at(0, 0); render_width = canvas->getWidth(); render_height = canvas->getHeight(); render_quality = 3; @@ -52,6 +51,9 @@ void SoftwareCanvasRenderer::render() prepare(); + // TODO Iterate portions + CanvasPortion *portion = canvas->at(0, 0); + portion->preparePixels(); rasterize(portion, true); postProcess(portion, true); }