canvas bounds update fix, gomobile example works again
This commit is contained in:
parent
9c3cccabdd
commit
ba8238ba66
3 changed files with 119 additions and 95 deletions
|
@ -236,14 +236,14 @@ func NewOffscreen(w, h int, alpha bool) (*GoGLBackendOffscreen, error) {
|
||||||
}
|
}
|
||||||
bo := &GoGLBackendOffscreen{}
|
bo := &GoGLBackendOffscreen{}
|
||||||
bo.offscrBuf.alpha = alpha
|
bo.offscrBuf.alpha = alpha
|
||||||
|
bo.offscrImg.flip = true
|
||||||
|
|
||||||
b.activateFn = func() {
|
b.activateFn = func() {
|
||||||
b.enableTextureRenderTarget(&bo.offscrBuf)
|
b.enableTextureRenderTarget(&bo.offscrBuf)
|
||||||
gl.Viewport(0, 0, int32(b.w), int32(b.h))
|
gl.Viewport(0, 0, int32(bo.GoGLBackend.w), int32(bo.GoGLBackend.h))
|
||||||
bo.offscrImg.w = bo.offscrBuf.w
|
bo.offscrImg.w = bo.offscrBuf.w
|
||||||
bo.offscrImg.h = bo.offscrBuf.h
|
bo.offscrImg.h = bo.offscrBuf.h
|
||||||
bo.offscrImg.tex = bo.offscrBuf.tex
|
bo.offscrImg.tex = bo.offscrBuf.tex
|
||||||
bo.offscrImg.flip = true
|
|
||||||
}
|
}
|
||||||
b.disableTextureRenderTarget = func() {
|
b.disableTextureRenderTarget = func() {
|
||||||
b.enableTextureRenderTarget(&bo.offscrBuf)
|
b.enableTextureRenderTarget(&bo.offscrBuf)
|
||||||
|
@ -270,6 +270,9 @@ func (b *GoGLBackend) SetBounds(x, y, w, h int) {
|
||||||
// SetBounds updates the size of the offscreen texture
|
// SetBounds updates the size of the offscreen texture
|
||||||
func (b *GoGLBackendOffscreen) SetBounds(w, h int) {
|
func (b *GoGLBackendOffscreen) SetBounds(w, h int) {
|
||||||
b.GoGLBackend.SetBounds(0, 0, w, h)
|
b.GoGLBackend.SetBounds(0, 0, w, h)
|
||||||
|
b.enableTextureRenderTarget(&b.offscrBuf)
|
||||||
|
b.offscrImg.w = b.offscrBuf.w
|
||||||
|
b.offscrImg.h = b.offscrBuf.h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *GoGLBackend) Size() (int, int) {
|
func (b *GoGLBackend) Size() (int, int) {
|
||||||
|
@ -452,48 +455,53 @@ func (b *GoGLBackend) useAlphaShader(style *backendbase.FillStyle, alphaTexSlot
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *GoGLBackend) enableTextureRenderTarget(offscr *offscreenBuffer) {
|
func (b *GoGLBackend) enableTextureRenderTarget(offscr *offscreenBuffer) {
|
||||||
if offscr.w != b.w || offscr.h != b.h {
|
if offscr.w == b.w && offscr.h == b.h {
|
||||||
if offscr.w != 0 && offscr.h != 0 {
|
|
||||||
gl.DeleteTextures(1, &offscr.tex)
|
|
||||||
gl.DeleteFramebuffers(1, &offscr.frameBuf)
|
|
||||||
gl.DeleteRenderbuffers(1, &offscr.renderStencilBuf)
|
|
||||||
}
|
|
||||||
offscr.w = b.w
|
|
||||||
offscr.h = b.h
|
|
||||||
|
|
||||||
gl.ActiveTexture(gl.TEXTURE0)
|
|
||||||
gl.GenTextures(1, &offscr.tex)
|
|
||||||
gl.BindTexture(gl.TEXTURE_2D, offscr.tex)
|
|
||||||
// todo do non-power-of-two textures work everywhere?
|
|
||||||
if offscr.alpha {
|
|
||||||
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(b.w), int32(b.h), 0, gl.RGBA, gl.UNSIGNED_BYTE, nil)
|
|
||||||
} else {
|
|
||||||
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB, int32(b.w), int32(b.h), 0, gl.RGB, gl.UNSIGNED_BYTE, nil)
|
|
||||||
}
|
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_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.GenFramebuffers(1, &offscr.frameBuf)
|
|
||||||
gl.BindFramebuffer(gl.FRAMEBUFFER, offscr.frameBuf)
|
|
||||||
|
|
||||||
gl.GenRenderbuffers(1, &offscr.renderStencilBuf)
|
|
||||||
gl.BindRenderbuffer(gl.RENDERBUFFER, offscr.renderStencilBuf)
|
|
||||||
gl.RenderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, int32(b.w), int32(b.h))
|
|
||||||
gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, offscr.renderStencilBuf)
|
|
||||||
|
|
||||||
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, offscr.tex, 0)
|
|
||||||
|
|
||||||
if err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER); err != gl.FRAMEBUFFER_COMPLETE {
|
|
||||||
// todo this should maybe not panic
|
|
||||||
panic(fmt.Sprintf("Failed to set up framebuffer for offscreen texture: %x", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
|
|
||||||
} else {
|
|
||||||
gl.BindFramebuffer(gl.FRAMEBUFFER, offscr.frameBuf)
|
gl.BindFramebuffer(gl.FRAMEBUFFER, offscr.frameBuf)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.w == 0 || b.h == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if offscr.w != 0 && offscr.h != 0 {
|
||||||
|
gl.DeleteTextures(1, &offscr.tex)
|
||||||
|
gl.DeleteFramebuffers(1, &offscr.frameBuf)
|
||||||
|
gl.DeleteRenderbuffers(1, &offscr.renderStencilBuf)
|
||||||
|
}
|
||||||
|
offscr.w = b.w
|
||||||
|
offscr.h = b.h
|
||||||
|
|
||||||
|
gl.ActiveTexture(gl.TEXTURE0)
|
||||||
|
gl.GenTextures(1, &offscr.tex)
|
||||||
|
gl.BindTexture(gl.TEXTURE_2D, offscr.tex)
|
||||||
|
// todo do non-power-of-two textures work everywhere?
|
||||||
|
if offscr.alpha {
|
||||||
|
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(b.w), int32(b.h), 0, gl.RGBA, gl.UNSIGNED_BYTE, nil)
|
||||||
|
} else {
|
||||||
|
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB, int32(b.w), int32(b.h), 0, gl.RGB, gl.UNSIGNED_BYTE, nil)
|
||||||
|
}
|
||||||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||||||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_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.GenFramebuffers(1, &offscr.frameBuf)
|
||||||
|
gl.BindFramebuffer(gl.FRAMEBUFFER, offscr.frameBuf)
|
||||||
|
|
||||||
|
gl.GenRenderbuffers(1, &offscr.renderStencilBuf)
|
||||||
|
gl.BindRenderbuffer(gl.RENDERBUFFER, offscr.renderStencilBuf)
|
||||||
|
gl.RenderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, int32(b.w), int32(b.h))
|
||||||
|
gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, offscr.renderStencilBuf)
|
||||||
|
|
||||||
|
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, offscr.tex, 0)
|
||||||
|
|
||||||
|
if err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER); err != gl.FRAMEBUFFER_COMPLETE {
|
||||||
|
// todo this should maybe not panic
|
||||||
|
panic(fmt.Sprintf("Failed to set up framebuffer for offscreen texture: %x", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.Clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
type vec [2]float64
|
type vec [2]float64
|
||||||
|
|
|
@ -239,14 +239,14 @@ func NewOffscreen(glctx gl.Context, w, h int, alpha bool) (*XMobileBackendOffscr
|
||||||
}
|
}
|
||||||
bo := &XMobileBackendOffscreen{}
|
bo := &XMobileBackendOffscreen{}
|
||||||
bo.offscrBuf.alpha = alpha
|
bo.offscrBuf.alpha = alpha
|
||||||
|
bo.offscrImg.flip = true
|
||||||
|
|
||||||
b.activateFn = func() {
|
b.activateFn = func() {
|
||||||
b.enableTextureRenderTarget(&bo.offscrBuf)
|
b.enableTextureRenderTarget(&bo.offscrBuf)
|
||||||
b.glctx.Viewport(0, 0, b.w, b.h)
|
b.glctx.Viewport(0, 0, bo.XMobileBackend.w, bo.XMobileBackend.h)
|
||||||
bo.offscrImg.w = bo.offscrBuf.w
|
bo.offscrImg.w = bo.offscrBuf.w
|
||||||
bo.offscrImg.h = bo.offscrBuf.h
|
bo.offscrImg.h = bo.offscrBuf.h
|
||||||
bo.offscrImg.tex = bo.offscrBuf.tex
|
bo.offscrImg.tex = bo.offscrBuf.tex
|
||||||
bo.offscrImg.flip = true
|
|
||||||
}
|
}
|
||||||
b.disableTextureRenderTarget = func() {
|
b.disableTextureRenderTarget = func() {
|
||||||
b.enableTextureRenderTarget(&bo.offscrBuf)
|
b.enableTextureRenderTarget(&bo.offscrBuf)
|
||||||
|
@ -273,6 +273,9 @@ func (b *XMobileBackend) SetBounds(x, y, w, h int) {
|
||||||
// SetBounds updates the size of the offscreen texture
|
// SetBounds updates the size of the offscreen texture
|
||||||
func (b *XMobileBackendOffscreen) SetBounds(w, h int) {
|
func (b *XMobileBackendOffscreen) SetBounds(w, h int) {
|
||||||
b.XMobileBackend.SetBounds(0, 0, w, h)
|
b.XMobileBackend.SetBounds(0, 0, w, h)
|
||||||
|
b.enableTextureRenderTarget(&b.offscrBuf)
|
||||||
|
b.offscrImg.w = b.offscrBuf.w
|
||||||
|
b.offscrImg.h = b.offscrBuf.h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *XMobileBackend) Size() (int, int) {
|
func (b *XMobileBackend) Size() (int, int) {
|
||||||
|
@ -455,48 +458,53 @@ func (b *XMobileBackend) useAlphaShader(style *backendbase.FillStyle, alphaTexSl
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *XMobileBackend) enableTextureRenderTarget(offscr *offscreenBuffer) {
|
func (b *XMobileBackend) enableTextureRenderTarget(offscr *offscreenBuffer) {
|
||||||
if offscr.w != b.w || offscr.h != b.h {
|
if offscr.w == b.w && offscr.h == b.h {
|
||||||
if offscr.w != 0 && offscr.h != 0 {
|
|
||||||
b.glctx.DeleteTexture(offscr.tex)
|
|
||||||
b.glctx.DeleteFramebuffer(offscr.frameBuf)
|
|
||||||
b.glctx.DeleteRenderbuffer(offscr.renderStencilBuf)
|
|
||||||
}
|
|
||||||
offscr.w = b.w
|
|
||||||
offscr.h = b.h
|
|
||||||
|
|
||||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
|
||||||
offscr.tex = b.glctx.CreateTexture()
|
|
||||||
b.glctx.BindTexture(gl.TEXTURE_2D, offscr.tex)
|
|
||||||
// todo do non-power-of-two textures work everywhere?
|
|
||||||
if offscr.alpha {
|
|
||||||
b.glctx.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, b.w, b.h, gl.RGBA, gl.UNSIGNED_BYTE, nil)
|
|
||||||
} else {
|
|
||||||
b.glctx.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB, b.w, b.h, gl.RGB, gl.UNSIGNED_BYTE, nil)
|
|
||||||
}
|
|
||||||
b.glctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
|
||||||
b.glctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
|
||||||
b.glctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
|
|
||||||
b.glctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
|
|
||||||
|
|
||||||
offscr.frameBuf = b.glctx.CreateFramebuffer()
|
|
||||||
b.glctx.BindFramebuffer(gl.FRAMEBUFFER, offscr.frameBuf)
|
|
||||||
|
|
||||||
offscr.renderStencilBuf = b.glctx.CreateRenderbuffer()
|
|
||||||
b.glctx.BindRenderbuffer(gl.RENDERBUFFER, offscr.renderStencilBuf)
|
|
||||||
b.glctx.RenderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, b.w, b.h)
|
|
||||||
b.glctx.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, offscr.renderStencilBuf)
|
|
||||||
|
|
||||||
b.glctx.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, offscr.tex, 0)
|
|
||||||
|
|
||||||
if err := b.glctx.CheckFramebufferStatus(gl.FRAMEBUFFER); err != gl.FRAMEBUFFER_COMPLETE {
|
|
||||||
// todo this should maybe not panic
|
|
||||||
panic(fmt.Sprintf("Failed to set up framebuffer for offscreen texture: %x", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
b.glctx.Clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
|
|
||||||
} else {
|
|
||||||
b.glctx.BindFramebuffer(gl.FRAMEBUFFER, offscr.frameBuf)
|
b.glctx.BindFramebuffer(gl.FRAMEBUFFER, offscr.frameBuf)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.w == 0 || b.h == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if offscr.w != 0 && offscr.h != 0 {
|
||||||
|
b.glctx.DeleteTexture(offscr.tex)
|
||||||
|
b.glctx.DeleteFramebuffer(offscr.frameBuf)
|
||||||
|
b.glctx.DeleteRenderbuffer(offscr.renderStencilBuf)
|
||||||
|
}
|
||||||
|
offscr.w = b.w
|
||||||
|
offscr.h = b.h
|
||||||
|
|
||||||
|
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||||
|
offscr.tex = b.glctx.CreateTexture()
|
||||||
|
b.glctx.BindTexture(gl.TEXTURE_2D, offscr.tex)
|
||||||
|
// todo do non-power-of-two textures work everywhere?
|
||||||
|
if offscr.alpha {
|
||||||
|
b.glctx.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, b.w, b.h, gl.RGBA, gl.UNSIGNED_BYTE, nil)
|
||||||
|
} else {
|
||||||
|
b.glctx.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB, b.w, b.h, gl.RGB, gl.UNSIGNED_BYTE, nil)
|
||||||
|
}
|
||||||
|
b.glctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||||||
|
b.glctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
||||||
|
b.glctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
|
||||||
|
b.glctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
|
||||||
|
|
||||||
|
offscr.frameBuf = b.glctx.CreateFramebuffer()
|
||||||
|
b.glctx.BindFramebuffer(gl.FRAMEBUFFER, offscr.frameBuf)
|
||||||
|
|
||||||
|
offscr.renderStencilBuf = b.glctx.CreateRenderbuffer()
|
||||||
|
b.glctx.BindRenderbuffer(gl.RENDERBUFFER, offscr.renderStencilBuf)
|
||||||
|
b.glctx.RenderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, b.w, b.h)
|
||||||
|
b.glctx.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, offscr.renderStencilBuf)
|
||||||
|
|
||||||
|
b.glctx.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, offscr.tex, 0)
|
||||||
|
|
||||||
|
if err := b.glctx.CheckFramebufferStatus(gl.FRAMEBUFFER); err != gl.FRAMEBUFFER_COMPLETE {
|
||||||
|
// todo this should maybe not panic
|
||||||
|
panic(fmt.Sprintf("Failed to set up framebuffer for offscreen texture: %x", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
b.glctx.Clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
type vec [2]float64
|
type vec [2]float64
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tfriedel6/canvas"
|
"github.com/tfriedel6/canvas"
|
||||||
"github.com/tfriedel6/canvas/glimpl/xmobile"
|
"github.com/tfriedel6/canvas/backend/xmobile"
|
||||||
"golang.org/x/mobile/app"
|
"golang.org/x/mobile/app"
|
||||||
"golang.org/x/mobile/event/lifecycle"
|
"golang.org/x/mobile/event/lifecycle"
|
||||||
"golang.org/x/mobile/event/paint"
|
"golang.org/x/mobile/event/paint"
|
||||||
|
@ -16,6 +17,8 @@ import (
|
||||||
func main() {
|
func main() {
|
||||||
app.Main(func(a app.App) {
|
app.Main(func(a app.App) {
|
||||||
var cv, painter *canvas.Canvas
|
var cv, painter *canvas.Canvas
|
||||||
|
var cvb *xmobilebackend.XMobileBackendOffscreen
|
||||||
|
var painterb *xmobilebackend.XMobileBackend
|
||||||
var w, h int
|
var w, h int
|
||||||
|
|
||||||
var glctx gl.Context
|
var glctx gl.Context
|
||||||
|
@ -24,30 +27,35 @@ func main() {
|
||||||
case lifecycle.Event:
|
case lifecycle.Event:
|
||||||
switch e.Crosses(lifecycle.StageVisible) {
|
switch e.Crosses(lifecycle.StageVisible) {
|
||||||
case lifecycle.CrossOn:
|
case lifecycle.CrossOn:
|
||||||
glctx, _ = e.DrawContext.(gl.Context)
|
var err error
|
||||||
canvas.LoadGL(glimplxmobile.New(glctx))
|
glctx = e.DrawContext.(gl.Context)
|
||||||
cv = canvas.NewOffscreen(0, 0)
|
cvb, err = xmobilebackend.NewOffscreen(glctx, 0, 0, false)
|
||||||
painter = canvas.New(0, 0, 0, 0)
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
painterb, err = xmobilebackend.New(glctx, 0, 0, 0, 0)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
cv = canvas.New(cvb)
|
||||||
|
painter = canvas.New(painterb)
|
||||||
a.Send(paint.Event{})
|
a.Send(paint.Event{})
|
||||||
case lifecycle.CrossOff:
|
case lifecycle.CrossOff:
|
||||||
|
cvb.Delete()
|
||||||
glctx = nil
|
glctx = nil
|
||||||
}
|
}
|
||||||
case size.Event:
|
case size.Event:
|
||||||
w, h = e.WidthPx, e.HeightPx
|
w, h = e.WidthPx, e.HeightPx
|
||||||
case paint.Event:
|
case paint.Event:
|
||||||
if glctx != nil {
|
if glctx != nil {
|
||||||
glctx.ClearColor(0, 0, 0, 0)
|
|
||||||
glctx.Clear(gl.COLOR_BUFFER_BIT)
|
|
||||||
|
|
||||||
cv.SetBounds(0, 0, w, h)
|
|
||||||
painter.SetBounds(0, 0, w, h)
|
|
||||||
|
|
||||||
fw, fh := float64(w), float64(h)
|
fw, fh := float64(w), float64(h)
|
||||||
color := math.Sin(float64(time.Now().UnixNano())*0.000000002)*0.3 + 0.7
|
color := math.Sin(float64(time.Now().UnixNano())*0.000000002)*0.3 + 0.7
|
||||||
|
|
||||||
|
cvb.SetBounds(w, h)
|
||||||
cv.SetFillStyle(color*0.2, color*0.2, color*0.8)
|
cv.SetFillStyle(color*0.2, color*0.2, color*0.8)
|
||||||
cv.FillRect(fw*0.25, fh*0.25, fw*0.5, fh*0.5)
|
cv.FillRect(fw*0.25, fh*0.25, fw*0.5, fh*0.5)
|
||||||
|
|
||||||
|
painterb.SetBounds(0, 0, w, h)
|
||||||
painter.DrawImage(cv)
|
painter.DrawImage(cv)
|
||||||
|
|
||||||
a.Publish()
|
a.Publish()
|
||||||
|
|
Loading…
Reference in a new issue