func (b *GoGLBackend) SetBounds(x, y, w, h int) {
	b.x, b.y = x, y
	b.fx, b.fy = float64(x), float64(y)
	b.w, b.h = w, h
	b.fw, b.fh = float64(w), float64(h)
	if b == activeContext {
		gl.Viewport(0, 0, int32(b.w), int32(b.h))
		gl.Clear(gl.STENCIL_BUFFER_BIT)
	}
}
SetBounds updates the bounds of the canvas. This would
usually be called for example when the window is resized
package goglbackend
import (
	"fmt"
	"github.com/tfriedel6/canvas/backend/backendbase"
	"github.com/tfriedel6/canvas/backend/goglbackend/gl"
)
const alphaTexSize = 2048
var zeroes [alphaTexSize]byte
type GLContext struct {
	buf       uint32
	shadowBuf uint32
	alphaTex  uint32
	shd unifiedShader
	offscr1 offscreenBuffer
	offscr2 offscreenBuffer
	imageBufTex uint32
	imageBuf    []byte
	ptsBuf []float32
}
func NewGLContext() (*GLContext, error) {
	ctx := &GLContext{
		ptsBuf: make([]float32, 0, 4096),
	}
	err := gl.Init()
	if err != nil {
		return nil, err
	}
	gl.GetError()  
	err = loadShader(unifiedVS, unifiedFS, &ctx.shd.shaderProgram)
	if err != nil {
		return nil, err
	}
	ctx.shd.shaderProgram.mustLoadLocations(&ctx.shd)
	if err = glError(); err != nil {
		return nil, err
	}
	gl.GenBuffers(1, &ctx.buf)
	if err = glError(); err != nil {
		return nil, err
	}
	gl.GenBuffers(1, &ctx.shadowBuf)
	if err = glError(); err != nil {
		return nil, err
	}
	gl.ActiveTexture(gl.TEXTURE0)
	gl.GenTextures(1, &ctx.alphaTex)
	gl.BindTexture(gl.TEXTURE_2D, ctx.alphaTex)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
	gl.TexImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, alphaTexSize, alphaTexSize, 0, gl.ALPHA, gl.UNSIGNED_BYTE, nil)
	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
	gl.Enable(gl.STENCIL_TEST)
	gl.StencilMask(0xFF)
	gl.Clear(gl.STENCIL_BUFFER_BIT)
	gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP)
	gl.StencilFunc(gl.EQUAL, 0, 0xFF)
	gl.Disable(gl.SCISSOR_TEST)
	return ctx, nil
}
type GoGLBackend struct {
	x, y, w, h     int
	fx, fy, fw, fh float64
	*GLContext
	activateFn                 func()
	disableTextureRenderTarget func()
}
type offscreenBuffer struct {
	tex              uint32
	w                int
	h                int
	renderStencilBuf uint32
	frameBuf         uint32
	alpha            bool
}
func New(x, y, w, h int, ctx *GLContext) (*GoGLBackend, error) {
	if ctx == nil {
		var err error
		ctx, err = NewGLContext()
		if err != nil {
			return nil, err
		}
	}
	b := &GoGLBackend{
		w:         w,
		h:         h,
		fw:        float64(w),
		fh:        float64(h),
		GLContext: ctx,
	}
	b.activateFn = func() {
		gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
		gl.Viewport(int32(b.x), int32(b.y), int32(b.w), int32(b.h))
	}
	b.disableTextureRenderTarget = func() {
		gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
		gl.Viewport(int32(b.x), int32(b.y), int32(b.w), int32(b.h))
	}
	return b, nil
}
type GoGLBackendOffscreen struct {
	GoGLBackend
	TextureID uint32
	offscrBuf offscreenBuffer
	offscrImg Image
}
func NewOffscreen(w, h int, alpha bool, ctx *GLContext) (*GoGLBackendOffscreen, error) {
	b, err := New(0, 0, w, h, ctx)
	if err != nil {
		return nil, err
	}
	bo := &GoGLBackendOffscreen{GoGLBackend: *b}
	bo.offscrBuf.alpha = alpha
	bo.offscrImg.flip = true
	bo.activateFn = func() {
		bo.enableTextureRenderTarget(&bo.offscrBuf)
		gl.Viewport(0, 0, int32(bo.w), int32(bo.h))
		bo.offscrImg.w = bo.offscrBuf.w
		bo.offscrImg.h = bo.offscrBuf.h
		bo.offscrImg.tex = bo.offscrBuf.tex
		bo.TextureID = bo.offscrBuf.tex
	}
	bo.disableTextureRenderTarget = func() {
		bo.enableTextureRenderTarget(&bo.offscrBuf)
	}
	return bo, nil
}