mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
ebiten: Allow SubImage at DrawRectShader
This commit is contained in:
parent
f287fada13
commit
41564533f9
54
image.go
54
image.go
@ -274,26 +274,23 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error {
|
|||||||
vs := graphics.QuadVertices(sx0, sy0, sx1, sy1, a, b, c, d, tx, ty, 1, 1, 1, 1, filter == driver.FilterScreen)
|
vs := graphics.QuadVertices(sx0, sy0, sx1, sy1, a, b, c, d, tx, ty, 1, 1, 1, 1, filter == driver.FilterScreen)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
|
|
||||||
var sr driver.Region
|
|
||||||
// Pass the source region only when the shader is used, since this affects the condition of merging graphics
|
|
||||||
// commands (#1293).
|
|
||||||
if options.Shader != nil {
|
|
||||||
sr = driver.Region{
|
|
||||||
X: float32(bounds.Min.X),
|
|
||||||
Y: float32(bounds.Min.Y),
|
|
||||||
Width: float32(bounds.Dx()),
|
|
||||||
Height: float32(bounds.Dy()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
srcs := [graphics.ShaderImageNum]*mipmap.Mipmap{img.mipmap}
|
srcs := [graphics.ShaderImageNum]*mipmap.Mipmap{img.mipmap}
|
||||||
if options.Shader == nil {
|
if options.Shader == nil {
|
||||||
i.mipmap.DrawTriangles(srcs, vs, is, options.ColorM.impl, mode, filter, driver.AddressUnsafe, sr, nil, nil, canSkipMipmap(options.GeoM, filter))
|
i.mipmap.DrawTriangles(srcs, vs, is, options.ColorM.impl, mode, filter, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, canSkipMipmap(options.GeoM, filter))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pass the source region only when the shader is used, since this affects the condition of merging graphics
|
||||||
|
// commands (#1293).
|
||||||
|
sr := driver.Region{
|
||||||
|
X: float32(bounds.Min.X),
|
||||||
|
Y: float32(bounds.Min.Y),
|
||||||
|
Width: float32(bounds.Dx()),
|
||||||
|
Height: float32(bounds.Dy()),
|
||||||
|
}
|
||||||
|
|
||||||
us := options.Shader.convertUniforms(options.Uniforms)
|
us := options.Shader.convertUniforms(options.Uniforms)
|
||||||
i.mipmap.DrawTriangles(srcs, vs, is, nil, mode, filter, driver.AddressUnsafe, sr, options.Shader.shader, us, canSkipMipmap(options.GeoM, filter))
|
i.mipmap.DrawTriangles(srcs, vs, is, nil, mode, filter, driver.AddressUnsafe, sr, [graphics.ShaderImageNum - 1][2]float32{}, options.Shader.shader, us, canSkipMipmap(options.GeoM, filter))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,12 +486,12 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o
|
|||||||
}
|
}
|
||||||
|
|
||||||
if options.Shader == nil {
|
if options.Shader == nil {
|
||||||
i.mipmap.DrawTriangles(srcs, vs, is, options.ColorM.impl, mode, filter, driver.Address(options.Address), sr, nil, nil, false)
|
i.mipmap.DrawTriangles(srcs, vs, is, options.ColorM.impl, mode, filter, driver.Address(options.Address), sr, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
us := options.Shader.convertUniforms(options.Uniforms)
|
us := options.Shader.convertUniforms(options.Uniforms)
|
||||||
i.mipmap.DrawTriangles(srcs, vs, is, nil, mode, driver.FilterNearest, driver.AddressUnsafe, sr, options.Shader.shader, us, false)
|
i.mipmap.DrawTriangles(srcs, vs, is, nil, mode, driver.FilterNearest, driver.AddressUnsafe, sr, [graphics.ShaderImageNum - 1][2]float32{}, options.Shader.shader, us, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DrawRectShaderOptions represents options for DrawRectShader
|
// DrawRectShaderOptions represents options for DrawRectShader
|
||||||
@ -557,18 +554,21 @@ func (i *Image) DrawRectShader(width, height int, shader *Shader, options *DrawR
|
|||||||
if img.isDisposed() {
|
if img.isDisposed() {
|
||||||
panic("ebiten: the given image to DrawRectShader must not be disposed")
|
panic("ebiten: the given image to DrawRectShader must not be disposed")
|
||||||
}
|
}
|
||||||
if img.isSubImage() {
|
|
||||||
// TODO: Implement this.
|
|
||||||
panic("ebiten: rendering a sub-image is not implemented (DrawRectShader)")
|
|
||||||
}
|
|
||||||
if w, h := img.Size(); width != w || height != h {
|
if w, h := img.Size(); width != w || height != h {
|
||||||
panic("ebiten: all the source images must be the same size with the rectangle")
|
panic("ebiten: all the source images must be the same size with the rectangle")
|
||||||
}
|
}
|
||||||
imgs[i] = img.mipmap
|
imgs[i] = img.mipmap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sx, sy := float32(0), float32(0)
|
||||||
|
if options.Images[0] != nil {
|
||||||
|
b := options.Images[0].Bounds()
|
||||||
|
sx = float32(b.Min.X)
|
||||||
|
sy = float32(b.Min.Y)
|
||||||
|
}
|
||||||
|
|
||||||
a, b, c, d, tx, ty := options.GeoM.elements32()
|
a, b, c, d, tx, ty := options.GeoM.elements32()
|
||||||
vs := graphics.QuadVertices(0, 0, float32(width), float32(height), a, b, c, d, tx, ty, 1, 1, 1, 1, false)
|
vs := graphics.QuadVertices(sx, sy, sx+float32(width), sy+float32(height), a, b, c, d, tx, ty, 1, 1, 1, 1, false)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
|
|
||||||
var sr driver.Region
|
var sr driver.Region
|
||||||
@ -582,8 +582,18 @@ func (i *Image) DrawRectShader(width, height int, shader *Shader, options *DrawR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var offsets [graphics.ShaderImageNum - 1][2]float32
|
||||||
|
for i, img := range options.Images[1:] {
|
||||||
|
if img == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
b := img.Bounds()
|
||||||
|
offsets[i][0] = -sx + float32(b.Min.X)
|
||||||
|
offsets[i][1] = -sy + float32(b.Min.Y)
|
||||||
|
}
|
||||||
|
|
||||||
us := shader.convertUniforms(options.Uniforms)
|
us := shader.convertUniforms(options.Uniforms)
|
||||||
i.mipmap.DrawTriangles(imgs, vs, is, nil, mode, driver.FilterNearest, driver.AddressUnsafe, sr, shader.shader, us, canSkipMipmap(options.GeoM, driver.FilterNearest))
|
i.mipmap.DrawTriangles(imgs, vs, is, nil, mode, driver.FilterNearest, driver.AddressUnsafe, sr, offsets, shader.shader, us, canSkipMipmap(options.GeoM, driver.FilterNearest))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubImage returns an image representing the portion of the image p visible through r.
|
// SubImage returns an image representing the portion of the image p visible through r.
|
||||||
|
@ -248,7 +248,7 @@ func (i *Image) replacePendingPixels(pix []byte, x, y, width, height int) {
|
|||||||
// DrawTriangles draws the src image with the given vertices.
|
// DrawTriangles draws the src image with the given vertices.
|
||||||
//
|
//
|
||||||
// Copying vertices and indices is the caller's responsibility.
|
// Copying vertices and indices is the caller's responsibility.
|
||||||
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}) {
|
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms []interface{}) {
|
||||||
for _, src := range srcs {
|
for _, src := range srcs {
|
||||||
if i == src {
|
if i == src {
|
||||||
panic("buffered: Image.DrawTriangles: source images must be different from the receiver")
|
panic("buffered: Image.DrawTriangles: source images must be different from the receiver")
|
||||||
@ -258,7 +258,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
|||||||
if maybeCanAddDelayedCommand() {
|
if maybeCanAddDelayedCommand() {
|
||||||
if tryAddDelayedCommand(func() error {
|
if tryAddDelayedCommand(func() error {
|
||||||
// Arguments are not copied. Copying is the caller's responsibility.
|
// Arguments are not copied. Copying is the caller's responsibility.
|
||||||
i.DrawTriangles(srcs, vertices, indices, colorm, mode, filter, address, sourceRegion, shader, uniforms)
|
i.DrawTriangles(srcs, vertices, indices, colorm, mode, filter, address, sourceRegion, subimageOffsets, shader, uniforms)
|
||||||
return nil
|
return nil
|
||||||
}) {
|
}) {
|
||||||
return
|
return
|
||||||
@ -286,7 +286,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
|||||||
imgs[i] = img.img
|
imgs[i] = img.img
|
||||||
}
|
}
|
||||||
|
|
||||||
i.img.DrawTriangles(imgs, vertices, indices, colorm, mode, filter, address, sourceRegion, s, uniforms)
|
i.img.DrawTriangles(imgs, vertices, indices, colorm, mode, filter, address, sourceRegion, subimageOffsets, s, uniforms)
|
||||||
i.invalidatePendingPixels()
|
i.invalidatePendingPixels()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ func (m *Mipmap) Pixels(x, y, width, height int) ([]byte, error) {
|
|||||||
return m.orig.Pixels(x, y, width, height)
|
return m.orig.Pixels(x, y, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderImageNum]*Mipmap, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}, canSkipMipmap bool) {
|
func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderImageNum]*Mipmap, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms []interface{}, canSkipMipmap bool) {
|
||||||
if len(indices) == 0 {
|
if len(indices) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -176,7 +176,7 @@ func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderImageNum]*Mipmap, vertices [
|
|||||||
imgs[i] = src.orig
|
imgs[i] = src.orig
|
||||||
}
|
}
|
||||||
|
|
||||||
m.orig.DrawTriangles(imgs, vertices, indices, colorm, mode, filter, address, sourceRegion, s, uniforms)
|
m.orig.DrawTriangles(imgs, vertices, indices, colorm, mode, filter, address, sourceRegion, subimageOffsets, s, uniforms)
|
||||||
m.disposeMipmaps()
|
m.disposeMipmaps()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +238,7 @@ func (m *Mipmap) level(level int) *buffered.Image {
|
|||||||
}
|
}
|
||||||
s := buffered.NewImage(w2, h2)
|
s := buffered.NewImage(w2, h2)
|
||||||
s.SetVolatile(m.volatile)
|
s.SetVolatile(m.volatile)
|
||||||
s.DrawTriangles([graphics.ShaderImageNum]*buffered.Image{src}, vs, is, nil, driver.CompositeModeCopy, filter, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
s.DrawTriangles([graphics.ShaderImageNum]*buffered.Image{src}, vs, is, nil, driver.CompositeModeCopy, filter, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil)
|
||||||
m.imgs[level] = s
|
m.imgs[level] = s
|
||||||
|
|
||||||
return m.imgs[level]
|
return m.imgs[level]
|
||||||
|
@ -306,7 +306,7 @@ func (i *Image) processSrc(src *Image) {
|
|||||||
// 5: Color G
|
// 5: Color G
|
||||||
// 6: Color B
|
// 6: Color B
|
||||||
// 7: Color Y
|
// 7: Color Y
|
||||||
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}) {
|
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms []interface{}) {
|
||||||
backendsM.Lock()
|
backendsM.Lock()
|
||||||
// Do not use defer for performance.
|
// Do not use defer for performance.
|
||||||
|
|
||||||
@ -362,8 +362,8 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
|||||||
ox, oy, _, _ := src.regionWithPadding()
|
ox, oy, _, _ := src.regionWithPadding()
|
||||||
ox += paddingSize
|
ox += paddingSize
|
||||||
oy += paddingSize
|
oy += paddingSize
|
||||||
offsets[i][0] = float32(ox) - oxf
|
offsets[i][0] = float32(ox) - oxf + subimageOffsets[i][0]
|
||||||
offsets[i][1] = float32(oy) - oyf
|
offsets[i][1] = float32(oy) - oyf + subimageOffsets[i][0]
|
||||||
}
|
}
|
||||||
|
|
||||||
var s *restorable.Shader
|
var s *restorable.Shader
|
||||||
|
@ -96,7 +96,7 @@ func TestEnsureNotShared(t *testing.T) {
|
|||||||
// img4.ensureNotShared() should be called.
|
// img4.ensureNotShared() should be called.
|
||||||
vs := quadVertices(size/2, size/2, size/4, size/4, 1)
|
vs := quadVertices(size/2, size/2, size/4, size/4, 1)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
img4.DrawTriangles([graphics.ShaderImageNum]*Image{img3}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
img4.DrawTriangles([graphics.ShaderImageNum]*Image{img3}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil)
|
||||||
want := false
|
want := false
|
||||||
if got := img4.IsSharedForTesting(); got != want {
|
if got := img4.IsSharedForTesting(); got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
@ -126,7 +126,7 @@ func TestEnsureNotShared(t *testing.T) {
|
|||||||
|
|
||||||
// Check further drawing doesn't cause panic.
|
// Check further drawing doesn't cause panic.
|
||||||
// This bug was fixed by 03dcd948.
|
// This bug was fixed by 03dcd948.
|
||||||
img4.DrawTriangles([graphics.ShaderImageNum]*Image{img3}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
img4.DrawTriangles([graphics.ShaderImageNum]*Image{img3}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReshared(t *testing.T) {
|
func TestReshared(t *testing.T) {
|
||||||
@ -167,7 +167,7 @@ func TestReshared(t *testing.T) {
|
|||||||
// Use img1 as a render target.
|
// Use img1 as a render target.
|
||||||
vs := quadVertices(size, size, 0, 0, 1)
|
vs := quadVertices(size, size, 0, 0, 1)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
img1.DrawTriangles([graphics.ShaderImageNum]*Image{img2}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
img1.DrawTriangles([graphics.ShaderImageNum]*Image{img2}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil)
|
||||||
if got, want := img1.IsSharedForTesting(), false; got != want {
|
if got, want := img1.IsSharedForTesting(), false; got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@ func TestReshared(t *testing.T) {
|
|||||||
if err := MakeImagesSharedForTesting(); err != nil {
|
if err := MakeImagesSharedForTesting(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
img0.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
img0.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil)
|
||||||
if got, want := img1.IsSharedForTesting(), false; got != want {
|
if got, want := img1.IsSharedForTesting(), false; got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ func TestReshared(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
img0.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
img0.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil)
|
||||||
if got, want := img1.IsSharedForTesting(), true; got != want {
|
if got, want := img1.IsSharedForTesting(), true; got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
@ -232,7 +232,7 @@ func TestReshared(t *testing.T) {
|
|||||||
if err := MakeImagesSharedForTesting(); err != nil {
|
if err := MakeImagesSharedForTesting(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
img0.DrawTriangles([graphics.ShaderImageNum]*Image{img3}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
img0.DrawTriangles([graphics.ShaderImageNum]*Image{img3}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil)
|
||||||
if got, want := img3.IsSharedForTesting(), false; got != want {
|
if got, want := img3.IsSharedForTesting(), false; got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
@ -327,7 +327,7 @@ func TestReplacePixelsAfterDrawTriangles(t *testing.T) {
|
|||||||
|
|
||||||
vs := quadVertices(w, h, 0, 0, 1)
|
vs := quadVertices(w, h, 0, 0, 1)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil)
|
||||||
dst.ReplacePixels(pix)
|
dst.ReplacePixels(pix)
|
||||||
|
|
||||||
pix, err := dst.Pixels(0, 0, w, h)
|
pix, err := dst.Pixels(0, 0, w, h)
|
||||||
@ -369,7 +369,7 @@ func TestSmallImages(t *testing.T) {
|
|||||||
|
|
||||||
vs := quadVertices(w, h, 0, 0, 1)
|
vs := quadVertices(w, h, 0, 0, 1)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil)
|
||||||
|
|
||||||
pix, err := dst.Pixels(0, 0, w, h)
|
pix, err := dst.Pixels(0, 0, w, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -411,7 +411,7 @@ func TestLongImages(t *testing.T) {
|
|||||||
const scale = 120
|
const scale = 120
|
||||||
vs := quadVertices(w, h, 0, 0, scale)
|
vs := quadVertices(w, h, 0, 0, scale)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil)
|
||||||
|
|
||||||
pix, err := dst.Pixels(0, 0, dstW, dstH)
|
pix, err := dst.Pixels(0, 0, dstW, dstH)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package ebiten_test
|
package ebiten_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -798,3 +799,66 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShaderSubImage(t *testing.T) {
|
||||||
|
const w, h = 16, 16
|
||||||
|
|
||||||
|
dst, _ := NewImage(w, h, FilterDefault)
|
||||||
|
s, err := NewShader([]byte(`package main
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
r := imageSrc0At(texCoord).r
|
||||||
|
g := imageSrc1At(texCoord).g
|
||||||
|
return vec4(r, g, 0, 1)
|
||||||
|
}
|
||||||
|
`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
src0, _ := NewImage(w, h, FilterDefault)
|
||||||
|
pix0 := make([]byte, 4*w*h)
|
||||||
|
for j := 0; j < h; j++ {
|
||||||
|
for i := 0; i < w; i++ {
|
||||||
|
if 2 <= i && i < 10 && 2 <= j && j < 10 {
|
||||||
|
pix0[4*(j*w+i)] = 0xff
|
||||||
|
pix0[4*(j*w+i)+1] = 0
|
||||||
|
pix0[4*(j*w+i)+2] = 0
|
||||||
|
pix0[4*(j*w+i)+3] = 0xff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
src0.ReplacePixels(pix0)
|
||||||
|
|
||||||
|
src1, _ := NewImage(w, h, FilterDefault)
|
||||||
|
pix1 := make([]byte, 4*w*h)
|
||||||
|
for j := 0; j < h; j++ {
|
||||||
|
for i := 0; i < w; i++ {
|
||||||
|
if 6 <= i && i < 14 && 6 <= j && j < 14 {
|
||||||
|
pix1[4*(j*w+i)] = 0
|
||||||
|
pix1[4*(j*w+i)+1] = 0xff
|
||||||
|
pix1[4*(j*w+i)+2] = 0
|
||||||
|
pix1[4*(j*w+i)+3] = 0xff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
src1.ReplacePixels(pix1)
|
||||||
|
|
||||||
|
op := &DrawRectShaderOptions{}
|
||||||
|
op.Images[0] = src0.SubImage(image.Rect(2, 2, 10, 10)).(*Image)
|
||||||
|
op.Images[1] = src1.SubImage(image.Rect(6, 6, 14, 14)).(*Image)
|
||||||
|
dst.DrawRectShader(w/2, h/2, s, op)
|
||||||
|
|
||||||
|
for j := 0; j < h; j++ {
|
||||||
|
for i := 0; i < w; i++ {
|
||||||
|
got := dst.At(i, j).(color.RGBA)
|
||||||
|
var want color.RGBA
|
||||||
|
if i < w/2 && j < h/2 {
|
||||||
|
want = color.RGBA{0xff, 0xff, 0, 0xff}
|
||||||
|
}
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user