removed FillMatrix and moved transformations to frontend
This commit is contained in:
parent
3e874d544b
commit
816582dbb3
5 changed files with 87 additions and 91 deletions
|
@ -13,8 +13,8 @@ type Backend interface {
|
|||
Size() (int, int)
|
||||
|
||||
LoadImage(img image.Image) (Image, error)
|
||||
LoadLinearGradient(data *LinearGradientData) LinearGradient
|
||||
LoadRadialGradient(data *RadialGradientData) RadialGradient
|
||||
LoadLinearGradient(data Gradient) LinearGradient
|
||||
LoadRadialGradient(data Gradient) RadialGradient
|
||||
|
||||
Clear(pts [4][2]float64)
|
||||
Fill(style *FillStyle, pts [][2]float64)
|
||||
|
@ -34,22 +34,13 @@ type FillStyle struct {
|
|||
Blur float64
|
||||
LinearGradient LinearGradient
|
||||
RadialGradient RadialGradient
|
||||
Image Image
|
||||
FillMatrix [9]float64
|
||||
}
|
||||
|
||||
type LinearGradientData struct {
|
||||
X0, Y0 float64
|
||||
X1, Y1 float64
|
||||
Stops Gradient
|
||||
}
|
||||
|
||||
type RadialGradientData struct {
|
||||
Gradient struct {
|
||||
X0, Y0 float64
|
||||
X1, Y1 float64
|
||||
RadFrom float64
|
||||
RadTo float64
|
||||
Stops Gradient
|
||||
}
|
||||
Image Image
|
||||
}
|
||||
|
||||
type Gradient []GradientStop
|
||||
|
@ -97,14 +88,14 @@ type LinearGradient interface {
|
|||
Delete()
|
||||
IsDeleted() bool
|
||||
IsOpaque() bool
|
||||
Replace(data *LinearGradientData)
|
||||
Replace(data Gradient)
|
||||
}
|
||||
|
||||
type RadialGradient interface {
|
||||
Delete()
|
||||
IsDeleted() bool
|
||||
IsOpaque() bool
|
||||
Replace(data *RadialGradientData)
|
||||
Replace(data Gradient)
|
||||
}
|
||||
|
||||
type Image interface {
|
||||
|
|
|
@ -306,8 +306,8 @@ func (b *GoGLBackend) useShader(style *backendbase.FillStyle) (vertexLoc uint32)
|
|||
gl.ActiveTexture(gl.TEXTURE0)
|
||||
gl.BindTexture(gl.TEXTURE_2D, lg.tex)
|
||||
gl.UseProgram(b.lgr.ID)
|
||||
from := mat(style.FillMatrix).mul(lg.from)
|
||||
to := mat(style.FillMatrix).mul(lg.to)
|
||||
from := vec{style.Gradient.X0, style.Gradient.Y0}
|
||||
to := vec{style.Gradient.X1, style.Gradient.Y1}
|
||||
dir := to.sub(from)
|
||||
length := dir.len()
|
||||
dir = dir.scale(1 / length)
|
||||
|
@ -324,13 +324,13 @@ func (b *GoGLBackend) useShader(style *backendbase.FillStyle) (vertexLoc uint32)
|
|||
gl.ActiveTexture(gl.TEXTURE0)
|
||||
gl.BindTexture(gl.TEXTURE_2D, rg.tex)
|
||||
gl.UseProgram(b.rgr.ID)
|
||||
from := mat(style.FillMatrix).mul(rg.from)
|
||||
to := mat(style.FillMatrix).mul(rg.to)
|
||||
from := vec{style.Gradient.X0, style.Gradient.Y0}
|
||||
to := vec{style.Gradient.X1, style.Gradient.Y1}
|
||||
gl.Uniform2f(b.rgr.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
gl.Uniform2f(b.rgr.From, float32(from[0]), float32(from[1]))
|
||||
gl.Uniform2f(b.rgr.To, float32(to[0]), float32(to[1]))
|
||||
gl.Uniform1f(b.rgr.RadFrom, float32(rg.radFrom))
|
||||
gl.Uniform1f(b.rgr.RadTo, float32(rg.radTo))
|
||||
gl.Uniform1f(b.rgr.RadFrom, float32(style.Gradient.RadFrom))
|
||||
gl.Uniform1f(b.rgr.RadTo, float32(style.Gradient.RadTo))
|
||||
gl.Uniform1i(b.rgr.Gradient, 0)
|
||||
gl.Uniform1f(b.rgr.GlobalAlpha, float32(style.Color.A)/255)
|
||||
return b.rgr.Vertex
|
||||
|
@ -361,8 +361,8 @@ func (b *GoGLBackend) useAlphaShader(style *backendbase.FillStyle, alphaTexSlot
|
|||
gl.ActiveTexture(gl.TEXTURE0)
|
||||
gl.BindTexture(gl.TEXTURE_2D, lg.tex)
|
||||
gl.UseProgram(b.lgar.ID)
|
||||
from := mat(style.FillMatrix).mul(lg.from)
|
||||
to := mat(style.FillMatrix).mul(lg.to)
|
||||
from := vec{style.Gradient.X0, style.Gradient.Y0}
|
||||
to := vec{style.Gradient.X1, style.Gradient.Y1}
|
||||
dir := to.sub(from)
|
||||
length := dir.len()
|
||||
dir = dir.scale(1 / length)
|
||||
|
@ -380,13 +380,13 @@ func (b *GoGLBackend) useAlphaShader(style *backendbase.FillStyle, alphaTexSlot
|
|||
gl.ActiveTexture(gl.TEXTURE0)
|
||||
gl.BindTexture(gl.TEXTURE_2D, rg.tex)
|
||||
gl.UseProgram(b.rgar.ID)
|
||||
from := mat(style.FillMatrix).mul(rg.from)
|
||||
to := mat(style.FillMatrix).mul(rg.to)
|
||||
from := vec{style.Gradient.X0, style.Gradient.Y0}
|
||||
to := vec{style.Gradient.X1, style.Gradient.Y1}
|
||||
gl.Uniform2f(b.rgar.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
gl.Uniform2f(b.rgar.From, float32(from[0]), float32(from[1]))
|
||||
gl.Uniform2f(b.rgar.To, float32(to[0]), float32(to[1]))
|
||||
gl.Uniform1f(b.rgar.RadFrom, float32(rg.radFrom))
|
||||
gl.Uniform1f(b.rgar.RadTo, float32(rg.radTo))
|
||||
gl.Uniform1f(b.rgar.RadFrom, float32(style.Gradient.RadFrom))
|
||||
gl.Uniform1f(b.rgar.RadTo, float32(style.Gradient.RadTo))
|
||||
gl.Uniform1i(b.rgar.Gradient, 0)
|
||||
gl.Uniform1i(b.rgar.AlphaTex, alphaTexSlot)
|
||||
gl.Uniform1f(b.rgar.GlobalAlpha, float32(style.Color.A)/255)
|
||||
|
|
|
@ -21,23 +21,21 @@ type LinearGradient struct {
|
|||
// will correspond to a circle
|
||||
type RadialGradient struct {
|
||||
gradient
|
||||
radFrom, radTo float64
|
||||
}
|
||||
|
||||
type gradient struct {
|
||||
b *GoGLBackend
|
||||
from, to vec
|
||||
tex uint32
|
||||
loaded bool
|
||||
deleted bool
|
||||
opaque bool
|
||||
}
|
||||
|
||||
func (b *GoGLBackend) LoadLinearGradient(data *backendbase.LinearGradientData) backendbase.LinearGradient {
|
||||
func (b *GoGLBackend) LoadLinearGradient(data backendbase.Gradient) backendbase.LinearGradient {
|
||||
b.activate()
|
||||
|
||||
lg := &LinearGradient{
|
||||
gradient: gradient{b: b, from: vec{data.X0, data.Y0}, to: vec{data.X1, data.Y1}, opaque: true},
|
||||
gradient: gradient{b: b, opaque: true},
|
||||
}
|
||||
gl.GenTextures(1, &lg.tex)
|
||||
gl.ActiveTexture(gl.TEXTURE0)
|
||||
|
@ -46,7 +44,7 @@ func (b *GoGLBackend) LoadLinearGradient(data *backendbase.LinearGradientData) b
|
|||
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_T, gl.CLAMP_TO_EDGE)
|
||||
lg.load(data.Stops)
|
||||
lg.load(data)
|
||||
runtime.SetFinalizer(lg, func(lg *LinearGradient) {
|
||||
b.glChan <- func() {
|
||||
gl.DeleteTextures(1, &lg.tex)
|
||||
|
@ -55,13 +53,11 @@ func (b *GoGLBackend) LoadLinearGradient(data *backendbase.LinearGradientData) b
|
|||
return lg
|
||||
}
|
||||
|
||||
func (b *GoGLBackend) LoadRadialGradient(data *backendbase.RadialGradientData) backendbase.RadialGradient {
|
||||
func (b *GoGLBackend) LoadRadialGradient(data backendbase.Gradient) backendbase.RadialGradient {
|
||||
b.activate()
|
||||
|
||||
rg := &RadialGradient{
|
||||
gradient: gradient{b: b, from: vec{data.X0, data.Y0}, to: vec{data.X1, data.Y1}, opaque: true},
|
||||
radFrom: data.RadFrom,
|
||||
radTo: data.RadTo,
|
||||
gradient: gradient{b: b, opaque: true},
|
||||
}
|
||||
gl.GenTextures(1, &rg.tex)
|
||||
gl.ActiveTexture(gl.TEXTURE0)
|
||||
|
@ -70,7 +66,7 @@ func (b *GoGLBackend) LoadRadialGradient(data *backendbase.RadialGradientData) b
|
|||
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_T, gl.CLAMP_TO_EDGE)
|
||||
rg.load(data.Stops)
|
||||
rg.load(data)
|
||||
runtime.SetFinalizer(rg, func(rg *RadialGradient) {
|
||||
b.glChan <- func() {
|
||||
gl.DeleteTextures(1, &rg.tex)
|
||||
|
@ -90,8 +86,8 @@ func (g *gradient) Delete() {
|
|||
func (g *gradient) IsDeleted() bool { return g.deleted }
|
||||
func (g *gradient) IsOpaque() bool { return g.opaque }
|
||||
|
||||
func (lg *LinearGradient) Replace(data *backendbase.LinearGradientData) { lg.load(data.Stops) }
|
||||
func (rg *RadialGradient) Replace(data *backendbase.RadialGradientData) { rg.load(data.Stops) }
|
||||
func (lg *LinearGradient) Replace(data backendbase.Gradient) { lg.load(data) }
|
||||
func (rg *RadialGradient) Replace(data backendbase.Gradient) { rg.load(data) }
|
||||
|
||||
func (g *gradient) load(stops backendbase.Gradient) {
|
||||
if g.loaded {
|
||||
|
|
16
canvas.go
16
canvas.go
|
@ -244,13 +244,27 @@ func (s *drawStyle) isOpaque() bool {
|
|||
}
|
||||
|
||||
func (cv *Canvas) backendFillStyle(s *drawStyle, alpha float64) backendbase.FillStyle {
|
||||
stl := backendbase.FillStyle{Color: s.color, FillMatrix: cv.state.transform}
|
||||
stl := backendbase.FillStyle{Color: s.color}
|
||||
alpha *= cv.state.globalAlpha
|
||||
if lg := s.linearGradient; lg != nil {
|
||||
lg.load()
|
||||
stl.LinearGradient = lg.grad
|
||||
from := cv.tf(lg.from)
|
||||
to := cv.tf(lg.to)
|
||||
stl.Gradient.X0 = from[0]
|
||||
stl.Gradient.Y0 = from[1]
|
||||
stl.Gradient.X1 = to[0]
|
||||
stl.Gradient.Y1 = to[1]
|
||||
} else if rg := s.radialGradient; rg != nil {
|
||||
rg.load()
|
||||
from := cv.tf(rg.from)
|
||||
to := cv.tf(rg.to)
|
||||
stl.Gradient.X0 = from[0]
|
||||
stl.Gradient.Y0 = from[1]
|
||||
stl.Gradient.X1 = to[0]
|
||||
stl.Gradient.Y1 = to[1]
|
||||
stl.Gradient.RadFrom = rg.radFrom
|
||||
stl.Gradient.RadTo = rg.radTo
|
||||
stl.RadialGradient = rg.grad
|
||||
} else if img := s.image; img != nil {
|
||||
stl.Image = img.img
|
||||
|
|
49
gradients.go
49
gradients.go
|
@ -12,12 +12,13 @@ import (
|
|||
// will correspond to a straight line
|
||||
type LinearGradient struct {
|
||||
cv *Canvas
|
||||
from, to vec
|
||||
created bool
|
||||
loaded bool
|
||||
deleted bool
|
||||
opaque bool
|
||||
grad backendbase.LinearGradient
|
||||
data backendbase.LinearGradientData
|
||||
data backendbase.Gradient
|
||||
}
|
||||
|
||||
// RadialGradient is a gradient with any number of
|
||||
|
@ -26,12 +27,15 @@ type LinearGradient struct {
|
|||
// will correspond to a circle
|
||||
type RadialGradient struct {
|
||||
cv *Canvas
|
||||
from, to vec
|
||||
radFrom float64
|
||||
radTo float64
|
||||
created bool
|
||||
loaded bool
|
||||
deleted bool
|
||||
opaque bool
|
||||
grad backendbase.RadialGradient
|
||||
data backendbase.RadialGradientData
|
||||
data backendbase.Gradient
|
||||
}
|
||||
|
||||
// NewLinearGradient creates a new linear gradient with
|
||||
|
@ -41,13 +45,9 @@ func (cv *Canvas) NewLinearGradient(x0, y0, x1, y1 float64) *LinearGradient {
|
|||
return &LinearGradient{
|
||||
cv: cv,
|
||||
opaque: true,
|
||||
data: backendbase.LinearGradientData{
|
||||
X0: x0,
|
||||
Y0: y0,
|
||||
X1: x1,
|
||||
Y1: y1,
|
||||
Stops: make(backendbase.Gradient, 0, 20),
|
||||
},
|
||||
from: vec{x0, y0},
|
||||
to: vec{x1, y1},
|
||||
data: make(backendbase.Gradient, 0, 20),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,17 +59,12 @@ func (cv *Canvas) NewRadialGradient(x0, y0, r0, x1, y1, r1 float64) *RadialGradi
|
|||
return &RadialGradient{
|
||||
cv: cv,
|
||||
opaque: true,
|
||||
data: backendbase.RadialGradientData{
|
||||
X0: x0,
|
||||
Y0: y0,
|
||||
X1: x1,
|
||||
Y1: y1,
|
||||
RadFrom: r0,
|
||||
RadTo: r1,
|
||||
Stops: make(backendbase.Gradient, 0, 20),
|
||||
},
|
||||
from: vec{x0, y0},
|
||||
to: vec{x1, y1},
|
||||
radFrom: r0,
|
||||
radTo: r1,
|
||||
data: make(backendbase.Gradient, 0, 20),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Delete explicitly deletes the gradient
|
||||
|
@ -79,28 +74,28 @@ func (lg *LinearGradient) Delete() { lg.grad.Delete() }
|
|||
func (rg *RadialGradient) Delete() { rg.grad.Delete() }
|
||||
|
||||
func (lg *LinearGradient) load() {
|
||||
if lg.loaded || len(lg.data.Stops) < 1 {
|
||||
if lg.loaded || len(lg.data) < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
if !lg.created {
|
||||
lg.grad = lg.cv.b.LoadLinearGradient(&lg.data)
|
||||
lg.grad = lg.cv.b.LoadLinearGradient(lg.data)
|
||||
} else {
|
||||
lg.grad.Replace(&lg.data)
|
||||
lg.grad.Replace(lg.data)
|
||||
}
|
||||
lg.created = true
|
||||
lg.loaded = true
|
||||
}
|
||||
|
||||
func (rg *RadialGradient) load() {
|
||||
if rg.loaded || len(rg.data.Stops) < 1 {
|
||||
if rg.loaded || len(rg.data) < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
if !rg.created {
|
||||
rg.grad = rg.cv.b.LoadRadialGradient(&rg.data)
|
||||
rg.grad = rg.cv.b.LoadRadialGradient(rg.data)
|
||||
} else {
|
||||
rg.grad.Replace(&rg.data)
|
||||
rg.grad.Replace(rg.data)
|
||||
}
|
||||
rg.created = true
|
||||
rg.loaded = true
|
||||
|
@ -111,7 +106,7 @@ func (rg *RadialGradient) load() {
|
|||
// right place
|
||||
func (lg *LinearGradient) AddColorStop(pos float64, stopColor ...interface{}) {
|
||||
var c color.RGBA
|
||||
lg.data.Stops, c = addColorStop(lg.data.Stops, pos, stopColor...)
|
||||
lg.data, c = addColorStop(lg.data, pos, stopColor...)
|
||||
if c.A < 255 {
|
||||
lg.opaque = false
|
||||
}
|
||||
|
@ -123,7 +118,7 @@ func (lg *LinearGradient) AddColorStop(pos float64, stopColor ...interface{}) {
|
|||
// right place
|
||||
func (rg *RadialGradient) AddColorStop(pos float64, stopColor ...interface{}) {
|
||||
var c color.RGBA
|
||||
rg.data.Stops, c = addColorStop(rg.data.Stops, pos, stopColor...)
|
||||
rg.data, c = addColorStop(rg.data, pos, stopColor...)
|
||||
if c.A < 255 {
|
||||
rg.opaque = false
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue