diff --git a/src/render/software/Canvas.cpp b/src/render/software/Canvas.cpp index 875b8fc..4e4e746 100644 --- a/src/render/software/Canvas.cpp +++ b/src/render/software/Canvas.cpp @@ -50,7 +50,9 @@ void Canvas::setSize(int width, int height) CanvasPortion *portion = new CanvasPortion(preview); portion->setSize((x == horizontal_portion_count - 1) ? width - done_width : portion_width, - (y == vertical_portion_count - 1) ? height - done_height : portion_height); + (y == vertical_portion_count - 1) ? height - done_height : portion_height, + done_width, + done_height); done_width += portion->getWidth(); if (x == horizontal_portion_count - 1) diff --git a/src/render/software/CanvasPortion.cpp b/src/render/software/CanvasPortion.cpp index ff0b15e..193404a 100644 --- a/src/render/software/CanvasPortion.cpp +++ b/src/render/software/CanvasPortion.cpp @@ -16,6 +16,8 @@ CanvasPortion::CanvasPortion(CanvasPreview* preview): { width = 1; height = 1; + xoffset = 0; + yoffset = 0; pixels = NULL; } @@ -50,10 +52,12 @@ void CanvasPortion::clear() } } -void CanvasPortion::setSize(int width, int height) +void CanvasPortion::setSize(int width, int height, int xoffset, int yoffset) { this->width = width; this->height = height; + this->xoffset = xoffset; + this->yoffset = yoffset; } void CanvasPortion::preparePixels() @@ -66,6 +70,15 @@ void CanvasPortion::preparePixels() clear(); } +void CanvasPortion::discardPixels() +{ + if (pixels) + { + delete[] pixels; + pixels = NULL; + } +} + void CanvasPortion::pushFragment(int x, int y, const CanvasFragment &fragment) { CHECK_COORDINATES(); @@ -77,7 +90,7 @@ void CanvasPortion::pushFragment(int x, int y, const CanvasFragment &fragment) if (preview) { - preview->pushPixel(x, y, old_color, pixel.getComposite()); + preview->pushPixel(xoffset + x, yoffset + y, old_color, pixel.getComposite()); } } @@ -99,6 +112,6 @@ void CanvasPortion::setColor(int x, int y, const Color &color) if (preview) { - preview->pushPixel(x, y, old_color, pixel.getComposite()); + preview->pushPixel(xoffset + x, yoffset + y, old_color, pixel.getComposite()); } } diff --git a/src/render/software/CanvasPortion.h b/src/render/software/CanvasPortion.h index 9d45f42..59d0153 100644 --- a/src/render/software/CanvasPortion.h +++ b/src/render/software/CanvasPortion.h @@ -21,17 +21,24 @@ public: inline int getWidth() const {return width;} inline int getHeight() const {return height;} + inline int getXOffset() const {return xoffset;} + inline int getYOffset() const {return yoffset;} int getFragmentCount(int x, int y) const; const CanvasFragment *getFrontFragment(int x, int y) const; void clear(); - void setSize(int width, int height); + void setSize(int width, int height, int xoffset=0, int yoffset=0); /** * Prepare (allocate in memory) the pixels area. */ void preparePixels(); + /** + * Discard the memory used by pixels. + */ + void discardPixels(); + /** * Add a fragment to the pixel located at (x, y). * @@ -56,6 +63,8 @@ public: private: int width; int height; + int xoffset; + int yoffset; CanvasPixel *pixels; CanvasPreview* preview; }; diff --git a/src/render/software/CanvasPreview.cpp b/src/render/software/CanvasPreview.cpp index cb63c03..f7cf1fc 100644 --- a/src/render/software/CanvasPreview.cpp +++ b/src/render/software/CanvasPreview.cpp @@ -108,7 +108,6 @@ void CanvasPreview::pushPixel(int real_x, int real_y, const Color &old_color, co lock->acquire(); - // TODO Assert-check if (scaled) { x = round(real_x / factor_x); @@ -120,6 +119,8 @@ void CanvasPreview::pushPixel(int real_x, int real_y, const Color &old_color, co y = real_y; } + // TODO Assert-check on x and y + 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; diff --git a/src/render/software/Rasterizer.cpp b/src/render/software/Rasterizer.cpp index 009d984..af9c6ff 100644 --- a/src/render/software/Rasterizer.cpp +++ b/src/render/software/Rasterizer.cpp @@ -48,33 +48,37 @@ void Rasterizer::pushProjectedTriangle(CanvasPortion *canvas, const Vector3 &pix double limit_width = (double)(canvas->getWidth() - 1); double limit_height = (double)(canvas->getHeight() - 1); + Vector3 canvas_offset(canvas->getXOffset(), canvas->getYOffset(), 0.0); + Vector3 dpixel1 = pixel1.sub(canvas_offset); + Vector3 dpixel2 = pixel2.sub(canvas_offset); + Vector3 dpixel3 = pixel3.sub(canvas_offset); + /* Filter if outside screen */ - if (pixel1.z < 1.0 || pixel2.z < 1.0 || pixel3.z < 1.0 || (pixel1.x < 0.0 && pixel2.x < 0.0 && pixel3.x < 0.0) || (pixel1.y < 0.0 && pixel2.y < 0.0 && pixel3.y < 0.0) || (pixel1.x > limit_width && pixel2.x > limit_width && pixel3.x > limit_width) || (pixel1.y > limit_height && pixel2.y > limit_height && pixel3.y > limit_height)) + if (dpixel1.z < 1.0 || dpixel2.z < 1.0 || dpixel3.z < 1.0 || (dpixel1.x < 0.0 && dpixel2.x < 0.0 && dpixel3.x < 0.0) || (dpixel1.y < 0.0 && dpixel2.y < 0.0 && dpixel3.y < 0.0) || (dpixel1.x > limit_width && dpixel2.x > limit_width && dpixel3.x > limit_width) || (dpixel1.y > limit_height && dpixel2.y > limit_height && dpixel3.y > limit_height)) { return; } /* Prepare vertices */ - // FIXME Apply canvas portion offset - point1.pixel.x = pixel1.x; - point1.pixel.y = pixel1.y; - point1.pixel.z = pixel1.z; + point1.pixel.x = dpixel1.x; + point1.pixel.y = dpixel1.y; + point1.pixel.z = dpixel1.z; point1.location.x = location1.x; point1.location.y = location1.y; point1.location.z = location1.z; point1.client = client_id; - point2.pixel.x = pixel2.x; - point2.pixel.y = pixel2.y; - point2.pixel.z = pixel2.z; + point2.pixel.x = dpixel2.x; + point2.pixel.y = dpixel2.y; + point2.pixel.z = dpixel2.z; point2.location.x = location2.x; point2.location.y = location2.y; point2.location.z = location2.z; point2.client = client_id; - point3.pixel.x = pixel3.x; - point3.pixel.y = pixel3.y; - point3.pixel.z = pixel3.z; + point3.pixel.x = dpixel3.x; + point3.pixel.y = dpixel3.y; + point3.pixel.z = dpixel3.z; point3.location.x = location3.x; point3.location.y = location3.y; point3.location.z = location3.z; diff --git a/src/render/software/SoftwareCanvasRenderer.cpp b/src/render/software/SoftwareCanvasRenderer.cpp index fde61ee..41890c5 100644 --- a/src/render/software/SoftwareCanvasRenderer.cpp +++ b/src/render/software/SoftwareCanvasRenderer.cpp @@ -51,11 +51,20 @@ void SoftwareCanvasRenderer::render() prepare(); - // TODO Iterate portions - CanvasPortion *portion = canvas->at(0, 0); - portion->preparePixels(); - rasterize(portion, true); - postProcess(portion, true); + // Iterate portions + int nx = canvas->getHorizontalPortionCount(); + int ny = canvas->getVerticalPortionCount(); + for (int y = 0; y < ny; y++) + { + for (int x = 0; x < nx; x++) + { + CanvasPortion *portion = canvas->at(x, y); + portion->preparePixels(); + rasterize(portion, true); + postProcess(portion, true); + portion->discardPixels(); + } + } } const std::vector &SoftwareCanvasRenderer::getRasterizers() const