mirror of https://github.com/buggins/dlangui.git
triangle clipping
This commit is contained in:
parent
e715c52d0b
commit
ec4b6c9392
|
@ -1088,11 +1088,22 @@ void main()
|
||||||
canvas.font.drawText(buf, x + 300, y + 100, "drawPixel()"d, 0x000080);
|
canvas.font.drawText(buf, x + 300, y + 100, "drawPixel()"d, 0x000080);
|
||||||
for (int i = 0; i < 80; i++)
|
for (int i = 0; i < 80; i++)
|
||||||
buf.drawPixel(x+300 + i * 4, y+140 + i * 3 % 100, 0xFF0000 + i * 2);
|
buf.drawPixel(x+300 + i * 4, y+140 + i * 3 % 100, 0xFF0000 + i * 2);
|
||||||
canvas.font.drawText(buf, x + 200, y + 250, "drawLine()"d, 0x800020);
|
canvas.font.drawText(buf, x + 300, y + 420, "drawLine()"d, 0x800020);
|
||||||
for (int i = 0; i < 40; i+=3)
|
for (int i = 0; i < 40; i+=3)
|
||||||
buf.drawLine(Point(x+200 + i * 4, y+290), Point(x+150 + i * 7, y+420 + i * 2), 0x008000 + i * 5);
|
buf.drawLine(Point(x+200 + i * 4, y+290), Point(x+150 + i * 7, y+420 + i * 2), 0x008000 + i * 5);
|
||||||
PointF[] poly = [vec2(130, 150), vec2(240, 110), vec2(270, 170), vec2(300, 290), vec2(220, 400), vec2(180, 330)];
|
// poly line test
|
||||||
buf.polyLineF(poly, 3.5f, 0x804020, true);
|
Rect newClipRect = Rect(x + 110, y + 100, x + 350, y + 320);
|
||||||
|
buf.fillRect(newClipRect, 0xC08080FF);
|
||||||
|
Rect oldClip = buf.clipRect;
|
||||||
|
buf.clipRect = newClipRect;
|
||||||
|
PointF[] poly = [vec2(x+130, y+150), vec2(x+240, y+80), vec2(x+170, y+170), vec2(x+380, y+270), vec2(x+220, y+400), vec2(x+180, y+330)];
|
||||||
|
buf.polyLineF(poly, 8.0f, 0x804020, true);
|
||||||
|
buf.fillTriangleF(vec2(x+230, y+50), vec2(x+400, y+250), vec2(x+130, y+200), 0xC0FF0000);
|
||||||
|
buf.fillTriangleF(vec2(x+230, y+250), vec2(x+200, y+350), vec2(x+80, y+200), 0xC000FF00);
|
||||||
|
buf.fillTriangleF(vec2(x+430, y+250), vec2(x+280, y+150), vec2(x+200, y+300), 0xC00000FF);
|
||||||
|
buf.fillTriangleF(vec2(x+80, y+150), vec2(x+280, y+250), vec2(x+80, y+200), 0xC0008080);
|
||||||
|
buf.clipRect = oldClip;
|
||||||
|
canvas.font.drawText(buf, x + 190, y + 260, "polyLineF()"d, 0x603010);
|
||||||
};
|
};
|
||||||
tabs.addTab(canvas, "TAB_CANVAS"c);
|
tabs.addTab(canvas, "TAB_CANVAS"c);
|
||||||
|
|
||||||
|
|
|
@ -371,9 +371,170 @@ class DrawBuf : RefCountedObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// draw filled triangle in float coordinates; clipping is already applied
|
||||||
|
protected void fillTriangleFClipped(PointF p1, PointF p2, PointF p3, uint colour) {
|
||||||
|
// override and implement it
|
||||||
|
}
|
||||||
|
|
||||||
|
/// find intersection of line p1..p2 with clip rectangle
|
||||||
|
protected bool intersectClipF(ref PointF p1, ref PointF p2, ref bool p1moved, ref bool p2moved) {
|
||||||
|
if (p1.x < _clipRect.left && p2.x < _clipRect.left)
|
||||||
|
return true;
|
||||||
|
if (p1.x >= _clipRect.right && p2.x >= _clipRect.right)
|
||||||
|
return true;
|
||||||
|
if (p1.y < _clipRect.top && p2.y < _clipRect.top)
|
||||||
|
return true;
|
||||||
|
if (p1.y >= _clipRect.bottom && p2.y >= _clipRect.bottom)
|
||||||
|
return true;
|
||||||
|
// horizontal clip
|
||||||
|
if (p1.x < _clipRect.left && p2.x >= _clipRect.left) {
|
||||||
|
// move p1 to clip left
|
||||||
|
p1 += (p2 - p1) * ((_clipRect.left - p1.x) / (p2.x - p1.x));
|
||||||
|
p1moved = true;
|
||||||
|
}
|
||||||
|
if (p2.x < _clipRect.left && p1.x >= _clipRect.left) {
|
||||||
|
// move p2 to clip left
|
||||||
|
p2 += (p1 - p2) * ((_clipRect.left - p2.x) / (p1.x - p2.x));
|
||||||
|
p2moved = true;
|
||||||
|
}
|
||||||
|
if (p1.x > _clipRect.right && p2.x < _clipRect.right) {
|
||||||
|
// move p1 to clip right
|
||||||
|
p1 += (p2 - p1) * ((_clipRect.right - p1.x) / (p2.x - p1.x));
|
||||||
|
p1moved = true;
|
||||||
|
}
|
||||||
|
if (p2.x > _clipRect.right && p1.x < _clipRect.right) {
|
||||||
|
// move p1 to clip right
|
||||||
|
p2 += (p1 - p2) * ((_clipRect.right - p2.x) / (p1.x - p2.x));
|
||||||
|
p2moved = true;
|
||||||
|
}
|
||||||
|
// vertical clip
|
||||||
|
if (p1.y < _clipRect.top && p2.y >= _clipRect.top) {
|
||||||
|
// move p1 to clip left
|
||||||
|
p1 += (p2 - p1) * ((_clipRect.top - p1.y) / (p2.y - p1.y));
|
||||||
|
p1moved = true;
|
||||||
|
}
|
||||||
|
if (p2.y < _clipRect.top && p1.y >= _clipRect.top) {
|
||||||
|
// move p2 to clip left
|
||||||
|
p2 += (p1 - p2) * ((_clipRect.top - p2.y) / (p1.y - p2.y));
|
||||||
|
p2moved = true;
|
||||||
|
}
|
||||||
|
if (p1.y > _clipRect.bottom && p2.y < _clipRect.bottom) {
|
||||||
|
// move p1 to clip right <0 <0
|
||||||
|
p1 += (p2 - p1) * ((_clipRect.bottom - p1.y) / (p2.y - p1.y));
|
||||||
|
p1moved = true;
|
||||||
|
}
|
||||||
|
if (p2.y > _clipRect.bottom && p1.y < _clipRect.bottom) {
|
||||||
|
// move p1 to clip right
|
||||||
|
p2 += (p1 - p2) * ((_clipRect.bottom - p2.y) / (p1.y - p2.y));
|
||||||
|
p2moved = true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// draw filled triangle in float coordinates
|
/// draw filled triangle in float coordinates
|
||||||
void fillTriangleF(PointF p1, PointF p2, PointF p3, uint colour) {
|
void fillTriangleF(PointF p1, PointF p2, PointF p3, uint colour) {
|
||||||
// override and implement it
|
if (_clipRect.empty) // clip rectangle is empty - all drawables are clipped out
|
||||||
|
return;
|
||||||
|
// apply clipping
|
||||||
|
bool p1insideClip = (p1.x >= _clipRect.left && p1.x < _clipRect.right && p1.y >= _clipRect.top && p1.y < _clipRect.bottom);
|
||||||
|
bool p2insideClip = (p2.x >= _clipRect.left && p2.x < _clipRect.right && p2.y >= _clipRect.top && p2.y < _clipRect.bottom);
|
||||||
|
bool p3insideClip = (p3.x >= _clipRect.left && p3.x < _clipRect.right && p3.y >= _clipRect.top && p3.y < _clipRect.bottom);
|
||||||
|
if (p1insideClip && p2insideClip && p3insideClip) {
|
||||||
|
// all points inside clipping area - no clipping required
|
||||||
|
fillTriangleFClipped(p1, p2, p3, colour);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// do triangle clipping
|
||||||
|
// check if all points outside the same bound
|
||||||
|
if ((p1.x < _clipRect.left && p2.x < _clipRect.left && p3.x < _clipRect.left)
|
||||||
|
|| (p1.x >= _clipRect.right && p2.x >= _clipRect.right && p3.x >= _clipRect.bottom)
|
||||||
|
|| (p1.y < _clipRect.top && p2.y < _clipRect.top && p3.y < _clipRect.top)
|
||||||
|
|| (p1.y >= _clipRect.bottom && p2.y >= _clipRect.bottom && p3.y >= _clipRect.bottom))
|
||||||
|
return;
|
||||||
|
/++
|
||||||
|
+ side 1
|
||||||
|
+ p1-------p11------------p21--------------p2
|
||||||
|
+ \ /
|
||||||
|
+ \ /
|
||||||
|
+ \ /
|
||||||
|
+ \ /
|
||||||
|
+ p13\ /p22
|
||||||
|
+ \ /
|
||||||
|
+ \ /
|
||||||
|
+ \ /
|
||||||
|
+ \ / side 2
|
||||||
|
+ side 3 \ /
|
||||||
|
+ \ /
|
||||||
|
+ \ /
|
||||||
|
+ \ /p32
|
||||||
|
+ p33\ /
|
||||||
|
+ \ /
|
||||||
|
+ \ /
|
||||||
|
+ \ /
|
||||||
|
+ \ /
|
||||||
|
+ \ /
|
||||||
|
+ \ /
|
||||||
|
+ p3
|
||||||
|
+/
|
||||||
|
PointF p11 = p1;
|
||||||
|
PointF p13 = p1;
|
||||||
|
PointF p21 = p2;
|
||||||
|
PointF p22 = p2;
|
||||||
|
PointF p32 = p3;
|
||||||
|
PointF p33 = p3;
|
||||||
|
bool p1moved = false;
|
||||||
|
bool p2moved = false;
|
||||||
|
bool p3moved = false;
|
||||||
|
bool side1clipped = intersectClipF(p11, p21, p1moved, p2moved);
|
||||||
|
bool side2clipped = intersectClipF(p22, p32, p2moved, p3moved);
|
||||||
|
bool side3clipped = intersectClipF(p33, p13, p3moved, p1moved);
|
||||||
|
if (!p1moved && !p2moved && !p3moved) {
|
||||||
|
// no moved - no clipping
|
||||||
|
fillTriangleFClipped(p1, p2, p3, colour);
|
||||||
|
} else if (p1moved && !p2moved && !p3moved) {
|
||||||
|
fillTriangleFClipped(p11, p2, p3, colour);
|
||||||
|
fillTriangleFClipped(p3, p13, p11, colour);
|
||||||
|
} else if (!p1moved && p2moved && !p3moved) {
|
||||||
|
fillTriangleFClipped(p22, p3, p1, colour);
|
||||||
|
fillTriangleFClipped(p1, p21, p22, colour);
|
||||||
|
} else if (!p1moved && !p2moved && p3moved) {
|
||||||
|
fillTriangleFClipped(p33, p1, p2, colour);
|
||||||
|
fillTriangleFClipped(p2, p32, p33, colour);
|
||||||
|
} else if (p1moved && p2moved && !p3moved) {
|
||||||
|
if (!side1clipped) {
|
||||||
|
fillTriangleFClipped(p13, p11, p21, colour);
|
||||||
|
fillTriangleFClipped(p21, p22, p13, colour);
|
||||||
|
}
|
||||||
|
fillTriangleFClipped(p22, p3, p13, colour);
|
||||||
|
} else if (!p1moved && p2moved && p3moved) {
|
||||||
|
if (!side2clipped) {
|
||||||
|
fillTriangleFClipped(p21, p22, p32, colour);
|
||||||
|
fillTriangleFClipped(p32, p33, p21, colour);
|
||||||
|
}
|
||||||
|
fillTriangleFClipped(p21, p33, p1, colour);
|
||||||
|
} else if (p1moved && !p2moved && p3moved) {
|
||||||
|
if (!side3clipped) {
|
||||||
|
fillTriangleFClipped(p13, p11, p32, colour);
|
||||||
|
fillTriangleFClipped(p32, p33, p13, colour);
|
||||||
|
}
|
||||||
|
fillTriangleFClipped(p11, p2, p32, colour);
|
||||||
|
} else if (p1moved && p2moved && p3moved) {
|
||||||
|
if (side1clipped) {
|
||||||
|
fillTriangleFClipped(p13, p22, p32, colour);
|
||||||
|
fillTriangleFClipped(p32, p33, p13, colour);
|
||||||
|
} else if (side2clipped) {
|
||||||
|
fillTriangleFClipped(p11, p21, p33, colour);
|
||||||
|
fillTriangleFClipped(p33, p13, p11, colour);
|
||||||
|
} else if (side3clipped) {
|
||||||
|
fillTriangleFClipped(p11, p21, p22, colour);
|
||||||
|
fillTriangleFClipped(p22, p32, p11, colour);
|
||||||
|
} else {
|
||||||
|
fillTriangleFClipped(p13, p11, p21, colour);
|
||||||
|
fillTriangleFClipped(p21, p22, p13, colour);
|
||||||
|
fillTriangleFClipped(p22, p32, p33, colour);
|
||||||
|
fillTriangleFClipped(p33, p13, p22, colour);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// draw filled quad in float coordinates
|
/// draw filled quad in float coordinates
|
||||||
|
|
|
@ -180,16 +180,12 @@ class GLDrawBuf : DrawBuf, GLConfigCallback {
|
||||||
_scene.add(new LineSceneItem(p1, p2, colour));
|
_scene.add(new LineSceneItem(p1, p2, colour));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// draw filled triangle in float coordinates
|
/// draw filled triangle in float coordinates; clipping is already applied
|
||||||
override void fillTriangleF(PointF p1, PointF p2, PointF p3, uint colour) {
|
override protected void fillTriangleFClipped(PointF p1, PointF p2, PointF p3, uint colour) {
|
||||||
assert(_scene !is null);
|
assert(_scene !is null);
|
||||||
//if (!clipLine(_clipRect, p1, p2))
|
|
||||||
// return;
|
|
||||||
// TODO: clipping
|
|
||||||
_scene.add(new TriangleSceneItem(p1, p2, p3, colour));
|
_scene.add(new TriangleSceneItem(p1, p2, p3, colour));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// cleanup resources
|
/// cleanup resources
|
||||||
override void clear() {
|
override void clear() {
|
||||||
if (_framebuffer) {
|
if (_framebuffer) {
|
||||||
|
|
Loading…
Reference in New Issue