mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
ebiten: Bug fix: Draw commands with EvenOdd should not be merged
Updates #1684
This commit is contained in:
parent
daa883d799
commit
674802d2f5
@ -2332,7 +2332,7 @@ func TestImageEvenOdd(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the same thing with a little shift. This confirms that the underlying stencil buffer is cleared correctly.
|
// Do the same thing but with a little shift. This confirms that the underlying stencil buffer is cleared correctly.
|
||||||
for i := range vs0 {
|
for i := range vs0 {
|
||||||
vs0[i].DstX++
|
vs0[i].DstX++
|
||||||
vs0[i].DstY++
|
vs0[i].DstY++
|
||||||
@ -2366,4 +2366,42 @@ func TestImageEvenOdd(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do the same thing but with split DrawTriangle calls. This confirms that the even-odd rule is applied for one call.
|
||||||
|
for i := range vs0 {
|
||||||
|
vs0[i].DstX--
|
||||||
|
vs0[i].DstY--
|
||||||
|
}
|
||||||
|
for i := range vs1 {
|
||||||
|
vs1[i].DstX--
|
||||||
|
vs1[i].DstY--
|
||||||
|
}
|
||||||
|
for i := range vs2 {
|
||||||
|
vs2[i].DstX--
|
||||||
|
vs2[i].DstY--
|
||||||
|
}
|
||||||
|
dst.Clear()
|
||||||
|
// Use the first indices set.
|
||||||
|
dst.DrawTriangles(vs0, is0, emptySubImage, op)
|
||||||
|
dst.DrawTriangles(vs1, is0, emptySubImage, op)
|
||||||
|
dst.DrawTriangles(vs2, is0, emptySubImage, op)
|
||||||
|
for j := 0; j < 16; j++ {
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
got := dst.At(i, j)
|
||||||
|
var want color.RGBA
|
||||||
|
switch {
|
||||||
|
case 3 <= i && i < 13 && 3 <= j && j < 13:
|
||||||
|
want = color.RGBA{0, 0, 0xff, 0xff}
|
||||||
|
case 2 <= i && i < 14 && 2 <= j && j < 14:
|
||||||
|
want = color.RGBA{0, 0xff, 0, 0xff}
|
||||||
|
case 1 <= i && i < 15 && 1 <= j && j < 15:
|
||||||
|
want = color.RGBA{0xff, 0, 0, 0xff}
|
||||||
|
default:
|
||||||
|
want = color.RGBA{0, 0, 0, 0}
|
||||||
|
}
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -482,7 +482,7 @@ func (c *drawTrianglesCommand) CanMergeWithDrawTrianglesCommand(dst *Image, srcs
|
|||||||
if c.srcRegion != srcRegion {
|
if c.srcRegion != srcRegion {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if c.evenOdd != evenOdd {
|
if c.evenOdd || evenOdd {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -316,7 +316,6 @@ type Graphics struct {
|
|||||||
screenDrawable ca.MetalDrawable
|
screenDrawable ca.MetalDrawable
|
||||||
|
|
||||||
lastDstTexture mtl.Texture
|
lastDstTexture mtl.Texture
|
||||||
lastStencilUse bool
|
|
||||||
|
|
||||||
vb mtl.Buffer
|
vb mtl.Buffer
|
||||||
ib mtl.Buffer
|
ib mtl.Buffer
|
||||||
@ -345,10 +344,6 @@ const (
|
|||||||
noStencil
|
noStencil
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s stencilMode) useStencil() bool {
|
|
||||||
return s != noStencil
|
|
||||||
}
|
|
||||||
|
|
||||||
var theGraphics Graphics
|
var theGraphics Graphics
|
||||||
|
|
||||||
func Get() *Graphics {
|
func Get() *Graphics {
|
||||||
@ -645,11 +640,13 @@ func (g *Graphics) flushRenderCommandEncoderIfNeeded() {
|
|||||||
g.rce.EndEncoding()
|
g.rce.EndEncoding()
|
||||||
g.rce = mtl.RenderCommandEncoder{}
|
g.rce = mtl.RenderCommandEncoder{}
|
||||||
g.lastDstTexture = mtl.Texture{}
|
g.lastDstTexture = mtl.Texture{}
|
||||||
g.lastStencilUse = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Graphics) draw(rps mtl.RenderPipelineState, dst *Image, dstRegion driver.Region, srcs [graphics.ShaderImageNum]*Image, indexLen int, indexOffset int, uniforms []interface{}, stencilMode stencilMode) error {
|
func (g *Graphics) draw(rps mtl.RenderPipelineState, dst *Image, dstRegion driver.Region, srcs [graphics.ShaderImageNum]*Image, indexLen int, indexOffset int, uniforms []interface{}, stencilMode stencilMode) error {
|
||||||
if g.lastDstTexture != dst.mtlTexture() || g.lastStencilUse != stencilMode.useStencil() {
|
// When prepareing a stencil buffer, flush the current render command encoder
|
||||||
|
// to make sure the stencil buffer is cleared when loading.
|
||||||
|
// TODO: What about clearing the stencil buffer by vertices?
|
||||||
|
if g.lastDstTexture != dst.mtlTexture() || stencilMode == prepareStencil {
|
||||||
g.flushRenderCommandEncoderIfNeeded()
|
g.flushRenderCommandEncoderIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,7 +665,7 @@ func (g *Graphics) draw(rps mtl.RenderPipelineState, dst *Image, dstRegion drive
|
|||||||
rpd.ColorAttachments[0].Texture = t
|
rpd.ColorAttachments[0].Texture = t
|
||||||
rpd.ColorAttachments[0].ClearColor = mtl.ClearColor{}
|
rpd.ColorAttachments[0].ClearColor = mtl.ClearColor{}
|
||||||
|
|
||||||
if stencilMode.useStencil() {
|
if stencilMode == prepareStencil {
|
||||||
dst.ensureStencil()
|
dst.ensureStencil()
|
||||||
rpd.StencilAttachment.LoadAction = mtl.LoadActionClear
|
rpd.StencilAttachment.LoadAction = mtl.LoadActionClear
|
||||||
rpd.StencilAttachment.StoreAction = mtl.StoreActionDontCare
|
rpd.StencilAttachment.StoreAction = mtl.StoreActionDontCare
|
||||||
@ -680,7 +677,6 @@ func (g *Graphics) draw(rps mtl.RenderPipelineState, dst *Image, dstRegion drive
|
|||||||
}
|
}
|
||||||
g.rce = g.cb.MakeRenderCommandEncoder(rpd)
|
g.rce = g.cb.MakeRenderCommandEncoder(rpd)
|
||||||
}
|
}
|
||||||
g.lastStencilUse = stencilMode.useStencil()
|
|
||||||
|
|
||||||
g.rce.SetRenderPipelineState(rps)
|
g.rce.SetRenderPipelineState(rps)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user