From fbcd04cda859cc423a87bdb59f4e1217fa8a259a Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Wed, 31 Dec 2014 15:22:15 +0900 Subject: [PATCH] Add opengl.Framebuffer.SetAsViewport --- graphicscontext.go | 4 ++-- image.go | 5 +++-- internal/graphics/framebuffer.go | 36 ++++++-------------------------- internal/opengl/context.go | 32 ++++++++++++++++++++++++++++ ui.go | 4 ++-- 5 files changed, 45 insertions(+), 36 deletions(-) diff --git a/graphicscontext.go b/graphicscontext.go index a53a8fbf8..816419b3e 100644 --- a/graphicscontext.go +++ b/graphicscontext.go @@ -20,7 +20,7 @@ import ( ) func newGraphicsContext(c *opengl.Context, screenWidth, screenHeight, screenScale int) (*graphicsContext, error) { - f, err := graphics.NewZeroFramebuffer(screenWidth*screenScale, screenHeight*screenScale) + f, err := graphics.NewZeroFramebuffer(c, screenWidth*screenScale, screenHeight*screenScale) if err != nil { return nil, err } @@ -29,7 +29,7 @@ func newGraphicsContext(c *opengl.Context, screenWidth, screenHeight, screenScal if err != nil { return nil, err } - screen, err := newInnerImage(texture) + screen, err := newInnerImage(c, texture) if err != nil { return nil, err } diff --git a/image.go b/image.go index 593e1bd0a..fdc870a4d 100644 --- a/image.go +++ b/image.go @@ -17,6 +17,7 @@ package ebiten import ( "github.com/hajimehoshi/ebiten/internal" "github.com/hajimehoshi/ebiten/internal/graphics" + "github.com/hajimehoshi/ebiten/internal/opengl" "image" "image/color" ) @@ -26,8 +27,8 @@ type innerImage struct { texture *graphics.Texture } -func newInnerImage(texture *graphics.Texture) (*innerImage, error) { - framebuffer, err := graphics.NewFramebufferFromTexture(texture) +func newInnerImage(c *opengl.Context, texture *graphics.Texture) (*innerImage, error) { + framebuffer, err := graphics.NewFramebufferFromTexture(c, texture) if err != nil { return nil, err } diff --git a/internal/graphics/framebuffer.go b/internal/graphics/framebuffer.go index d2e9a9051..769306397 100644 --- a/internal/graphics/framebuffer.go +++ b/internal/graphics/framebuffer.go @@ -15,11 +15,10 @@ package graphics import ( - "errors" - "fmt" "github.com/go-gl/gl" "github.com/hajimehoshi/ebiten/internal" "github.com/hajimehoshi/ebiten/internal/graphics/internal/shader" + "github.com/hajimehoshi/ebiten/internal/opengl" ) func orthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 { @@ -37,13 +36,13 @@ func orthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 { } type Framebuffer struct { - framebuffer gl.Framebuffer + framebuffer opengl.Framebuffer width int height int flipY bool } -func NewZeroFramebuffer(width, height int) (*Framebuffer, error) { +func NewZeroFramebuffer(c *opengl.Context, width, height int) (*Framebuffer, error) { r := &Framebuffer{ width: width, height: height, @@ -52,8 +51,8 @@ func NewZeroFramebuffer(width, height int) (*Framebuffer, error) { return r, nil } -func NewFramebufferFromTexture(texture *Texture) (*Framebuffer, error) { - framebuffer, err := createFramebuffer(gl.Texture(texture.native)) +func NewFramebufferFromTexture(c *opengl.Context, texture *Texture) (*Framebuffer, error) { + framebuffer, err := c.NewFramebuffer(opengl.Texture(texture.native)) if err != nil { return nil, err } @@ -73,33 +72,10 @@ func (f *Framebuffer) Dispose() { f.framebuffer.Delete() } -func createFramebuffer(nativeTexture gl.Texture) (gl.Framebuffer, error) { - framebuffer := gl.GenFramebuffer() - framebuffer.Bind() - - gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, nativeTexture, 0) - if gl.CheckFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE { - return 0, errors.New("creating framebuffer failed") - } - - return framebuffer, nil -} - func (f *Framebuffer) setAsViewport() error { - gl.Flush() - f.framebuffer.Bind() - err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER) - if err != gl.FRAMEBUFFER_COMPLETE { - if gl.GetError() != 0 { - return errors.New(fmt.Sprintf("glBindFramebuffer failed: %d", gl.GetError())) - } - return errors.New("glBindFramebuffer failed: the context is different?") - } - width := internal.NextPowerOf2Int(f.width) height := internal.NextPowerOf2Int(f.height) - gl.Viewport(0, 0, width, height) - return nil + return f.framebuffer.SetAsViewport(width, height) } func (f *Framebuffer) projectionMatrix() [4][4]float64 { diff --git a/internal/opengl/context.go b/internal/opengl/context.go index 1214ee087..874ff6797 100644 --- a/internal/opengl/context.go +++ b/internal/opengl/context.go @@ -50,6 +50,26 @@ func (t Texture) Delete() { gl.Texture(t).Delete() } +type Framebuffer gl.Framebuffer + +func (f Framebuffer) SetAsViewport(width, height int) error { + gl.Flush() + gl.Framebuffer(f).Bind() + err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER) + if err != gl.FRAMEBUFFER_COMPLETE { + if gl.GetError() != 0 { + return errors.New(fmt.Sprintf("glBindFramebuffer failed: %d", gl.GetError())) + } + return errors.New("glBindFramebuffer failed: the context is different?") + } + gl.Viewport(0, 0, width, height) + return nil +} + +func (f Framebuffer) Delete() { + gl.Framebuffer(f).Delete() +} + func NewContext() *Context { c := &Context{ Nearest: filterNearest, @@ -83,3 +103,15 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) ( return Texture(t), nil } + +func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) { + f := gl.GenFramebuffer() + f.Bind() + + gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, gl.Texture(texture), 0) + if gl.CheckFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE { + return 0, errors.New("creating framebuffer failed") + } + + return Framebuffer(f), nil +} diff --git a/ui.go b/ui.go index 1fbafa0d3..1910efb33 100644 --- a/ui.go +++ b/ui.go @@ -156,7 +156,7 @@ func (u *ui) newImageFromImage(img image.Image, filter Filter) (*Image, error) { if err != nil { return } - innerImage, err = newInnerImage(texture) + innerImage, err = newInnerImage(u.glContext, texture) }) if err != nil { return nil, err @@ -173,7 +173,7 @@ func (u *ui) newImage(width, height int, filter Filter) (*Image, error) { if err != nil { return } - innerImage, err = newInnerImage(texture) + innerImage, err = newInnerImage(u.glContext, texture) innerImage.Clear() }) if err != nil {