mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
ScanLine rasterizer
git-svn-id: svn://ultimatepp.org/upp/trunk@824 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
989a81ecfc
commit
00580386fa
5 changed files with 46 additions and 34 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue