From eca175e0f440b7fabb636b6d8824db72015b1acd Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 12 Jun 2016 01:34:21 +0900 Subject: [PATCH] graphics: Add Image --- image.go | 38 +++++++++++++------------------- internal/graphics/framebuffer.go | 31 ++++++++++++++------------ internal/graphics/texture.go | 33 +++++++++++++++++---------- 3 files changed, 53 insertions(+), 49 deletions(-) diff --git a/image.go b/image.go index 72d484810..661f0cd92 100644 --- a/image.go +++ b/image.go @@ -163,8 +163,7 @@ func (i *Image) ReplacePixels(p []uint8) error { } type imageImpl struct { - framebuffer *graphics.Framebuffer - texture *graphics.Texture + image *graphics.Image defaultFramebuffer bool disposed bool width int @@ -180,7 +179,7 @@ func (i *imageImpl) Fill(clr color.Color) error { return errors.New("ebiten: image is already disposed") } i.pixels = nil - return i.framebuffer.Fill(clr) + return i.image.Fill(clr) } func isWholeNumber(x float64) bool { @@ -222,7 +221,7 @@ func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error { geom := &options.GeoM colorm := &options.ColorM mode := opengl.CompositeMode(options.CompositeMode) - if err := i.framebuffer.DrawTexture(image.impl.texture, vertices[:16*n], geom, colorm, mode); err != nil { + if err := i.image.DrawImage(image.impl.image, vertices[:16*n], geom, colorm, mode); err != nil { return err } return nil @@ -239,7 +238,7 @@ func (i *imageImpl) At(x, y int) color.Color { } if i.pixels == nil { var err error - i.pixels, err = i.framebuffer.Pixels(ui.GLContext()) + i.pixels, err = i.image.Pixels(ui.GLContext()) if err != nil { panic(err) } @@ -259,7 +258,7 @@ func (i *imageImpl) restorePixels(context *opengl.Context) error { return nil } // TODO: As the texture is already disposed, is it correct to delete it here? - if err := graphics.Dispose(i.texture, i.framebuffer); err != nil { + if err := i.image.Dispose(); err != nil { return err } // TODO: Recalc i.pixels here @@ -267,12 +266,11 @@ func (i *imageImpl) restorePixels(context *opengl.Context) error { for j := 0; j < i.height; j++ { copy(img.Pix[j*img.Stride:], i.pixels[j*i.width*4:(j+1)*i.width*4]) } - texture, framebuffer, err := graphics.NewImageFromImage(img, glFilter(context, i.filter)) + var err error + i.image, err = graphics.NewImageFromImage(img, glFilter(context, i.filter)) if err != nil { return err } - i.texture = texture - i.framebuffer = framebuffer return nil } @@ -282,11 +280,10 @@ func (i *imageImpl) Dispose() error { if i.isDisposed() { return errors.New("ebiten: image is already disposed") } - if err := graphics.Dispose(i.texture, i.framebuffer); err != nil { + if err := i.image.Dispose(); err != nil { return err } - i.framebuffer = nil - i.texture = nil + i.image = nil i.disposed = true i.pixels = nil runtime.SetFinalizer(i, nil) @@ -308,7 +305,7 @@ func (i *imageImpl) ReplacePixels(p []uint8) error { if i.isDisposed() { return errors.New("ebiten: image is already disposed") } - return i.framebuffer.ReplacePixels(i.texture, p) + return i.image.ReplacePixels(p) } // A DrawImageOptions represents options to render an image on an image. @@ -339,14 +336,12 @@ func NewImage(width, height int, filter Filter) (*Image, error) { } imageM.Lock() defer imageM.Unlock() - texture, framebuffer, err := graphics.NewImage(width, height, glFilter(ui.GLContext(), filter)) + image.image, err = graphics.NewImage(width, height, glFilter(ui.GLContext(), filter)) if err != nil { return nil, err } - image.framebuffer = framebuffer - image.texture = texture runtime.SetFinalizer(image, (*imageImpl).Dispose) - if err := image.framebuffer.Fill(color.Transparent); err != nil { + if err := image.image.Fill(color.Transparent); err != nil { return nil, err } return eimg, nil @@ -380,13 +375,11 @@ func NewImageFromImage(source image.Image, filter Filter) (*Image, error) { } imageM.Lock() defer imageM.Unlock() - texture, framebuffer, err := graphics.NewImageFromImage(rgbaImg, glFilter(ui.GLContext(), filter)) + img.image, err = graphics.NewImageFromImage(rgbaImg, glFilter(ui.GLContext(), filter)) if err != nil { // TODO: texture should be removed here? return nil, err } - img.framebuffer = framebuffer - img.texture = texture runtime.SetFinalizer(img, (*imageImpl).Dispose) return eimg, nil } @@ -402,13 +395,12 @@ func newImageWithZeroFramebuffer(width, height int) (*Image, error) { func newImageWithZeroFramebufferImpl(width, height int) (*Image, error) { imageM.Lock() defer imageM.Unlock() - f, err := graphics.NewZeroFramebuffer(width, height) + i, err := graphics.NewZeroFramebufferImage(width, height) if err != nil { return nil, err } img := &imageImpl{ - framebuffer: f, - texture: nil, + image: i, width: width, height: height, defaultFramebuffer: true, diff --git a/internal/graphics/framebuffer.go b/internal/graphics/framebuffer.go index 30cb3b009..7446e173b 100644 --- a/internal/graphics/framebuffer.go +++ b/internal/graphics/framebuffer.go @@ -42,13 +42,15 @@ type Framebuffer struct { proMatrix *[4][4]float64 } -func NewZeroFramebuffer(width, height int) (*Framebuffer, error) { +func NewZeroFramebufferImage(width, height int) (*Image, error) { f := &Framebuffer{ width: width, height: height, flipY: true, } - return f, nil + return &Image{ + framebuffer: f, + }, nil } func (f *Framebuffer) initFromTexture(context *opengl.Context, texture *Texture) error { @@ -62,10 +64,10 @@ func (f *Framebuffer) initFromTexture(context *opengl.Context, texture *Texture) return nil } -func Dispose(texture *Texture, framebuffer *Framebuffer) error { +func (i *Image) Dispose() error { c := &disposeCommand{ - framebuffer: framebuffer, - texture: texture, + framebuffer: i.framebuffer, + texture: i.texture, } theCommandQueue.Enqueue(c) return nil @@ -94,19 +96,19 @@ func (f *Framebuffer) projectionMatrix() *[4][4]float64 { return f.proMatrix } -func (f *Framebuffer) Fill(clr color.Color) error { +func (i *Image) Fill(clr color.Color) error { c := &fillCommand{ - dst: f, + dst: i.framebuffer, color: clr, } theCommandQueue.Enqueue(c) return nil } -func (f *Framebuffer) DrawTexture(t *Texture, vertices []int16, geo, clr Matrix, mode opengl.CompositeMode) error { +func (i *Image) DrawImage(src *Image, vertices []int16, geo, clr Matrix, mode opengl.CompositeMode) error { c := &drawImageCommand{ - dst: f, - src: t, + dst: i.framebuffer, + src: src.texture, vertices: vertices, geo: geo, color: clr, @@ -116,18 +118,19 @@ func (f *Framebuffer) DrawTexture(t *Texture, vertices []int16, geo, clr Matrix, return nil } -func (f *Framebuffer) Pixels(context *opengl.Context) ([]uint8, error) { +func (i *Image) Pixels(context *opengl.Context) ([]uint8, error) { // Flush the enqueued commands so that pixels are certainly read. if err := theCommandQueue.Flush(context); err != nil { return nil, err } + f := i.framebuffer return context.FramebufferPixels(f.native, f.width, f.height) } -func (f *Framebuffer) ReplacePixels(t *Texture, p []uint8) error { +func (i *Image) ReplacePixels(p []uint8) error { c := &replacePixelsCommand{ - dst: f, - texture: t, + dst: i.framebuffer, + texture: i.texture, pixels: p, } theCommandQueue.Enqueue(c) diff --git a/internal/graphics/texture.go b/internal/graphics/texture.go index 842d430fb..899f34e8e 100644 --- a/internal/graphics/texture.go +++ b/internal/graphics/texture.go @@ -43,35 +43,44 @@ func adjustImageForTexture(img *image.RGBA) *image.RGBA { return adjustedImage } +type Image struct { + texture *Texture + framebuffer *Framebuffer +} + type Texture struct { native opengl.Texture width int height int } -func NewImage(width, height int, filter opengl.Filter) (*Texture, *Framebuffer, error) { - texture := &Texture{} - framebuffer := &Framebuffer{} +func NewImage(width, height int, filter opengl.Filter) (*Image, error) { + i := &Image{ + texture: &Texture{}, + framebuffer: &Framebuffer{}, + } c := &newImageCommand{ - texture: texture, - framebuffer: framebuffer, + texture: i.texture, + framebuffer: i.framebuffer, width: width, height: height, filter: filter, } theCommandQueue.Enqueue(c) - return texture, framebuffer, nil + return i, nil } -func NewImageFromImage(img *image.RGBA, filter opengl.Filter) (*Texture, *Framebuffer, error) { - texture := &Texture{} - framebuffer := &Framebuffer{} +func NewImageFromImage(img *image.RGBA, filter opengl.Filter) (*Image, error) { + i := &Image{ + texture: &Texture{}, + framebuffer: &Framebuffer{}, + } c := &newImageFromImageCommand{ - texture: texture, - framebuffer: framebuffer, + texture: i.texture, + framebuffer: i.framebuffer, img: img, filter: filter, } theCommandQueue.Enqueue(c) - return texture, framebuffer, nil + return i, nil }