From 275fc0341364ab6556369905e498534d423c6c0d Mon Sep 17 00:00:00 2001 From: faiface Date: Tue, 6 Dec 2016 16:36:23 +0100 Subject: [PATCH] add Picture --- picture.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 picture.go diff --git a/picture.go b/picture.go new file mode 100644 index 0000000..fabfd6a --- /dev/null +++ b/picture.go @@ -0,0 +1,73 @@ +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. +// +// However note, that all of the sliced pictures share the same underlying texture. Deleting one picture also deletes +// all pictures that share the same underlying texture. +type Picture struct { + texture *pixelgl.Texture + bounds Rect +} + +// NewPicture creates a new picture from an image.Image. +func NewPicture(img image.Image) Picture { + // 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(), + rgba.Pix, + ) + if err != nil { + panic(errors.Wrap(err, "failed to create picture")) + } + + return Picture{ + texture: texture, + bounds: R(0, 0, float64(texture.Width()), float64(texture.Height())), + } +} + +// Delete deletes this picture and all pictures that share the same underlying texuture (all that have been +// created from the same parent using slicing). +func (p Picture) Delete() { + p.texture.Delete() +} + +// Texture returns a pointer to the underlying OpenGL texture of a picture. +func (p Picture) Texture() *pixelgl.Texture { + return p.texture +} + +// Slice returns a picture within the supplied rectangle of the original picture. The original and the sliced picture +// share the same texture. Thus deleting one also deletes the other one. +// +// 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. +func (p Picture) Slice(slice Rect) Picture { + return Picture{ + 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. +func (p Picture) Bounds() Rect { + return p.bounds +}