mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
internal/restorable: refactoring: use image.Rectangle
This commit is contained in:
parent
d9a2b0922d
commit
cdcffd7d4f
@ -518,15 +518,15 @@ func (i *Image) drawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices [
|
||||
func (i *Image) WritePixels(pix []byte, x, y, width, height int) {
|
||||
backendsM.Lock()
|
||||
defer backendsM.Unlock()
|
||||
i.writePixels(pix, x, y, width, height)
|
||||
i.writePixels(pix, image.Rect(x, y, x+width, y+height))
|
||||
}
|
||||
|
||||
func (i *Image) writePixels(pix []byte, x, y, width, height int) {
|
||||
func (i *Image) writePixels(pix []byte, region image.Rectangle) {
|
||||
if i.disposed {
|
||||
panic("atlas: the image must not be disposed at writePixels")
|
||||
}
|
||||
|
||||
if l := 4 * width * height; len(pix) != l {
|
||||
if l := 4 * region.Dx() * region.Dy(); len(pix) != l {
|
||||
panic(fmt.Sprintf("atlas: len(p) must be %d but %d", l, len(pix)))
|
||||
}
|
||||
|
||||
@ -542,19 +542,18 @@ func (i *Image) writePixels(pix []byte, x, y, width, height int) {
|
||||
|
||||
r := i.regionWithPadding()
|
||||
|
||||
if x != 0 || y != 0 || width != i.width || height != i.height || i.paddingSize() == 0 {
|
||||
x += r.Min.X
|
||||
y += r.Min.Y
|
||||
if region.Min.X != 0 || region.Min.Y != 0 || region.Dx() != i.width || region.Dy() != i.height || i.paddingSize() == 0 {
|
||||
region = region.Add(r.Min)
|
||||
|
||||
if pix == nil {
|
||||
i.backend.restorable.WritePixels(nil, x, y, width, height)
|
||||
i.backend.restorable.WritePixels(nil, region)
|
||||
return
|
||||
}
|
||||
|
||||
// Copy pixels in the case when pix is modified before the graphics command is executed.
|
||||
pix2 := theTemporaryBytes.alloc(len(pix))
|
||||
copy(pix2, pix)
|
||||
i.backend.restorable.WritePixels(pix2, x, y, width, height)
|
||||
i.backend.restorable.WritePixels(pix2, region)
|
||||
return
|
||||
}
|
||||
|
||||
@ -579,11 +578,11 @@ func (i *Image) writePixels(pix []byte, x, y, width, height int) {
|
||||
}
|
||||
|
||||
// Copy the content.
|
||||
for j := 0; j < height; j++ {
|
||||
copy(pixb[4*j*r.Dx():], pix[4*j*width:4*(j+1)*width])
|
||||
for j := 0; j < region.Dy(); j++ {
|
||||
copy(pixb[4*j*r.Dx():], pix[4*j*region.Dx():4*(j+1)*region.Dx()])
|
||||
}
|
||||
|
||||
i.backend.restorable.WritePixels(pixb, r.Min.X, r.Min.Y, r.Dx(), r.Dy())
|
||||
i.backend.restorable.WritePixels(pixb, r)
|
||||
}
|
||||
|
||||
func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, pixels []byte, x, y, width, height int) error {
|
||||
@ -604,7 +603,7 @@ func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, pixels []byte
|
||||
r := i.regionWithPadding()
|
||||
x += r.Min.X
|
||||
y += r.Min.Y
|
||||
return i.backend.restorable.ReadPixels(graphicsDriver, pixels, x, y, width, height)
|
||||
return i.backend.restorable.ReadPixels(graphicsDriver, pixels, image.Rect(x, y, x+width, y+height))
|
||||
}
|
||||
|
||||
// MarkDisposed marks the image as disposed. The actual operation is deferred.
|
||||
@ -653,7 +652,7 @@ func (i *Image) dispose(markDisposed bool) {
|
||||
if !i.backend.page.IsEmpty() {
|
||||
// As this part can be reused, this should be cleared explicitly.
|
||||
r := i.regionWithPadding()
|
||||
i.backend.restorable.ClearPixels(r.Min.X, r.Min.Y, r.Dx(), r.Dy())
|
||||
i.backend.restorable.ClearPixels(r)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -38,30 +38,30 @@ func (p *Pixels) Apply(img *graphicscommand.Image) {
|
||||
p.pixelsRecords.apply(img)
|
||||
}
|
||||
|
||||
func (p *Pixels) AddOrReplace(pix []byte, x, y, width, height int) {
|
||||
func (p *Pixels) AddOrReplace(pix []byte, region image.Rectangle) {
|
||||
if p.pixelsRecords == nil {
|
||||
p.pixelsRecords = &pixelsRecords{}
|
||||
}
|
||||
p.pixelsRecords.addOrReplace(pix, x, y, width, height)
|
||||
p.pixelsRecords.addOrReplace(pix, region)
|
||||
}
|
||||
|
||||
func (p *Pixels) Clear(x, y, width, height int) {
|
||||
func (p *Pixels) Clear(region image.Rectangle) {
|
||||
// Note that we don't care whether the region is actually removed or not here. There is an actual case that
|
||||
// the region is allocated but nothing is rendered. See TestDisposeImmediately at shareable package.
|
||||
if p.pixelsRecords == nil {
|
||||
return
|
||||
}
|
||||
p.pixelsRecords.clear(x, y, width, height)
|
||||
p.pixelsRecords.clear(region)
|
||||
}
|
||||
|
||||
func (p *Pixels) ReadPixels(pixels []byte, x, y, width, height, imageWidth, imageHeight int) {
|
||||
func (p *Pixels) ReadPixels(pixels []byte, region image.Rectangle, imageWidth, imageHeight int) {
|
||||
if p.pixelsRecords == nil {
|
||||
for i := range pixels {
|
||||
pixels[i] = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
p.pixelsRecords.readPixels(pixels, x, y, width, height, imageWidth, imageHeight)
|
||||
p.pixelsRecords.readPixels(pixels, region, imageWidth, imageHeight)
|
||||
}
|
||||
|
||||
func (p *Pixels) AppendRegion(regions []image.Rectangle) []image.Rectangle {
|
||||
@ -247,7 +247,7 @@ func (i *Image) makeStale(rect image.Rectangle) {
|
||||
if r.Empty() {
|
||||
continue
|
||||
}
|
||||
i.basePixels.Clear(r.Min.X, r.Min.Y, r.Dx(), r.Dy())
|
||||
i.basePixels.Clear(r)
|
||||
}
|
||||
|
||||
// Don't have to call makeStale recursively here.
|
||||
@ -257,8 +257,8 @@ func (i *Image) makeStale(rect image.Rectangle) {
|
||||
}
|
||||
|
||||
// ClearPixels clears the specified region by WritePixels.
|
||||
func (i *Image) ClearPixels(x, y, width, height int) {
|
||||
i.WritePixels(nil, x, y, width, height)
|
||||
func (i *Image) ClearPixels(region image.Rectangle) {
|
||||
i.WritePixels(nil, region)
|
||||
}
|
||||
|
||||
func (i *Image) needsRestoring() bool {
|
||||
@ -268,13 +268,13 @@ func (i *Image) needsRestoring() bool {
|
||||
// WritePixels replaces the image pixels with the given pixels slice.
|
||||
//
|
||||
// The specified region must not be overlapped with other regions by WritePixels.
|
||||
func (i *Image) WritePixels(pixels []byte, x, y, width, height int) {
|
||||
if width <= 0 || height <= 0 {
|
||||
func (i *Image) WritePixels(pixels []byte, region image.Rectangle) {
|
||||
if region.Dx() <= 0 || region.Dy() <= 0 {
|
||||
panic("restorable: width/height must be positive")
|
||||
}
|
||||
w, h := i.width, i.height
|
||||
if x < 0 || y < 0 || w <= x || h <= y || x+width <= 0 || y+height <= 0 || w < x+width || h < y+height {
|
||||
panic(fmt.Sprintf("restorable: out of range x: %d, y: %d, width: %d, height: %d", x, y, width, height))
|
||||
if !region.In(image.Rect(0, 0, w, h)) {
|
||||
panic(fmt.Sprintf("restorable: out of range %v", region))
|
||||
}
|
||||
|
||||
// TODO: Avoid making other images stale if possible. (#514)
|
||||
@ -282,29 +282,29 @@ func (i *Image) WritePixels(pixels []byte, x, y, width, height int) {
|
||||
theImages.makeStaleIfDependingOn(i)
|
||||
|
||||
if pixels != nil {
|
||||
i.image.WritePixels(pixels, x, y, width, height)
|
||||
i.image.WritePixels(pixels, region.Min.X, region.Min.Y, region.Dx(), region.Dy())
|
||||
} else {
|
||||
// TODO: When pixels == nil, we don't have to care the pixel state there. In such cases, the image
|
||||
// accepts only WritePixels and not Fill or DrawTriangles.
|
||||
// TODO: Separate Image struct into two: images for WritePixels-only, and the others.
|
||||
i.image.WritePixels(make([]byte, 4*width*height), x, y, width, height)
|
||||
i.image.WritePixels(make([]byte, 4*region.Dx()*region.Dy()), region.Min.X, region.Min.Y, region.Dx(), region.Dy())
|
||||
}
|
||||
|
||||
// Even if the image is already stale, call makeStale to extend the stale region.
|
||||
if !needsRestoring() || !i.needsRestoring() || i.stale {
|
||||
i.makeStale(image.Rect(x, y, x+width, y+height))
|
||||
i.makeStale(region)
|
||||
return
|
||||
}
|
||||
|
||||
if x == 0 && y == 0 && width == w && height == h {
|
||||
if region.Eq(image.Rect(0, 0, w, h)) {
|
||||
if pixels != nil {
|
||||
// pixels can point to a shared region.
|
||||
// This function is responsible to copy this.
|
||||
copiedPixels := make([]byte, len(pixels))
|
||||
copy(copiedPixels, pixels)
|
||||
i.basePixels.AddOrReplace(copiedPixels, 0, 0, w, h)
|
||||
i.basePixels.AddOrReplace(copiedPixels, image.Rect(0, 0, w, h))
|
||||
} else {
|
||||
i.basePixels.Clear(0, 0, w, h)
|
||||
i.basePixels.Clear(image.Rect(0, 0, w, h))
|
||||
}
|
||||
i.clearDrawTrianglesHistory()
|
||||
i.stale = false
|
||||
@ -314,7 +314,7 @@ func (i *Image) WritePixels(pixels []byte, x, y, width, height int) {
|
||||
|
||||
// Records for DrawTriangles cannot come before records for WritePixels.
|
||||
if len(i.drawTrianglesHistory) > 0 {
|
||||
i.makeStale(image.Rect(x, y, x+width, y+height))
|
||||
i.makeStale(region)
|
||||
return
|
||||
}
|
||||
|
||||
@ -323,9 +323,9 @@ func (i *Image) WritePixels(pixels []byte, x, y, width, height int) {
|
||||
// This function is responsible to copy this.
|
||||
copiedPixels := make([]byte, len(pixels))
|
||||
copy(copiedPixels, pixels)
|
||||
i.basePixels.AddOrReplace(copiedPixels, x, y, width, height)
|
||||
i.basePixels.AddOrReplace(copiedPixels, region)
|
||||
} else {
|
||||
i.basePixels.Clear(x, y, width, height)
|
||||
i.basePixels.Clear(region)
|
||||
}
|
||||
}
|
||||
|
||||
@ -427,9 +427,9 @@ func (i *Image) readPixelsFromGPUIfNeeded(graphicsDriver graphicsdriver.Graphics
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, pixels []byte, x, y, width, height int) error {
|
||||
func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, pixels []byte, region image.Rectangle) error {
|
||||
if AlwaysReadPixelsFromGPU() {
|
||||
if err := i.image.ReadPixels(graphicsDriver, pixels, x, y, width, height); err != nil {
|
||||
if err := i.image.ReadPixels(graphicsDriver, pixels, region.Min.X, region.Min.Y, region.Dx(), region.Dy()); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -438,10 +438,10 @@ func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, pixels []byte
|
||||
if err := i.readPixelsFromGPUIfNeeded(graphicsDriver); err != nil {
|
||||
return err
|
||||
}
|
||||
if got, want := len(pixels), 4*width*height; got != want {
|
||||
if got, want := len(pixels), 4*region.Dx()*region.Dy(); got != want {
|
||||
return fmt.Errorf("restorable: len(pixels) must be %d but %d at ReadPixels", want, got)
|
||||
}
|
||||
i.basePixels.ReadPixels(pixels, x, y, width, height, i.width, i.height)
|
||||
i.basePixels.ReadPixels(pixels, region, i.width, i.height)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -497,7 +497,7 @@ func (i *Image) readPixelsFromGPU(graphicsDriver graphicsdriver.Graphics) error
|
||||
if err := i.image.ReadPixels(graphicsDriver, pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy()); err != nil {
|
||||
return err
|
||||
}
|
||||
i.basePixels.AddOrReplace(pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy())
|
||||
i.basePixels.AddOrReplace(pix, r)
|
||||
}
|
||||
|
||||
i.clearDrawTrianglesHistory()
|
||||
@ -636,7 +636,7 @@ func (i *Image) restore(graphicsDriver graphicsdriver.Graphics) error {
|
||||
if err := gimg.ReadPixels(graphicsDriver, pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy()); err != nil {
|
||||
return err
|
||||
}
|
||||
i.basePixels.AddOrReplace(pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy())
|
||||
i.basePixels.AddOrReplace(pix, r)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ func TestMain(m *testing.M) {
|
||||
|
||||
func pixelsToColor(p *restorable.Pixels, i, j, imageWidth, imageHeight int) color.RGBA {
|
||||
var pix [4]byte
|
||||
p.ReadPixels(pix[:], i, j, 1, 1, imageWidth, imageHeight)
|
||||
p.ReadPixels(pix[:], image.Rect(i, j, i+1, j+1), imageWidth, imageHeight)
|
||||
return color.RGBA{R: pix[0], G: pix[1], B: pix[2], A: pix[3]}
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ func TestRestore(t *testing.T) {
|
||||
defer img0.Dispose()
|
||||
|
||||
clr0 := color.RGBA{A: 0xff}
|
||||
img0.WritePixels([]byte{clr0.R, clr0.G, clr0.B, clr0.A}, 0, 0, 1, 1)
|
||||
img0.WritePixels([]byte{clr0.R, clr0.G, clr0.B, clr0.A}, image.Rect(0, 0, 1, 1))
|
||||
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -129,7 +129,7 @@ func TestRestoreChain(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
clr := color.RGBA{A: 0xff}
|
||||
imgs[0].WritePixels([]byte{clr.R, clr.G, clr.B, clr.A}, 0, 0, 1, 1)
|
||||
imgs[0].WritePixels([]byte{clr.R, clr.G, clr.B, clr.A}, image.Rect(0, 0, 1, 1))
|
||||
for i := 0; i < num-1; i++ {
|
||||
vs := quadVertices(1, 1, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
@ -174,11 +174,11 @@ func TestRestoreChain2(t *testing.T) {
|
||||
}()
|
||||
|
||||
clr0 := color.RGBA{R: 0xff, A: 0xff}
|
||||
imgs[0].WritePixels([]byte{clr0.R, clr0.G, clr0.B, clr0.A}, 0, 0, w, h)
|
||||
imgs[0].WritePixels([]byte{clr0.R, clr0.G, clr0.B, clr0.A}, image.Rect(0, 0, w, h))
|
||||
clr7 := color.RGBA{G: 0xff, A: 0xff}
|
||||
imgs[7].WritePixels([]byte{clr7.R, clr7.G, clr7.B, clr7.A}, 0, 0, w, h)
|
||||
imgs[7].WritePixels([]byte{clr7.R, clr7.G, clr7.B, clr7.A}, image.Rect(0, 0, w, h))
|
||||
clr8 := color.RGBA{B: 0xff, A: 0xff}
|
||||
imgs[8].WritePixels([]byte{clr8.R, clr8.G, clr8.B, clr8.A}, 0, 0, w, h)
|
||||
imgs[8].WritePixels([]byte{clr8.R, clr8.G, clr8.B, clr8.A}, image.Rect(0, 0, w, h))
|
||||
|
||||
is := graphics.QuadIndices()
|
||||
dr := graphicsdriver.Region{
|
||||
@ -228,7 +228,7 @@ func TestRestoreOverrideSource(t *testing.T) {
|
||||
}()
|
||||
clr0 := color.RGBA{A: 0xff}
|
||||
clr1 := color.RGBA{B: 0x01, A: 0xff}
|
||||
img1.WritePixels([]byte{clr0.R, clr0.G, clr0.B, clr0.A}, 0, 0, w, h)
|
||||
img1.WritePixels([]byte{clr0.R, clr0.G, clr0.B, clr0.A}, image.Rect(0, 0, w, h))
|
||||
is := graphics.QuadIndices()
|
||||
dr := graphicsdriver.Region{
|
||||
X: 0,
|
||||
@ -238,7 +238,7 @@ func TestRestoreOverrideSource(t *testing.T) {
|
||||
}
|
||||
img2.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, [graphics.ShaderImageCount - 1][2]float32{}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendSourceOver, dr, graphicsdriver.Region{}, restorable.NearestFilterShader, nil, false)
|
||||
img3.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, [graphics.ShaderImageCount - 1][2]float32{}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendSourceOver, dr, graphicsdriver.Region{}, restorable.NearestFilterShader, nil, false)
|
||||
img0.WritePixels([]byte{clr1.R, clr1.G, clr1.B, clr1.A}, 0, 0, w, h)
|
||||
img0.WritePixels([]byte{clr1.R, clr1.G, clr1.B, clr1.A}, image.Rect(0, 0, w, h))
|
||||
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, [graphics.ShaderImageCount - 1][2]float32{}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendSourceOver, dr, graphicsdriver.Region{}, restorable.NearestFilterShader, nil, false)
|
||||
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -411,7 +411,7 @@ func TestRestoreComplexGraph(t *testing.T) {
|
||||
func newImageFromImage(rgba *image.RGBA) *restorable.Image {
|
||||
s := rgba.Bounds().Size()
|
||||
img := restorable.NewImage(s.X, s.Y, restorable.ImageTypeRegular)
|
||||
img.WritePixels(rgba.Pix, 0, 0, s.X, s.Y)
|
||||
img.WritePixels(rgba.Pix, image.Rect(0, 0, s.X, s.Y))
|
||||
return img
|
||||
}
|
||||
|
||||
@ -485,12 +485,12 @@ func TestWritePixels(t *testing.T) {
|
||||
for i := range pix {
|
||||
pix[i] = 0xff
|
||||
}
|
||||
img.WritePixels(pix, 5, 7, 4, 4)
|
||||
img.WritePixels(pix, image.Rect(5, 7, 9, 11))
|
||||
// Check the region (5, 7)-(9, 11). Outside state is indeterminate.
|
||||
for i := range pix {
|
||||
pix[i] = 0
|
||||
}
|
||||
if err := img.ReadPixels(ui.GraphicsDriverForTesting(), pix, 5, 7, 4, 4); err != nil {
|
||||
if err := img.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(5, 7, 9, 11)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 7; j < 11; j++ {
|
||||
@ -509,7 +509,7 @@ func TestWritePixels(t *testing.T) {
|
||||
if err := restorable.RestoreIfNeeded(ui.GraphicsDriverForTesting()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := img.ReadPixels(ui.GraphicsDriverForTesting(), pix, 5, 7, 4, 4); err != nil {
|
||||
if err := img.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(5, 7, 9, 11)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 7; j < 11; j++ {
|
||||
@ -544,7 +544,7 @@ func TestDrawTrianglesAndWritePixels(t *testing.T) {
|
||||
Height: 1,
|
||||
}
|
||||
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, [graphics.ShaderImageCount - 1][2]float32{}, vs, is, graphicsdriver.BlendCopy, dr, graphicsdriver.Region{}, restorable.NearestFilterShader, nil, false)
|
||||
img1.WritePixels([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, 0, 2, 1)
|
||||
img1.WritePixels([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, image.Rect(0, 0, 2, 1))
|
||||
|
||||
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -553,7 +553,7 @@ func TestDrawTrianglesAndWritePixels(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var pix [4]byte
|
||||
if err := img1.ReadPixels(ui.GraphicsDriverForTesting(), pix[:], 0, 0, 1, 1); err != nil {
|
||||
if err := img1.ReadPixels(ui.GraphicsDriverForTesting(), pix[:], image.Rect(0, 0, 1, 1)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := color.RGBA{R: pix[0], G: pix[1], B: pix[2], A: pix[3]}
|
||||
@ -597,7 +597,7 @@ func TestDispose(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var pix [4]byte
|
||||
if err := img0.ReadPixels(ui.GraphicsDriverForTesting(), pix[:], 0, 0, 1, 1); err != nil {
|
||||
if err := img0.ReadPixels(ui.GraphicsDriverForTesting(), pix[:], image.Rect(0, 0, 1, 1)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := color.RGBA{R: pix[0], G: pix[1], B: pix[2], A: pix[3]}
|
||||
@ -615,7 +615,7 @@ func TestWritePixelsPart(t *testing.T) {
|
||||
|
||||
img := restorable.NewImage(4, 4, restorable.ImageTypeRegular)
|
||||
// This doesn't make the image stale. Its base pixels are available.
|
||||
img.WritePixels(pix, 1, 1, 2, 2)
|
||||
img.WritePixels(pix, image.Rect(1, 1, 3, 3))
|
||||
|
||||
cases := []struct {
|
||||
i int
|
||||
@ -690,7 +690,7 @@ func TestWritePixelsOnly(t *testing.T) {
|
||||
defer img1.Dispose()
|
||||
|
||||
for i := 0; i < w*h; i += 5 {
|
||||
img0.WritePixels([]byte{1, 2, 3, 4}, i%w, i/w, 1, 1)
|
||||
img0.WritePixels([]byte{1, 2, 3, 4}, image.Rect(i%w, i/w, i%w+1, i/w+1))
|
||||
}
|
||||
|
||||
vs := quadVertices(1, 1, 0, 0)
|
||||
@ -702,7 +702,7 @@ func TestWritePixelsOnly(t *testing.T) {
|
||||
Height: 1,
|
||||
}
|
||||
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, [graphics.ShaderImageCount - 1][2]float32{}, vs, is, graphicsdriver.BlendCopy, dr, graphicsdriver.Region{}, restorable.NearestFilterShader, nil, false)
|
||||
img0.WritePixels([]byte{5, 6, 7, 8}, 0, 0, 1, 1)
|
||||
img0.WritePixels([]byte{5, 6, 7, 8}, image.Rect(0, 0, 1, 1))
|
||||
|
||||
// BasePixelsForTesting is available without GPU accessing.
|
||||
for j := 0; j < h; j++ {
|
||||
@ -744,14 +744,14 @@ func TestReadPixelsFromVolatileImage(t *testing.T) {
|
||||
src := restorable.NewImage(w, h, restorable.ImageTypeRegular)
|
||||
|
||||
// First, make sure that dst has pixels
|
||||
dst.WritePixels(make([]byte, 4*w*h), 0, 0, w, h)
|
||||
dst.WritePixels(make([]byte, 4*w*h), image.Rect(0, 0, w, h))
|
||||
|
||||
// Second, draw src to dst. If the implementation is correct, dst becomes stale.
|
||||
pix := make([]byte, 4*w*h)
|
||||
for i := range pix {
|
||||
pix[i] = 0xff
|
||||
}
|
||||
src.WritePixels(pix, 0, 0, w, h)
|
||||
src.WritePixels(pix, image.Rect(0, 0, w, h))
|
||||
vs := quadVertices(1, 1, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
dr := graphicsdriver.Region{
|
||||
@ -767,7 +767,7 @@ func TestReadPixelsFromVolatileImage(t *testing.T) {
|
||||
want := byte(0xff)
|
||||
|
||||
var result [4]byte
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result[:], 0, 0, 1, 1); err != nil {
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result[:], image.Rect(0, 0, 1, 1)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := result[0]
|
||||
@ -790,7 +790,7 @@ func TestAllowWritePixelsAfterDrawTriangles(t *testing.T) {
|
||||
Height: h,
|
||||
}
|
||||
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, [graphics.ShaderImageCount - 1][2]float32{}, vs, is, graphicsdriver.BlendSourceOver, dr, graphicsdriver.Region{}, restorable.NearestFilterShader, nil, false)
|
||||
dst.WritePixels(make([]byte, 4*w*h), 0, 0, w, h)
|
||||
dst.WritePixels(make([]byte, 4*w*h), image.Rect(0, 0, w, h))
|
||||
// WritePixels for a whole image doesn't panic.
|
||||
}
|
||||
|
||||
@ -803,7 +803,7 @@ func TestAllowWritePixelsForPartAfterDrawTriangles(t *testing.T) {
|
||||
for i := range pix {
|
||||
pix[i] = 0xff
|
||||
}
|
||||
src.WritePixels(pix, 0, 0, w, h)
|
||||
src.WritePixels(pix, image.Rect(0, 0, w, h))
|
||||
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
@ -814,7 +814,7 @@ func TestAllowWritePixelsForPartAfterDrawTriangles(t *testing.T) {
|
||||
Height: h,
|
||||
}
|
||||
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, [graphics.ShaderImageCount - 1][2]float32{}, vs, is, graphicsdriver.BlendSourceOver, dr, graphicsdriver.Region{}, restorable.NearestFilterShader, nil, false)
|
||||
dst.WritePixels(make([]byte, 4*2*2), 0, 0, 2, 2)
|
||||
dst.WritePixels(make([]byte, 4*2*2), image.Rect(0, 0, 2, 2))
|
||||
// WritePixels for a part of image doesn't panic.
|
||||
|
||||
if err := restorable.ResolveStaleImages(ui.GraphicsDriverForTesting(), false); err != nil {
|
||||
@ -825,7 +825,7 @@ func TestAllowWritePixelsForPartAfterDrawTriangles(t *testing.T) {
|
||||
}
|
||||
|
||||
result := make([]byte, 4*w*h)
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, 0, 0, w, h); err != nil {
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, w, h)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < h; j++ {
|
||||
@ -861,11 +861,11 @@ func TestExtend(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
orig.WritePixels(pix, 0, 0, w, h)
|
||||
orig.WritePixels(pix, image.Rect(0, 0, w, h))
|
||||
extended := orig.Extend(w*2, h*2) // After this, orig is already disposed.
|
||||
|
||||
result := make([]byte, 4*(w*2)*(h*2))
|
||||
if err := extended.ReadPixels(ui.GraphicsDriverForTesting(), result, 0, 0, w*2, h*2); err != nil {
|
||||
if err := extended.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, w*2, h*2)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < h*2; j++ {
|
||||
@ -901,7 +901,7 @@ func TestDrawTrianglesAndExtend(t *testing.T) {
|
||||
pix[4*idx+3] = v
|
||||
}
|
||||
}
|
||||
src.WritePixels(pix, 0, 0, w, h)
|
||||
src.WritePixels(pix, image.Rect(0, 0, w, h))
|
||||
|
||||
orig := restorable.NewImage(w, h, restorable.ImageTypeRegular)
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
@ -916,7 +916,7 @@ func TestDrawTrianglesAndExtend(t *testing.T) {
|
||||
extended := orig.Extend(w*2, h*2) // After this, orig is already disposed.
|
||||
|
||||
result := make([]byte, 4*(w*2)*(h*2))
|
||||
if err := extended.ReadPixels(ui.GraphicsDriverForTesting(), result, 0, 0, w*2, h*2); err != nil {
|
||||
if err := extended.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, w*2, h*2)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < h*2; j++ {
|
||||
@ -936,13 +936,13 @@ func TestDrawTrianglesAndExtend(t *testing.T) {
|
||||
func TestClearPixels(t *testing.T) {
|
||||
const w, h = 16, 16
|
||||
img := restorable.NewImage(w, h, restorable.ImageTypeRegular)
|
||||
img.WritePixels(make([]byte, 4*4*4), 0, 0, 4, 4)
|
||||
img.WritePixels(make([]byte, 4*4*4), 4, 0, 4, 4)
|
||||
img.ClearPixels(0, 0, 4, 4)
|
||||
img.ClearPixels(4, 0, 4, 4)
|
||||
img.WritePixels(make([]byte, 4*4*4), image.Rect(0, 0, 4, 4))
|
||||
img.WritePixels(make([]byte, 4*4*4), image.Rect(4, 0, 8, 4))
|
||||
img.ClearPixels(image.Rect(0, 0, 4, 4))
|
||||
img.ClearPixels(image.Rect(4, 0, 8, 4))
|
||||
|
||||
// After clearing, the regions will be available again.
|
||||
img.WritePixels(make([]byte, 4*8*4), 0, 0, 8, 4)
|
||||
img.WritePixels(make([]byte, 4*8*4), image.Rect(0, 0, 8, 4))
|
||||
}
|
||||
|
||||
func TestMutateSlices(t *testing.T) {
|
||||
@ -956,7 +956,7 @@ func TestMutateSlices(t *testing.T) {
|
||||
pix[4*i+2] = byte(i)
|
||||
pix[4*i+3] = 0xff
|
||||
}
|
||||
src.WritePixels(pix, 0, 0, w, h)
|
||||
src.WritePixels(pix, image.Rect(0, 0, w, h))
|
||||
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := make([]uint16, len(graphics.QuadIndices()))
|
||||
@ -982,11 +982,11 @@ func TestMutateSlices(t *testing.T) {
|
||||
}
|
||||
|
||||
srcPix := make([]byte, 4*w*h)
|
||||
if err := src.ReadPixels(ui.GraphicsDriverForTesting(), srcPix, 0, 0, w, h); err != nil {
|
||||
if err := src.ReadPixels(ui.GraphicsDriverForTesting(), srcPix, image.Rect(0, 0, w, h)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dstPix := make([]byte, 4*w*h)
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), dstPix, 0, 0, w, h); err != nil {
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), dstPix, image.Rect(0, 0, w, h)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -1015,7 +1015,7 @@ func TestOverlappedPixels(t *testing.T) {
|
||||
pix0[idx+3] = 0xff
|
||||
}
|
||||
}
|
||||
dst.WritePixels(pix0, 0, 0, 2, 2)
|
||||
dst.WritePixels(pix0, image.Rect(0, 0, 2, 2))
|
||||
|
||||
pix1 := make([]byte, 4*2*2)
|
||||
for j := 0; j < 2; j++ {
|
||||
@ -1027,7 +1027,7 @@ func TestOverlappedPixels(t *testing.T) {
|
||||
pix1[idx+3] = 0xff
|
||||
}
|
||||
}
|
||||
dst.WritePixels(pix1, 1, 1, 2, 2)
|
||||
dst.WritePixels(pix1, image.Rect(1, 1, 3, 3))
|
||||
|
||||
wantColors := []color.RGBA{
|
||||
{0xff, 0, 0, 0xff},
|
||||
@ -1044,7 +1044,7 @@ func TestOverlappedPixels(t *testing.T) {
|
||||
}
|
||||
|
||||
result := make([]byte, 4*3*3)
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, 0, 0, 3, 3); err != nil {
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, 3, 3)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < 3; j++ {
|
||||
@ -1058,7 +1058,7 @@ func TestOverlappedPixels(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
dst.WritePixels(nil, 1, 0, 2, 2)
|
||||
dst.WritePixels(nil, image.Rect(1, 0, 3, 2))
|
||||
|
||||
wantColors = []color.RGBA{
|
||||
{0xff, 0, 0, 0xff},
|
||||
@ -1073,7 +1073,7 @@ func TestOverlappedPixels(t *testing.T) {
|
||||
{0, 0xff, 0, 0xff},
|
||||
{0, 0xff, 0, 0xff},
|
||||
}
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, 0, 0, 3, 3); err != nil {
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, 3, 3)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < 3; j++ {
|
||||
@ -1097,7 +1097,7 @@ func TestOverlappedPixels(t *testing.T) {
|
||||
pix2[idx+3] = 0xff
|
||||
}
|
||||
}
|
||||
dst.WritePixels(pix2, 1, 1, 2, 2)
|
||||
dst.WritePixels(pix2, image.Rect(1, 1, 3, 3))
|
||||
|
||||
wantColors = []color.RGBA{
|
||||
{0xff, 0, 0, 0xff},
|
||||
@ -1112,7 +1112,7 @@ func TestOverlappedPixels(t *testing.T) {
|
||||
{0, 0, 0xff, 0xff},
|
||||
{0, 0, 0xff, 0xff},
|
||||
}
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, 0, 0, 3, 3); err != nil {
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, 3, 3)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < 3; j++ {
|
||||
@ -1133,7 +1133,7 @@ func TestOverlappedPixels(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, 0, 0, 3, 3); err != nil {
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), result, image.Rect(0, 0, 3, 3)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < 3; j++ {
|
||||
@ -1154,7 +1154,7 @@ func TestDrawTrianglesAndReadPixels(t *testing.T) {
|
||||
src := restorable.NewImage(w, h, restorable.ImageTypeRegular)
|
||||
dst := restorable.NewImage(w, h, restorable.ImageTypeRegular)
|
||||
|
||||
src.WritePixels([]byte{0x80, 0x80, 0x80, 0x80}, 0, 0, 1, 1)
|
||||
src.WritePixels([]byte{0x80, 0x80, 0x80, 0x80}, image.Rect(0, 0, 1, 1))
|
||||
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
@ -1167,7 +1167,7 @@ func TestDrawTrianglesAndReadPixels(t *testing.T) {
|
||||
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, [graphics.ShaderImageCount - 1][2]float32{}, vs, is, graphicsdriver.BlendSourceOver, dr, graphicsdriver.Region{}, restorable.NearestFilterShader, nil, false)
|
||||
|
||||
pix := make([]byte, 4*w*h)
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix, 0, 0, w, h); err != nil {
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got, want := (color.RGBA{R: pix[0], G: pix[1], B: pix[2], A: pix[3]}), (color.RGBA{R: 0x80, G: 0x80, B: 0x80, A: 0x80}); !sameColors(got, want, 1) {
|
||||
@ -1179,10 +1179,10 @@ func TestWritePixelsAndDrawTriangles(t *testing.T) {
|
||||
src := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
|
||||
dst := restorable.NewImage(2, 1, restorable.ImageTypeRegular)
|
||||
|
||||
src.WritePixels([]byte{0x80, 0x80, 0x80, 0x80}, 0, 0, 1, 1)
|
||||
src.WritePixels([]byte{0x80, 0x80, 0x80, 0x80}, image.Rect(0, 0, 1, 1))
|
||||
|
||||
// Call WritePixels first.
|
||||
dst.WritePixels([]byte{0x40, 0x40, 0x40, 0x40}, 0, 0, 1, 1)
|
||||
dst.WritePixels([]byte{0x40, 0x40, 0x40, 0x40}, image.Rect(0, 0, 1, 1))
|
||||
|
||||
// Call DrawTriangles at a different region second.
|
||||
vs := quadVertices(1, 1, 1, 0)
|
||||
@ -1197,7 +1197,7 @@ func TestWritePixelsAndDrawTriangles(t *testing.T) {
|
||||
|
||||
// Get the pixels.
|
||||
pix := make([]byte, 4*2*1)
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix, 0, 0, 2, 1); err != nil {
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, 2, 1)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got, want := (color.RGBA{R: pix[0], G: pix[1], B: pix[2], A: pix[3]}), (color.RGBA{R: 0x40, G: 0x40, B: 0x40, A: 0x40}); !sameColors(got, want, 1) {
|
||||
|
@ -42,19 +42,19 @@ func (p *pixelsRecord) clearIfOverlapped(rect image.Rectangle) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *pixelsRecord) readPixels(pixels []byte, x, y, width, height, imageWidth, imageHeight int) {
|
||||
r := p.rect.Intersect(image.Rect(x, y, x+width, y+height)).Intersect(image.Rect(0, 0, imageWidth, imageHeight))
|
||||
func (p *pixelsRecord) readPixels(pixels []byte, region image.Rectangle, imageWidth, imageHeight int) {
|
||||
r := p.rect.Intersect(region.Intersect(image.Rect(0, 0, imageWidth, imageHeight)))
|
||||
if r.Empty() {
|
||||
return
|
||||
}
|
||||
|
||||
dstBaseX := r.Min.X - x
|
||||
dstBaseY := r.Min.Y - y
|
||||
dstBaseX := r.Min.X - region.Min.X
|
||||
dstBaseY := r.Min.Y - region.Min.Y
|
||||
srcBaseX := r.Min.X - p.rect.Min.X
|
||||
srcBaseY := r.Min.Y - p.rect.Min.Y
|
||||
lineWidth := 4 * r.Dx()
|
||||
for j := 0; j < r.Dy(); j++ {
|
||||
dstX := 4 * ((dstBaseY+j)*width + dstBaseX)
|
||||
dstX := 4 * ((dstBaseY+j)*region.Dx() + dstBaseX)
|
||||
srcX := 4 * ((srcBaseY+j)*p.rect.Dx() + srcBaseX)
|
||||
copy(pixels[dstX:dstX+lineWidth], p.pix[srcX:srcX+lineWidth])
|
||||
}
|
||||
@ -64,21 +64,19 @@ type pixelsRecords struct {
|
||||
records []*pixelsRecord
|
||||
}
|
||||
|
||||
func (pr *pixelsRecords) addOrReplace(pixels []byte, x, y, width, height int) {
|
||||
if len(pixels) != 4*width*height {
|
||||
msg := fmt.Sprintf("restorable: len(pixels) must be 4*%d*%d = %d but %d", width, height, 4*width*height, len(pixels))
|
||||
func (pr *pixelsRecords) addOrReplace(pixels []byte, region image.Rectangle) {
|
||||
if len(pixels) != 4*region.Dx()*region.Dy() {
|
||||
msg := fmt.Sprintf("restorable: len(pixels) must be 4*%d*%d = %d but %d", region.Dx(), region.Dy(), 4*region.Dx()*region.Dy(), len(pixels))
|
||||
if pixels == nil {
|
||||
msg += " (nil)"
|
||||
}
|
||||
panic(msg)
|
||||
}
|
||||
|
||||
rect := image.Rect(x, y, x+width, y+height)
|
||||
|
||||
// Remove or update the duplicated records first.
|
||||
var n int
|
||||
for _, r := range pr.records {
|
||||
if r.rect.In(rect) {
|
||||
if r.rect.In(region) {
|
||||
continue
|
||||
}
|
||||
pr.records[n] = r
|
||||
@ -91,19 +89,18 @@ func (pr *pixelsRecords) addOrReplace(pixels []byte, x, y, width, height int) {
|
||||
|
||||
// Add the new record.
|
||||
pr.records = append(pr.records, &pixelsRecord{
|
||||
rect: rect,
|
||||
rect: region,
|
||||
pix: pixels,
|
||||
})
|
||||
}
|
||||
|
||||
func (pr *pixelsRecords) clear(x, y, width, height int) {
|
||||
newr := image.Rect(x, y, x+width, y+height)
|
||||
func (pr *pixelsRecords) clear(region image.Rectangle) {
|
||||
var n int
|
||||
for _, r := range pr.records {
|
||||
if r.rect.In(newr) {
|
||||
if r.rect.In(region) {
|
||||
continue
|
||||
}
|
||||
r.clearIfOverlapped(newr)
|
||||
r.clearIfOverlapped(region)
|
||||
pr.records[n] = r
|
||||
n++
|
||||
}
|
||||
@ -113,12 +110,12 @@ func (pr *pixelsRecords) clear(x, y, width, height int) {
|
||||
pr.records = pr.records[:n]
|
||||
}
|
||||
|
||||
func (pr *pixelsRecords) readPixels(pixels []byte, x, y, width, height, imageWidth, imageHeight int) {
|
||||
func (pr *pixelsRecords) readPixels(pixels []byte, region image.Rectangle, imageWidth, imageHeight int) {
|
||||
for i := range pixels {
|
||||
pixels[i] = 0
|
||||
}
|
||||
for _, r := range pr.records {
|
||||
r.readPixels(pixels, x, y, width, height, imageWidth, imageHeight)
|
||||
r.readPixels(pixels, region, imageWidth, imageHeight)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
package restorable_test
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"testing"
|
||||
|
||||
@ -89,7 +90,7 @@ func TestShaderChain(t *testing.T) {
|
||||
imgs = append(imgs, img)
|
||||
}
|
||||
|
||||
imgs[0].WritePixels([]byte{0xff, 0, 0, 0xff}, 0, 0, 1, 1)
|
||||
imgs[0].WritePixels([]byte{0xff, 0, 0, 0xff}, image.Rect(0, 0, 1, 1))
|
||||
|
||||
s := restorable.NewShader(etesting.ShaderProgramImages(1))
|
||||
for i := 0; i < num-1; i++ {
|
||||
@ -123,9 +124,9 @@ func TestShaderMultipleSources(t *testing.T) {
|
||||
for i := range srcs {
|
||||
srcs[i] = restorable.NewImage(1, 1, restorable.ImageTypeRegular)
|
||||
}
|
||||
srcs[0].WritePixels([]byte{0x40, 0, 0, 0xff}, 0, 0, 1, 1)
|
||||
srcs[1].WritePixels([]byte{0, 0x80, 0, 0xff}, 0, 0, 1, 1)
|
||||
srcs[2].WritePixels([]byte{0, 0, 0xc0, 0xff}, 0, 0, 1, 1)
|
||||
srcs[0].WritePixels([]byte{0x40, 0, 0, 0xff}, image.Rect(0, 0, 1, 1))
|
||||
srcs[1].WritePixels([]byte{0, 0x80, 0, 0xff}, image.Rect(0, 0, 1, 1))
|
||||
srcs[2].WritePixels([]byte{0, 0, 0xc0, 0xff}, image.Rect(0, 0, 1, 1))
|
||||
|
||||
dst := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
|
||||
|
||||
@ -162,7 +163,7 @@ func TestShaderMultipleSourcesOnOneTexture(t *testing.T) {
|
||||
0x40, 0, 0, 0xff,
|
||||
0, 0x80, 0, 0xff,
|
||||
0, 0, 0xc0, 0xff,
|
||||
}, 0, 0, 3, 1)
|
||||
}, image.Rect(0, 0, 3, 1))
|
||||
srcs := [graphics.ShaderImageCount]*restorable.Image{src, src, src}
|
||||
|
||||
dst := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
|
||||
|
Loading…
Reference in New Issue
Block a user