zntg/ui/textures.go

124 lines
2.4 KiB
Go

package ui
import (
"image"
"github.com/nfnt/resize"
"opslag.de/schobers/geom"
)
type CreateImageFn func() (image.Image, error)
func ScaleTexture(render Renderer, texture Texture, scale float32) Texture {
w := uint(texture.Width() * scale)
if w == 0 {
return nil
}
scaled := resize.Resize(w, 0, texture.Texture(), resize.Bilinear)
res, err := render.CreateTexture(scaled)
if err != nil {
return nil
}
return res
}
type Textures struct {
render Renderer
textures map[string]Texture
scaled map[Texture]ScaledTextures
}
func NewTextures(render Renderer) *Textures {
return &Textures{render, map[string]Texture{}, map[Texture]ScaledTextures{}}
}
func (t *Textures) AddTexture(name string, texture Texture) {
curr := t.textures[name]
if curr != nil {
curr.Destroy()
}
t.textures[name] = texture
}
func (t *Textures) AddTextureFn(name string, create CreateImageFn) error {
im, err := create()
if err != nil {
return err
}
return t.AddTextureNative(name, im)
}
func (t *Textures) AddTextureNative(name string, im image.Image) error {
texture, err := t.render.CreateTexture(im)
if err != nil {
return err
}
t.AddTexture(name, texture)
return nil
}
func (t *Textures) Destroy() {
for _, texture := range t.textures {
texture.Destroy()
}
t.textures = nil
for _, textures := range t.scaled {
textures.Destroy()
}
t.scaled = nil
}
func (t *Textures) Texture(name string) Texture {
texture, ok := t.textures[name]
if ok {
return texture
}
return nil
}
func (t *Textures) Scaled(texture Texture, scale float32) Texture {
if scale <= 0 {
return nil
}
if scale == 1 {
return texture
}
textures := t.scaled[texture]
if textures == nil {
textures = make(ScaledTextures)
} else {
scaled := textures[scale]
if scaled != nil {
return scaled
}
}
scaled := ScaleTexture(t.render, texture, scale)
textures[scale] = scaled
t.scaled[texture] = textures
return scaled
}
func (t *Textures) ScaledHeight(textures Texture, height float32) (Texture, float32) {
scale := height / textures.Height()
if geom.IsNaN32(scale) {
return nil, 0
}
return t.Scaled(textures, scale), scale
}
func (t *Textures) ScaledByName(name string, scale float32) Texture {
textures := t.Texture(name)
if textures == nil {
return nil
}
return t.Scaled(textures, scale)
}
type ScaledTextures map[float32]Texture
func (t ScaledTextures) Destroy() {
for _, textures := range t {
textures.Destroy()
}
}