ebiten: Add FillRule

Closes #1715
This commit is contained in:
Hajime Hoshi 2021-09-19 16:19:40 +09:00
parent 8ed55ef42d
commit 42cd923418
2 changed files with 26 additions and 22 deletions

View File

@ -110,7 +110,7 @@ func drawEbitenText(screen *ebiten.Image) {
path.LineTo(290, 20) path.LineTo(290, 20)
op := &ebiten.DrawTrianglesOptions{ op := &ebiten.DrawTrianglesOptions{
EvenOdd: true, FillRule: ebiten.EvenOdd,
} }
vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil)
for i := range vs { for i := range vs {
@ -150,7 +150,7 @@ func drawEbitenLogo(screen *ebiten.Image, x, y int) {
path.LineTo(xf+unit, yf+4*unit) path.LineTo(xf+unit, yf+4*unit)
op := &ebiten.DrawTrianglesOptions{ op := &ebiten.DrawTrianglesOptions{
EvenOdd: true, FillRule: ebiten.EvenOdd,
} }
vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil)
for i := range vs { 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) path.Arc(550, 100, 50, float32(theta1), float32(theta2), vector.Clockwise)
op := &ebiten.DrawTrianglesOptions{ op := &ebiten.DrawTrianglesOptions{
EvenOdd: true, FillRule: ebiten.EvenOdd,
} }
vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil)
for i := range vs { for i := range vs {
@ -221,7 +221,7 @@ func drawWave(screen *ebiten.Image, counter int) {
path.LineTo(0, screenHeight) path.LineTo(0, screenHeight)
op := &ebiten.DrawTrianglesOptions{ op := &ebiten.DrawTrianglesOptions{
EvenOdd: true, FillRule: ebiten.EvenOdd,
} }
vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil)
for i := range vs { for i := range vs {

View File

@ -253,6 +253,18 @@ const (
AddressRepeat Address = Address(driver.AddressRepeat) 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. // DrawTrianglesOptions represents options for DrawTriangles.
type DrawTrianglesOptions struct { type DrawTrianglesOptions struct {
// ColorM is a color matrix to draw. // ColorM is a color matrix to draw.
@ -274,18 +286,14 @@ type DrawTrianglesOptions struct {
// The default (zero) value is AddressUnsafe. // The default (zero) value is AddressUnsafe.
Address Address 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. // The rule EvenOdd is useful when you want to render a complex polygon.
// 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.
// A complex polygon is a non-convex polygon like a concave polygon, a polygon with holes, or a self-intersecting 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. // See examples/vector for actual usages.
// //
// The default value is false. // The default (zero) value is FillAll.
EvenOdd bool FillRule FillRule
} }
// MaxIndicesNum is the maximum number of indices for DrawTriangles. // 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} 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. // DrawTrianglesShaderOptions represents options for DrawTrianglesShader.
@ -387,18 +395,14 @@ type DrawTrianglesShaderOptions struct {
// All the image must be the same size. // All the image must be the same size.
Images [4]*Image 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. // The rule EvenOdd is useful when you want to render a complex polygon.
// 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.
// A complex polygon is a non-convex polygon like a concave polygon, a polygon with holes, or a self-intersecting 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. // See examples/vector for actual usages.
// //
// The default value is false. // The default (zero) value is FillAll.
EvenOdd bool FillRule FillRule
} }
func init() { func init() {
@ -514,7 +518,7 @@ func (i *Image) DrawTrianglesShader(vertices []Vertex, indices []uint16, shader
us := shader.convertUniforms(options.Uniforms) 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. // DrawRectShaderOptions represents options for DrawRectShader.