mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +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 {
|
type imageImpl struct {
|
||||||
framebuffer *graphics.Framebuffer
|
image *graphics.Image
|
||||||
texture *graphics.Texture
|
|
||||||
defaultFramebuffer bool
|
defaultFramebuffer bool
|
||||||
disposed bool
|
disposed bool
|
||||||
width int
|
width int
|
||||||
@ -180,7 +179,7 @@ func (i *imageImpl) Fill(clr color.Color) error {
|
|||||||
return errors.New("ebiten: image is already disposed")
|
return errors.New("ebiten: image is already disposed")
|
||||||
}
|
}
|
||||||
i.pixels = nil
|
i.pixels = nil
|
||||||
return i.framebuffer.Fill(clr)
|
return i.image.Fill(clr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isWholeNumber(x float64) bool {
|
func isWholeNumber(x float64) bool {
|
||||||
@ -222,7 +221,7 @@ func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error {
|
|||||||
geom := &options.GeoM
|
geom := &options.GeoM
|
||||||
colorm := &options.ColorM
|
colorm := &options.ColorM
|
||||||
mode := opengl.CompositeMode(options.CompositeMode)
|
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 err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -239,7 +238,7 @@ func (i *imageImpl) At(x, y int) color.Color {
|
|||||||
}
|
}
|
||||||
if i.pixels == nil {
|
if i.pixels == nil {
|
||||||
var err error
|
var err error
|
||||||
i.pixels, err = i.framebuffer.Pixels(ui.GLContext())
|
i.pixels, err = i.image.Pixels(ui.GLContext())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -259,7 +258,7 @@ func (i *imageImpl) restorePixels(context *opengl.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// TODO: As the texture is already disposed, is it correct to delete it here?
|
// 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
|
return err
|
||||||
}
|
}
|
||||||
// TODO: Recalc i.pixels here
|
// TODO: Recalc i.pixels here
|
||||||
@ -267,12 +266,11 @@ func (i *imageImpl) restorePixels(context *opengl.Context) error {
|
|||||||
for j := 0; j < i.height; j++ {
|
for j := 0; j < i.height; j++ {
|
||||||
copy(img.Pix[j*img.Stride:], i.pixels[j*i.width*4:(j+1)*i.width*4])
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
i.texture = texture
|
|
||||||
i.framebuffer = framebuffer
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,11 +280,10 @@ func (i *imageImpl) Dispose() error {
|
|||||||
if i.isDisposed() {
|
if i.isDisposed() {
|
||||||
return errors.New("ebiten: image is already disposed")
|
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
|
return err
|
||||||
}
|
}
|
||||||
i.framebuffer = nil
|
i.image = nil
|
||||||
i.texture = nil
|
|
||||||
i.disposed = true
|
i.disposed = true
|
||||||
i.pixels = nil
|
i.pixels = nil
|
||||||
runtime.SetFinalizer(i, nil)
|
runtime.SetFinalizer(i, nil)
|
||||||
@ -308,7 +305,7 @@ func (i *imageImpl) ReplacePixels(p []uint8) error {
|
|||||||
if i.isDisposed() {
|
if i.isDisposed() {
|
||||||
return errors.New("ebiten: image is already disposed")
|
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.
|
// 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()
|
imageM.Lock()
|
||||||
defer imageM.Unlock()
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
image.framebuffer = framebuffer
|
|
||||||
image.texture = texture
|
|
||||||
runtime.SetFinalizer(image, (*imageImpl).Dispose)
|
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 nil, err
|
||||||
}
|
}
|
||||||
return eimg, nil
|
return eimg, nil
|
||||||
@ -380,13 +375,11 @@ func NewImageFromImage(source image.Image, filter Filter) (*Image, error) {
|
|||||||
}
|
}
|
||||||
imageM.Lock()
|
imageM.Lock()
|
||||||
defer imageM.Unlock()
|
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 {
|
if err != nil {
|
||||||
// TODO: texture should be removed here?
|
// TODO: texture should be removed here?
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
img.framebuffer = framebuffer
|
|
||||||
img.texture = texture
|
|
||||||
runtime.SetFinalizer(img, (*imageImpl).Dispose)
|
runtime.SetFinalizer(img, (*imageImpl).Dispose)
|
||||||
return eimg, nil
|
return eimg, nil
|
||||||
}
|
}
|
||||||
@ -402,13 +395,12 @@ func newImageWithZeroFramebuffer(width, height int) (*Image, error) {
|
|||||||
func newImageWithZeroFramebufferImpl(width, height int) (*Image, error) {
|
func newImageWithZeroFramebufferImpl(width, height int) (*Image, error) {
|
||||||
imageM.Lock()
|
imageM.Lock()
|
||||||
defer imageM.Unlock()
|
defer imageM.Unlock()
|
||||||
f, err := graphics.NewZeroFramebuffer(width, height)
|
i, err := graphics.NewZeroFramebufferImage(width, height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
img := &imageImpl{
|
img := &imageImpl{
|
||||||
framebuffer: f,
|
image: i,
|
||||||
texture: nil,
|
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
defaultFramebuffer: true,
|
defaultFramebuffer: true,
|
||||||
|
@ -42,13 +42,15 @@ type Framebuffer struct {
|
|||||||
proMatrix *[4][4]float64
|
proMatrix *[4][4]float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewZeroFramebuffer(width, height int) (*Framebuffer, error) {
|
func NewZeroFramebufferImage(width, height int) (*Image, error) {
|
||||||
f := &Framebuffer{
|
f := &Framebuffer{
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
flipY: true,
|
flipY: true,
|
||||||
}
|
}
|
||||||
return f, nil
|
return &Image{
|
||||||
|
framebuffer: f,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Framebuffer) initFromTexture(context *opengl.Context, texture *Texture) error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Dispose(texture *Texture, framebuffer *Framebuffer) error {
|
func (i *Image) Dispose() error {
|
||||||
c := &disposeCommand{
|
c := &disposeCommand{
|
||||||
framebuffer: framebuffer,
|
framebuffer: i.framebuffer,
|
||||||
texture: texture,
|
texture: i.texture,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
return nil
|
return nil
|
||||||
@ -94,19 +96,19 @@ func (f *Framebuffer) projectionMatrix() *[4][4]float64 {
|
|||||||
return f.proMatrix
|
return f.proMatrix
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Framebuffer) Fill(clr color.Color) error {
|
func (i *Image) Fill(clr color.Color) error {
|
||||||
c := &fillCommand{
|
c := &fillCommand{
|
||||||
dst: f,
|
dst: i.framebuffer,
|
||||||
color: clr,
|
color: clr,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
return nil
|
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{
|
c := &drawImageCommand{
|
||||||
dst: f,
|
dst: i.framebuffer,
|
||||||
src: t,
|
src: src.texture,
|
||||||
vertices: vertices,
|
vertices: vertices,
|
||||||
geo: geo,
|
geo: geo,
|
||||||
color: clr,
|
color: clr,
|
||||||
@ -116,18 +118,19 @@ func (f *Framebuffer) DrawTexture(t *Texture, vertices []int16, geo, clr Matrix,
|
|||||||
return nil
|
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.
|
// Flush the enqueued commands so that pixels are certainly read.
|
||||||
if err := theCommandQueue.Flush(context); err != nil {
|
if err := theCommandQueue.Flush(context); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
f := i.framebuffer
|
||||||
return context.FramebufferPixels(f.native, f.width, f.height)
|
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{
|
c := &replacePixelsCommand{
|
||||||
dst: f,
|
dst: i.framebuffer,
|
||||||
texture: t,
|
texture: i.texture,
|
||||||
pixels: p,
|
pixels: p,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
|
@ -43,35 +43,44 @@ func adjustImageForTexture(img *image.RGBA) *image.RGBA {
|
|||||||
return adjustedImage
|
return adjustedImage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Image struct {
|
||||||
|
texture *Texture
|
||||||
|
framebuffer *Framebuffer
|
||||||
|
}
|
||||||
|
|
||||||
type Texture struct {
|
type Texture struct {
|
||||||
native opengl.Texture
|
native opengl.Texture
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImage(width, height int, filter opengl.Filter) (*Texture, *Framebuffer, error) {
|
func NewImage(width, height int, filter opengl.Filter) (*Image, error) {
|
||||||
texture := &Texture{}
|
i := &Image{
|
||||||
framebuffer := &Framebuffer{}
|
texture: &Texture{},
|
||||||
|
framebuffer: &Framebuffer{},
|
||||||
|
}
|
||||||
c := &newImageCommand{
|
c := &newImageCommand{
|
||||||
texture: texture,
|
texture: i.texture,
|
||||||
framebuffer: framebuffer,
|
framebuffer: i.framebuffer,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
filter: filter,
|
filter: filter,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
return texture, framebuffer, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImageFromImage(img *image.RGBA, filter opengl.Filter) (*Texture, *Framebuffer, error) {
|
func NewImageFromImage(img *image.RGBA, filter opengl.Filter) (*Image, error) {
|
||||||
texture := &Texture{}
|
i := &Image{
|
||||||
framebuffer := &Framebuffer{}
|
texture: &Texture{},
|
||||||
|
framebuffer: &Framebuffer{},
|
||||||
|
}
|
||||||
c := &newImageFromImageCommand{
|
c := &newImageFromImageCommand{
|
||||||
texture: texture,
|
texture: i.texture,
|
||||||
framebuffer: framebuffer,
|
framebuffer: i.framebuffer,
|
||||||
img: img,
|
img: img,
|
||||||
filter: filter,
|
filter: filter,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
return texture, framebuffer, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user