mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-23 17:32:02 +01:00
ebiten: add FillRuleFillAll
, FillRuleEvenOdd
, and FillRuleNonZero
This change also deprecates the existing constants. Closes #3006
This commit is contained in:
parent
d37301eeeb
commit
b121468991
@ -72,11 +72,11 @@ type DrawTrianglesOptions struct {
|
||||
|
||||
// FillRule indicates the rule how an overlapped region is rendered.
|
||||
//
|
||||
// The rules NonZero and EvenOdd are useful when you want to render a complex polygon.
|
||||
// The rules FileRuleNonZero and FillRuleEvenOdd are 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 (zero) value is ebiten.FillAll.
|
||||
// The default (zero) value is ebiten.FillRuleFillAll.
|
||||
FillRule ebiten.FillRule
|
||||
|
||||
// AntiAlias indicates whether the rendering uses anti-alias or not.
|
||||
|
@ -141,14 +141,14 @@ func drawEbitenText(screen *ebiten.Image, x, y int, aa bool, line bool) {
|
||||
op := &ebiten.DrawTrianglesOptions{}
|
||||
op.AntiAlias = aa
|
||||
|
||||
// For strokes (AppendVerticesAndIndicesForStroke), FillAll and NonZero work.
|
||||
// For strokes (AppendVerticesAndIndicesForStroke), FillRuleFillAll and FillRuleNonZero work.
|
||||
//
|
||||
// For filling (AppendVerticesAndIndicesForFilling), NonZero and EvenOdd work.
|
||||
// NonZero and EvenOdd differ when rendering a complex polygons with self-intersections and/or holes.
|
||||
// For filling (AppendVerticesAndIndicesForFilling), FillRuleNonZero and FillRuleEvenOdd work.
|
||||
// FillRuleNonZero and FillRuleEvenOdd differ when rendering a complex polygons with self-intersections and/or holes.
|
||||
// See https://en.wikipedia.org/wiki/Nonzero-rule and https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule .
|
||||
//
|
||||
// For simplicity, this example always uses NonZero, whichever strokes or filling is done.
|
||||
op.FillRule = ebiten.NonZero
|
||||
// For simplicity, this example always uses FillRuleNonZero, whichever strokes or filling is done.
|
||||
op.FillRule = ebiten.FillRuleNonZero
|
||||
|
||||
screen.DrawTriangles(vs, is, whiteSubImage, op)
|
||||
}
|
||||
@ -203,7 +203,7 @@ func drawEbitenLogo(screen *ebiten.Image, x, y int, aa bool, line bool) {
|
||||
|
||||
op := &ebiten.DrawTrianglesOptions{}
|
||||
op.AntiAlias = aa
|
||||
op.FillRule = ebiten.NonZero
|
||||
op.FillRule = ebiten.FillRuleNonZero
|
||||
screen.DrawTriangles(vs, is, whiteSubImage, op)
|
||||
}
|
||||
|
||||
@ -245,7 +245,7 @@ func drawArc(screen *ebiten.Image, count int, aa bool, line bool) {
|
||||
|
||||
op := &ebiten.DrawTrianglesOptions{}
|
||||
op.AntiAlias = aa
|
||||
op.FillRule = ebiten.NonZero
|
||||
op.FillRule = ebiten.FillRuleNonZero
|
||||
screen.DrawTriangles(vs, is, whiteSubImage, op)
|
||||
}
|
||||
|
||||
@ -300,7 +300,7 @@ func drawWave(screen *ebiten.Image, counter int, aa bool, line bool) {
|
||||
|
||||
op := &ebiten.DrawTrianglesOptions{}
|
||||
op.AntiAlias = aa
|
||||
op.FillRule = ebiten.NonZero
|
||||
op.FillRule = ebiten.FillRuleNonZero
|
||||
screen.DrawTriangles(vs, is, whiteSubImage, op)
|
||||
}
|
||||
|
||||
|
33
image.go
33
image.go
@ -310,17 +310,36 @@ const (
|
||||
// FillRule is the rule whether an overlapped region is rendered with DrawTriangles(Shader).
|
||||
type FillRule int
|
||||
|
||||
const (
|
||||
// FillRuleFillAll indicates all the triangles are rendered regardless of overlaps.
|
||||
FillRuleFillAll FillRule = FillRule(graphicsdriver.FillRuleFillAll)
|
||||
|
||||
// FillRuleNonZero means that triangles are rendered based on the non-zero rule.
|
||||
// If and only if the number of overlaps is not 0, the region is rendered.
|
||||
FillRuleNonZero FillRule = FillRule(graphicsdriver.FillRuleNonZero)
|
||||
|
||||
// FillRuleEvenOdd means that triangles are rendered based on the even-odd rule.
|
||||
// If and only if the number of overlaps is odd, the region is rendered.
|
||||
FillRuleEvenOdd FillRule = FillRule(graphicsdriver.FillRuleEvenOdd)
|
||||
)
|
||||
|
||||
const (
|
||||
// FillAll indicates all the triangles are rendered regardless of overlaps.
|
||||
FillAll FillRule = FillRule(graphicsdriver.FillRuleFillAll)
|
||||
//
|
||||
// Deprecated: as of v2.8. Use FillRuleFillAll instead.
|
||||
FillAll = FillRuleFillAll
|
||||
|
||||
// NonZero means that triangles are rendered based on the non-zero rule.
|
||||
// If and only if the number of overlaps is not 0, the region is rendered.
|
||||
NonZero FillRule = FillRule(graphicsdriver.FillRuleNonZero)
|
||||
//
|
||||
// Deprecated: as of v2.8. Use FillRuleNonZero instead.
|
||||
NonZero = FillRuleNonZero
|
||||
|
||||
// EvenOdd means that triangles are rendered based on the even-odd rule.
|
||||
// If and only if the number of overlaps is odd, the region is rendered.
|
||||
EvenOdd FillRule = FillRule(graphicsdriver.FillRuleEvenOdd)
|
||||
//
|
||||
// Deprecated: as of v2.8. Use FillRuleEvenOdd instead.
|
||||
EvenOdd = FillRuleEvenOdd
|
||||
)
|
||||
|
||||
// ColorScaleMode is the mode of color scales in vertices.
|
||||
@ -371,11 +390,11 @@ type DrawTrianglesOptions struct {
|
||||
|
||||
// FillRule indicates the rule how an overlapped region is rendered.
|
||||
//
|
||||
// The rules NonZero and EvenOdd are useful when you want to render a complex polygon.
|
||||
// The rules FillRuleNonZero and FillRuleEvenOdd are 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 (zero) value is FillAll.
|
||||
// The default (zero) value is FillRuleFillAll.
|
||||
FillRule FillRule
|
||||
|
||||
// AntiAlias indicates whether the rendering uses anti-alias or not.
|
||||
@ -547,11 +566,11 @@ type DrawTrianglesShaderOptions struct {
|
||||
|
||||
// FillRule indicates the rule how an overlapped region is rendered.
|
||||
//
|
||||
// The rules NonZero and EvenOdd are useful when you want to render a complex polygon.
|
||||
// The rules FillRuleNonZero and FillRuleEvenOdd are 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 (zero) value is FillAll.
|
||||
// The default (zero) value is FillRuleFillAll.
|
||||
FillRule FillRule
|
||||
|
||||
// AntiAlias indicates whether the rendering uses anti-alias or not.
|
||||
|
@ -2696,7 +2696,7 @@ func TestImageEvenOdd(t *testing.T) {
|
||||
// Draw all the vertices once. The even-odd rule is applied for all the vertices once.
|
||||
dst := ebiten.NewImage(16, 16)
|
||||
op := &ebiten.DrawTrianglesOptions{
|
||||
FillRule: ebiten.EvenOdd,
|
||||
FillRule: ebiten.FillRuleEvenOdd,
|
||||
}
|
||||
dst.DrawTriangles(append(append(vs0, vs1...), vs2...), append(append(is0, is1...), is2...), emptySubImage, op)
|
||||
for j := 0; j < 16; j++ {
|
||||
@ -2794,15 +2794,15 @@ func TestImageEvenOdd(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestImageFillRule(t *testing.T) {
|
||||
for _, fillRule := range []ebiten.FillRule{ebiten.FillAll, ebiten.NonZero, ebiten.EvenOdd} {
|
||||
for _, fillRule := range []ebiten.FillRule{ebiten.FillRuleFillAll, ebiten.FillRuleNonZero, ebiten.FillRuleEvenOdd} {
|
||||
fillRule := fillRule
|
||||
var name string
|
||||
switch fillRule {
|
||||
case ebiten.FillAll:
|
||||
case ebiten.FillRuleFillAll:
|
||||
name = "FillAll"
|
||||
case ebiten.NonZero:
|
||||
case ebiten.FillRuleNonZero:
|
||||
name = "NonZero"
|
||||
case ebiten.EvenOdd:
|
||||
case ebiten.FillRuleEvenOdd:
|
||||
name = "EvenOdd"
|
||||
}
|
||||
t.Run(name, func(t *testing.T) {
|
||||
@ -2885,11 +2885,11 @@ func TestImageFillRule(t *testing.T) {
|
||||
var want color.RGBA
|
||||
switch {
|
||||
case 2 <= i && i < 7 && 2 <= j && j < 7:
|
||||
if fillRule != ebiten.EvenOdd {
|
||||
if fillRule != ebiten.FillRuleEvenOdd {
|
||||
want = color.RGBA{G: 0xff, A: 0xff}
|
||||
}
|
||||
case 9 <= i && i < 14 && 9 <= j && j < 14:
|
||||
if fillRule == ebiten.FillAll {
|
||||
if fillRule == ebiten.FillRuleFillAll {
|
||||
want = color.RGBA{B: 0xff, A: 0xff}
|
||||
}
|
||||
case 1 <= i && i < 15 && 1 <= j && j < 15:
|
||||
@ -2922,11 +2922,11 @@ func TestImageFillRule(t *testing.T) {
|
||||
var want color.RGBA
|
||||
switch {
|
||||
case 3 <= i && i < 8 && 3 <= j && j < 8:
|
||||
if fillRule != ebiten.EvenOdd {
|
||||
if fillRule != ebiten.FillRuleEvenOdd {
|
||||
want = color.RGBA{G: 0xff, A: 0xff}
|
||||
}
|
||||
case 10 <= i && i < 15 && 10 <= j && j < 15:
|
||||
if fillRule == ebiten.FillAll {
|
||||
if fillRule == ebiten.FillRuleFillAll {
|
||||
want = color.RGBA{B: 0xff, A: 0xff}
|
||||
}
|
||||
case 2 <= i && i < 16 && 2 <= j && j < 16:
|
||||
@ -3726,7 +3726,7 @@ func TestImageTooManyConstantBuffersInDirectX(t *testing.T) {
|
||||
dst0 := ebiten.NewImage(16, 16)
|
||||
dst1 := ebiten.NewImage(16, 16)
|
||||
op := &ebiten.DrawTrianglesOptions{
|
||||
FillRule: ebiten.EvenOdd,
|
||||
FillRule: ebiten.FillRuleEvenOdd,
|
||||
}
|
||||
for i := 0; i < 100; i++ {
|
||||
dst0.DrawTriangles(vs, is, src, op)
|
||||
|
4
internal/processtest/testdata/issue2138.go
vendored
4
internal/processtest/testdata/issue2138.go
vendored
@ -59,7 +59,7 @@ func (g *Game) Update() error {
|
||||
}
|
||||
|
||||
func (g *Game) Draw(screen *ebiten.Image) {
|
||||
// Before the fix, some complex renderings with EvenOdd might cause a DirectX error like this (#2138):
|
||||
// Before the fix, some complex renderings with FillRuleEvenOdd might cause a DirectX error like this (#2138):
|
||||
// panic: directx: IDXGISwapChain4::Present failed: HRESULT(2289696773)
|
||||
|
||||
screen.DrawImage(debugCircleImage, nil)
|
||||
@ -74,7 +74,7 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
||||
p.Arc(100, 100, 6, 0, 2*math.Pi, vector.Clockwise)
|
||||
filling, indicies := p.AppendVerticesAndIndicesForFilling(nil, nil)
|
||||
screen.DrawTriangles(filling, indicies, whiteTextureImage, &ebiten.DrawTrianglesOptions{
|
||||
FillRule: ebiten.EvenOdd,
|
||||
FillRule: ebiten.FillRuleEvenOdd,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -396,7 +396,7 @@ func (p *Path) Close() {
|
||||
//
|
||||
// The returned vertice's SrcX and SrcY are 0, and ColorR, ColorG, ColorB, and ColorA are 1.
|
||||
//
|
||||
// The returned values are intended to be passed to DrawTriangles or DrawTrianglesShader with the fill rule NonZero or EvenOdd
|
||||
// The returned values are intended to be passed to DrawTriangles or DrawTrianglesShader with FileRuleNonZero or FillRuleEvenOdd
|
||||
// in order to render a complex polygon like a concave polygon, a polygon with holes, or a self-intersecting polygon.
|
||||
//
|
||||
// The returned vertices and indices should be rendered with a solid (non-transparent) color with the default Blend (source-over).
|
||||
@ -480,7 +480,7 @@ type StrokeOptions struct {
|
||||
// The returned vertice's SrcX and SrcY are 0, and ColorR, ColorG, ColorB, and ColorA are 1.
|
||||
//
|
||||
// The returned values are intended to be passed to DrawTriangles or DrawTrianglesShader with a solid (non-transparent) color
|
||||
// with FillAll or NonZero fill rule, not EvenOdd fill rule.
|
||||
// with FillRuleFillAll or FillRuleNonZero, not FileRuleEvenOdd.
|
||||
func (p *Path) AppendVerticesAndIndicesForStroke(vertices []ebiten.Vertex, indices []uint16, op *StrokeOptions) ([]ebiten.Vertex, []uint16) {
|
||||
if op == nil {
|
||||
return vertices, indices
|
||||
@ -536,7 +536,7 @@ func (p *Path) AppendVerticesAndIndicesForStroke(vertices []ebiten.Vertex, indic
|
||||
ColorA: 1,
|
||||
})
|
||||
}
|
||||
// All the triangles are rendered in clockwise order to enable NonZero filling rule (#2833).
|
||||
// All the triangles are rendered in clockwise order to enable FillRuleNonZero (#2833).
|
||||
indices = append(indices, idx, idx+1, idx+2, idx+1, idx+3, idx+2)
|
||||
|
||||
// Add line joints.
|
||||
|
Loading…
Reference in New Issue
Block a user