Iterate over portions to render the whole canvas

This commit is contained in:
Michaël Lemaire 2014-08-18 17:33:15 +02:00
parent 3a2ec1c75f
commit 31b74c660e
6 changed files with 60 additions and 22 deletions

View file

@ -50,7 +50,9 @@ void Canvas::setSize(int width, int height)
CanvasPortion *portion = new CanvasPortion(preview); CanvasPortion *portion = new CanvasPortion(preview);
portion->setSize((x == horizontal_portion_count - 1) ? width - done_width : portion_width, 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(); done_width += portion->getWidth();
if (x == horizontal_portion_count - 1) if (x == horizontal_portion_count - 1)

View file

@ -16,6 +16,8 @@ CanvasPortion::CanvasPortion(CanvasPreview* preview):
{ {
width = 1; width = 1;
height = 1; height = 1;
xoffset = 0;
yoffset = 0;
pixels = NULL; 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->width = width;
this->height = height; this->height = height;
this->xoffset = xoffset;
this->yoffset = yoffset;
} }
void CanvasPortion::preparePixels() void CanvasPortion::preparePixels()
@ -66,6 +70,15 @@ void CanvasPortion::preparePixels()
clear(); clear();
} }
void CanvasPortion::discardPixels()
{
if (pixels)
{
delete[] pixels;
pixels = NULL;
}
}
void CanvasPortion::pushFragment(int x, int y, const CanvasFragment &fragment) void CanvasPortion::pushFragment(int x, int y, const CanvasFragment &fragment)
{ {
CHECK_COORDINATES(); CHECK_COORDINATES();
@ -77,7 +90,7 @@ void CanvasPortion::pushFragment(int x, int y, const CanvasFragment &fragment)
if (preview) 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) if (preview)
{ {
preview->pushPixel(x, y, old_color, pixel.getComposite()); preview->pushPixel(xoffset + x, yoffset + y, old_color, pixel.getComposite());
} }
} }

View file

@ -21,17 +21,24 @@ public:
inline int getWidth() const {return width;} inline int getWidth() const {return width;}
inline int getHeight() const {return height;} 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; int getFragmentCount(int x, int y) const;
const CanvasFragment *getFrontFragment(int x, int y) const; const CanvasFragment *getFrontFragment(int x, int y) const;
void clear(); 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. * Prepare (allocate in memory) the pixels area.
*/ */
void preparePixels(); void preparePixels();
/**
* Discard the memory used by pixels.
*/
void discardPixels();
/** /**
* Add a fragment to the pixel located at (x, y). * Add a fragment to the pixel located at (x, y).
* *
@ -56,6 +63,8 @@ public:
private: private:
int width; int width;
int height; int height;
int xoffset;
int yoffset;
CanvasPixel *pixels; CanvasPixel *pixels;
CanvasPreview* preview; CanvasPreview* preview;
}; };

View file

@ -108,7 +108,6 @@ void CanvasPreview::pushPixel(int real_x, int real_y, const Color &old_color, co
lock->acquire(); lock->acquire();
// TODO Assert-check
if (scaled) if (scaled)
{ {
x = round(real_x / factor_x); 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; y = real_y;
} }
// TODO Assert-check on x and y
Color* pixel = pixels + (y * width + x); Color* pixel = pixels + (y * width + x);
pixel->r = pixel->r - old_color.r / factor + new_color.r / factor; 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->g = pixel->g - old_color.g / factor + new_color.g / factor;

View file

@ -48,33 +48,37 @@ void Rasterizer::pushProjectedTriangle(CanvasPortion *canvas, const Vector3 &pix
double limit_width = (double)(canvas->getWidth() - 1); double limit_width = (double)(canvas->getWidth() - 1);
double limit_height = (double)(canvas->getHeight() - 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 */ /* 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; return;
} }
/* Prepare vertices */ /* Prepare vertices */
// FIXME Apply canvas portion offset point1.pixel.x = dpixel1.x;
point1.pixel.x = pixel1.x; point1.pixel.y = dpixel1.y;
point1.pixel.y = pixel1.y; point1.pixel.z = dpixel1.z;
point1.pixel.z = pixel1.z;
point1.location.x = location1.x; point1.location.x = location1.x;
point1.location.y = location1.y; point1.location.y = location1.y;
point1.location.z = location1.z; point1.location.z = location1.z;
point1.client = client_id; point1.client = client_id;
point2.pixel.x = pixel2.x; point2.pixel.x = dpixel2.x;
point2.pixel.y = pixel2.y; point2.pixel.y = dpixel2.y;
point2.pixel.z = pixel2.z; point2.pixel.z = dpixel2.z;
point2.location.x = location2.x; point2.location.x = location2.x;
point2.location.y = location2.y; point2.location.y = location2.y;
point2.location.z = location2.z; point2.location.z = location2.z;
point2.client = client_id; point2.client = client_id;
point3.pixel.x = pixel3.x; point3.pixel.x = dpixel3.x;
point3.pixel.y = pixel3.y; point3.pixel.y = dpixel3.y;
point3.pixel.z = pixel3.z; point3.pixel.z = dpixel3.z;
point3.location.x = location3.x; point3.location.x = location3.x;
point3.location.y = location3.y; point3.location.y = location3.y;
point3.location.z = location3.z; point3.location.z = location3.z;

View file

@ -51,11 +51,20 @@ void SoftwareCanvasRenderer::render()
prepare(); prepare();
// TODO Iterate portions // Iterate portions
CanvasPortion *portion = canvas->at(0, 0); int nx = canvas->getHorizontalPortionCount();
portion->preparePixels(); int ny = canvas->getVerticalPortionCount();
rasterize(portion, true); for (int y = 0; y < ny; y++)
postProcess(portion, true); {
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<Rasterizer *> &SoftwareCanvasRenderer::getRasterizers() const const std::vector<Rasterizer *> &SoftwareCanvasRenderer::getRasterizers() const