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.
master
Noah 2019-06-27 12:46:35 -07:00
parent 5893daba58
commit 4ad32c6edf
2 changed files with 47 additions and 31 deletions

View File

@ -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{},
}
}

View File

@ -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)
}