Iterate over portions to render the whole canvas
This commit is contained in:
parent
3a2ec1c75f
commit
31b74c660e
6 changed files with 60 additions and 22 deletions
|
@ -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)
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -51,11 +51,20 @@ void SoftwareCanvasRenderer::render()
|
||||||
|
|
||||||
prepare();
|
prepare();
|
||||||
|
|
||||||
// TODO Iterate portions
|
// Iterate portions
|
||||||
CanvasPortion *portion = canvas->at(0, 0);
|
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();
|
portion->preparePixels();
|
||||||
rasterize(portion, true);
|
rasterize(portion, true);
|
||||||
postProcess(portion, true);
|
postProcess(portion, true);
|
||||||
|
portion->discardPixels();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Rasterizer *> &SoftwareCanvasRenderer::getRasterizers() const
|
const std::vector<Rasterizer *> &SoftwareCanvasRenderer::getRasterizers() const
|
||||||
|
|
Loading…
Reference in a new issue