From 275fc66f06f0bea0b7aaf1064a5b4675d0962115 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 9 Jul 2016 19:15:53 +0900 Subject: [PATCH] graphics: Bug fix: textuer should be stored at OpenGL layer --- internal/graphics/opengl/context.go | 12 ++++++++++++ internal/graphics/opengl/context_desktop.go | 16 +++++++++++----- internal/graphics/opengl/context_js.go | 7 +++++-- internal/graphics/opengl/context_mobile.go | 7 +++++-- internal/graphics/program.go | 8 +------- 5 files changed, 34 insertions(+), 16 deletions(-) diff --git a/internal/graphics/opengl/context.go b/internal/graphics/opengl/context.go index 4a2768994..8757bff88 100644 --- a/internal/graphics/opengl/context.go +++ b/internal/graphics/opengl/context.go @@ -38,12 +38,24 @@ type Context struct { locationCache *locationCache screenFramebuffer Framebuffer // This might not be the default frame buffer '0' (e.g. iOS). lastFramebuffer Framebuffer + lastTexture Texture lastViewportWidth int lastViewportHeight int lastCompositeMode CompositeMode context } +func (c *Context) BindTexture(t Texture) error { + if c.lastTexture == t { + return nil + } + if err := c.bindTextureImpl(t); err != nil { + return err + } + c.lastTexture = t + return nil +} + func (c *Context) bindFramebuffer(f Framebuffer) error { if c.lastFramebuffer == f { return nil diff --git a/internal/graphics/opengl/context_desktop.go b/internal/graphics/opengl/context_desktop.go index 9d1c557c2..336ffe5e7 100644 --- a/internal/graphics/opengl/context_desktop.go +++ b/internal/graphics/opengl/context_desktop.go @@ -150,8 +150,15 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) ( return errors.New("opengl: creating texture failed") } gl.PixelStorei(gl.UNPACK_ALIGNMENT, 4) - gl.BindTexture(gl.TEXTURE_2D, t) - + texture = Texture(t) + return nil + }); err != nil { + return 0, err + } + if err := c.BindTexture(texture); err != nil { + return 0, err + } + if err := c.RunOnContextThread(func() error { gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, int32(filter)) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, int32(filter)) @@ -160,8 +167,6 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) ( p = pixels } gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(width), int32(height), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(p)) - - texture = Texture(t) return nil }); err != nil { return 0, err @@ -202,11 +207,12 @@ func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, return pixels, nil } -func (c *Context) BindTexture(t Texture) { +func (c *Context) bindTextureImpl(t Texture) error { c.RunOnContextThread(func() error { gl.BindTexture(gl.TEXTURE_2D, uint32(t)) return nil }) + return nil } func (c *Context) DeleteTexture(t Texture) { diff --git a/internal/graphics/opengl/context_js.go b/internal/graphics/opengl/context_js.go index a034844a6..bdac953de 100644 --- a/internal/graphics/opengl/context_js.go +++ b/internal/graphics/opengl/context_js.go @@ -144,7 +144,9 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) ( return Texture{nil}, errors.New("opengl: glGenTexture failed") } gl.PixelStorei(gl.UNPACK_ALIGNMENT, 4) - gl.BindTexture(gl.TEXTURE_2D, t) + if err := c.BindTexture(Texture{t}); err != nil { + return Texture{}, err + } gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, int(filter)) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, int(filter)) @@ -182,9 +184,10 @@ func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, return pixels.Interface().([]uint8), nil } -func (c *Context) BindTexture(t Texture) { +func (c *Context) bindTextureImpl(t Texture) error { gl := c.gl gl.BindTexture(gl.TEXTURE_2D, t.Object) + return nil } func (c *Context) DeleteTexture(t Texture) { diff --git a/internal/graphics/opengl/context_mobile.go b/internal/graphics/opengl/context_mobile.go index 515ccd2e2..da3e4d0c7 100644 --- a/internal/graphics/opengl/context_mobile.go +++ b/internal/graphics/opengl/context_mobile.go @@ -122,7 +122,9 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) ( return Texture{}, errors.New("opengl: creating texture failed") } gl.PixelStorei(mgl.UNPACK_ALIGNMENT, 4) - gl.BindTexture(mgl.TEXTURE_2D, t) + if err := c.BindTexture(Texture(t)); err != nil { + return Texture{}, err + } gl.TexParameteri(mgl.TEXTURE_2D, mgl.TEXTURE_MAG_FILTER, int(filter)) gl.TexParameteri(mgl.TEXTURE_2D, mgl.TEXTURE_MIN_FILTER, int(filter)) @@ -156,9 +158,10 @@ func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, return pixels, nil } -func (c *Context) BindTexture(t Texture) { +func (c *Context) bindTextureImpl(t Texture) error { gl := c.gl gl.BindTexture(mgl.TEXTURE_2D, mgl.Texture(t)) + return nil } func (c *Context) DeleteTexture(t Texture) { diff --git a/internal/graphics/program.go b/internal/graphics/program.go index 5ae5fdbce..3f4aae921 100644 --- a/internal/graphics/program.go +++ b/internal/graphics/program.go @@ -30,7 +30,6 @@ type openGLState struct { lastModelviewMatrix []float32 lastColorMatrix []float32 lastColorMatrixTranslation []float32 - lastTexture opengl.Texture } var ( @@ -63,7 +62,6 @@ func (s *openGLState) reset(context *opengl.Context) error { s.lastModelviewMatrix = nil s.lastColorMatrix = nil s.lastColorMatrixTranslation = nil - s.lastTexture = zeroTexture if s.arrayBuffer != zeroBuffer { context.DeleteBuffer(s.arrayBuffer) @@ -152,7 +150,6 @@ func (p *programContext) begin() { p.state.lastModelviewMatrix = nil p.state.lastColorMatrix = nil p.state.lastColorMatrixTranslation = nil - p.state.lastTexture = zeroTexture c.BindElementArrayBuffer(p.state.indexBufferQuads) c.UniformInt(p.program, "texture", 0) } @@ -218,10 +215,7 @@ func (p *programContext) begin() { // We don't have to call gl.ActiveTexture here: GL_TEXTURE0 is the default active texture // See also: https://www.opengl.org/sdk/docs/man2/xhtml/glActiveTexture.xml - if p.state.lastTexture != p.texture { - c.BindTexture(p.texture) - p.state.lastTexture = p.texture - } + c.BindTexture(p.texture) } func (p *programContext) end() {