image pattern support in backend

This commit is contained in:
Thomas Friedel 2019-02-21 12:26:35 +01:00
parent 476dbac6e2
commit a354e192b6
3 changed files with 62 additions and 30 deletions

View file

@ -22,7 +22,8 @@ type FillStyle struct {
Blur float64
// radialGradient *RadialGradient
// linearGradient *LinearGradient
// image *Image
Image Image
FillMatrix [9]float64
}
type Image interface {

View file

@ -292,18 +292,19 @@ func (b *GoGLBackend) useShader(style *backendbase.FillStyle) (vertexLoc uint32)
// gl.Uniform1f(rgr.globalAlpha, float32(cv.state.globalAlpha))
// return rgr.vertex
// }
// if img := style.Image; img != nil {
// gl.UseProgram(ipr.id)
// gl.ActiveTexture(gl.TEXTURE0)
// gl.BindTexture(gl.TEXTURE_2D, img.tex)
// gl.Uniform2f(ipr.canvasSize, float32(cv.fw), float32(cv.fh))
// inv := cv.state.transform.invert().f32()
// gl.UniformMatrix3fv(ipr.invmat, 1, false, &inv[0])
// gl.Uniform2f(ipr.imageSize, float32(img.w), float32(img.h))
// gl.Uniform1i(ipr.image, 0)
// gl.Uniform1f(ipr.globalAlpha, float32(cv.state.globalAlpha))
// return ipr.vertex
// }
if img := style.Image; img != nil {
img := img.(*Image)
gl.UseProgram(b.ipr.ID)
gl.ActiveTexture(gl.TEXTURE0)
gl.BindTexture(gl.TEXTURE_2D, img.tex)
gl.Uniform2f(b.ipr.CanvasSize, float32(b.fw), float32(b.fh))
inv := mat(style.FillMatrix).invert().f32()
gl.UniformMatrix3fv(b.ipr.Invmat, 1, false, &inv[0])
gl.Uniform2f(b.ipr.ImageSize, float32(img.w), float32(img.h))
gl.Uniform1i(b.ipr.Image, 0)
gl.Uniform1f(b.ipr.GlobalAlpha, float32(style.Color.A)/255)
return b.ipr.Vertex
}
gl.UseProgram(b.sr.ID)
gl.Uniform2f(b.sr.CanvasSize, float32(b.fw), float32(b.fh))
@ -359,19 +360,20 @@ func (b *GoGLBackend) useAlphaShader(style *backendbase.FillStyle, alphaTexSlot
// gl.Uniform1f(rgar.globalAlpha, float32(cv.state.globalAlpha))
// return rgar.vertex, rgar.alphaTexCoord
// }
// if img := style.Image; img != nil {
// gl.UseProgram(ipar.id)
// gl.ActiveTexture(gl.TEXTURE0)
// gl.BindTexture(gl.TEXTURE_2D, img.tex)
// gl.Uniform2f(ipar.canvasSize, float32(cv.fw), float32(cv.fh))
// inv := cv.state.transform.invert().f32()
// gl.UniformMatrix3fv(ipar.invmat, 1, false, &inv[0])
// gl.Uniform2f(ipar.imageSize, float32(img.w), float32(img.h))
// gl.Uniform1i(ipar.image, 0)
// gl.Uniform1i(ipar.alphaTex, alphaTexSlot)
// gl.Uniform1f(ipar.globalAlpha, float32(cv.state.globalAlpha))
// return ipar.vertex, ipar.alphaTexCoord
// }
if img := style.Image; img != nil {
img := img.(*Image)
gl.UseProgram(b.ipar.ID)
gl.ActiveTexture(gl.TEXTURE0)
gl.BindTexture(gl.TEXTURE_2D, img.tex)
gl.Uniform2f(b.ipar.CanvasSize, float32(b.fw), float32(b.fh))
inv := mat(style.FillMatrix).invert().f32()
gl.UniformMatrix3fv(b.ipar.Invmat, 1, false, &inv[0])
gl.Uniform2f(b.ipar.ImageSize, float32(img.w), float32(img.h))
gl.Uniform1i(b.ipar.Image, 0)
gl.Uniform1i(b.ipar.AlphaTex, alphaTexSlot)
gl.Uniform1f(b.ipar.GlobalAlpha, float32(style.Color.A)/255)
return b.ipar.Vertex, b.ipar.AlphaTexCoord
}
gl.UseProgram(b.sar.ID)
gl.Uniform2f(b.sar.CanvasSize, float32(b.fw), float32(b.fh))
@ -432,3 +434,27 @@ func (b *GoGLBackend) disableTextureRenderTarget() {
gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
// }
}
type mat [9]float64
func (m mat) invert() mat {
var identity float64 = 1.0 / (m[0]*m[4]*m[8] + m[3]*m[7]*m[2] + m[6]*m[1]*m[5] - m[6]*m[4]*m[2] - m[3]*m[1]*m[8] - m[0]*m[7]*m[5])
return mat{
(m[4]*m[8] - m[5]*m[7]) * identity,
(m[2]*m[7] - m[1]*m[8]) * identity,
(m[1]*m[5] - m[2]*m[4]) * identity,
(m[5]*m[6] - m[3]*m[8]) * identity,
(m[0]*m[8] - m[2]*m[6]) * identity,
(m[2]*m[3] - m[0]*m[5]) * identity,
(m[3]*m[7] - m[4]*m[6]) * identity,
(m[1]*m[6] - m[0]*m[7]) * identity,
(m[0]*m[4] - m[1]*m[3]) * identity}
}
func (m mat) f32() [9]float32 {
return [9]float32{
float32(m[0]), float32(m[1]), float32(m[2]),
float32(m[3]), float32(m[4]), float32(m[5]),
float32(m[6]), float32(m[7]), float32(m[8])}
}

View file

@ -502,10 +502,15 @@ func (s *drawStyle) isOpaque() bool {
}
func (cv *Canvas) backendFillStyle(s *drawStyle, alpha float64) backendbase.FillStyle {
col := s.color
finalAlpha := (float64(s.color.A) / 255) * alpha * cv.state.globalAlpha
col.A = uint8(finalAlpha * 255)
return backendbase.FillStyle{Color: col}
stl := backendbase.FillStyle{Color: s.color, FillMatrix: cv.state.transform}
alpha *= cv.state.globalAlpha
if img := cv.state.fill.image; img != nil {
stl.Image = img.img
} else {
alpha *= float64(s.color.A) / 255
}
stl.Color.A = uint8(alpha * 255)
return stl
}
func (cv *Canvas) useShader(style *drawStyle) (vertexLoc uint32) {