SDL2: Cache Bitmaps in Memory, Not on Disk
* Update the SDL2 engine's texture caching to use an sdl.RWops file buffer in memory instead of outputting bitmap images to the filesystem.
This commit is contained in:
parent
ba6892aa95
commit
3d199ca263
|
@ -25,6 +25,7 @@ type Renderer struct {
|
|||
renderer *sdl.Renderer
|
||||
running bool
|
||||
ticks uint64
|
||||
textures map[string]*Texture // cached textures
|
||||
|
||||
// Optimizations to minimize SDL calls.
|
||||
lastColor render.Color
|
||||
|
@ -33,10 +34,11 @@ type Renderer struct {
|
|||
// New creates the SDL renderer.
|
||||
func New(title string, width, height int) *Renderer {
|
||||
return &Renderer{
|
||||
events: events.New(),
|
||||
title: title,
|
||||
width: int32(width),
|
||||
height: int32(height),
|
||||
events: events.New(),
|
||||
title: title,
|
||||
width: int32(width),
|
||||
height: int32(height),
|
||||
textures: map[string]*Texture{},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package sdl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"os"
|
||||
|
||||
"git.kirsle.net/apps/doodle/lib/render"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
|
@ -30,14 +30,44 @@ type Texture struct {
|
|||
|
||||
// NewTexture caches an SDL texture from a bitmap.
|
||||
func (r *Renderer) NewTexture(filename string, img image.Image) (render.Texturer, error) {
|
||||
fh, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer fh.Close()
|
||||
var (
|
||||
fh = bytes.NewBuffer([]byte{})
|
||||
)
|
||||
|
||||
err = bmp.Encode(fh, img)
|
||||
return nil, err
|
||||
err := bmp.Encode(fh, img)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewTexture: bmp.Encode: %s", err)
|
||||
}
|
||||
|
||||
// Create an SDL RWOps from the bitmap data in memory.
|
||||
sdlRW, err := sdl.RWFromMem(fh.Bytes())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewTexture: sdl.RWFromMem: %s", err)
|
||||
}
|
||||
|
||||
surface, err := sdl.LoadBMPRW(sdlRW, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewTexture: sdl.LoadBMPRW: %s", err)
|
||||
}
|
||||
defer surface.Free()
|
||||
|
||||
// TODO: chroma key color hardcoded to white here
|
||||
key := sdl.MapRGB(surface.Format, 255, 255, 255)
|
||||
surface.SetColorKey(true, key)
|
||||
|
||||
texture, err := r.renderer.CreateTextureFromSurface(surface)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewBitmap: create texture: %s", err)
|
||||
}
|
||||
|
||||
tex := &Texture{
|
||||
width: surface.W,
|
||||
height: surface.H,
|
||||
tex: texture,
|
||||
}
|
||||
r.textures[filename] = tex
|
||||
|
||||
return tex, nil
|
||||
}
|
||||
|
||||
// Size returns the dimensions of the texture.
|
||||
|
@ -47,24 +77,8 @@ func (t *Texture) Size() render.Rect {
|
|||
|
||||
// NewBitmap initializes a texture from a bitmap image.
|
||||
func (r *Renderer) NewBitmap(filename string) (render.Texturer, error) {
|
||||
surface, err := sdl.LoadBMP(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewBitmap: LoadBMP: %s", err)
|
||||
if tex, ok := r.textures[filename]; ok {
|
||||
return tex, nil
|
||||
}
|
||||
defer surface.Free()
|
||||
|
||||
// TODO: chroma key color hardcoded to white here
|
||||
key := sdl.MapRGB(surface.Format, 255, 255, 255)
|
||||
surface.SetColorKey(true, key)
|
||||
|
||||
tex, err := r.renderer.CreateTextureFromSurface(surface)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NewBitmap: create texture: %s", err)
|
||||
}
|
||||
|
||||
return &Texture{
|
||||
width: surface.W,
|
||||
height: surface.H,
|
||||
tex: tex,
|
||||
}, nil
|
||||
return nil, fmt.Errorf("NewBitmap(%s): not found in texture cache", filename)
|
||||
}
|
||||
|
|
|
@ -4,13 +4,11 @@ package wallpaper
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"os"
|
||||
|
||||
"git.kirsle.net/apps/doodle/lib/render"
|
||||
"git.kirsle.net/apps/doodle/pkg/shmem"
|
||||
"git.kirsle.net/apps/doodle/pkg/userdir"
|
||||
"golang.org/x/image/bmp"
|
||||
)
|
||||
|
||||
// CornerTexture returns the Texture.
|
||||
|
@ -57,28 +55,9 @@ func (wp *Wallpaper) RepeatTexture(e render.Engine) (render.Texturer, error) {
|
|||
return wp.tex.repeat, nil
|
||||
}
|
||||
|
||||
// texture creates or returns a cached texture for a wallpaper.
|
||||
func texture(e render.Engine, img *image.RGBA, name string) (render.Texturer, error) {
|
||||
filename := userdir.CacheFilename("wallpaper", name+".bmp")
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
fh, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("texture(%s): %s", name, err.Error())
|
||||
}
|
||||
|
||||
err = bmp.Encode(fh, img)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("texture(%s): bmp.Encode: %s", name, err.Error())
|
||||
}
|
||||
|
||||
err = fh.Close()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("texture(%s): fh.Close: %s", name, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
texture, err := e.NewBitmap(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("CornerTexture: NewBitmap(%s): %s", filename, err.Error())
|
||||
}
|
||||
return texture, nil
|
||||
texture, err := shmem.CurrentRenderEngine.NewTexture(filename, img)
|
||||
return texture, err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user