ScanLine rasterizer

git-svn-id: svn://ultimatepp.org/upp/trunk@824 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2009-01-29 11:06:17 +00:00
parent 7f214e9aeb
commit e98ea96de9
5 changed files with 46 additions and 34 deletions

View file

@ -14,7 +14,7 @@ Rasterizer::Rasterizer(Size _sz)
inline void Rasterizer::AddCurrent()
{
if((current.area | current.cover) && current_y >= 0 && current_y < sz.cy) {
if((current.area | current.cover)) {
cell[current_y].Add(current);
// DLOG(current.x << ", y=" << current_y);
}
@ -22,8 +22,8 @@ inline void Rasterizer::AddCurrent()
inline void Rasterizer::SetCurrent(int x, int y)
{
DLOG("cury=" << y);
if(current.x != x || current_y != y) {
// DLOG("cury=" << y);
if((current.x - x) | (current_y - y)) {
AddCurrent();
current.x = x;
current_y = y;
@ -44,7 +44,7 @@ inline void Rasterizer::RenderHLine(int ey, int x1, int y1, int x2, int y2)
if(ex1 == ex2) {
int delta = y2 - y1;
current.cover += delta;
current.area += (fx1 + fx2) * delta;
current.area += (fx1 + fx2) * delta;
return;
}
int p = (256 - fx1) * (y2 - y1);
@ -69,7 +69,7 @@ inline void Rasterizer::RenderHLine(int ey, int x1, int y1, int x2, int y2)
SetCurrent(ex1, ey);
y1 += delta;
if(ex1 != ex2) {
p = (y2 - y1 + delta) << 8;
p = (y2 - y1 + delta) * 256;
int lift = p / dx;
int rem = p % dx;
if (rem < 0) {
@ -85,7 +85,7 @@ inline void Rasterizer::RenderHLine(int ey, int x1, int y1, int x2, int y2)
delta++;
}
current.cover += delta;
current.area += delta << 8;
current.area += delta * 256;
y1 += delta;
ex1 += incr;
SetCurrent(ex1, ey);
@ -114,6 +114,8 @@ void Rasterizer::LineRaw(int x1, int y1, int x2, int y2)
int ey2 = y2 >> 8;
int fy1 = y1 & 255;
int fy2 = y2 & 255;
ASSERT(ey1 >= 0 && ey1 < sz.cy && ey2 >= 0 && ey2 < sz.cy);
DLOG(ex1 << ", " << ey1 << " - " << ex2 << ", " << ey2);
@ -169,7 +171,7 @@ void Rasterizer::LineRaw(int x1, int y1, int x2, int y2)
dy = -dy;
}
delta = p / dy;
mod = p % dy;
mod = p % dy;
if(mod < 0) {
delta--;
mod += dy;
@ -235,7 +237,7 @@ ScanLine Rasterizer::Get(int y)
int cover = 0;
DDUMP(y);
while(c < e) {
DDUMP(c->x);
// DDUMP(c->x);
int x = c->x;
int area = c->area;
cover += c->cover;
@ -245,12 +247,13 @@ ScanLine Rasterizer::Get(int y)
cover += c->cover;
c++;
}
if(area)
if(area) {
r.data.Cat(Alpha((cover << (8 + 1)) - area));
else
r.data.Cat(0);
r.len++;
x++;
r.len++;
x++;
}
// else
// r.data.Cat(0);
if(c < e && c->x > x) {
byte val = Alpha(cover << (8 + 1));
int n = c->x - x;

View file

@ -6,6 +6,11 @@ void Rasterizer::Move(double x, double y)
y1 = y;
}
inline int Cv(double x)
{
return int(minmax(x * 256 + 65536.5, 0.0, 200000.0)) - 65536;
}
void Rasterizer::LineClip(double x1, double y1, double x2, double y2)
{
if(y1 < cliprect.top) {
@ -29,6 +34,7 @@ void Rasterizer::LineClip(double x1, double y1, double x2, double y2)
if(y2 > cliprect.bottom) {
x2 = (x2 - x1) * (cliprect.bottom - y1) / (y2 - y1) + x1;
y2 = cliprect.bottom;
DDUMP(Cv(y2));
}
/*
if(x1 < cliprect.left) {
@ -54,7 +60,8 @@ void Rasterizer::LineClip(double x1, double y1, double x2, double y2)
x2 = cliprect.right;
}
*/
LineRaw(int(x1 * 256 + 0.5), int(y1 * 256 + 0.5), int(x2 * 256 + 0.5), int(y2 * 256 + 0.5));
int ymax = (sz.cy << 8) - 1;
LineRaw(Cv(x1), min(Cv(y1), ymax), Cv(x2), min(Cv(y2), ymax));
}
void Rasterizer::Line(double x2, double y2)

View file

@ -117,18 +117,20 @@ String ScanLine::ToString() const
void Apply(RGBA *t, int len, const RGBA& color, const ScanLine& s)
{
RGBA *e = t + len;
const char *q = ~s.data;
const char *qe = s.data.End();
t += s.x;
int si = 0;
const RGBA *e = t + len;
while(t < e && si < s.data.GetLength()) {
byte val = s.data[si++];
while(t < e && q < qe) {
byte val = *q++;
if(val > 128) {
int n = min(e - t, val - 128);
val = s.data[si++];
while(n--)
RGBA *e1 = min(e, t + val - 128);
val = *q++;
while(t < e1)
AlphaBlendCover7(*t++, color, val);
}
else
AlphaBlendCover7(*t++, color, val);
// DDUMP(t - e);
}
}

View file

@ -42,9 +42,9 @@ ScanLine Pack(int x, const byte *data, int len);
class Rasterizer {
struct Cell : Moveable<Cell> {
int x;
int cover;
int area;
int x;
int cover;
int area;
void Init() { x = 0x7FFFFFFF; cover = area = 0; }
bool operator<(const Cell& b) const { return x < b.x; }

View file

@ -47,8 +47,15 @@ struct App : TopWindow {
}
*/
Rasterizer r(Size(500, 500));
r.SetClip(RectfC(100, 100, 200, 200));
// r.SetClip(RectfC(100, 100, 200, 200));
#if 1
r.Move( 36.000000, 142.000000);
r.Line(480.000000, 148.000000);
r.Line(429.000000, 148.000000);
r.Line( 36.000000, 142.000000);
#endif
#if 0
r.Move(121.000000, 121.000000);
r.Line(0.000000, 0.000000);
@ -61,23 +68,16 @@ struct App : TopWindow {
r.Line(564.000000, 213.000000);
r.Line(153.000000, 297.000000);
#endif
#if 1
r.Move( 36.000000, 142.000000);
r.Line(480.000000, 148.000000);
r.Line(429.000000, 148.000000);
r.Line( 36.000000, 142.000000);
#endif
#if 0
r.Move(x1, y1);
r.Line(x2, y2);
r.Line(x3, y3);
r.Line(x1, y1);
#endif
for(int y = r.MinY(); y <= r.MaxY(); y++) {
ScanLine sl = r.Get(y);
DUMP(sl);
Apply(ib[y], 400, Blue(), sl);
Apply(ib[y], 500, Blue(), sl);
}
w.DrawRect(GetSize(), White());
@ -86,13 +86,13 @@ struct App : TopWindow {
}
App() {
Sizeable().Zoomable();
x1 = y1 = x2 = y2 = 0;
}
};
GUI_APP_MAIN {
App().Run();
return;
ScanLine a, b, c;
static byte line1[] = { 1, 50, 100, 128, 128, 128, 128, 128, 100, 50, 1 };