From 42cd923418e47f70ded868e12637419fe437ca16 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 19 Sep 2021 16:19:40 +0900 Subject: [PATCH] ebiten: Add FillRule Closes #1715 --- examples/vector/main.go | 8 ++++---- image.go | 40 ++++++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/examples/vector/main.go b/examples/vector/main.go index 1b89f8770..2b6e06cc3 100644 --- a/examples/vector/main.go +++ b/examples/vector/main.go @@ -110,7 +110,7 @@ func drawEbitenText(screen *ebiten.Image) { path.LineTo(290, 20) op := &ebiten.DrawTrianglesOptions{ - EvenOdd: true, + FillRule: ebiten.EvenOdd, } vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) for i := range vs { @@ -150,7 +150,7 @@ func drawEbitenLogo(screen *ebiten.Image, x, y int) { path.LineTo(xf+unit, yf+4*unit) op := &ebiten.DrawTrianglesOptions{ - EvenOdd: true, + FillRule: ebiten.EvenOdd, } vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) for i := range vs { @@ -178,7 +178,7 @@ func drawArc(screen *ebiten.Image, count int) { path.Arc(550, 100, 50, float32(theta1), float32(theta2), vector.Clockwise) op := &ebiten.DrawTrianglesOptions{ - EvenOdd: true, + FillRule: ebiten.EvenOdd, } vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) for i := range vs { @@ -221,7 +221,7 @@ func drawWave(screen *ebiten.Image, counter int) { path.LineTo(0, screenHeight) op := &ebiten.DrawTrianglesOptions{ - EvenOdd: true, + FillRule: ebiten.EvenOdd, } vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) for i := range vs { diff --git a/image.go b/image.go index ba8d5adb3..6271d0edd 100644 --- a/image.go +++ b/image.go @@ -253,6 +253,18 @@ const ( AddressRepeat Address = Address(driver.AddressRepeat) ) +// FillRule is the rule whether an overlapped region is rendered with DrawTriangles(Shader). +type FillRule int + +const ( + // FillAll indicates all the triangles are rendered regardless of overlaps. + FillAll FillRule = iota + + // EvenOdd means that triangles are rendered based on the even-odd rule. + // If and only if the number of overlappings is odd, the region is rendered. + EvenOdd +) + // DrawTrianglesOptions represents options for DrawTriangles. type DrawTrianglesOptions struct { // ColorM is a color matrix to draw. @@ -274,18 +286,14 @@ type DrawTrianglesOptions struct { // The default (zero) value is AddressUnsafe. Address Address - // EvenOdd represents whether the even-odd rule is applied or not. + // FillRule indicates the rule how an overlapped region is rendered. // - // If EvenOdd is true, triangles are rendered based on the even-odd rule. If false, triangles are rendered without condition. - // Whether overlapped regions by multiple triangles is rendered or not depends on the number of the overlapping: - // if and only if the number is odd, the region is rendered. - // - // EvenOdd is useful when you want to render a complex polygon. + // The rule EvenOdd is useful when you want to render a complex polygon. // A complex polygon is a non-convex polygon like a concave polygon, a polygon with holes, or a self-intersecting polygon. // See examples/vector for actual usages. // - // The default value is false. - EvenOdd bool + // The default (zero) value is FillAll. + FillRule FillRule } // MaxIndicesNum is the maximum number of indices for DrawTriangles. @@ -364,7 +372,7 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o srcs := [graphics.ShaderImageNum]*mipmap.Mipmap{img.mipmap} - i.mipmap.DrawTriangles(srcs, vs, is, options.ColorM.affineColorM(), mode, filter, address, dstRegion, sr, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, options.EvenOdd, false) + i.mipmap.DrawTriangles(srcs, vs, is, options.ColorM.affineColorM(), mode, filter, address, dstRegion, sr, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, options.FillRule == EvenOdd, false) } // DrawTrianglesShaderOptions represents options for DrawTrianglesShader. @@ -387,18 +395,14 @@ type DrawTrianglesShaderOptions struct { // All the image must be the same size. Images [4]*Image - // EvenOdd represents whether the even-odd rule is applied or not. + // FillRule indicates the rule how an overlapped region is rendered. // - // If EvenOdd is true, triangles are rendered based on the even-odd rule. If false, triangles are rendered without condition. - // Whether overlapped regions by multiple triangles is rendered or not depends on the number of the overlapping: - // if and only if the number is odd, the region is rendered. - // - // EvenOdd is useful when you want to render a complex polygon. + // The rule EvenOdd is useful when you want to render a complex polygon. // A complex polygon is a non-convex polygon like a concave polygon, a polygon with holes, or a self-intersecting polygon. // See examples/vector for actual usages. // - // The default value is false. - EvenOdd bool + // The default (zero) value is FillAll. + FillRule FillRule } func init() { @@ -514,7 +518,7 @@ func (i *Image) DrawTrianglesShader(vertices []Vertex, indices []uint16, shader us := shader.convertUniforms(options.Uniforms) - i.mipmap.DrawTriangles(imgs, vs, is, affine.ColorMIdentity{}, mode, driver.FilterNearest, driver.AddressUnsafe, dstRegion, sr, offsets, shader.shader, us, options.EvenOdd, false) + i.mipmap.DrawTriangles(imgs, vs, is, affine.ColorMIdentity{}, mode, driver.FilterNearest, driver.AddressUnsafe, dstRegion, sr, offsets, shader.shader, us, options.FillRule == EvenOdd, false) } // DrawRectShaderOptions represents options for DrawRectShader.