From 604c0d095f323036be78f9aabe6b7c57cadc8e9d Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Wed, 24 Dec 2014 02:04:56 +0900 Subject: [PATCH] Remove ImagePart --- ebitenutil/debugprint.go | 12 ++++----- example/blocks/blocks/font.go | 10 +++---- example/blocks/blocks/piece.go | 9 +++---- example/blocks/blocks/titlescene.go | 10 +++---- example/perspective/main.go | 11 +++----- graphics.go | 13 +++------ graphicscontext.go | 7 +++-- image.go | 42 ++++++++++++++++------------- 8 files changed, 52 insertions(+), 62 deletions(-) diff --git a/ebitenutil/debugprint.go b/ebitenutil/debugprint.go index dd5cab429..320b007b8 100644 --- a/ebitenutil/debugprint.go +++ b/ebitenutil/debugprint.go @@ -37,7 +37,7 @@ func DebugPrint(r *ebiten.Image, str string) { } func (d *debugPrintState) drawText(rt *ebiten.Image, str string, x, y int, c color.Color) { - parts := []ebiten.ImagePart{} + dsts, srcs := []image.Rectangle{}, []image.Rectangle{} locationX, locationY := 0, 0 for _, c := range str { if c == '\n' { @@ -49,10 +49,10 @@ func (d *debugPrintState) drawText(rt *ebiten.Image, str string, x, y int, c col const xCharNum = assets.TextImageWidth / assets.TextImageCharWidth srcX := (code % xCharNum) * assets.TextImageCharWidth srcY := (code / xCharNum) * assets.TextImageCharHeight - parts = append(parts, ebiten.ImagePart{ - Dst: image.Rect(locationX, locationY, locationX+assets.TextImageCharWidth, locationY+assets.TextImageCharHeight), - Src: image.Rect(srcX, srcY, srcX+assets.TextImageCharWidth, srcY+assets.TextImageCharHeight), - }) + dst := image.Rect(locationX, locationY, locationX+assets.TextImageCharWidth, locationY+assets.TextImageCharHeight) + src := image.Rect(srcX, srcY, srcX+assets.TextImageCharWidth, srcY+assets.TextImageCharHeight) + dsts = append(dsts, dst) + srcs = append(srcs, src) locationX += assets.TextImageCharWidth } geo := ebiten.TranslateGeometry(float64(x)+1, float64(y)) @@ -62,7 +62,7 @@ func (d *debugPrintState) drawText(rt *ebiten.Image, str string, x, y int, c col b := float64(cc.B) / math.MaxUint16 a := float64(cc.A) / math.MaxUint16 clr := ebiten.ScaleColor(r, g, b, a) - rt.DrawImage(d.textImage, parts, geo, clr) + rt.DrawImage(dsts, d.textImage, srcs, geo, clr) } func (d *debugPrintState) DebugPrint(r *ebiten.Image, str string) { diff --git a/example/blocks/blocks/font.go b/example/blocks/blocks/font.go index 5e58886a0..9d997aa79 100644 --- a/example/blocks/blocks/font.go +++ b/example/blocks/blocks/font.go @@ -36,7 +36,7 @@ func textWidth(str string) int { func drawText(rt *ebiten.Image, images *Images, str string, ox, oy, scale int, c color.Color) { fontImageId := images.GetImage("font") - parts := []ebiten.ImagePart{} + dsts, srcs := []image.Rectangle{}, []image.Rectangle{} locationX, locationY := 0, 0 for _, c := range str { @@ -48,10 +48,8 @@ func drawText(rt *ebiten.Image, images *Images, str string, ox, oy, scale int, c code := int(c) x := (code % 16) * charWidth y := ((code - 32) / 16) * charHeight - parts = append(parts, ebiten.ImagePart{ - Dst: image.Rect(locationX, locationY, locationX+charWidth, locationY+charHeight), - Src: image.Rect(x, y, x+charWidth, y+charHeight), - }) + dsts = append(dsts, image.Rect(locationX, locationY, locationX+charWidth, locationY+charHeight)) + srcs = append(srcs, image.Rect(x, y, x+charWidth, y+charHeight)) locationX += charWidth } @@ -64,7 +62,7 @@ func drawText(rt *ebiten.Image, images *Images, str string, ox, oy, scale int, c b := float64(c2.B) / max a := float64(c2.A) / max clr := ebiten.ScaleColor(r, g, b, a) - rt.DrawImage(fontImageId, parts, geo, clr) + rt.DrawImage(dsts, fontImageId, srcs, geo, clr) } func drawTextWithShadow(rt *ebiten.Image, images *Images, str string, x, y, scale int, clr color.Color) { diff --git a/example/blocks/blocks/piece.go b/example/blocks/blocks/piece.go index 0cb876502..c063e036e 100644 --- a/example/blocks/blocks/piece.go +++ b/example/blocks/blocks/piece.go @@ -140,7 +140,7 @@ const fieldBlockNumX = 10 const fieldBlockNumY = 20 func drawBlocks(r *ebiten.Image, images *Images, blocks [][]BlockType, geo ebiten.GeometryMatrix) { - parts := []ebiten.ImagePart{} + dsts, srcs := []image.Rectangle{}, []image.Rectangle{} for i, blockCol := range blocks { for j, block := range blockCol { if block == BlockTypeNone { @@ -148,14 +148,13 @@ func drawBlocks(r *ebiten.Image, images *Images, blocks [][]BlockType, geo ebite } locationX := i * blockWidth locationY := j * blockHeight - dst := image.Rect(locationX, locationY, locationX+blockWidth, locationY+blockHeight) + dsts = append(dsts, image.Rect(locationX, locationY, locationX+blockWidth, locationY+blockHeight)) srcX := (int(block) - 1) * blockWidth - src := image.Rect(srcX, 0, srcX+blockWidth, blockHeight) - parts = append(parts, ebiten.ImagePart{dst, src}) + srcs = append(srcs, image.Rect(srcX, 0, srcX+blockWidth, blockHeight)) } } blocksImage := images.GetImage("blocks") - r.DrawImage(blocksImage, parts, geo, ebiten.ColorMatrixI()) + r.DrawImage(dsts, blocksImage, srcs, geo, ebiten.ColorMatrixI()) } func (p *Piece) InitialPosition() (int, int) { diff --git a/example/blocks/blocks/titlescene.go b/example/blocks/blocks/titlescene.go index 743464242..ff563bd0e 100644 --- a/example/blocks/blocks/titlescene.go +++ b/example/blocks/blocks/titlescene.go @@ -56,15 +56,13 @@ func drawTitleBackground(r *ebiten.Image, images *Images, c int) { const imageHeight = 32 backgroundImage := images.GetImage("background") - parts := []ebiten.ImagePart{} + dsts, srcs := []image.Rectangle{}, []image.Rectangle{} for j := -1; j < ScreenHeight/imageHeight+1; j++ { for i := 0; i < ScreenWidth/imageWidth+1; i++ { dstX := i * imageWidth dstY := j * imageHeight - parts = append(parts, ebiten.ImagePart{ - Dst: image.Rect(dstX, dstY, dstX+imageWidth, dstY+imageHeight), - Src: image.Rect(0, 0, imageWidth, imageHeight), - }) + dsts = append(dsts, image.Rect(dstX, dstY, dstX+imageWidth, dstY+imageHeight)) + srcs = append(srcs, image.Rect(0, 0, imageWidth, imageHeight)) } } @@ -73,7 +71,7 @@ func drawTitleBackground(r *ebiten.Image, images *Images, c int) { geo := ebiten.GeometryMatrixI() geo.Concat(ebiten.TranslateGeometry(float64(dx), float64(dy))) clr := ebiten.ColorMatrixI() - r.DrawImage(backgroundImage, parts, geo, clr) + r.DrawImage(dsts, backgroundImage, srcs, geo, clr) } func drawLogo(r *ebiten.Image, images *Images, str string) { diff --git a/example/perspective/main.go b/example/perspective/main.go index b9165af28..e0dc12800 100644 --- a/example/perspective/main.go +++ b/example/perspective/main.go @@ -34,22 +34,19 @@ var ( ) func Update(screen *ebiten.Image) error { - parts := []ebiten.ImagePart{} + dsts, srcs := []image.Rectangle{}, []image.Rectangle{} w, h := gophersImage.Size() for i := 0; i < h; i++ { width := w + i*3/4 x := ((h - i) * 3 / 4) / 2 - part := ebiten.ImagePart{ - Dst: image.Rect(x, i, x+width, i+1), - Src: image.Rect(0, i, w, i+1), - } - parts = append(parts, part) + dsts = append(dsts, image.Rect(x, i, x+width, i+1)) + srcs = append(srcs, image.Rect(0, i, w, i+1)) } maxWidth := float64(w) + float64(h)*0.75 geo := ebiten.TranslateGeometry(-maxWidth/2, -float64(h)/2) geo.Concat(ebiten.ScaleGeometry(0.4, 0.4)) geo.Concat(ebiten.TranslateGeometry(screenWidth/2, screenHeight/2)) - screen.DrawImage(gophersImage, parts, geo, ebiten.ColorMatrixI()) + screen.DrawImage(dsts, gophersImage, srcs, geo, ebiten.ColorMatrixI()) return nil } diff --git a/graphics.go b/graphics.go index 4e7935bf7..f48dd9bef 100644 --- a/graphics.go +++ b/graphics.go @@ -21,19 +21,12 @@ import ( "image" ) -// An ImagePart represents a part of an image. -type ImagePart struct { - Dst image.Rectangle - Src image.Rectangle -} - // DrawWholeImage draws the whole image. func DrawWholeImage(target *Image, img *Image, geo GeometryMatrix, color ColorMatrix) error { w, h := img.Size() - parts := []ImagePart{ - {image.Rect(0, 0, w, h), image.Rect(0, 0, w, h)}, - } - return target.DrawImage(img, parts, geo, color) + dsts := []image.Rectangle{image.Rect(0, 0, w, h)} + srcs := []image.Rectangle{image.Rect(0, 0, w, h)} + return target.DrawImage(dsts, img, srcs, geo, color) } // Filter represents the type of filter to be used when an image is maginified or minified. diff --git a/graphicscontext.go b/graphicscontext.go index d40a378c9..a9834fc68 100644 --- a/graphicscontext.go +++ b/graphicscontext.go @@ -72,10 +72,9 @@ func (c *graphicsContext) postUpdate() error { geo := ScaleGeometry(scale, scale) clr := ColorMatrixI() w, h := c.screen.size() - parts := []ImagePart{ - {image.Rect(0, 0, w, h), image.Rect(0, 0, w, h)}, - } - if err := c.defaultR.drawImage(c.screen, parts, geo, clr); err != nil { + dsts := []image.Rectangle{image.Rect(0, 0, w, h)} + srcs := []image.Rectangle{image.Rect(0, 0, w, h)} + if err := c.defaultR.drawImage(dsts, c.screen, srcs, geo, clr); err != nil { return err } diff --git a/image.go b/image.go index 33a870238..d3b51d968 100644 --- a/image.go +++ b/image.go @@ -54,12 +54,12 @@ func (i *innerImage) Fill(clr color.Color) error { return nil } -func (i *innerImage) drawImage(image *innerImage, parts []ImagePart, geo GeometryMatrix, color ColorMatrix) error { +func (i *innerImage) drawImage(dsts []image.Rectangle, image *innerImage, srcs []image.Rectangle, geo GeometryMatrix, color ColorMatrix) error { if err := i.framebuffer.SetAsViewport(); err != nil { return err } w, h := image.texture.Size() - quads := textureQuads(parts, w, h) + quads := textureQuads(dsts, srcs, w, h) projectionMatrix := i.framebuffer.ProjectionMatrix() shader.DrawTexture(image.texture.Native(), projectionMatrix, quads, &geo, &color) return nil @@ -73,17 +73,22 @@ func v(y float64, height int) float32 { return float32(y) / float32(internal.NextPowerOf2Int(height)) } -func textureQuads(parts []ImagePart, width, height int) []shader.TextureQuad { - quads := make([]shader.TextureQuad, 0, len(parts)) - for _, part := range parts { - x1 := float32(part.Dst.Min.X) - x2 := float32(part.Dst.Max.X) - y1 := float32(part.Dst.Min.Y) - y2 := float32(part.Dst.Max.Y) - u1 := u(float64(part.Src.Min.X), width) - u2 := u(float64(part.Src.Max.X), width) - v1 := v(float64(part.Src.Min.Y), height) - v2 := v(float64(part.Src.Max.Y), height) +func textureQuads(dsts, srcs []image.Rectangle, width, height int) []shader.TextureQuad { + l := len(dsts) + if len(srcs) < l { + l = len(srcs) + } + quads := make([]shader.TextureQuad, 0, l) + for i := 0; i < l; i++ { + dst, src := dsts[i], srcs[i] + x1 := float32(dst.Min.X) + x2 := float32(dst.Max.X) + y1 := float32(dst.Min.Y) + y2 := float32(dst.Max.Y) + u1 := u(float64(src.Min.X), width) + u2 := u(float64(src.Max.X), width) + v1 := v(float64(src.Min.Y), height) + v2 := v(float64(src.Max.Y), height) quad := shader.TextureQuad{x1, x2, y1, y2, u1, u2, v1, v2} quads = append(quads, quad) } @@ -127,14 +132,14 @@ func (i *Image) Fill(clr color.Color) (err error) { } // DrawImage draws the given image on the receiver (i). -func (i *Image) DrawImage(image *Image, parts []ImagePart, geo GeometryMatrix, color ColorMatrix) (err error) { - return i.drawImage(image.inner, parts, geo, color) +func (i *Image) DrawImage(dsts []image.Rectangle, image *Image, srcs []image.Rectangle, geo GeometryMatrix, color ColorMatrix) (err error) { + return i.drawImage(dsts, image.inner, srcs, geo, color) } -func (i *Image) drawImage(image *innerImage, parts []ImagePart, geo GeometryMatrix, color ColorMatrix) (err error) { +func (i *Image) drawImage(dsts []image.Rectangle, image *innerImage, srcs []image.Rectangle, geo GeometryMatrix, color ColorMatrix) (err error) { i.pixels = nil i.syncer.Sync(func() { - err = i.inner.drawImage(image, parts, geo, color) + err = i.inner.drawImage(dsts, image, srcs, geo, color) }) return } @@ -151,7 +156,8 @@ func (i *Image) ColorModel() color.Model { } // At returns the color of the image at (x, y). -// This method may read pixels from GPU to VRAM and be slow. +// +// This method loads pixels from GPU to VRAM if necessary. func (i *Image) At(x, y int) color.Color { if i.pixels == nil { i.syncer.Sync(func() {