opengl: Call glViewport each time when different framebuffer is set

This commit is contained in:
Hajime Hoshi 2016-06-18 22:47:34 +09:00
parent 83ab4352f8
commit bc2703c345
5 changed files with 62 additions and 45 deletions

View File

@ -40,12 +40,28 @@ type Context struct {
context
}
func (c *Context) bindFramebuffer(f Framebuffer) {
func (c *Context) bindFramebuffer(f Framebuffer) error {
if c.lastFramebuffer == f {
return
return nil
}
if err := c.bindFramebufferImpl(f); err != nil {
return err
}
c.bindFramebufferImpl(f)
c.lastFramebuffer = f
return nil
}
func (c *Context) SetViewport(f Framebuffer, width, height int) error {
lf := c.lastFramebuffer
c.bindFramebuffer(f)
if lf != f || c.lastViewportWidth != width || c.lastViewportHeight != height {
if err := c.setViewportImpl(width, height); err != nil {
return nil
}
c.lastViewportWidth = width
c.lastViewportHeight = height
}
return nil
}
func (c *Context) ScreenFramebuffer() Framebuffer {

View File

@ -180,15 +180,26 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (
return texture, nil
}
func (c *Context) bindFramebufferImpl(f Framebuffer) {
gl.BindFramebuffer(gl.FRAMEBUFFER, uint32(f))
func (c *Context) bindFramebufferImpl(f Framebuffer) error {
if err := c.RunOnContextThread(func() error {
gl.BindFramebuffer(gl.FRAMEBUFFER, uint32(f))
return nil
}); err != nil {
return err
}
return nil
}
func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) {
var pixels []uint8
if err := c.RunOnContextThread(func() error {
gl.Flush()
c.bindFramebuffer(f)
return nil
}); err != nil {
return nil, err
}
c.bindFramebuffer(f)
if err := c.RunOnContextThread(func() error {
pixels = make([]uint8, 4*width*height)
gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(pixels))
if e := gl.GetError(); e != gl.NO_ERROR {
@ -236,24 +247,25 @@ func (c *Context) TexSubImage2D(p []uint8, width, height int) {
})
}
func (c *Context) BindScreenFramebuffer() {
c.RunOnContextThread(func() error {
c.bindFramebuffer(c.screenFramebuffer)
return nil
})
func (c *Context) BindScreenFramebuffer() error {
return c.bindFramebuffer(c.screenFramebuffer)
}
func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
var framebuffer Framebuffer
var f uint32
if err := c.RunOnContextThread(func() error {
var f uint32
gl.GenFramebuffers(1, &f)
// TODO: Use gl.IsFramebuffer
if f <= 0 {
return errors.New("opengl: creating framebuffer failed: gl.IsFramebuffer returns false")
}
c.bindFramebuffer(Framebuffer(f))
return nil
}); err != nil {
return 0, err
}
c.bindFramebuffer(Framebuffer(f))
if err := c.RunOnContextThread(func() error {
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, uint32(texture), 0)
s := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
if s != gl.FRAMEBUFFER_COMPLETE {
@ -273,14 +285,9 @@ func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
return framebuffer, nil
}
func (c *Context) SetViewport(f Framebuffer, width, height int) error {
func (c *Context) setViewportImpl(width, height int) error {
return c.RunOnContextThread(func() error {
c.bindFramebuffer(f)
if c.lastViewportWidth != width || c.lastViewportHeight != height {
gl.Viewport(0, 0, int32(width), int32(height))
c.lastViewportWidth = width
c.lastViewportHeight = height
}
gl.Viewport(0, 0, int32(width), int32(height))
return nil
})
}

View File

@ -172,9 +172,10 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (
return Texture{t}, nil
}
func (c *Context) bindFramebufferImpl(f Framebuffer) {
func (c *Context) bindFramebufferImpl(f Framebuffer) error {
gl := c.gl
gl.BindFramebuffer(gl.FRAMEBUFFER, f.Object)
return nil
}
func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) {
@ -230,14 +231,9 @@ func (c *Context) NewFramebuffer(t Texture) (Framebuffer, error) {
return Framebuffer{f}, nil
}
func (c *Context) SetViewport(f Framebuffer, width, height int) error {
c.bindFramebuffer(f)
if c.lastViewportWidth != width || c.lastViewportHeight != height {
gl := c.gl
gl.Viewport(0, 0, width, height)
c.lastViewportWidth = width
c.lastViewportHeight = height
}
func (c *Context) setViewportImpl(width, height int) error {
gl := c.gl
gl.Viewport(0, 0, width, height)
return nil
}

View File

@ -192,8 +192,8 @@ func (c *Context) TexSubImage2D(p []uint8, width, height int) {
gl.TexSubImage2D(mgl.TEXTURE_2D, 0, 0, 0, width, height, mgl.RGBA, mgl.UNSIGNED_BYTE, p)
}
func (c *Context) BindScreenFramebuffer() {
c.bindFramebuffer(c.screenFramebuffer)
func (c *Context) BindScreenFramebuffer() error {
return c.bindFramebuffer(c.screenFramebuffer)
}
func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
@ -215,18 +215,12 @@ func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
}
return Framebuffer{}, fmt.Errorf("opengl: creating framebuffer failed: unknown error")
}
return Framebuffer(f), nil
}
func (c *Context) SetViewport(f Framebuffer, width, height int) error {
c.bindFramebuffer(f)
if c.lastViewportWidth != width || c.lastViewportHeight != height {
gl := c.gl
gl.Viewport(0, 0, width, height)
c.lastViewportWidth = width
c.lastViewportHeight = height
}
func (c *Context) setViewportImpl(width, height int) error {
gl := c.gl
gl.Viewport(0, 0, width, height)
return nil
}

View File

@ -247,19 +247,23 @@ func (u *userInterface) Terminate() error {
}
func (u *userInterface) SwapBuffers() error {
var err error
u.runOnMainThread(func() {
u.swapBuffers()
err = u.swapBuffers()
})
return nil
return err
}
func (u *userInterface) swapBuffers() {
func (u *userInterface) swapBuffers() error {
// The bound framebuffer must be the default one (0) before swapping buffers.
u.context.BindScreenFramebuffer()
if err := u.context.BindScreenFramebuffer(); err != nil {
return err
}
u.context.RunOnContextThread(func() error {
u.window.SwapBuffers()
return nil
})
return nil
}
func (u *userInterface) FinishRendering() error {