mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
parent
bb6430d3ba
commit
6cdabf09d1
12
image.go
12
image.go
@ -587,6 +587,9 @@ var _ [len(DrawTrianglesShaderOptions{}.Images) - graphics.ShaderImageCount]stru
|
||||
//
|
||||
// If a specified uniform variable's length or type doesn't match with an expected one, DrawTrianglesShader panics.
|
||||
//
|
||||
// Even if a result is an invalid color as a premultiplied-alpha color, i.e. an alpha value exceeds other color values,
|
||||
// the value is kept and is not clamped.
|
||||
//
|
||||
// When the image i is disposed, DrawTrianglesShader does nothing.
|
||||
func (i *Image) DrawTrianglesShader(vertices []Vertex, indices []uint16, shader *Shader, options *DrawTrianglesShaderOptions) {
|
||||
i.copyCheck()
|
||||
@ -742,6 +745,9 @@ var _ [len(DrawRectShaderOptions{}.Images)]struct{} = [graphics.ShaderImageCount
|
||||
// If no source images are specified, imageSrc0Size returns a valid size only when the unit is pixels,
|
||||
// but always returns 0 when the unit is texels (default).
|
||||
//
|
||||
// Even if a result is an invalid color as a premultiplied-alpha color, i.e. an alpha value exceeds other color values,
|
||||
// the value is kept and is not clamped.
|
||||
//
|
||||
// When the image i is disposed, DrawRectShader does nothing.
|
||||
func (i *Image) DrawRectShader(width, height int, shader *Shader, options *DrawRectShaderOptions) {
|
||||
i.copyCheck()
|
||||
@ -954,6 +960,9 @@ func (i *Image) at(x, y int) (r, g, b, a byte) {
|
||||
//
|
||||
// Set implements the standard draw.Image's Set.
|
||||
//
|
||||
// Even if a result is an invalid color as a premultiplied-alpha color, i.e. an alpha value exceeds other color values,
|
||||
// the value is kept and is not clamped.
|
||||
//
|
||||
// If the image is disposed, Set does nothing.
|
||||
func (i *Image) Set(x, y int, clr color.Color) {
|
||||
i.copyCheck()
|
||||
@ -1028,6 +1037,9 @@ func (i *Image) Deallocate() {
|
||||
//
|
||||
// WritePixels also works on a sub-image.
|
||||
//
|
||||
// Even if a result is an invalid color as a premultiplied-alpha color, i.e. an alpha value exceeds other color values,
|
||||
// the value is kept and is not clamped.
|
||||
//
|
||||
// When the image is disposed, WritePixels does nothing.
|
||||
func (i *Image) WritePixels(pixels []byte) {
|
||||
i.copyCheck()
|
||||
|
@ -4582,3 +4582,44 @@ func TestImageDrawImageAfterDeallocation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Issue #2798
|
||||
func TestImageInvalidPremultipliedAlphaColor(t *testing.T) {
|
||||
// This test checks the rendering result when Set and WritePixels use an invalid premultiplied alpha color.
|
||||
// The result values are kept and not clamped.
|
||||
|
||||
const (
|
||||
w = 16
|
||||
h = 16
|
||||
)
|
||||
|
||||
dst := ebiten.NewImage(w, h)
|
||||
dst.Set(0, 0, color.RGBA{R: 0xff, G: 0xc0, B: 0x80, A: 0x40})
|
||||
dst.Set(0, 1, color.RGBA{R: 0xff, G: 0xc0, B: 0x80, A: 0x00})
|
||||
if got, want := dst.At(0, 0).(color.RGBA), (color.RGBA{R: 0xff, G: 0xc0, B: 0x80, A: 0x40}); got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
}
|
||||
if got, want := dst.At(0, 1).(color.RGBA), (color.RGBA{R: 0xff, G: 0xc0, B: 0x80, A: 0x00}); got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
}
|
||||
|
||||
pix := make([]byte, 4*w*h)
|
||||
for j := 0; j < h; j++ {
|
||||
for i := 0; i < w; i++ {
|
||||
pix[4*(j*16+i)] = byte(i)
|
||||
pix[4*(j*16+i)+1] = byte(j)
|
||||
pix[4*(j*16+i)+2] = 0x80
|
||||
pix[4*(j*16+i)+3] = byte(i - j)
|
||||
}
|
||||
}
|
||||
dst.WritePixels(pix)
|
||||
for j := 0; j < h; j++ {
|
||||
for i := 0; i < w; i++ {
|
||||
got := dst.At(i, j)
|
||||
want := color.RGBA{R: byte(i), G: byte(j), B: 0x80, A: byte(i - j)}
|
||||
if got != want {
|
||||
t.Errorf("At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2429,3 +2429,61 @@ func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Issue #2798
|
||||
func TestShaderInvalidPremultipliedAlphaColor(t *testing.T) {
|
||||
// This test checks the rendering result when the shader returns an invalid premultiplied alpha color.
|
||||
// The result values are kept and not clamped.
|
||||
|
||||
const w, h = 16, 16
|
||||
|
||||
dst := ebiten.NewImage(w, h)
|
||||
s, err := ebiten.NewShader([]byte(`//kage:unit pixels
|
||||
|
||||
package main
|
||||
|
||||
func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
|
||||
return vec4(1, 0.75, 0.5, 0.25)
|
||||
}
|
||||
`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dst.DrawRectShader(w, h, s, nil)
|
||||
|
||||
for j := 0; j < h; j++ {
|
||||
for i := 0; i < w; i++ {
|
||||
got := dst.At(i, j).(color.RGBA)
|
||||
want := color.RGBA{R: 0xff, G: 0xc0, B: 0x80, A: 0x40}
|
||||
if !sameColors(got, want, 2) {
|
||||
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dst.Clear()
|
||||
s, err = ebiten.NewShader([]byte(`//kage:unit pixels
|
||||
|
||||
package main
|
||||
|
||||
func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
|
||||
return vec4(1, 0.75, 0.5, 0)
|
||||
}
|
||||
`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dst.DrawRectShader(w, h, s, nil)
|
||||
|
||||
for j := 0; j < h; j++ {
|
||||
for i := 0; i < w; i++ {
|
||||
got := dst.At(i, j).(color.RGBA)
|
||||
want := color.RGBA{R: 0xff, G: 0xc0, B: 0x80, A: 0}
|
||||
if !sameColors(got, want, 2) {
|
||||
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user