Textured rectangles are working (if a bit slow)
This commit is contained in:
parent
e2a370259b
commit
ab80658cd9
@ -13,34 +13,53 @@ func (this *pen) textureRectangle (bounds image.Rectangle) {
|
||||
}
|
||||
|
||||
func (this *pen) textureRectangleOpaque (bounds image.Rectangle) {
|
||||
|
||||
dstBounds := bounds.Intersect(this.image.Bounds())
|
||||
srcBounds := this.texture.rect
|
||||
|
||||
offset := dstBounds.Min.Sub(bounds.Min)
|
||||
|
||||
var pos image.Point
|
||||
|
||||
dstStep := this.image.Stride - bounds.Dx() * 4
|
||||
srcStep := this.texture.stride - srcBounds.Dx() * 4
|
||||
dst := this.image.Pix
|
||||
src := this.texture.pix
|
||||
offset := this.texture.rect.Min.Sub(bounds.Min)
|
||||
|
||||
for pos.Y = dstBounds.Min.Y; pos.Y < dstBounds.Max.Y; pos.Y ++ {
|
||||
for pos.X = dstBounds.Min.X; pos.X < dstBounds.Max.X; pos.X ++ {
|
||||
srcPos := pos.Add(offset)
|
||||
dstIndex := this.image.PixOffset(pos.X, pos.Y)
|
||||
srcIndex := this.texture.PixOffset(srcPos.X, srcPos.Y)
|
||||
dst[dstIndex + 0] = src[srcIndex + 0]
|
||||
dst[dstIndex + 1] = src[srcIndex + 1]
|
||||
dst[dstIndex + 2] = src[srcIndex + 2]
|
||||
dst[dstIndex + 3] = src[srcIndex + 3]
|
||||
}}
|
||||
}
|
||||
|
||||
func (this *pen) textureRectangleTransparent (bounds image.Rectangle) {
|
||||
bounds = bounds.Intersect(this.image.Bounds())
|
||||
dstBounds := bounds.Intersect(this.image.Bounds())
|
||||
var pos image.Point
|
||||
|
||||
for pos.Y = bounds.Min.Y; pos.Y < bounds.Max.Y; pos.Y ++ {
|
||||
for pos.X = bounds.Min.X; pos.X < bounds.Max.X; pos.X ++ {
|
||||
index := this.image.PixOffset(pos.X, pos.Y)
|
||||
dst := this.image.Pix
|
||||
src := this.texture.pix
|
||||
offset := this.texture.rect.Min.Sub(bounds.Min)
|
||||
|
||||
for pos.Y = dstBounds.Min.Y; pos.Y < dstBounds.Max.Y; pos.Y ++ {
|
||||
for pos.X = dstBounds.Min.X; pos.X < dstBounds.Max.X; pos.X ++ {
|
||||
srcPos := pos.Add(offset)
|
||||
dstIndex := this.image.PixOffset(pos.X, pos.Y)
|
||||
srcIndex := this.texture.PixOffset(srcPos.X, srcPos.Y)
|
||||
pixel := xgraphics.BlendBGRA(xgraphics.BGRA {
|
||||
B: this.image.Pix[index + 0],
|
||||
G: this.image.Pix[index + 1],
|
||||
R: this.image.Pix[index + 2],
|
||||
A: this.image.Pix[index + 3],
|
||||
}, c)
|
||||
this.image.Pix[index + 0] = pixel.B
|
||||
this.image.Pix[index + 1] = pixel.G
|
||||
this.image.Pix[index + 2] = pixel.R
|
||||
this.image.Pix[index + 3] = pixel.A
|
||||
B: dst[dstIndex + 0],
|
||||
G: dst[dstIndex + 1],
|
||||
R: dst[dstIndex + 2],
|
||||
A: dst[dstIndex + 3],
|
||||
}, xgraphics.BGRA {
|
||||
B: src[srcIndex + 0],
|
||||
G: src[srcIndex + 1],
|
||||
R: src[srcIndex + 2],
|
||||
A: src[srcIndex + 3],
|
||||
})
|
||||
dst[dstIndex + 0] = pixel.B
|
||||
dst[dstIndex + 1] = pixel.G
|
||||
dst[dstIndex + 2] = pixel.R
|
||||
dst[dstIndex + 3] = pixel.A
|
||||
}}
|
||||
}
|
||||
|
||||
@ -91,7 +110,7 @@ func (this *pen) strokeRectangle (c xgraphics.BGRA, bounds image.Rectangle) {
|
||||
this.fillRectangle(c, bounds)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
top := image.Rect (
|
||||
bounds.Min.X,
|
||||
bounds.Min.Y,
|
||||
@ -122,7 +141,7 @@ func (this *pen) strokeRectangle (c xgraphics.BGRA, bounds image.Rectangle) {
|
||||
// the polygon filling algorithm is adapted from:
|
||||
// https://www.alienryderflex.com/polygon_fill/
|
||||
// (if you write C like that i will disassemble you)
|
||||
|
||||
|
||||
func (this *pen) fillPolygon (c xgraphics.BGRA, points ...image.Point) {
|
||||
if len(points) < 3 { return }
|
||||
|
||||
@ -183,7 +202,7 @@ func (this *pen) fillPolygon (c xgraphics.BGRA, points ...image.Point) {
|
||||
context.fillPolygonHotTransparent()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
type fillingContext struct {
|
||||
@ -207,7 +226,7 @@ func (context *fillingContext) fillPolygonHotOpaque () {
|
||||
// constrain boundaries to image size
|
||||
if left < context.min { left = context.min }
|
||||
if right > context.max { right = context.max }
|
||||
|
||||
|
||||
// fill pixels in between
|
||||
for x := left; x < right; x ++ {
|
||||
index := context.image.PixOffset(x, context.y)
|
||||
@ -232,7 +251,7 @@ func (context *fillingContext) fillPolygonHotTransparent () {
|
||||
// constrain boundaries to image size
|
||||
if left < context.min { left = context.min }
|
||||
if right > context.max { right = context.max }
|
||||
|
||||
|
||||
// fill pixels in between
|
||||
for x := left; x < right; x ++ {
|
||||
index := context.image.PixOffset(x, context.y)
|
||||
|
@ -36,7 +36,7 @@ func NewTextureFrom (source image.Image) *Texture {
|
||||
texture.transparent = true
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
return texture
|
||||
}
|
||||
|
||||
@ -59,7 +59,11 @@ func (this *Texture) Clip (bounds image.Rectangle) canvas.Texture {
|
||||
return &clipped
|
||||
}
|
||||
|
||||
func (this *Texture) pixOffset
|
||||
func (this *Texture) PixOffset (x, y int) int {
|
||||
x = wrap(x, this.rect.Min.X, this.rect.Max.X)
|
||||
y = wrap(y, this.rect.Min.Y, this.rect.Max.Y)
|
||||
return x * 4 + y * this.stride
|
||||
}
|
||||
|
||||
// AssertTexture checks if a given canvas.Texture is a texture from this package.
|
||||
func AssertTexture (unknown canvas.Texture) *Texture {
|
||||
|
Reference in New Issue
Block a user