diff --git a/internal/graphicscommand/command.go b/internal/graphicscommand/command.go index 0a29b0466..0f815cf4b 100644 --- a/internal/graphicscommand/command.go +++ b/internal/graphicscommand/command.go @@ -245,7 +245,7 @@ func (c *drawImageCommand) Exec(indexOffsetInBytes int) error { proj := f.ProjectionMatrix() dw, dh := c.dst.Size() sw, sh := c.src.Size() - opengl.UseProgram(proj, c.src.texture, dw, dh, sw, sh, c.color, c.filter) + opengl.UseProgram(proj, c.src.image.Texture, dw, dh, sw, sh, c.color, c.filter) opengl.GetContext().DrawElements(c.nindices, indexOffsetInBytes) // glFlush() might be necessary at least on MacBook Pro (a smilar problem at #419), @@ -311,7 +311,7 @@ func (c *replacePixelsCommand) Exec(indexOffsetInBytes int) error { // glFlush is necessary on Android. // glTexSubImage2D didn't work without this hack at least on Nexus 5x and NuAns NEO [Reloaded] (#211). opengl.GetContext().Flush() - opengl.GetContext().TexSubImage2D(c.dst.texture, c.pixels, c.x, c.y, c.width, c.height) + opengl.GetContext().TexSubImage2D(c.dst.image.Texture, c.pixels, c.x, c.y, c.width, c.height) return nil } @@ -344,7 +344,8 @@ func (c *pixelsCommand) Exec(indexOffsetInBytes int) error { if err != nil { return err } - p, err := opengl.GetContext().FramebufferPixels(f, c.img.width, c.img.height) + w, h := c.img.Size() + p, err := opengl.GetContext().FramebufferPixels(f, w, h) if err != nil { return err } @@ -385,11 +386,11 @@ func (c *disposeCommand) String() string { // Exec executes the disposeCommand. func (c *disposeCommand) Exec(indexOffsetInBytes int) error { - if c.target.framebuffer != nil { - c.target.framebuffer.Delete() + if c.target.image.Framebuffer != nil { + c.target.image.Framebuffer.Delete() } - if c.target.texture != *new(opengl.Texture) { - opengl.GetContext().DeleteTexture(c.target.texture) + if c.target.image.Texture != *new(opengl.Texture) { + opengl.GetContext().DeleteTexture(c.target.image.Texture) } return nil } @@ -448,7 +449,7 @@ func (c *newImageCommand) Exec(indexOffsetInBytes int) error { if err != nil { return err } - c.result.texture = t + c.result.image.Texture = t return nil } @@ -487,7 +488,7 @@ func (c *newScreenFramebufferImageCommand) Exec(indexOffsetInBytes int) error { // The (default) framebuffer size can't be converted to a power of 2. // On browsers, c.width and c.height are used as viewport size and // Edge can't treat a bigger viewport than the drawing area (#71). - c.result.framebuffer = opengl.NewScreenFramebuffer(c.width, c.height) + c.result.image.Framebuffer = opengl.NewScreenFramebuffer(c.width, c.height) return nil } diff --git a/internal/graphicscommand/image.go b/internal/graphicscommand/image.go index 0baaa512b..1b33aaa13 100644 --- a/internal/graphicscommand/image.go +++ b/internal/graphicscommand/image.go @@ -42,16 +42,12 @@ func MaxImageSize() int { // Image represents an image that is implemented with OpenGL. type Image struct { - texture opengl.Texture - framebuffer *opengl.Framebuffer - width int - height int + image *opengl.Image } func NewImage(width, height int) *Image { i := &Image{ - width: width, - height: height, + image: opengl.NewImage(width, height), } c := &newImageCommand{ result: i, @@ -64,8 +60,7 @@ func NewImage(width, height int) *Image { func NewScreenFramebufferImage(width, height int) *Image { i := &Image{ - width: width, - height: height, + image: opengl.NewImage(width, height), } c := &newScreenFramebufferImageCommand{ result: i, @@ -84,7 +79,7 @@ func (i *Image) Dispose() { } func (i *Image) Size() (int, int) { - return i.width, i.height + return i.image.Size() } func (i *Image) DrawImage(src *Image, vertices []float32, indices []uint16, clr *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter) { @@ -118,17 +113,18 @@ func (i *Image) ReplacePixels(p []byte, x, y, width, height int) { } func (i *Image) IsInvalidated() bool { - return !opengl.GetContext().IsTexture(i.texture) + return i.image.IsInvalidated() } func (i *Image) ensureFramebuffer() (*opengl.Framebuffer, error) { - if i.framebuffer != nil { - return i.framebuffer, nil + if i.image.Framebuffer != nil { + return i.image.Framebuffer, nil } - f, err := opengl.NewFramebufferFromTexture(i.texture, math.NextPowerOf2Int(i.width), math.NextPowerOf2Int(i.height)) + w, h := i.image.Size() + f, err := opengl.NewFramebufferFromTexture(i.image.Texture, math.NextPowerOf2Int(w), math.NextPowerOf2Int(h)) if err != nil { return nil, err } - i.framebuffer = f - return i.framebuffer, nil + i.image.Framebuffer = f + return i.image.Framebuffer, nil } diff --git a/internal/opengl/context_desktop.go b/internal/opengl/context_desktop.go index a18aa82fe..17f85dc7c 100644 --- a/internal/opengl/context_desktop.go +++ b/internal/opengl/context_desktop.go @@ -211,7 +211,7 @@ func (c *Context) DeleteTexture(t Texture) { }) } -func (c *Context) IsTexture(t Texture) bool { +func (c *Context) isTexture(t Texture) bool { r := false _ = c.runOnContextThread(func() error { r = gl.IsTexture(uint32(t)) diff --git a/internal/opengl/context_js.go b/internal/opengl/context_js.go index 392f6923b..a9ee33ffe 100644 --- a/internal/opengl/context_js.go +++ b/internal/opengl/context_js.go @@ -236,7 +236,7 @@ func (c *Context) DeleteTexture(t Texture) { gl.Call("deleteTexture", js.Value(t)) } -func (c *Context) IsTexture(t Texture) bool { +func (c *Context) isTexture(t Texture) bool { gl := c.gl return gl.Call("isTexture", js.Value(t)).Bool() } diff --git a/internal/opengl/context_mobile.go b/internal/opengl/context_mobile.go index 1c50ed421..02f3e1d7c 100644 --- a/internal/opengl/context_mobile.go +++ b/internal/opengl/context_mobile.go @@ -186,7 +186,7 @@ func (c *Context) DeleteTexture(t Texture) { gl.DeleteTexture(mgl.Texture(t)) } -func (c *Context) IsTexture(t Texture) bool { +func (c *Context) isTexture(t Texture) bool { gl := c.gl return gl.IsTexture(mgl.Texture(t)) } diff --git a/internal/opengl/image.go b/internal/opengl/image.go new file mode 100644 index 000000000..69b519817 --- /dev/null +++ b/internal/opengl/image.go @@ -0,0 +1,37 @@ +// Copyright 2018 The Ebiten Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package opengl + +type Image struct { + Texture Texture + Framebuffer *Framebuffer + width int + height int +} + +func NewImage(width, height int) *Image { + return &Image{ + width: width, + height: height, + } +} + +func (i *Image) Size() (int, int) { + return i.width, i.height +} + +func (i *Image) IsInvalidated() bool { + return !theContext.isTexture(i.Texture) +}