mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
ebiten: allow different-size source images at DrawTrianglesShader (pixel mode)
Updates #1870
This commit is contained in:
parent
e1b77fefae
commit
101372a8c3
19
image.go
19
image.go
@ -575,8 +575,9 @@ var _ [len(DrawTrianglesShaderOptions{}.Images) - graphics.ShaderImageCount]stru
|
||||
//
|
||||
// For the details about the shader, see https://ebitengine.org/en/documents/shader.html.
|
||||
//
|
||||
// When one of the specified image is non-nil and its size is different from (width, height), DrawTrianglesShader panics.
|
||||
// When one of the specified image is non-nil and is disposed, DrawTrianglesShader panics.
|
||||
// If the shader unit is texels, one of the specified image is non-nil and its size is different from (width, height),
|
||||
// DrawTrianglesShader panics.
|
||||
// If one of the specified image is non-nil and is disposed, DrawTrianglesShader panics.
|
||||
//
|
||||
// If len(vertices) is more than MaxVerticesCount, the exceeding part is ignored.
|
||||
//
|
||||
@ -653,12 +654,14 @@ func (i *Image) DrawTrianglesShader(vertices []Vertex, indices []uint16, shader
|
||||
if img.isDisposed() {
|
||||
panic("ebiten: the given image to DrawTrianglesShader must not be disposed")
|
||||
}
|
||||
if i == 0 {
|
||||
imgSize = img.Bounds().Size()
|
||||
} else {
|
||||
// TODO: Check imgw > 0 && imgh > 0
|
||||
if img.Bounds().Size() != imgSize {
|
||||
panic("ebiten: all the source images must be the same size with the rectangle")
|
||||
if shader.unit == shaderir.Texels {
|
||||
if i == 0 {
|
||||
imgSize = img.Bounds().Size()
|
||||
} else {
|
||||
// TODO: Check imgw > 0 && imgh > 0
|
||||
if img.Bounds().Size() != imgSize {
|
||||
panic("ebiten: all the source images must be the same size with the rectangle")
|
||||
}
|
||||
}
|
||||
}
|
||||
imgs[i] = img.image
|
||||
|
110
shader_test.go
110
shader_test.go
@ -2136,3 +2136,113 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestShaderDifferentSourceSizes(t *testing.T) {
|
||||
src0 := ebiten.NewImageWithOptions(image.Rect(0, 0, 20, 4000), &ebiten.NewImageOptions{
|
||||
Unmanaged: true,
|
||||
}).SubImage(image.Rect(4, 1025, 7, 1029)).(*ebiten.Image) // 3x4
|
||||
defer src0.Dispose()
|
||||
|
||||
src1 := ebiten.NewImageWithOptions(image.Rect(0, 0, 4000, 20), &ebiten.NewImageOptions{
|
||||
Unmanaged: true,
|
||||
}).SubImage(image.Rect(2047, 7, 2049, 10)).(*ebiten.Image) // 2x3
|
||||
defer src1.Dispose()
|
||||
|
||||
src0.Fill(color.RGBA{0x10, 0x20, 0x30, 0xff})
|
||||
src1.Fill(color.RGBA{0x30, 0x20, 0x10, 0xff})
|
||||
|
||||
for _, unit := range []string{"texels", "pixels"} {
|
||||
unit := unit
|
||||
t.Run(fmt.Sprintf("unit %s", unit), func(t *testing.T) {
|
||||
if unit == "texels" {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("DrawTrianglesShader must panic with different sizes but not (unit=%s)", unit)
|
||||
}
|
||||
}()
|
||||
}
|
||||
shader, err := ebiten.NewShader([]byte(fmt.Sprintf(`//kage:unit %s
|
||||
|
||||
package main
|
||||
|
||||
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
return imageSrc0At(texCoord) + imageSrc1At(texCoord)
|
||||
}
|
||||
`, unit)))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer shader.Dispose()
|
||||
|
||||
dst := ebiten.NewImage(3, 4)
|
||||
defer dst.Dispose()
|
||||
|
||||
op := &ebiten.DrawTrianglesShaderOptions{}
|
||||
op.Images[0] = src0
|
||||
op.Images[1] = src1
|
||||
vs := []ebiten.Vertex{
|
||||
{
|
||||
DstX: 0,
|
||||
DstY: 0,
|
||||
SrcX: 4,
|
||||
SrcY: 1025,
|
||||
ColorR: 1,
|
||||
ColorG: 1,
|
||||
ColorB: 1,
|
||||
ColorA: 1,
|
||||
},
|
||||
{
|
||||
DstX: 3,
|
||||
DstY: 0,
|
||||
SrcX: 7,
|
||||
SrcY: 1025,
|
||||
ColorR: 1,
|
||||
ColorG: 1,
|
||||
ColorB: 1,
|
||||
ColorA: 1,
|
||||
},
|
||||
{
|
||||
DstX: 0,
|
||||
DstY: 4,
|
||||
SrcX: 4,
|
||||
SrcY: 1029,
|
||||
ColorR: 1,
|
||||
ColorG: 1,
|
||||
ColorB: 1,
|
||||
ColorA: 1,
|
||||
},
|
||||
{
|
||||
DstX: 3,
|
||||
DstY: 4,
|
||||
SrcX: 7,
|
||||
SrcY: 1029,
|
||||
ColorR: 1,
|
||||
ColorG: 1,
|
||||
ColorB: 1,
|
||||
ColorA: 1,
|
||||
},
|
||||
}
|
||||
is := []uint16{0, 1, 2, 1, 2, 3}
|
||||
dst.DrawTrianglesShader(vs, is, shader, op)
|
||||
|
||||
if unit == "texel" {
|
||||
t.Fatal("not reached")
|
||||
}
|
||||
|
||||
for j := 0; j < 4; j++ {
|
||||
for i := 0; i < 3; i++ {
|
||||
got := dst.At(i, j).(color.RGBA)
|
||||
var want color.RGBA
|
||||
if i < 2 && j < 3 {
|
||||
want = color.RGBA{0x40, 0x40, 0x40, 0xff}
|
||||
} else {
|
||||
want = color.RGBA{0x10, 0x20, 0x30, 0xff}
|
||||
}
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user