2016-12-06 09:36:23 -06:00
|
|
|
package pixel
|
|
|
|
|
|
|
|
import (
|
|
|
|
"image"
|
|
|
|
"image/draw"
|
|
|
|
|
|
|
|
"github.com/faiface/pixel/pixelgl"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Picture is a raster picture. It is usually used with sprites.
|
|
|
|
//
|
|
|
|
// A picture is created from an image.Image, that can be either loaded from a file, or generated. After the creation
|
|
|
|
// a picture can be sliced (slicing creates a "sub-picture" from a picture) into smaller pictures.
|
|
|
|
type Picture struct {
|
|
|
|
texture *pixelgl.Texture
|
|
|
|
bounds Rect
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewPicture creates a new picture from an image.Image.
|
2016-12-21 13:51:05 -06:00
|
|
|
func NewPicture(img image.Image, smooth bool) *Picture {
|
2016-12-06 09:36:23 -06:00
|
|
|
// convert the image to RGBA format
|
|
|
|
rgba := image.NewRGBA(image.Rect(0, 0, img.Bounds().Dx(), img.Bounds().Dy()))
|
|
|
|
draw.Draw(rgba, rgba.Bounds(), img, img.Bounds().Min, draw.Src)
|
|
|
|
|
|
|
|
texture, err := pixelgl.NewTexture(
|
|
|
|
pixelgl.NoOpDoer,
|
|
|
|
img.Bounds().Dx(),
|
|
|
|
img.Bounds().Dy(),
|
2016-12-21 13:51:05 -06:00
|
|
|
smooth,
|
2016-12-06 09:36:23 -06:00
|
|
|
rgba.Pix,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
panic(errors.Wrap(err, "failed to create picture"))
|
|
|
|
}
|
|
|
|
|
2016-12-18 18:11:34 -06:00
|
|
|
return &Picture{
|
2016-12-06 09:36:23 -06:00
|
|
|
texture: texture,
|
|
|
|
bounds: R(0, 0, float64(texture.Width()), float64(texture.Height())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Texture returns a pointer to the underlying OpenGL texture of a picture.
|
2016-12-06 09:38:00 -06:00
|
|
|
//
|
|
|
|
// Note, that the parent of this texture is pixelgl.NoOpDoer.
|
2016-12-18 18:11:34 -06:00
|
|
|
func (p *Picture) Texture() *pixelgl.Texture {
|
2016-12-06 09:36:23 -06:00
|
|
|
return p.texture
|
|
|
|
}
|
|
|
|
|
|
|
|
// Slice returns a picture within the supplied rectangle of the original picture. The original and the sliced picture
|
2016-12-18 13:16:27 -06:00
|
|
|
// share the same texture.
|
2016-12-06 09:36:23 -06:00
|
|
|
//
|
|
|
|
// For example, suppose we have a 100x200 pixels picture. If we slice it with rectangle (50, 100, 50, 100), we get
|
|
|
|
// the upper-right quadrant of the original picture.
|
2016-12-18 18:11:34 -06:00
|
|
|
func (p *Picture) Slice(slice Rect) *Picture {
|
|
|
|
return &Picture{
|
2016-12-06 09:36:23 -06:00
|
|
|
texture: p.texture,
|
|
|
|
bounds: Rect{p.bounds.Pos + slice.Pos, slice.Size},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bounds returns the bounding rectangle of this picture relative to the most original picture.
|
|
|
|
//
|
|
|
|
// If the original picture gets sliced with the return value of this method, this picture will be obtained.
|
2016-12-18 18:11:34 -06:00
|
|
|
func (p *Picture) Bounds() Rect {
|
2016-12-06 09:36:23 -06:00
|
|
|
return p.bounds
|
|
|
|
}
|