opengl: Add Image struct

This commit is contained in:
Hajime Hoshi 2018-11-04 18:34:36 +09:00
parent c7ea761031
commit 96f1a8aff6
6 changed files with 61 additions and 27 deletions

View File

@ -245,7 +245,7 @@ func (c *drawImageCommand) Exec(indexOffsetInBytes int) error {
proj := f.ProjectionMatrix() proj := f.ProjectionMatrix()
dw, dh := c.dst.Size() dw, dh := c.dst.Size()
sw, sh := c.src.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) opengl.GetContext().DrawElements(c.nindices, indexOffsetInBytes)
// glFlush() might be necessary at least on MacBook Pro (a smilar problem at #419), // 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. // glFlush is necessary on Android.
// glTexSubImage2D didn't work without this hack at least on Nexus 5x and NuAns NEO [Reloaded] (#211). // glTexSubImage2D didn't work without this hack at least on Nexus 5x and NuAns NEO [Reloaded] (#211).
opengl.GetContext().Flush() 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 return nil
} }
@ -344,7 +344,8 @@ func (c *pixelsCommand) Exec(indexOffsetInBytes int) error {
if err != nil { if err != nil {
return err 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 { if err != nil {
return err return err
} }
@ -385,11 +386,11 @@ func (c *disposeCommand) String() string {
// Exec executes the disposeCommand. // Exec executes the disposeCommand.
func (c *disposeCommand) Exec(indexOffsetInBytes int) error { func (c *disposeCommand) Exec(indexOffsetInBytes int) error {
if c.target.framebuffer != nil { if c.target.image.Framebuffer != nil {
c.target.framebuffer.Delete() c.target.image.Framebuffer.Delete()
} }
if c.target.texture != *new(opengl.Texture) { if c.target.image.Texture != *new(opengl.Texture) {
opengl.GetContext().DeleteTexture(c.target.texture) opengl.GetContext().DeleteTexture(c.target.image.Texture)
} }
return nil return nil
} }
@ -448,7 +449,7 @@ func (c *newImageCommand) Exec(indexOffsetInBytes int) error {
if err != nil { if err != nil {
return err return err
} }
c.result.texture = t c.result.image.Texture = t
return nil 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. // 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 // 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). // 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 return nil
} }

View File

@ -42,16 +42,12 @@ func MaxImageSize() int {
// Image represents an image that is implemented with OpenGL. // Image represents an image that is implemented with OpenGL.
type Image struct { type Image struct {
texture opengl.Texture image *opengl.Image
framebuffer *opengl.Framebuffer
width int
height int
} }
func NewImage(width, height int) *Image { func NewImage(width, height int) *Image {
i := &Image{ i := &Image{
width: width, image: opengl.NewImage(width, height),
height: height,
} }
c := &newImageCommand{ c := &newImageCommand{
result: i, result: i,
@ -64,8 +60,7 @@ func NewImage(width, height int) *Image {
func NewScreenFramebufferImage(width, height int) *Image { func NewScreenFramebufferImage(width, height int) *Image {
i := &Image{ i := &Image{
width: width, image: opengl.NewImage(width, height),
height: height,
} }
c := &newScreenFramebufferImageCommand{ c := &newScreenFramebufferImageCommand{
result: i, result: i,
@ -84,7 +79,7 @@ func (i *Image) Dispose() {
} }
func (i *Image) Size() (int, int) { 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) { 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 { func (i *Image) IsInvalidated() bool {
return !opengl.GetContext().IsTexture(i.texture) return i.image.IsInvalidated()
} }
func (i *Image) ensureFramebuffer() (*opengl.Framebuffer, error) { func (i *Image) ensureFramebuffer() (*opengl.Framebuffer, error) {
if i.framebuffer != nil { if i.image.Framebuffer != nil {
return i.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 { if err != nil {
return nil, err return nil, err
} }
i.framebuffer = f i.image.Framebuffer = f
return i.framebuffer, nil return i.image.Framebuffer, nil
} }

View File

@ -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 r := false
_ = c.runOnContextThread(func() error { _ = c.runOnContextThread(func() error {
r = gl.IsTexture(uint32(t)) r = gl.IsTexture(uint32(t))

View File

@ -236,7 +236,7 @@ func (c *Context) DeleteTexture(t Texture) {
gl.Call("deleteTexture", js.Value(t)) gl.Call("deleteTexture", js.Value(t))
} }
func (c *Context) IsTexture(t Texture) bool { func (c *Context) isTexture(t Texture) bool {
gl := c.gl gl := c.gl
return gl.Call("isTexture", js.Value(t)).Bool() return gl.Call("isTexture", js.Value(t)).Bool()
} }

View File

@ -186,7 +186,7 @@ func (c *Context) DeleteTexture(t Texture) {
gl.DeleteTexture(mgl.Texture(t)) gl.DeleteTexture(mgl.Texture(t))
} }
func (c *Context) IsTexture(t Texture) bool { func (c *Context) isTexture(t Texture) bool {
gl := c.gl gl := c.gl
return gl.IsTexture(mgl.Texture(t)) return gl.IsTexture(mgl.Texture(t))
} }

37
internal/opengl/image.go Normal file
View File

@ -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)
}