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);
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)

View file

@ -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());
}
}

View file

@ -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;
};

View file

@ -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;

View file

@ -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;

View file

@ -51,11 +51,20 @@ void SoftwareCanvasRenderer::render()
prepare();
// TODO Iterate portions
CanvasPortion *portion = canvas->at(0, 0);
// 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<Rasterizer *> &SoftwareCanvasRenderer::getRasterizers() const