graphics: Refactoring: Use map in mipmap

This commit is contained in:
Hajime Hoshi 2019-07-30 17:50:37 +09:00
parent d25d184ed7
commit 69ef9eb184

View File

@ -23,15 +23,17 @@ import (
"github.com/hajimehoshi/ebiten/internal/shareable" "github.com/hajimehoshi/ebiten/internal/shareable"
) )
type levelToImage map[int]*shareable.Image
type mipmap struct { type mipmap struct {
orig *shareable.Image orig *shareable.Image
imgs map[image.Rectangle][]*shareable.Image imgs map[image.Rectangle]levelToImage
} }
func newMipmap(s *shareable.Image) *mipmap { func newMipmap(s *shareable.Image) *mipmap {
return &mipmap{ return &mipmap{
orig: s, orig: s,
imgs: map[image.Rectangle][]*shareable.Image{}, imgs: map[image.Rectangle]levelToImage{},
} }
} }
@ -44,51 +46,50 @@ func (m *mipmap) level(r image.Rectangle, level int) *shareable.Image {
panic("ebiten: level must be positive at level") panic("ebiten: level must be positive at level")
} }
imgs, ok := m.imgs[r]
if !ok {
imgs = []*shareable.Image{}
m.imgs[r] = imgs
}
idx := level - 1
size := r.Size()
w, h := size.X, size.Y
if len(imgs) > 0 {
w, h = imgs[len(imgs)-1].Size()
}
for len(imgs) < idx+1 {
if m.orig.IsVolatile() { if m.orig.IsVolatile() {
panic("ebiten: mipmap images for a volatile image is not implemented yet") panic("ebiten: mipmap images for a volatile image is not implemented yet")
} }
w2 := w / 2 if _, ok := m.imgs[r]; !ok {
h2 := h / 2 m.imgs[r] = levelToImage{}
if w2 == 0 || h2 == 0 { }
imgs := m.imgs[r]
if img, ok := imgs[level]; ok {
return img
}
size := r.Size()
w, h := size.X, size.Y
w2, h2 := w, h
for i := 0; i < level; i++ {
w2 /= 2
h2 /= 2
if w == 0 || h == 0 {
imgs[level] = nil
return nil return nil
} }
}
s := shareable.NewImage(w2, h2) s := shareable.NewImage(w2, h2)
var src *shareable.Image var src *shareable.Image
vs := vertexSlice(4) vs := vertexSlice(4)
if l := len(imgs); l == 0 { if level == 1 {
src = m.orig src = m.orig
graphics.PutQuadVertices(vs, src, r.Min.X, r.Min.Y, r.Max.X, r.Max.Y, 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1) graphics.PutQuadVertices(vs, src, r.Min.X, r.Min.Y, r.Max.X, r.Max.Y, 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1)
} else { } else {
src = m.level(r, l) src = m.level(r, level-1)
if src == nil {
imgs[level] = nil
return nil
}
graphics.PutQuadVertices(vs, src, 0, 0, w, h, 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1) graphics.PutQuadVertices(vs, src, 0, 0, w, h, 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1)
} }
is := graphics.QuadIndices() is := graphics.QuadIndices()
s.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, driver.FilterLinear, driver.AddressClampToZero) s.DrawTriangles(src, vs, is, nil, driver.CompositeModeCopy, driver.FilterLinear, driver.AddressClampToZero)
imgs = append(imgs, s) imgs[level] = s
w = w2
h = h2
}
m.imgs[r] = imgs
if len(imgs) <= idx { return imgs[level]
return nil
}
return imgs[idx]
} }
func (m *mipmap) isDisposed() bool { func (m *mipmap) isDisposed() bool {