Bug fix: image.Pixels didn't work on WebGL

This commit is contained in:
Hajime Hoshi 2015-01-17 18:22:58 +09:00
parent d91a467c53
commit 683ffafe8d
6 changed files with 21 additions and 16 deletions

View File

@ -147,7 +147,7 @@ func (i *Image) At(x, y int) color.Color {
if i.pixels == nil { if i.pixels == nil {
ui.Use(func(c *opengl.Context) { ui.Use(func(c *opengl.Context) {
var err error var err error
i.pixels, err = i.texture.Pixels(c) i.pixels, err = i.framebuffer.Pixels(c)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -168,7 +168,7 @@ func TestImageDotByDotInversion(t *testing.T) {
c0 := img0.At(i, j).(color.RGBA) c0 := img0.At(i, j).(color.RGBA)
c1 := img1.At(w-i-1, h-j-1).(color.RGBA) c1 := img1.At(w-i-1, h-j-1).(color.RGBA)
if c0 != c1 { if c0 != c1 {
t.Errorf("c0 should equal to c1 but not: c0: %v, c1: %v", c0, c1) t.Errorf("img0.At(%[1]d, %[2]d) should equal to img1.At(%[1]d, %[2]d) but not: %[3]v vs %[4]v", i, j, c0, c1)
} }
} }
} }

View File

@ -141,3 +141,9 @@ func (f *Framebuffer) FillRects(c *opengl.Context, rects Rects) error {
p := f.projectionMatrix() p := f.projectionMatrix()
return shader.FillRects(c, p, rects) return shader.FillRects(c, p, rects)
} }
func (f *Framebuffer) Pixels(c *opengl.Context) ([]uint8, error) {
w, h := f.Size()
w, h = internal.NextPowerOf2Int(w), internal.NextPowerOf2Int(h)
return c.FramebufferPixels(f.native, w, h)
}

View File

@ -90,8 +90,3 @@ func NewTextureFromImage(c *opengl.Context, img image.Image, filter opengl.Filte
func (t *Texture) Dispose(c *opengl.Context) { func (t *Texture) Dispose(c *opengl.Context) {
c.DeleteTexture(t.native) c.DeleteTexture(t.native)
} }
func (t *Texture) Pixels(c *opengl.Context) ([]uint8, error) {
w, h := internal.NextPowerOf2Int(t.width), internal.NextPowerOf2Int(t.height)
return c.TexturePixels(t.native, w, h)
}

View File

@ -84,12 +84,13 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (
return Texture(t), nil return Texture(t), nil
} }
func (c *Context) TexturePixels(t Texture, width, height int) ([]uint8, error) { func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) {
gl.Flush() gl.Flush()
// TODO: Use glGetTexLevelParameteri and GL_TEXTURE_WIDTH?
gl.Framebuffer(f).Bind()
pixels := make([]uint8, 4*width*height) pixels := make([]uint8, 4*width*height)
gl.Texture(t).Bind(gl.TEXTURE_2D) gl.ReadPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels)
gl.GetTexImage(gl.TEXTURE_2D, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels)
if e := gl.GetError(); e != gl.NO_ERROR { if e := gl.GetError(); e != gl.NO_ERROR {
return nil, errors.New(fmt.Sprintf("gl error: %d", e)) return nil, errors.New(fmt.Sprintf("gl error: %d", e))
} }

View File

@ -64,6 +64,8 @@ type context struct {
gl *webgl.Context gl *webgl.Context
} }
var lastFramebuffer Framebuffer
func NewContext(gl *webgl.Context) *Context { func NewContext(gl *webgl.Context) *Context {
c := &Context{ c := &Context{
Nearest: Filter(gl.NEAREST), Nearest: Filter(gl.NEAREST),
@ -113,12 +115,14 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (
return Texture{t}, nil return Texture{t}, nil
} }
func (c *Context) TexturePixels(t Texture, width, height int) ([]uint8, error) { func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) {
gl := c.gl gl := c.gl
gl.Flush() gl.Flush()
// TODO: Use glGetTexLevelParameteri and GL_TEXTURE_WIDTH?
lastFramebuffer = Framebuffer{nil}
gl.BindFramebuffer(gl.FRAMEBUFFER, f.Object)
pixels := js.Global.Get("Uint8Array").New(4 * width * height) pixels := js.Global.Get("Uint8Array").New(4 * width * height)
gl.BindTexture(gl.TEXTURE_2D, t.Object)
gl.ReadPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels) gl.ReadPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels)
if e := gl.GetError(); e != gl.NO_ERROR { if e := gl.GetError(); e != gl.NO_ERROR {
return nil, errors.New(fmt.Sprintf("gl error: %d", e)) return nil, errors.New(fmt.Sprintf("gl error: %d", e))
@ -148,6 +152,7 @@ func (c *Context) GlslHighpSupported() bool {
func (c *Context) NewFramebuffer(t Texture) (Framebuffer, error) { func (c *Context) NewFramebuffer(t Texture) (Framebuffer, error) {
gl := c.gl gl := c.gl
f := gl.CreateFramebuffer() f := gl.CreateFramebuffer()
lastFramebuffer = Framebuffer{nil}
gl.BindFramebuffer(gl.FRAMEBUFFER, f) gl.BindFramebuffer(gl.FRAMEBUFFER, f)
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, t.Object, 0) gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, t.Object, 0)
@ -158,8 +163,6 @@ func (c *Context) NewFramebuffer(t Texture) (Framebuffer, error) {
return Framebuffer{f}, nil return Framebuffer{f}, nil
} }
var lastFramebuffer Framebuffer
func (c *Context) SetViewport(f Framebuffer, width, height int) error { func (c *Context) SetViewport(f Framebuffer, width, height int) error {
gl := c.gl gl := c.gl
// TODO: Fix this after the GopherJS bug was fixed (#159) // TODO: Fix this after the GopherJS bug was fixed (#159)