removed opaque and deleted flags from backend, deleted state is now maintained in frontend
This commit is contained in:
parent
ba8238ba66
commit
22c3c25d8e
6 changed files with 41 additions and 91 deletions
|
@ -89,15 +89,11 @@ type GradientStop struct {
|
||||||
|
|
||||||
type LinearGradient interface {
|
type LinearGradient interface {
|
||||||
Delete()
|
Delete()
|
||||||
IsDeleted() bool
|
|
||||||
IsOpaque() bool
|
|
||||||
Replace(data Gradient)
|
Replace(data Gradient)
|
||||||
}
|
}
|
||||||
|
|
||||||
type RadialGradient interface {
|
type RadialGradient interface {
|
||||||
Delete()
|
Delete()
|
||||||
IsDeleted() bool
|
|
||||||
IsOpaque() bool
|
|
||||||
Replace(data Gradient)
|
Replace(data Gradient)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +102,5 @@ type Image interface {
|
||||||
Height() int
|
Height() int
|
||||||
Size() (w, h int)
|
Size() (w, h int)
|
||||||
Delete()
|
Delete()
|
||||||
IsDeleted() bool
|
|
||||||
Replace(src image.Image) error
|
Replace(src image.Image) error
|
||||||
IsOpaque() bool
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,18 +24,16 @@ type RadialGradient struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type gradient struct {
|
type gradient struct {
|
||||||
b *GoGLBackend
|
b *GoGLBackend
|
||||||
tex uint32
|
tex uint32
|
||||||
loaded bool
|
loaded bool
|
||||||
deleted bool
|
|
||||||
opaque bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *GoGLBackend) LoadLinearGradient(data backendbase.Gradient) backendbase.LinearGradient {
|
func (b *GoGLBackend) LoadLinearGradient(data backendbase.Gradient) backendbase.LinearGradient {
|
||||||
b.activate()
|
b.activate()
|
||||||
|
|
||||||
lg := &LinearGradient{
|
lg := &LinearGradient{
|
||||||
gradient: gradient{b: b, opaque: true},
|
gradient: gradient{b: b},
|
||||||
}
|
}
|
||||||
gl.GenTextures(1, &lg.tex)
|
gl.GenTextures(1, &lg.tex)
|
||||||
gl.ActiveTexture(gl.TEXTURE0)
|
gl.ActiveTexture(gl.TEXTURE0)
|
||||||
|
@ -57,7 +55,7 @@ func (b *GoGLBackend) LoadRadialGradient(data backendbase.Gradient) backendbase.
|
||||||
b.activate()
|
b.activate()
|
||||||
|
|
||||||
rg := &RadialGradient{
|
rg := &RadialGradient{
|
||||||
gradient: gradient{b: b, opaque: true},
|
gradient: gradient{b: b},
|
||||||
}
|
}
|
||||||
gl.GenTextures(1, &rg.tex)
|
gl.GenTextures(1, &rg.tex)
|
||||||
gl.ActiveTexture(gl.TEXTURE0)
|
gl.ActiveTexture(gl.TEXTURE0)
|
||||||
|
@ -80,12 +78,8 @@ func (g *gradient) Delete() {
|
||||||
g.b.activate()
|
g.b.activate()
|
||||||
|
|
||||||
gl.DeleteTextures(1, &g.tex)
|
gl.DeleteTextures(1, &g.tex)
|
||||||
g.deleted = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *gradient) IsDeleted() bool { return g.deleted }
|
|
||||||
func (g *gradient) IsOpaque() bool { return g.opaque }
|
|
||||||
|
|
||||||
func (lg *LinearGradient) Replace(data backendbase.Gradient) { lg.load(data) }
|
func (lg *LinearGradient) Replace(data backendbase.Gradient) { lg.load(data) }
|
||||||
func (rg *RadialGradient) Replace(data backendbase.Gradient) { rg.load(data) }
|
func (rg *RadialGradient) Replace(data backendbase.Gradient) { rg.load(data) }
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,10 @@ import (
|
||||||
|
|
||||||
// Image represents a loaded image that can be used in various drawing functions
|
// Image represents a loaded image that can be used in various drawing functions
|
||||||
type Image struct {
|
type Image struct {
|
||||||
b *GoGLBackend
|
b *GoGLBackend
|
||||||
w, h int
|
w, h int
|
||||||
tex uint32
|
tex uint32
|
||||||
deleted bool
|
flip bool
|
||||||
opaque bool
|
|
||||||
flip bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *GoGLBackend) LoadImage(src image.Image) (backendbase.Image, error) {
|
func (b *GoGLBackend) LoadImage(src image.Image) (backendbase.Image, error) {
|
||||||
|
@ -38,10 +36,8 @@ func (b *GoGLBackend) LoadImage(src image.Image) (backendbase.Image, error) {
|
||||||
img.b = b
|
img.b = b
|
||||||
|
|
||||||
runtime.SetFinalizer(img, func(img *Image) {
|
runtime.SetFinalizer(img, func(img *Image) {
|
||||||
if !img.deleted {
|
b.glChan <- func() {
|
||||||
b.glChan <- func() {
|
gl.DeleteTextures(1, &img.tex)
|
||||||
gl.DeleteTextures(1, &img.tex)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -74,19 +70,7 @@ func loadImage(src image.Image, tex uint32) (*Image, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadImageRGBA(src *image.RGBA, tex uint32) (*Image, error) {
|
func loadImageRGBA(src *image.RGBA, tex uint32) (*Image, error) {
|
||||||
img := &Image{tex: tex, w: src.Bounds().Dx(), h: src.Bounds().Dy(), opaque: true}
|
img := &Image{tex: tex, w: src.Bounds().Dx(), h: src.Bounds().Dy()}
|
||||||
|
|
||||||
checkOpaque:
|
|
||||||
for y := 0; y < img.h; y++ {
|
|
||||||
off := src.PixOffset(0, y) + 3
|
|
||||||
for x := 0; x < img.w; x++ {
|
|
||||||
if src.Pix[off] < 255 {
|
|
||||||
img.opaque = false
|
|
||||||
break checkOpaque
|
|
||||||
}
|
|
||||||
off += 4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
||||||
|
@ -147,7 +131,7 @@ func loadImageGray(src *image.Gray, tex uint32) (*Image, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadImageConverted(src image.Image, tex uint32) (*Image, error) {
|
func loadImageConverted(src image.Image, tex uint32) (*Image, error) {
|
||||||
img := &Image{tex: tex, w: src.Bounds().Dx(), h: src.Bounds().Dy(), opaque: true}
|
img := &Image{tex: tex, w: src.Bounds().Dx(), h: src.Bounds().Dy()}
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
|
||||||
|
@ -161,9 +145,6 @@ func loadImageConverted(src image.Image, tex uint32) (*Image, error) {
|
||||||
ir, ig, ib, ia := src.At(x, y).RGBA()
|
ir, ig, ib, ia := src.At(x, y).RGBA()
|
||||||
r, g, b, a := uint8(ir>>8), uint8(ig>>8), uint8(ib>>8), uint8(ia>>8)
|
r, g, b, a := uint8(ir>>8), uint8(ig>>8), uint8(ib>>8), uint8(ia>>8)
|
||||||
data = append(data, r, g, b, a)
|
data = append(data, r, g, b, a)
|
||||||
if a < 255 {
|
|
||||||
img.opaque = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(img.w), int32(img.h), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(&data[0]))
|
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(img.w), int32(img.h), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(&data[0]))
|
||||||
|
@ -192,13 +173,8 @@ func (img *Image) Delete() {
|
||||||
img.b.activate()
|
img.b.activate()
|
||||||
|
|
||||||
gl.DeleteTextures(1, &img.tex)
|
gl.DeleteTextures(1, &img.tex)
|
||||||
img.deleted = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDeleted returns true if the Delete function has been
|
|
||||||
// called on this image
|
|
||||||
func (img *Image) IsDeleted() bool { return img.deleted }
|
|
||||||
|
|
||||||
// Replace replaces the image with the new one
|
// Replace replaces the image with the new one
|
||||||
func (img *Image) Replace(src image.Image) error {
|
func (img *Image) Replace(src image.Image) error {
|
||||||
img.b.activate()
|
img.b.activate()
|
||||||
|
@ -214,10 +190,6 @@ func (img *Image) Replace(src image.Image) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsOpaque returns true if all pixels in the image
|
|
||||||
// have a full alpha value
|
|
||||||
func (img *Image) IsOpaque() bool { return img.opaque }
|
|
||||||
|
|
||||||
func (b *GoGLBackend) DrawImage(dimg backendbase.Image, sx, sy, sw, sh float64, pts [4][2]float64, alpha float64) {
|
func (b *GoGLBackend) DrawImage(dimg backendbase.Image, sx, sy, sw, sh float64, pts [4][2]float64, alpha float64) {
|
||||||
b.activate()
|
b.activate()
|
||||||
|
|
||||||
|
|
13
canvas.go
13
canvas.go
|
@ -226,19 +226,6 @@ func (cv *Canvas) parseStyle(value ...interface{}) drawStyle {
|
||||||
return style
|
return style
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *drawStyle) isOpaque() bool {
|
|
||||||
if lg := s.linearGradient; lg != nil {
|
|
||||||
return lg.opaque
|
|
||||||
}
|
|
||||||
if rg := s.radialGradient; rg != nil {
|
|
||||||
return rg.opaque
|
|
||||||
}
|
|
||||||
if img := s.image; img != nil {
|
|
||||||
return img.img.IsOpaque()
|
|
||||||
}
|
|
||||||
return s.color.A >= 255
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cv *Canvas) backendFillStyle(s *drawStyle, alpha float64) backendbase.FillStyle {
|
func (cv *Canvas) backendFillStyle(s *drawStyle, alpha float64) backendbase.FillStyle {
|
||||||
stl := backendbase.FillStyle{Color: s.color}
|
stl := backendbase.FillStyle{Color: s.color}
|
||||||
alpha *= cv.state.globalAlpha
|
alpha *= cv.state.globalAlpha
|
||||||
|
|
22
gradients.go
22
gradients.go
|
@ -68,13 +68,27 @@ func (cv *Canvas) CreateRadialGradient(x0, y0, r0, x1, y1, r1 float64) *RadialGr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete explicitly deletes the gradient
|
// Delete explicitly deletes the gradient
|
||||||
func (lg *LinearGradient) Delete() { lg.grad.Delete() }
|
func (lg *LinearGradient) Delete() {
|
||||||
|
if lg.deleted {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lg.grad.Delete()
|
||||||
|
lg.grad = nil
|
||||||
|
lg.deleted = true
|
||||||
|
}
|
||||||
|
|
||||||
// Delete explicitly deletes the gradient
|
// Delete explicitly deletes the gradient
|
||||||
func (rg *RadialGradient) Delete() { rg.grad.Delete() }
|
func (rg *RadialGradient) Delete() {
|
||||||
|
if rg.deleted {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rg.grad.Delete()
|
||||||
|
rg.grad = nil
|
||||||
|
rg.deleted = true
|
||||||
|
}
|
||||||
|
|
||||||
func (lg *LinearGradient) load() {
|
func (lg *LinearGradient) load() {
|
||||||
if lg.loaded || len(lg.data) < 1 {
|
if lg.loaded || len(lg.data) < 1 || lg.deleted {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +102,7 @@ func (lg *LinearGradient) load() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rg *RadialGradient) load() {
|
func (rg *RadialGradient) load() {
|
||||||
if rg.loaded || len(rg.data) < 1 {
|
if rg.loaded || len(rg.data) < 1 || rg.deleted {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
31
images.go
31
images.go
|
@ -13,8 +13,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Image struct {
|
type Image struct {
|
||||||
cv *Canvas
|
cv *Canvas
|
||||||
img backendbase.Image
|
img backendbase.Image
|
||||||
|
deleted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadImage loads an image. The src parameter can be either an image from the
|
// LoadImage loads an image. The src parameter can be either an image from the
|
||||||
|
@ -113,7 +114,11 @@ func (img *Image) Size() (int, int) { return img.img.Size() }
|
||||||
|
|
||||||
// Delete deletes the image from memory. Any draw calls with a deleted image
|
// Delete deletes the image from memory. Any draw calls with a deleted image
|
||||||
// will not do anything
|
// will not do anything
|
||||||
func (img *Image) Delete() { img.img.Delete() }
|
func (img *Image) Delete() {
|
||||||
|
img.img.Delete()
|
||||||
|
img.img = nil
|
||||||
|
img.deleted = true
|
||||||
|
}
|
||||||
|
|
||||||
// Replace replaces the image with the new one
|
// Replace replaces the image with the new one
|
||||||
func (img *Image) Replace(src interface{}) error {
|
func (img *Image) Replace(src interface{}) error {
|
||||||
|
@ -137,20 +142,9 @@ func (img *Image) Replace(src interface{}) error {
|
||||||
// Where dx/dy/dw/dh are the destination coordinates and sx/sy/sw/sh are the
|
// Where dx/dy/dw/dh are the destination coordinates and sx/sy/sw/sh are the
|
||||||
// source coordinates
|
// source coordinates
|
||||||
func (cv *Canvas) DrawImage(image interface{}, coords ...float64) {
|
func (cv *Canvas) DrawImage(image interface{}, coords ...float64) {
|
||||||
var img *Image
|
img := cv.getImage(image)
|
||||||
// var flip bool
|
|
||||||
// if cv2, ok := image.(*Canvas); ok && cv2.offscreen {
|
|
||||||
// img = &cv2.offscrImg
|
|
||||||
// flip = true
|
|
||||||
// } else {
|
|
||||||
img = cv.getImage(image)
|
|
||||||
// }
|
|
||||||
|
|
||||||
if img == nil {
|
if img == nil || img.deleted {
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if img.img.IsDeleted() {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,11 +163,6 @@ func (cv *Canvas) DrawImage(image interface{}, coords ...float64) {
|
||||||
dw, dh = coords[6], coords[7]
|
dw, dh = coords[6], coords[7]
|
||||||
}
|
}
|
||||||
|
|
||||||
// if flip {
|
|
||||||
// dy += dh
|
|
||||||
// dh = -dh
|
|
||||||
// }
|
|
||||||
|
|
||||||
var data [4][2]float64
|
var data [4][2]float64
|
||||||
data[0] = cv.tf(vec{dx, dy})
|
data[0] = cv.tf(vec{dx, dy})
|
||||||
data[1] = cv.tf(vec{dx, dy + dh})
|
data[1] = cv.tf(vec{dx, dy + dh})
|
||||||
|
|
Loading…
Reference in a new issue