diff --git a/sdl/sdl.go b/sdl/sdl.go index a3a176a..c54767f 100644 --- a/sdl/sdl.go +++ b/sdl/sdl.go @@ -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{}, } } diff --git a/sdl/texture.go b/sdl/texture.go index 0fdad45..677ef72 100644 --- a/sdl/texture.go +++ b/sdl/texture.go @@ -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,26 +30,24 @@ 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) + var ( + fh = bytes.NewBuffer([]byte{}) + ) + + err := bmp.Encode(fh, img) if err != nil { - return nil, err + return nil, fmt.Errorf("NewTexture: bmp.Encode: %s", err) } - defer fh.Close() - - err = bmp.Encode(fh, img) - return nil, err -} -// Size returns the dimensions of the texture. -func (t *Texture) Size() render.Rect { - return render.NewRect(t.width, t.height) -} + // 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) + } -// NewBitmap initializes a texture from a bitmap image. -func (r *Renderer) NewBitmap(filename string) (render.Texturer, error) { - surface, err := sdl.LoadBMP(filename) + surface, err := sdl.LoadBMPRW(sdlRW, true) if err != nil { - return nil, fmt.Errorf("NewBitmap: LoadBMP: %s", err) + return nil, fmt.Errorf("NewTexture: sdl.LoadBMPRW: %s", err) } defer surface.Free() @@ -57,14 +55,30 @@ func (r *Renderer) NewBitmap(filename string) (render.Texturer, error) { key := sdl.MapRGB(surface.Format, 255, 255, 255) surface.SetColorKey(true, key) - tex, err := r.renderer.CreateTextureFromSurface(surface) + texture, err := r.renderer.CreateTextureFromSurface(surface) if err != nil { return nil, fmt.Errorf("NewBitmap: create texture: %s", err) } - return &Texture{ + tex := &Texture{ width: surface.W, height: surface.H, - tex: tex, - }, nil + tex: texture, + } + r.textures[filename] = tex + + return tex, nil +} + +// Size returns the dimensions of the texture. +func (t *Texture) Size() render.Rect { + return render.NewRect(t.width, t.height) +} + +// NewBitmap initializes a texture from a bitmap image. +func (r *Renderer) NewBitmap(filename string) (render.Texturer, error) { + if tex, ok := r.textures[filename]; ok { + return tex, nil + } + return nil, fmt.Errorf("NewBitmap(%s): not found in texture cache", filename) }