removed FillMatrix and moved transformations to frontend

This commit is contained in:
Thomas Friedel 2019-02-22 16:53:53 +01:00
parent 3e874d544b
commit 816582dbb3
5 changed files with 87 additions and 91 deletions

View file

@ -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 {

View file

@ -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)

View file

@ -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 {

View file

@ -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

View file

@ -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
}