mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-13 22:47:26 +01:00
opengl: Move Framebuffer from graphicscommand to opengl and rename it to FramebufferStruct
This commit is contained in:
parent
97a9e99112
commit
c935c28498
@ -236,13 +236,13 @@ func (c *drawImageCommand) Exec(indexOffsetInBytes int) error {
|
|||||||
// On some environments, viewport size must be within the framebuffer size.
|
// On some environments, viewport size must be within the framebuffer size.
|
||||||
// e.g. Edge (#71), Chrome on GPD Pocket (#420), macOS Mojave (#691).
|
// e.g. Edge (#71), Chrome on GPD Pocket (#420), macOS Mojave (#691).
|
||||||
// Use the same size of the framebuffer here.
|
// 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)
|
opengl.GetContext().BlendFunc(c.mode)
|
||||||
|
|
||||||
if c.nindices == 0 {
|
if c.nindices == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
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.texture, dw, dh, sw, sh, c.color, c.filter)
|
||||||
@ -344,7 +344,7 @@ func (c *pixelsCommand) Exec(indexOffsetInBytes int) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -385,9 +385,8 @@ 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.framebuffer != nil {
|
||||||
c.target.framebuffer.native != opengl.GetContext().ScreenFramebuffer() {
|
c.target.framebuffer.Delete()
|
||||||
opengl.GetContext().DeleteFramebuffer(c.target.framebuffer.native)
|
|
||||||
}
|
}
|
||||||
if c.target.texture != *new(opengl.Texture) {
|
if c.target.texture != *new(opengl.Texture) {
|
||||||
opengl.GetContext().DeleteTexture(c.target.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.
|
// 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 = newScreenFramebuffer(c.width, c.height)
|
c.result.framebuffer = opengl.NewScreenFramebuffer(c.width, c.height)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ 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
|
texture opengl.Texture
|
||||||
framebuffer *framebuffer
|
framebuffer *opengl.FramebufferStruct
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
}
|
}
|
||||||
@ -121,11 +121,11 @@ func (i *Image) IsInvalidated() bool {
|
|||||||
return !opengl.GetContext().IsTexture(i.texture)
|
return !opengl.GetContext().IsTexture(i.texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) ensureFramebuffer() (*framebuffer, error) {
|
func (i *Image) ensureFramebuffer() (*opengl.FramebufferStruct, error) {
|
||||||
if i.framebuffer != nil {
|
if i.framebuffer != nil {
|
||||||
return 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -96,24 +96,24 @@ func (c *Context) bindFramebuffer(f Framebuffer) {
|
|||||||
c.lastFramebuffer = f
|
c.lastFramebuffer = f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) SetViewport(f Framebuffer, width, height int) {
|
func (c *Context) SetViewport(f *FramebufferStruct) {
|
||||||
c.bindFramebuffer(f)
|
c.bindFramebuffer(f.native)
|
||||||
if c.lastViewportWidth != width || c.lastViewportHeight != height {
|
if c.lastViewportWidth != f.width || c.lastViewportHeight != f.height {
|
||||||
c.setViewportImpl(width, height)
|
c.setViewportImpl(f.width, f.height)
|
||||||
// glViewport must be called at least at every frame on iOS.
|
// glViewport must be called at least at every frame on iOS.
|
||||||
// As the screen framebuffer is the last render target, next SetViewport should be
|
// As the screen framebuffer is the last render target, next SetViewport should be
|
||||||
// the first call at a frame.
|
// the first call at a frame.
|
||||||
if f == c.screenFramebuffer {
|
if f.native == c.screenFramebuffer {
|
||||||
c.lastViewportWidth = 0
|
c.lastViewportWidth = 0
|
||||||
c.lastViewportHeight = 0
|
c.lastViewportHeight = 0
|
||||||
} else {
|
} else {
|
||||||
c.lastViewportWidth = width
|
c.lastViewportWidth = f.width
|
||||||
c.lastViewportHeight = height
|
c.lastViewportHeight = f.height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) ScreenFramebuffer() Framebuffer {
|
func (c *Context) getScreenFramebuffer() Framebuffer {
|
||||||
return c.screenFramebuffer
|
return c.screenFramebuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
var pixels []byte
|
||||||
_ = c.runOnContextThread(func() error {
|
_ = c.runOnContextThread(func() error {
|
||||||
gl.Flush()
|
gl.Flush()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
c.bindFramebuffer(f)
|
c.bindFramebuffer(f.native)
|
||||||
if err := c.runOnContextThread(func() error {
|
if err := c.runOnContextThread(func() error {
|
||||||
pixels = make([]byte, 4*width*height)
|
pixels = make([]byte, 4*width*height)
|
||||||
gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(pixels))
|
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)
|
c.bindFramebuffer(c.screenFramebuffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
|
func (c *Context) newFramebuffer(texture Texture) (Framebuffer, error) {
|
||||||
var framebuffer Framebuffer
|
var framebuffer Framebuffer
|
||||||
var f uint32
|
var f uint32
|
||||||
if err := c.runOnContextThread(func() error {
|
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 {
|
_ = c.runOnContextThread(func() error {
|
||||||
ff := uint32(f)
|
ff := uint32(f)
|
||||||
if !gl.IsFramebufferEXT(ff) {
|
if !gl.IsFramebufferEXT(ff) {
|
||||||
|
@ -204,10 +204,10 @@ func (c *Context) bindFramebufferImpl(f Framebuffer) {
|
|||||||
gl.Call("bindFramebuffer", framebuffer, js.Value(f))
|
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
|
gl := c.gl
|
||||||
|
|
||||||
c.bindFramebuffer(f)
|
c.bindFramebuffer(f.native)
|
||||||
|
|
||||||
pixels := make([]byte, 4*width*height)
|
pixels := make([]byte, 4*width*height)
|
||||||
p := js.TypedArrayOf(pixels)
|
p := js.TypedArrayOf(pixels)
|
||||||
@ -252,7 +252,7 @@ func (c *Context) TexSubImage2D(t Texture, pixels []byte, x, y, width, height in
|
|||||||
p.Release()
|
p.Release()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) NewFramebuffer(t Texture) (Framebuffer, error) {
|
func (c *Context) newFramebuffer(t Texture) (Framebuffer, error) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
f := gl.Call("createFramebuffer")
|
f := gl.Call("createFramebuffer")
|
||||||
c.bindFramebuffer(Framebuffer(f))
|
c.bindFramebuffer(Framebuffer(f))
|
||||||
@ -270,7 +270,7 @@ func (c *Context) setViewportImpl(width, height int) {
|
|||||||
gl.Call("viewport", 0, 0, width, height)
|
gl.Call("viewport", 0, 0, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) DeleteFramebuffer(f Framebuffer) {
|
func (c *Context) deleteFramebuffer(f Framebuffer) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
if !gl.Call("isFramebuffer", js.Value(f)).Bool() {
|
if !gl.Call("isFramebuffer", js.Value(f)).Bool() {
|
||||||
return
|
return
|
||||||
|
@ -156,11 +156,11 @@ func (c *Context) bindFramebufferImpl(f Framebuffer) {
|
|||||||
gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(f))
|
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 := c.gl
|
||||||
gl.Flush()
|
gl.Flush()
|
||||||
|
|
||||||
c.bindFramebuffer(f)
|
c.bindFramebuffer(f.native)
|
||||||
|
|
||||||
pixels := make([]byte, 4*width*height)
|
pixels := make([]byte, 4*width*height)
|
||||||
gl.ReadPixels(pixels, 0, 0, width, height, mgl.RGBA, mgl.UNSIGNED_BYTE)
|
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)
|
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
|
gl := c.gl
|
||||||
f := gl.CreateFramebuffer()
|
f := gl.CreateFramebuffer()
|
||||||
if f.Value <= 0 {
|
if f.Value <= 0 {
|
||||||
@ -224,7 +224,7 @@ func (c *Context) setViewportImpl(width, height int) {
|
|||||||
gl.Viewport(0, 0, width, height)
|
gl.Viewport(0, 0, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) DeleteFramebuffer(f Framebuffer) {
|
func (c *Context) deleteFramebuffer(f Framebuffer) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
if !gl.IsFramebuffer(mgl.Framebuffer(f)) {
|
if !gl.IsFramebuffer(mgl.Framebuffer(f)) {
|
||||||
return
|
return
|
||||||
|
@ -12,51 +12,55 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package graphicscommand
|
package opengl
|
||||||
|
|
||||||
import (
|
// FramebufferStruct is a wrapper of OpenGL's framebuffer.
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
//
|
||||||
)
|
// TODO: Create a new struct Image and embed this struct.
|
||||||
|
type FramebufferStruct struct {
|
||||||
// framebuffer is a wrapper of OpenGL's framebuffer.
|
native Framebuffer
|
||||||
type framebuffer struct {
|
|
||||||
native opengl.Framebuffer
|
|
||||||
proMatrix []float32
|
proMatrix []float32
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
}
|
}
|
||||||
|
|
||||||
// newFramebufferFromTexture creates a framebuffer from the given texture.
|
// NewFramebufferFromTexture creates a framebuffer from the given texture.
|
||||||
func newFramebufferFromTexture(texture opengl.Texture, width, height int) (*framebuffer, error) {
|
func NewFramebufferFromTexture(texture Texture, width, height int) (*FramebufferStruct, error) {
|
||||||
native, err := opengl.GetContext().NewFramebuffer(texture)
|
native, err := theContext.newFramebuffer(texture)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &framebuffer{
|
return &FramebufferStruct{
|
||||||
native: native,
|
native: native,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// newScreenFramebuffer creates a framebuffer for the screen.
|
// NewScreenFramebuffer creates a framebuffer for the screen.
|
||||||
func newScreenFramebuffer(width, height int) *framebuffer {
|
func NewScreenFramebuffer(width, height int) *FramebufferStruct {
|
||||||
return &framebuffer{
|
return &FramebufferStruct{
|
||||||
native: opengl.GetContext().ScreenFramebuffer(),
|
native: theContext.getScreenFramebuffer(),
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
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
|
// A projection matrix converts the coodinates on the framebuffer
|
||||||
// (0, 0) - (viewport width, viewport height)
|
// (0, 0) - (viewport width, viewport height)
|
||||||
// to the normalized device coodinates (-1, -1) - (1, 1) with adjustment.
|
// 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 {
|
if f.proMatrix != nil {
|
||||||
return f.proMatrix
|
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
|
return f.proMatrix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *FramebufferStruct) Delete() {
|
||||||
|
if f.native != theContext.getScreenFramebuffer() {
|
||||||
|
theContext.deleteFramebuffer(f.native)
|
||||||
|
}
|
||||||
|
}
|
@ -14,10 +14,10 @@
|
|||||||
|
|
||||||
package opengl
|
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).
|
// 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)
|
e11 := 2 / float32(right-left)
|
||||||
e22 := 2 / float32(top-bottom)
|
e22 := 2 / float32(top-bottom)
|
||||||
e14 := -1 * float32(right+left) / float32(right-left)
|
e14 := -1 * float32(right+left) / float32(right-left)
|
||||||
|
Loading…
Reference in New Issue
Block a user