mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
graphics: Add Image
This commit is contained in:
parent
32e773cf10
commit
eca175e0f4
38
image.go
38
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,
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user