zntg/ui/textures.go
Sander Schobers 0f03760e66 Added Resize & SetIcon to Renderer.
Refactored Size (on Renderer) to return geom.Point instead of geom.PointF32.
Refactored Width and Height (on Texture) to return int instead of float32.

Refactored texture dimensions to be represented by ints instead of float32s.
2020-12-13 07:40:19 +01:00

143 lines
3.0 KiB
Go

package ui
import (
"image"
"github.com/nfnt/resize"
"opslag.de/schobers/geom"
)
func ScaleTexture(render Renderer, texture Texture, scale float32) Texture {
w := uint(float32(texture.Width()) * scale)
if w == 0 {
return nil
}
source, ok := texture.(ImageSource)
if !ok {
return nil
}
image, err := source.CreateImage()
if err != nil {
return nil
}
scaled := resize.Resize(w, 0, image, resize.Bilinear)
res, err := render.CreateTextureGo(scaled, false)
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) createTexture(name string, create func() (Texture, error)) (Texture, error) {
texture, err := create()
if err != nil {
return nil, err
}
t.AddTexture(name, texture)
return texture, nil
}
func (t *Textures) CreateTexture(name string, source ImageSource) (Texture, error) {
return t.createTexture(name, func() (Texture, error) {
return t.render.CreateTexture(source)
})
}
func (t *Textures) CreateTextureGo(name string, im image.Image, source bool) (Texture, error) {
return t.createTexture(name, func() (Texture, error) {
return t.render.CreateTextureGo(im, source)
})
}
func (t *Textures) CreateTexturePath(name string, path string, source bool) (Texture, error) {
return t.createTexture(name, func() (Texture, error) {
return t.render.CreateTexturePath(path, source)
})
}
func (t *Textures) Destroy() {
for _, texture := range t.textures {
texture.Destroy()
}
t.textures = nil
for _, texture := range t.scaled {
texture.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)
if scaled == nil {
return nil
}
textures[scale] = scaled
t.scaled[texture] = textures
return scaled
}
func (t *Textures) ScaledHeight(texture Texture, height float32) (Texture, float32) {
scale := height / float32(texture.Height())
if geom.IsNaN32(scale) {
return nil, 0
}
return t.Scaled(texture, scale), scale
}
func (t *Textures) ScaledByName(name string, scale float32) Texture {
texture := t.Texture(name)
if texture == nil {
return nil
}
return t.Scaled(texture, scale)
}
type ScaledTextures map[float32]Texture
func (t ScaledTextures) Destroy() {
for _, texture := range t {
texture.Destroy()
}
}