diff --git a/gpu/backend.go b/gpu/backend.go index 9e56f040..b596723e 100644 --- a/gpu/backend.go +++ b/gpu/backend.go @@ -18,7 +18,7 @@ type Backend interface { // IsContinuousTime reports whether all timer measurements // are valid at the point of call. IsTimeContinuous() bool - NewTexture(minFilter, magFilter TextureFilter) Texture + NewTexture(format TextureFormat, width, height int, minFilter, magFilter TextureFilter) Texture DefaultFramebuffer() Framebuffer NilTexture() Texture NewFramebuffer() Framebuffer @@ -143,7 +143,6 @@ type Texture interface { Upload(img *image.RGBA) Release() Bind(unit int) - Resize(format TextureFormat, width, height int) } const ( diff --git a/gpu/gl/backend.go b/gpu/gl/backend.go index 381050e6..53f0304a 100644 --- a/gpu/gl/backend.go +++ b/gpu/gl/backend.go @@ -53,6 +53,7 @@ type gpuTimer struct { type gpuTexture struct { backend *Backend obj Texture + triple textureTriple } type gpuFramebuffer struct { @@ -174,13 +175,22 @@ func (b *Backend) DefaultFramebuffer() gpu.Framebuffer { return b.defFBO } -func (b *Backend) NewTexture(minFilter, magFilter gpu.TextureFilter) gpu.Texture { +func (b *Backend) NewTexture(format gpu.TextureFormat, width, height int, minFilter, magFilter gpu.TextureFilter) gpu.Texture { tex := &gpuTexture{backend: b, obj: b.funcs.CreateTexture()} + switch format { + case gpu.TextureFormatFloat: + tex.triple = b.floatTriple + case gpu.TextureFormatSRGB: + tex.triple = b.srgbaTriple + default: + panic("unsupported texture format") + } tex.Bind(0) b.funcs.TexParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, toTexFilter(magFilter)) b.funcs.TexParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, toTexFilter(minFilter)) b.funcs.TexParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE) b.funcs.TexParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE) + b.funcs.TexImage2D(TEXTURE_2D, 0, tex.triple.internalFormat, width, height, tex.triple.format, tex.triple.typ, nil) return tex } @@ -571,12 +581,6 @@ func (t *gpuTexture) Release() { t.backend.funcs.DeleteTexture(t.obj) } -func (t *gpuTexture) Resize(format gpu.TextureFormat, width, height int) { - t.Bind(0) - tt := t.backend.floatTriple - t.backend.funcs.TexImage2D(TEXTURE_2D, 0, tt.internalFormat, width, height, tt.format, tt.typ, nil) -} - func (t *gpuTexture) Upload(img *image.RGBA) { t.Bind(0) var pixels []byte @@ -588,8 +592,7 @@ func (t *gpuTexture) Upload(img *image.RGBA) { start := (b.Min.X + b.Min.Y*w) * 4 end := (b.Max.X + (b.Max.Y-1)*w) * 4 pixels = img.Pix[start:end] - tt := t.backend.srgbaTriple - t.backend.funcs.TexImage2D(TEXTURE_2D, 0, tt.internalFormat, w, h, tt.format, tt.typ, pixels) + t.backend.funcs.TexImage2D(TEXTURE_2D, 0, t.triple.internalFormat, w, h, t.triple.format, t.triple.typ, pixels) } func (t *gpuTimer) Begin() { diff --git a/gpu/gpu.go b/gpu/gpu.go index a19079f1..45db52ae 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -378,7 +378,7 @@ func (r *renderer) texHandle(t *texture) Texture { if t.tex != nil { return t.tex } - t.tex = r.ctx.NewTexture(FilterLinear, FilterLinear) + t.tex = r.ctx.NewTexture(TextureFormatSRGB, t.src.Bounds().Dx(), t.src.Bounds().Dy(), FilterLinear, FilterLinear) t.tex.Upload(t.src) return t.tex } diff --git a/gpu/path.go b/gpu/path.go index 5d4fef02..f4e04198 100644 --- a/gpu/path.go +++ b/gpu/path.go @@ -195,7 +195,6 @@ func (s *fboSet) resize(ctx Backend, sizes []image.Point) { for i := len(s.fbos); i < len(sizes); i++ { s.fbos = append(s.fbos, stencilFBO{ fbo: ctx.NewFramebuffer(), - tex: ctx.NewTexture(FilterNearest, FilterNearest), }) } // Resize fbos. @@ -207,8 +206,11 @@ func (s *fboSet) resize(ctx Backend, sizes []image.Point) { waste := float32(sz.X*sz.Y) / float32(f.size.X*f.size.Y) resize = resize || waste > 1.2 if resize { + if f.tex != nil { + f.tex.Release() + } f.size = sz - f.tex.Resize(TextureFormatFloat, sz.X, sz.Y) + f.tex = ctx.NewTexture(TextureFormatFloat, sz.X, sz.Y, FilterNearest, FilterNearest) f.fbo.BindTexture(f.tex) } }