opengl: Move Framebuffer from graphicscommand to opengl and rename it to FramebufferStruct

This commit is contained in:
Hajime Hoshi 2018-11-04 17:28:33 +09:00
parent 97a9e99112
commit c935c28498
8 changed files with 54 additions and 51 deletions

View File

@ -236,13 +236,13 @@ func (c *drawImageCommand) Exec(indexOffsetInBytes int) error {
// On some environments, viewport size must be within the framebuffer size.
// e.g. Edge (#71), Chrome on GPD Pocket (#420), macOS Mojave (#691).
// Use the same size of the framebuffer here.
opengl.GetContext().SetViewport(f.native, f.width, f.height)
opengl.GetContext().SetViewport(f)
opengl.GetContext().BlendFunc(c.mode)
if c.nindices == 0 {
return nil
}
proj := f.projectionMatrix()
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)
@ -344,7 +344,7 @@ func (c *pixelsCommand) Exec(indexOffsetInBytes int) error {
if err != nil {
return err
}
p, err := opengl.GetContext().FramebufferPixels(f.native, c.img.width, c.img.height)
p, err := opengl.GetContext().FramebufferPixels(f, c.img.width, c.img.height)
if err != nil {
return err
}
@ -385,9 +385,8 @@ func (c *disposeCommand) String() string {
// Exec executes the disposeCommand.
func (c *disposeCommand) Exec(indexOffsetInBytes int) error {
if c.target.framebuffer != nil &&
c.target.framebuffer.native != opengl.GetContext().ScreenFramebuffer() {
opengl.GetContext().DeleteFramebuffer(c.target.framebuffer.native)
if c.target.framebuffer != nil {
c.target.framebuffer.Delete()
}
if c.target.texture != *new(opengl.Texture) {
opengl.GetContext().DeleteTexture(c.target.texture)
@ -488,7 +487,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 = newScreenFramebuffer(c.width, c.height)
c.result.framebuffer = opengl.NewScreenFramebuffer(c.width, c.height)
return nil
}

View File

@ -43,7 +43,7 @@ func MaxImageSize() int {
// Image represents an image that is implemented with OpenGL.
type Image struct {
texture opengl.Texture
framebuffer *framebuffer
framebuffer *opengl.FramebufferStruct
width int
height int
}
@ -121,11 +121,11 @@ func (i *Image) IsInvalidated() bool {
return !opengl.GetContext().IsTexture(i.texture)
}
func (i *Image) ensureFramebuffer() (*framebuffer, error) {
func (i *Image) ensureFramebuffer() (*opengl.FramebufferStruct, error) {
if i.framebuffer != nil {
return i.framebuffer, nil
}
f, err := newFramebufferFromTexture(i.texture, math.NextPowerOf2Int(i.width), math.NextPowerOf2Int(i.height))
f, err := opengl.NewFramebufferFromTexture(i.texture, math.NextPowerOf2Int(i.width), math.NextPowerOf2Int(i.height))
if err != nil {
return nil, err
}

View File

@ -96,24 +96,24 @@ func (c *Context) bindFramebuffer(f Framebuffer) {
c.lastFramebuffer = f
}
func (c *Context) SetViewport(f Framebuffer, width, height int) {
c.bindFramebuffer(f)
if c.lastViewportWidth != width || c.lastViewportHeight != height {
c.setViewportImpl(width, height)
func (c *Context) SetViewport(f *FramebufferStruct) {
c.bindFramebuffer(f.native)
if c.lastViewportWidth != f.width || c.lastViewportHeight != f.height {
c.setViewportImpl(f.width, f.height)
// glViewport must be called at least at every frame on iOS.
// As the screen framebuffer is the last render target, next SetViewport should be
// the first call at a frame.
if f == c.screenFramebuffer {
if f.native == c.screenFramebuffer {
c.lastViewportWidth = 0
c.lastViewportHeight = 0
} else {
c.lastViewportWidth = width
c.lastViewportHeight = height
c.lastViewportWidth = f.width
c.lastViewportHeight = f.height
}
}
}
func (c *Context) ScreenFramebuffer() Framebuffer {
func (c *Context) getScreenFramebuffer() Framebuffer {
return c.screenFramebuffer
}

View File

@ -169,13 +169,13 @@ func (c *Context) bindFramebufferImpl(f Framebuffer) {
})
}
func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]byte, error) {
func (c *Context) FramebufferPixels(f *FramebufferStruct, width, height int) ([]byte, error) {
var pixels []byte
_ = c.runOnContextThread(func() error {
gl.Flush()
return nil
})
c.bindFramebuffer(f)
c.bindFramebuffer(f.native)
if err := c.runOnContextThread(func() error {
pixels = make([]byte, 4*width*height)
gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(pixels))
@ -232,7 +232,7 @@ func (c *Context) BeforeSwapping() {
c.bindFramebuffer(c.screenFramebuffer)
}
func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
func (c *Context) newFramebuffer(texture Texture) (Framebuffer, error) {
var framebuffer Framebuffer
var f uint32
if err := c.runOnContextThread(func() error {
@ -273,7 +273,7 @@ func (c *Context) setViewportImpl(width, height int) {
})
}
func (c *Context) DeleteFramebuffer(f Framebuffer) {
func (c *Context) deleteFramebuffer(f Framebuffer) {
_ = c.runOnContextThread(func() error {
ff := uint32(f)
if !gl.IsFramebufferEXT(ff) {

View File

@ -204,10 +204,10 @@ func (c *Context) bindFramebufferImpl(f Framebuffer) {
gl.Call("bindFramebuffer", framebuffer, js.Value(f))
}
func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]byte, error) {
func (c *Context) FramebufferPixels(f *FramebufferStruct, width, height int) ([]byte, error) {
gl := c.gl
c.bindFramebuffer(f)
c.bindFramebuffer(f.native)
pixels := make([]byte, 4*width*height)
p := js.TypedArrayOf(pixels)
@ -252,7 +252,7 @@ func (c *Context) TexSubImage2D(t Texture, pixels []byte, x, y, width, height in
p.Release()
}
func (c *Context) NewFramebuffer(t Texture) (Framebuffer, error) {
func (c *Context) newFramebuffer(t Texture) (Framebuffer, error) {
gl := c.gl
f := gl.Call("createFramebuffer")
c.bindFramebuffer(Framebuffer(f))
@ -270,7 +270,7 @@ func (c *Context) setViewportImpl(width, height int) {
gl.Call("viewport", 0, 0, width, height)
}
func (c *Context) DeleteFramebuffer(f Framebuffer) {
func (c *Context) deleteFramebuffer(f Framebuffer) {
gl := c.gl
if !gl.Call("isFramebuffer", js.Value(f)).Bool() {
return

View File

@ -156,11 +156,11 @@ func (c *Context) bindFramebufferImpl(f Framebuffer) {
gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(f))
}
func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]byte, error) {
func (c *Context) FramebufferPixels(f *FramebufferStruct, width, height int) ([]byte, error) {
gl := c.gl
gl.Flush()
c.bindFramebuffer(f)
c.bindFramebuffer(f.native)
pixels := make([]byte, 4*width*height)
gl.ReadPixels(pixels, 0, 0, width, height, mgl.RGBA, mgl.UNSIGNED_BYTE)
@ -197,7 +197,7 @@ func (c *Context) TexSubImage2D(t Texture, p []byte, x, y, width, height int) {
gl.TexSubImage2D(mgl.TEXTURE_2D, 0, x, y, width, height, mgl.RGBA, mgl.UNSIGNED_BYTE, p)
}
func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
func (c *Context) newFramebuffer(texture Texture) (Framebuffer, error) {
gl := c.gl
f := gl.CreateFramebuffer()
if f.Value <= 0 {
@ -224,7 +224,7 @@ func (c *Context) setViewportImpl(width, height int) {
gl.Viewport(0, 0, width, height)
}
func (c *Context) DeleteFramebuffer(f Framebuffer) {
func (c *Context) deleteFramebuffer(f Framebuffer) {
gl := c.gl
if !gl.IsFramebuffer(mgl.Framebuffer(f)) {
return

View File

@ -12,51 +12,55 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package graphicscommand
package opengl
import (
"github.com/hajimehoshi/ebiten/internal/opengl"
)
// framebuffer is a wrapper of OpenGL's framebuffer.
type framebuffer struct {
native opengl.Framebuffer
// FramebufferStruct is a wrapper of OpenGL's framebuffer.
//
// TODO: Create a new struct Image and embed this struct.
type FramebufferStruct struct {
native Framebuffer
proMatrix []float32
width int
height int
}
// newFramebufferFromTexture creates a framebuffer from the given texture.
func newFramebufferFromTexture(texture opengl.Texture, width, height int) (*framebuffer, error) {
native, err := opengl.GetContext().NewFramebuffer(texture)
// NewFramebufferFromTexture creates a framebuffer from the given texture.
func NewFramebufferFromTexture(texture Texture, width, height int) (*FramebufferStruct, error) {
native, err := theContext.newFramebuffer(texture)
if err != nil {
return nil, err
}
return &framebuffer{
return &FramebufferStruct{
native: native,
width: width,
height: height,
}, nil
}
// newScreenFramebuffer creates a framebuffer for the screen.
func newScreenFramebuffer(width, height int) *framebuffer {
return &framebuffer{
native: opengl.GetContext().ScreenFramebuffer(),
// NewScreenFramebuffer creates a framebuffer for the screen.
func NewScreenFramebuffer(width, height int) *FramebufferStruct {
return &FramebufferStruct{
native: theContext.getScreenFramebuffer(),
width: width,
height: height,
}
}
// projectionMatrix returns a projection matrix of the framebuffer.
// ProjectionMatrix returns a projection matrix of the framebuffer.
//
// A projection matrix converts the coodinates on the framebuffer
// (0, 0) - (viewport width, viewport height)
// to the normalized device coodinates (-1, -1) - (1, 1) with adjustment.
func (f *framebuffer) projectionMatrix() []float32 {
func (f *FramebufferStruct) ProjectionMatrix() []float32 {
if f.proMatrix != nil {
return f.proMatrix
}
f.proMatrix = opengl.OrthoProjectionMatrix(0, f.width, 0, f.height)
f.proMatrix = orthoProjectionMatrix(0, f.width, 0, f.height)
return f.proMatrix
}
func (f *FramebufferStruct) Delete() {
if f.native != theContext.getScreenFramebuffer() {
theContext.deleteFramebuffer(f.native)
}
}

View File

@ -14,10 +14,10 @@
package opengl
// OrthoProjectionMatrix returns an orthogonal projection matrix for OpenGL.
// orthoProjectionMatrix returns an orthogonal projection matrix for OpenGL.
//
// The matrix converts the coodinates (left, bottom) - (right, top) to the normalized device coodinates (-1, -1) - (1, 1).
func OrthoProjectionMatrix(left, right, bottom, top int) []float32 {
func orthoProjectionMatrix(left, right, bottom, top int) []float32 {
e11 := 2 / float32(right-left)
e22 := 2 / float32(top-bottom)
e14 := -1 * float32(right+left) / float32(right-left)