updated xmobile backend
This commit is contained in:
parent
a0ba7b2ad3
commit
896af05ba4
8 changed files with 309 additions and 830 deletions
|
@ -33,13 +33,15 @@ func (b *XMobileBackend) Clip(pts [][2]float64) {
|
|||
|
||||
b.glctx.BindBuffer(gl.ARRAY_BUFFER, b.buf)
|
||||
b.glctx.BufferData(gl.ARRAY_BUFFER, byteSlice(unsafe.Pointer(&b.ptsBuf[0]), len(b.ptsBuf)*4), gl.STREAM_DRAW)
|
||||
b.glctx.VertexAttribPointer(b.sr.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
b.glctx.VertexAttribPointer(b.shd.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
|
||||
b.glctx.UseProgram(b.sr.ID)
|
||||
b.glctx.Uniform4f(b.sr.Color, 1, 1, 1, 1)
|
||||
b.glctx.Uniform2f(b.sr.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform1f(b.sr.GlobalAlpha, 1)
|
||||
b.glctx.EnableVertexAttribArray(b.sr.Vertex)
|
||||
b.glctx.UseProgram(b.shd.ID)
|
||||
b.glctx.Uniform4f(b.shd.Color, 1, 1, 1, 1)
|
||||
b.glctx.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform1f(b.shd.GlobalAlpha, 1)
|
||||
b.glctx.Uniform1i(b.shd.UseAlphaTex, 0)
|
||||
b.glctx.Uniform1i(b.shd.Func, shdFuncSolid)
|
||||
b.glctx.EnableVertexAttribArray(b.shd.Vertex)
|
||||
|
||||
b.glctx.ColorMask(false, false, false, false)
|
||||
|
||||
|
@ -61,7 +63,7 @@ func (b *XMobileBackend) Clip(pts [][2]float64) {
|
|||
b.glctx.StencilOp(gl.ZERO, gl.ZERO, gl.ZERO)
|
||||
b.glctx.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
|
||||
|
||||
b.glctx.DisableVertexAttribArray(b.sr.Vertex)
|
||||
b.glctx.DisableVertexAttribArray(b.shd.Vertex)
|
||||
|
||||
b.glctx.ColorMask(true, true, true, true)
|
||||
b.glctx.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP)
|
||||
|
|
|
@ -33,10 +33,12 @@ func (b *XMobileBackend) Clear(pts [4][2]float64) {
|
|||
float32(pts[2][0]), float32(pts[2][1]),
|
||||
float32(pts[3][0]), float32(pts[3][1])}
|
||||
|
||||
b.glctx.UseProgram(b.sr.ID)
|
||||
b.glctx.Uniform2f(b.sr.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform4f(b.sr.Color, 0, 0, 0, 0)
|
||||
b.glctx.Uniform1f(b.sr.GlobalAlpha, 1)
|
||||
b.glctx.UseProgram(b.shd.ID)
|
||||
b.glctx.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform4f(b.shd.Color, 0, 0, 0, 0)
|
||||
b.glctx.Uniform1f(b.shd.GlobalAlpha, 1)
|
||||
b.glctx.Uniform1i(b.shd.UseAlphaTex, 0)
|
||||
b.glctx.Uniform1i(b.shd.Func, shdFuncSolid)
|
||||
|
||||
b.glctx.Disable(gl.BLEND)
|
||||
|
||||
|
@ -45,10 +47,10 @@ func (b *XMobileBackend) Clear(pts [4][2]float64) {
|
|||
|
||||
b.glctx.StencilFunc(gl.EQUAL, 0, 0xFF)
|
||||
|
||||
b.glctx.VertexAttribPointer(b.sr.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
b.glctx.EnableVertexAttribArray(b.sr.Vertex)
|
||||
b.glctx.VertexAttribPointer(b.shd.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
b.glctx.EnableVertexAttribArray(b.shd.Vertex)
|
||||
b.glctx.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
|
||||
b.glctx.DisableVertexAttribArray(b.sr.Vertex)
|
||||
b.glctx.DisableVertexAttribArray(b.shd.Vertex)
|
||||
|
||||
b.glctx.StencilFunc(gl.ALWAYS, 0, 0xFF)
|
||||
|
||||
|
@ -70,6 +72,8 @@ func (b *XMobileBackend) clearRect(x, y, w, h int) {
|
|||
}
|
||||
|
||||
func extent(pts [][2]float64) (min, max vec) {
|
||||
max[0] = -math.MaxFloat64
|
||||
max[1] = -math.MaxFloat64
|
||||
min[0] = math.MaxFloat64
|
||||
min[1] = math.MaxFloat64
|
||||
for _, v := range pts {
|
||||
|
@ -111,7 +115,7 @@ func (b *XMobileBackend) Fill(style *backendbase.FillStyle, pts [][2]float64, ca
|
|||
b.glctx.BufferData(gl.ARRAY_BUFFER, byteSlice(unsafe.Pointer(&b.ptsBuf[0]), len(b.ptsBuf)*4), gl.STREAM_DRAW)
|
||||
|
||||
if !canOverlap || style.Color.A >= 255 {
|
||||
vertex := b.useShader(style)
|
||||
vertex, _ := b.useShader(style, false, 0)
|
||||
|
||||
b.glctx.StencilFunc(gl.EQUAL, 0, 0xFF)
|
||||
b.glctx.EnableVertexAttribArray(vertex)
|
||||
|
@ -125,21 +129,23 @@ func (b *XMobileBackend) Fill(style *backendbase.FillStyle, pts [][2]float64, ca
|
|||
b.glctx.StencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE)
|
||||
b.glctx.StencilMask(0x01)
|
||||
|
||||
b.glctx.UseProgram(b.sr.ID)
|
||||
b.glctx.Uniform4f(b.sr.Color, 0, 0, 0, 0)
|
||||
b.glctx.Uniform2f(b.sr.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform1f(b.sr.GlobalAlpha, 1)
|
||||
b.glctx.UseProgram(b.shd.ID)
|
||||
b.glctx.Uniform4f(b.shd.Color, 0, 0, 0, 0)
|
||||
b.glctx.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform1f(b.shd.GlobalAlpha, 1)
|
||||
b.glctx.Uniform1i(b.shd.UseAlphaTex, 0)
|
||||
b.glctx.Uniform1i(b.shd.Func, shdFuncSolid)
|
||||
|
||||
b.glctx.EnableVertexAttribArray(b.sr.Vertex)
|
||||
b.glctx.VertexAttribPointer(b.sr.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
b.glctx.EnableVertexAttribArray(b.shd.Vertex)
|
||||
b.glctx.VertexAttribPointer(b.shd.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
b.glctx.DrawArrays(mode, 4, len(pts))
|
||||
b.glctx.DisableVertexAttribArray(b.sr.Vertex)
|
||||
b.glctx.DisableVertexAttribArray(b.shd.Vertex)
|
||||
|
||||
b.glctx.ColorMask(true, true, true, true)
|
||||
|
||||
b.glctx.StencilFunc(gl.EQUAL, 1, 0xFF)
|
||||
|
||||
vertex := b.useShader(style)
|
||||
vertex, _ := b.useShader(style, false, 0)
|
||||
b.glctx.EnableVertexAttribArray(vertex)
|
||||
b.glctx.VertexAttribPointer(vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
|
||||
|
@ -154,7 +160,7 @@ func (b *XMobileBackend) Fill(style *backendbase.FillStyle, pts [][2]float64, ca
|
|||
}
|
||||
|
||||
if style.Blur > 0 {
|
||||
b.drawBlurred(style.Blur)
|
||||
b.drawBlurred(style.Blur, min, max)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,7 +187,7 @@ func (b *XMobileBackend) FillImageMask(style *backendbase.FillStyle, mask *image
|
|||
|
||||
b.glctx.BindBuffer(gl.ARRAY_BUFFER, b.buf)
|
||||
|
||||
vertex, alphaTexCoord := b.useAlphaShader(style, 1)
|
||||
vertex, alphaTexCoord := b.useShader(style, true, 1)
|
||||
|
||||
b.glctx.EnableVertexAttribArray(vertex)
|
||||
b.glctx.EnableVertexAttribArray(alphaTexCoord)
|
||||
|
@ -216,105 +222,103 @@ func (b *XMobileBackend) FillImageMask(style *backendbase.FillStyle, mask *image
|
|||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||
|
||||
if style.Blur > 0 {
|
||||
b.drawBlurred(style.Blur)
|
||||
min, max := extent(pts[:])
|
||||
b.drawBlurred(style.Blur, min, max)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *XMobileBackend) drawBlurred(blur float64) {
|
||||
b.glctx.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
|
||||
func (b *XMobileBackend) drawBlurred(size float64, min, max vec) {
|
||||
b.offscr1.alpha = true
|
||||
b.offscr2.alpha = true
|
||||
|
||||
var kernel []float32
|
||||
var kernelBuf [255]float32
|
||||
var gs *gaussianShader
|
||||
if blur < 3 {
|
||||
gs = &b.gauss15r
|
||||
kernel = kernelBuf[:15]
|
||||
} else if blur < 12 {
|
||||
gs = &b.gauss63r
|
||||
kernel = kernelBuf[:63]
|
||||
} else {
|
||||
gs = &b.gauss127r
|
||||
kernel = kernelBuf[:127]
|
||||
// calculate box blur size
|
||||
fsize := math.Max(1, math.Floor(size))
|
||||
sizea := int(fsize)
|
||||
sizeb := sizea
|
||||
sizec := sizea
|
||||
if size-fsize > 0.333333333 {
|
||||
sizeb++
|
||||
}
|
||||
if size-fsize > 0.666666666 {
|
||||
sizec++
|
||||
}
|
||||
|
||||
gaussianKernel(blur, kernel)
|
||||
min[0] -= fsize * 3
|
||||
min[1] -= fsize * 3
|
||||
max[0] += fsize * 3
|
||||
max[1] += fsize * 3
|
||||
min[0] = math.Max(0.0, math.Min(b.fw, min[0]))
|
||||
min[1] = math.Max(0.0, math.Min(b.fh, min[1]))
|
||||
max[0] = math.Max(0.0, math.Min(b.fw, max[0]))
|
||||
max[1] = math.Max(0.0, math.Min(b.fh, max[1]))
|
||||
|
||||
b.glctx.BindBuffer(gl.ARRAY_BUFFER, b.shadowBuf)
|
||||
data := [16]float32{
|
||||
float32(min[0]), float32(min[1]),
|
||||
float32(min[0]), float32(max[1]),
|
||||
float32(max[0]), float32(max[1]),
|
||||
float32(max[0]), float32(min[1]),
|
||||
float32(min[0] / b.fw), 1 - float32(min[1]/b.fh),
|
||||
float32(min[0] / b.fw), 1 - float32(max[1]/b.fh),
|
||||
float32(max[0] / b.fw), 1 - float32(max[1]/b.fh),
|
||||
float32(max[0] / b.fw), 1 - float32(min[1]/b.fh),
|
||||
}
|
||||
b.glctx.BufferData(gl.ARRAY_BUFFER, byteSlice(unsafe.Pointer(&data[0]), len(data)*4), gl.STREAM_DRAW)
|
||||
|
||||
b.glctx.UseProgram(b.shd.ID)
|
||||
b.glctx.Uniform1i(b.shd.Image, 0)
|
||||
b.glctx.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform1i(b.shd.UseAlphaTex, 0)
|
||||
b.glctx.Uniform1i(b.shd.Func, shdFuncBoxBlur)
|
||||
|
||||
b.glctx.VertexAttribPointer(b.shd.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
b.glctx.VertexAttribPointer(b.shd.TexCoord, 2, gl.FLOAT, false, 0, 8*4)
|
||||
b.glctx.EnableVertexAttribArray(b.shd.Vertex)
|
||||
b.glctx.EnableVertexAttribArray(b.shd.TexCoord)
|
||||
|
||||
b.glctx.Disable(gl.BLEND)
|
||||
|
||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||
|
||||
b.offscr2.alpha = true
|
||||
b.enableTextureRenderTarget(&b.offscr2)
|
||||
b.glctx.ClearColor(0, 0, 0, 0)
|
||||
b.glctx.Clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
|
||||
|
||||
b.glctx.StencilFunc(gl.EQUAL, 0, 0xFF)
|
||||
|
||||
b.glctx.BindBuffer(gl.ARRAY_BUFFER, b.shadowBuf)
|
||||
data := [16]float32{0, 0, 0, float32(b.h), float32(b.w), float32(b.h), float32(b.w), 0, 0, 0, 0, 1, 1, 1, 1, 0}
|
||||
b.glctx.BufferData(gl.ARRAY_BUFFER, byteSlice(unsafe.Pointer(&data[0]), len(data)*4), gl.STREAM_DRAW)
|
||||
|
||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||
b.enableTextureRenderTarget(&b.offscr2)
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, b.offscr1.tex)
|
||||
|
||||
b.glctx.UseProgram(gs.ID)
|
||||
b.glctx.Uniform1i(gs.Image, 0)
|
||||
b.glctx.Uniform2f(gs.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform2f(gs.KernelScale, 1.0/float32(b.fw), 0.0)
|
||||
b.glctx.Uniform1fv(gs.Kernel, kernel)
|
||||
b.glctx.VertexAttribPointer(gs.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
b.glctx.VertexAttribPointer(gs.TexCoord, 2, gl.FLOAT, false, 0, 8*4)
|
||||
b.glctx.EnableVertexAttribArray(gs.Vertex)
|
||||
b.glctx.EnableVertexAttribArray(gs.TexCoord)
|
||||
b.glctx.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
|
||||
b.glctx.DisableVertexAttribArray(gs.Vertex)
|
||||
b.glctx.DisableVertexAttribArray(gs.TexCoord)
|
||||
|
||||
b.glctx.StencilFunc(gl.ALWAYS, 0, 0xFF)
|
||||
|
||||
b.disableTextureRenderTarget()
|
||||
|
||||
b.glctx.StencilFunc(gl.EQUAL, 0, 0xFF)
|
||||
|
||||
b.glctx.BindBuffer(gl.ARRAY_BUFFER, b.shadowBuf)
|
||||
data = [16]float32{0, 0, 0, float32(b.h), float32(b.w), float32(b.h), float32(b.w), 0, 0, 0, 0, 1, 1, 1, 1, 0}
|
||||
b.glctx.BufferData(gl.ARRAY_BUFFER, byteSlice(unsafe.Pointer(&data[0]), len(data)*4), gl.STREAM_DRAW)
|
||||
|
||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||
b.glctx.Clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
|
||||
b.box3(sizea, 0, false)
|
||||
b.enableTextureRenderTarget(&b.offscr1)
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, b.offscr2.tex)
|
||||
b.box3(sizeb, -0.5, false)
|
||||
b.enableTextureRenderTarget(&b.offscr2)
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, b.offscr1.tex)
|
||||
b.box3(sizec, 0, false)
|
||||
b.enableTextureRenderTarget(&b.offscr1)
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, b.offscr2.tex)
|
||||
b.box3(sizea, 0, true)
|
||||
b.enableTextureRenderTarget(&b.offscr2)
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, b.offscr1.tex)
|
||||
b.box3(sizeb, -0.5, true)
|
||||
b.glctx.Enable(gl.BLEND)
|
||||
b.glctx.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
|
||||
b.disableTextureRenderTarget()
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, b.offscr2.tex)
|
||||
b.box3(sizec, 0, true)
|
||||
|
||||
b.glctx.UseProgram(gs.ID)
|
||||
b.glctx.Uniform1i(gs.Image, 0)
|
||||
b.glctx.Uniform2f(gs.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform2f(gs.KernelScale, 0.0, 1.0/float32(b.fh))
|
||||
b.glctx.Uniform1fv(gs.Kernel, kernel)
|
||||
b.glctx.VertexAttribPointer(gs.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
b.glctx.VertexAttribPointer(gs.TexCoord, 2, gl.FLOAT, false, 0, 8*4)
|
||||
b.glctx.EnableVertexAttribArray(gs.Vertex)
|
||||
b.glctx.EnableVertexAttribArray(gs.TexCoord)
|
||||
b.glctx.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
|
||||
b.glctx.DisableVertexAttribArray(gs.Vertex)
|
||||
b.glctx.DisableVertexAttribArray(gs.TexCoord)
|
||||
|
||||
b.glctx.StencilFunc(gl.ALWAYS, 0, 0xFF)
|
||||
b.glctx.DisableVertexAttribArray(b.shd.Vertex)
|
||||
b.glctx.DisableVertexAttribArray(b.shd.TexCoord)
|
||||
|
||||
b.glctx.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
|
||||
}
|
||||
|
||||
func gaussianKernel(stddev float64, target []float32) {
|
||||
stddevSqr := stddev * stddev
|
||||
center := float64(len(target) / 2)
|
||||
factor := 1.0 / math.Sqrt(2*math.Pi*stddevSqr)
|
||||
for i := range target {
|
||||
x := float64(i) - center
|
||||
target[i] = float32(factor * math.Pow(math.E, -x*x/(2*stddevSqr)))
|
||||
}
|
||||
// normalizeKernel(target)
|
||||
}
|
||||
|
||||
func normalizeKernel(kernel []float32) {
|
||||
var sum float32
|
||||
for _, v := range kernel {
|
||||
sum += v
|
||||
}
|
||||
factor := 1.0 / sum
|
||||
for i := range kernel {
|
||||
kernel[i] *= factor
|
||||
func (b *XMobileBackend) box3(size int, offset float32, vertical bool) {
|
||||
b.glctx.Uniform1i(b.shd.BoxSize, size)
|
||||
if vertical {
|
||||
b.glctx.Uniform1i(b.shd.BoxVertical, 1)
|
||||
b.glctx.Uniform1f(b.shd.BoxScale, 1/float32(b.fh))
|
||||
} else {
|
||||
b.glctx.Uniform1i(b.shd.BoxVertical, 0)
|
||||
b.glctx.Uniform1f(b.shd.BoxScale, 1/float32(b.fw))
|
||||
}
|
||||
b.glctx.Uniform1f(b.shd.BoxOffset, offset)
|
||||
b.glctx.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
|
||||
}
|
||||
|
|
|
@ -142,6 +142,12 @@ func rewrite(filename, src string) (string, string) {
|
|||
params[2] = params[2][1 : len(params[2])-3]
|
||||
return "b.glctx.Uniform1fv(" + params[0] + ", " + params[2] + ")"
|
||||
})
|
||||
src = rewriteCalls(src, "b.glctx.Uniform1i", func(params []string) string {
|
||||
if strings.HasPrefix(params[1], "int32(") {
|
||||
params[1] = params[1][6 : len(params[1])-1]
|
||||
}
|
||||
return "b.glctx.Uniform1i(" + strings.Join(params, ",") + ")"
|
||||
})
|
||||
src = rewriteCalls(src, "b.glctx.UniformMatrix3fv", func(params []string) string {
|
||||
return "b.glctx.UniformMatrix3fv(" + params[0] + ", " + params[3][1:len(params[3])-3] + "[:])"
|
||||
})
|
||||
|
@ -364,23 +370,18 @@ func byteSlice(ptr unsafe.Pointer, size int) []byte {
|
|||
|
||||
func rewriteShaders(src string) string {
|
||||
src = strings.Replace(src,
|
||||
`import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
`package xmobilebackend
|
||||
`,
|
||||
`import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
`package xmobilebackend
|
||||
|
||||
import (
|
||||
"golang.org/x/mobile/gl"
|
||||
)
|
||||
`, 1)
|
||||
|
||||
src = strings.Replace(src, "uint32", "gl.Attrib", -1)
|
||||
src = strings.Replace(src, "int32", "gl.Uniform", -1)
|
||||
src = strings.Replace(src, "shdFuncSolid gl.Uniform", "shdFuncSolid int", -1)
|
||||
|
||||
return src
|
||||
}
|
||||
|
|
|
@ -24,9 +24,8 @@ type RadialGradient struct {
|
|||
}
|
||||
|
||||
type gradient struct {
|
||||
b *XMobileBackend
|
||||
tex gl.Texture
|
||||
loaded bool
|
||||
b *XMobileBackend
|
||||
tex gl.Texture
|
||||
}
|
||||
|
||||
func (b *XMobileBackend) LoadLinearGradient(data backendbase.Gradient) backendbase.LinearGradient {
|
||||
|
@ -86,10 +85,6 @@ func (rg *RadialGradient) Replace(data backendbase.Gradient) { rg.load(data) }
|
|||
|
||||
func (g *gradient) load(stops backendbase.Gradient) {
|
||||
b := g.b
|
||||
if g.loaded {
|
||||
return
|
||||
}
|
||||
|
||||
g.b.activate()
|
||||
|
||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||
|
@ -106,5 +101,4 @@ func (g *gradient) load(stops backendbase.Gradient) {
|
|||
}
|
||||
|
||||
b.glctx.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2048, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels[0:])
|
||||
g.loaded = true
|
||||
}
|
||||
|
|
|
@ -85,15 +85,17 @@ func (b *XMobileBackend) PutImageData(img *image.RGBA, x, y int) {
|
|||
0, 0, 1, 0, 1, 1, 0, 1}
|
||||
b.glctx.BufferData(gl.ARRAY_BUFFER, byteSlice(unsafe.Pointer(&data[0]), len(data)*4), gl.STREAM_DRAW)
|
||||
|
||||
b.glctx.UseProgram(b.ir.ID)
|
||||
b.glctx.Uniform1i(b.ir.Image, 0)
|
||||
b.glctx.Uniform2f(b.ir.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform1f(b.ir.GlobalAlpha, 1)
|
||||
b.glctx.VertexAttribPointer(b.ir.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
b.glctx.VertexAttribPointer(b.ir.TexCoord, 2, gl.FLOAT, false, 0, 8*4)
|
||||
b.glctx.EnableVertexAttribArray(b.ir.Vertex)
|
||||
b.glctx.EnableVertexAttribArray(b.ir.TexCoord)
|
||||
b.glctx.UseProgram(b.shd.ID)
|
||||
b.glctx.Uniform1i(b.shd.Image, 0)
|
||||
b.glctx.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform1f(b.shd.GlobalAlpha, 1)
|
||||
b.glctx.Uniform1i(b.shd.UseAlphaTex, 0)
|
||||
b.glctx.Uniform1i(b.shd.Func, shdFuncImage)
|
||||
b.glctx.VertexAttribPointer(b.shd.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
b.glctx.VertexAttribPointer(b.shd.TexCoord, 2, gl.FLOAT, false, 0, 8*4)
|
||||
b.glctx.EnableVertexAttribArray(b.shd.Vertex)
|
||||
b.glctx.EnableVertexAttribArray(b.shd.TexCoord)
|
||||
b.glctx.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
|
||||
b.glctx.DisableVertexAttribArray(b.ir.Vertex)
|
||||
b.glctx.DisableVertexAttribArray(b.ir.TexCoord)
|
||||
b.glctx.DisableVertexAttribArray(b.shd.Vertex)
|
||||
b.glctx.DisableVertexAttribArray(b.shd.TexCoord)
|
||||
}
|
||||
|
|
|
@ -196,17 +196,19 @@ func (b *XMobileBackend) DrawImage(dimg backendbase.Image, sx, sy, sw, sh float6
|
|||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, img.tex)
|
||||
|
||||
b.glctx.UseProgram(b.ir.ID)
|
||||
b.glctx.Uniform1i(b.ir.Image, 0)
|
||||
b.glctx.Uniform2f(b.ir.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform1f(b.ir.GlobalAlpha, float32(alpha))
|
||||
b.glctx.VertexAttribPointer(b.ir.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
b.glctx.VertexAttribPointer(b.ir.TexCoord, 2, gl.FLOAT, false, 0, 8*4)
|
||||
b.glctx.EnableVertexAttribArray(b.ir.Vertex)
|
||||
b.glctx.EnableVertexAttribArray(b.ir.TexCoord)
|
||||
b.glctx.UseProgram(b.shd.ID)
|
||||
b.glctx.Uniform1i(b.shd.Image, 0)
|
||||
b.glctx.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform1f(b.shd.GlobalAlpha, float32(alpha))
|
||||
b.glctx.Uniform1i(b.shd.UseAlphaTex, 0)
|
||||
b.glctx.Uniform1i(b.shd.Func, shdFuncImage)
|
||||
b.glctx.VertexAttribPointer(b.shd.Vertex, 2, gl.FLOAT, false, 0, 0)
|
||||
b.glctx.VertexAttribPointer(b.shd.TexCoord, 2, gl.FLOAT, false, 0, 8*4)
|
||||
b.glctx.EnableVertexAttribArray(b.shd.Vertex)
|
||||
b.glctx.EnableVertexAttribArray(b.shd.TexCoord)
|
||||
b.glctx.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
|
||||
b.glctx.DisableVertexAttribArray(b.ir.Vertex)
|
||||
b.glctx.DisableVertexAttribArray(b.ir.TexCoord)
|
||||
b.glctx.DisableVertexAttribArray(b.shd.Vertex)
|
||||
b.glctx.DisableVertexAttribArray(b.shd.TexCoord)
|
||||
|
||||
b.glctx.StencilFunc(gl.ALWAYS, 0, 0xFF)
|
||||
}
|
||||
|
|
|
@ -1,492 +1,158 @@
|
|||
package xmobilebackend
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/mobile/gl"
|
||||
)
|
||||
|
||||
var imageVS = `
|
||||
var unifiedVS = `
|
||||
attribute vec2 vertex, texCoord;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_texCoord;
|
||||
void main() {
|
||||
v_texCoord = texCoord;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var imageFS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_texCoord;
|
||||
uniform sampler2D image;
|
||||
uniform float globalAlpha;
|
||||
void main() {
|
||||
vec4 col = texture2D(image, v_texCoord);
|
||||
col.a *= globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var solidVS = `
|
||||
attribute vec2 vertex;
|
||||
uniform vec2 canvasSize;
|
||||
|
||||
varying vec2 v_cp, v_tc;
|
||||
|
||||
void main() {
|
||||
v_tc = texCoord;
|
||||
v_cp = vertex;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var solidFS = `
|
||||
}
|
||||
`
|
||||
var unifiedFS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
varying vec2 v_cp, v_tc;
|
||||
|
||||
uniform int func;
|
||||
|
||||
uniform vec4 color;
|
||||
uniform float globalAlpha;
|
||||
|
||||
uniform sampler2D gradient;
|
||||
uniform vec2 from, dir, to;
|
||||
uniform float len, radFrom, radTo;
|
||||
|
||||
uniform vec2 imageSize;
|
||||
uniform sampler2D image;
|
||||
uniform mat3 imageTransform;
|
||||
uniform vec2 repeat;
|
||||
|
||||
uniform bool useAlphaTex;
|
||||
uniform sampler2D alphaTex;
|
||||
|
||||
uniform int boxSize;
|
||||
uniform bool boxVertical;
|
||||
uniform float boxScale;
|
||||
uniform float boxOffset;
|
||||
|
||||
bool isNaN(float v) {
|
||||
return v < 0.0 || 0.0 < v || v == 0.0 ? false : true;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 col = color;
|
||||
col.a *= globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var linearGradientVS = `
|
||||
attribute vec2 vertex;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_cp;
|
||||
void main() {
|
||||
v_cp = vertex;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var linearGradientFS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_cp;
|
||||
uniform sampler2D gradient;
|
||||
uniform vec2 from, dir;
|
||||
uniform float len;
|
||||
uniform float globalAlpha;
|
||||
void main() {
|
||||
vec2 v = v_cp - from;
|
||||
float r = dot(v, dir) / len;
|
||||
r = clamp(r, 0.0, 1.0);
|
||||
vec4 col = texture2D(gradient, vec2(r, 0.0));
|
||||
col.a *= globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var radialGradientVS = `
|
||||
attribute vec2 vertex;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_cp;
|
||||
void main() {
|
||||
v_cp = vertex;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var radialGradientFS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_cp;
|
||||
uniform sampler2D gradient;
|
||||
uniform vec2 from, to;
|
||||
uniform float radFrom, radTo;
|
||||
uniform float globalAlpha;
|
||||
bool isNaN(float v) {
|
||||
return v < 0.0 || 0.0 < v || v == 0.0 ? false : true;
|
||||
}
|
||||
void main() {
|
||||
float o_a = 0.5 * sqrt(
|
||||
pow(-2.0*from.x*from.x+2.0*from.x*to.x+2.0*from.x*v_cp.x-2.0*to.x*v_cp.x-2.0*from.y*from.y+2.0*from.y*to.y+2.0*from.y*v_cp.y-2.0*to.y*v_cp.y+2.0*radFrom*radFrom-2.0*radFrom*radTo, 2.0)
|
||||
-4.0*(from.x*from.x-2.0*from.x*v_cp.x+v_cp.x*v_cp.x+from.y*from.y-2.0*from.y*v_cp.y+v_cp.y*v_cp.y-radFrom*radFrom)
|
||||
*(from.x*from.x-2.0*from.x*to.x+to.x*to.x+from.y*from.y-2.0*from.y*to.y+to.y*to.y-radFrom*radFrom+2.0*radFrom*radTo-radTo*radTo)
|
||||
);
|
||||
float o_b = (from.x*from.x-from.x*to.x-from.x*v_cp.x+to.x*v_cp.x+from.y*from.y-from.y*to.y-from.y*v_cp.y+to.y*v_cp.y-radFrom*radFrom+radFrom*radTo);
|
||||
float o_c = (from.x*from.x-2.0*from.x*to.x+to.x*to.x+from.y*from.y-2.0*from.y*to.y+to.y*to.y-radFrom*radFrom+2.0*radFrom*radTo-radTo*radTo);
|
||||
float o1 = (-o_a + o_b) / o_c;
|
||||
float o2 = (o_a + o_b) / o_c;
|
||||
if (isNaN(o1) && isNaN(o2)) {
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
if (func == 5) {
|
||||
vec4 sum = vec4(0.0);
|
||||
if (boxVertical) {
|
||||
vec2 start = v_tc - vec2(0.0, (float(boxSize) * 0.5 + boxOffset) * boxScale);
|
||||
for (int i=0; i <= boxSize; i++) {
|
||||
sum += texture2D(image, start + vec2(0.0, float(i) * boxScale));
|
||||
}
|
||||
} else {
|
||||
vec2 start = v_tc - vec2((float(boxSize) * 0.5 + boxOffset) * boxScale, 0.0);
|
||||
for (int i=0; i <= boxSize; i++) {
|
||||
sum += texture2D(image, start + vec2(float(i) * boxScale, 0.0));
|
||||
}
|
||||
}
|
||||
gl_FragColor = sum / float(boxSize+1);
|
||||
return;
|
||||
}
|
||||
float o = max(o1, o2);
|
||||
//float r = radFrom + o * (radTo - radFrom);
|
||||
vec4 col = texture2D(gradient, vec2(o, 0.0));
|
||||
col.a *= globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var imagePatternVS = `
|
||||
attribute vec2 vertex;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_cp;
|
||||
void main() {
|
||||
v_cp = vertex;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var imagePatternFS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_cp;
|
||||
uniform vec2 imageSize;
|
||||
uniform sampler2D image;
|
||||
uniform mat3 imageTransform;
|
||||
uniform vec2 repeat;
|
||||
uniform float globalAlpha;
|
||||
void main() {
|
||||
vec3 tfpt = vec3(v_cp, 1.0) * imageTransform;
|
||||
vec2 imgpt = tfpt.xy / imageSize;
|
||||
vec4 col = texture2D(image, mod(imgpt, 1.0));
|
||||
if (imgpt.x < 0.0 || imgpt.x > 1.0) {
|
||||
col *= repeat.x;
|
||||
if (func == 1) {
|
||||
vec2 v = v_cp - from;
|
||||
float r = dot(v, dir) / len;
|
||||
r = clamp(r, 0.0, 1.0);
|
||||
col = texture2D(gradient, vec2(r, 0.0));
|
||||
} else if (func == 2) {
|
||||
float o_a = 0.5 * sqrt(
|
||||
pow(-2.0*from.x*from.x+2.0*from.x*to.x+2.0*from.x*v_cp.x-2.0*to.x*v_cp.x-2.0*from.y*from.y+2.0*from.y*to.y+2.0*from.y*v_cp.y-2.0*to.y*v_cp.y+2.0*radFrom*radFrom-2.0*radFrom*radTo, 2.0)
|
||||
-4.0*(from.x*from.x-2.0*from.x*v_cp.x+v_cp.x*v_cp.x+from.y*from.y-2.0*from.y*v_cp.y+v_cp.y*v_cp.y-radFrom*radFrom)
|
||||
*(from.x*from.x-2.0*from.x*to.x+to.x*to.x+from.y*from.y-2.0*from.y*to.y+to.y*to.y-radFrom*radFrom+2.0*radFrom*radTo-radTo*radTo)
|
||||
);
|
||||
float o_b = (from.x*from.x-from.x*to.x-from.x*v_cp.x+to.x*v_cp.x+from.y*from.y-from.y*to.y-from.y*v_cp.y+to.y*v_cp.y-radFrom*radFrom+radFrom*radTo);
|
||||
float o_c = (from.x*from.x-2.0*from.x*to.x+to.x*to.x+from.y*from.y-2.0*from.y*to.y+to.y*to.y-radFrom*radFrom+2.0*radFrom*radTo-radTo*radTo);
|
||||
float o1 = (-o_a + o_b) / o_c;
|
||||
float o2 = (o_a + o_b) / o_c;
|
||||
if (isNaN(o1) && isNaN(o2)) {
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
return;
|
||||
}
|
||||
float o = max(o1, o2);
|
||||
o = clamp(o, 0.0, 1.0);
|
||||
col = texture2D(gradient, vec2(o, 0.0));
|
||||
} else if (func == 3) {
|
||||
vec3 tfpt = vec3(v_cp, 1.0) * imageTransform;
|
||||
vec2 imgpt = tfpt.xy / imageSize;
|
||||
col = texture2D(image, mod(imgpt, 1.0));
|
||||
if (imgpt.x < 0.0 || imgpt.x > 1.0) {
|
||||
col *= repeat.x;
|
||||
}
|
||||
if (imgpt.y < 0.0 || imgpt.y > 1.0) {
|
||||
col *= repeat.y;
|
||||
}
|
||||
} else if (func == 4) {
|
||||
col = texture2D(image, v_tc);
|
||||
}
|
||||
if (imgpt.y < 0.0 || imgpt.y > 1.0) {
|
||||
col *= repeat.y;
|
||||
|
||||
if (useAlphaTex) {
|
||||
col.a *= texture2D(alphaTex, v_tc).a * globalAlpha;
|
||||
} else {
|
||||
col.a *= globalAlpha;
|
||||
}
|
||||
col.a *= globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var solidAlphaVS = `
|
||||
attribute vec2 vertex, alphaTexCoord;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_atc;
|
||||
void main() {
|
||||
v_atc = alphaTexCoord;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var solidAlphaFS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_atc;
|
||||
uniform vec4 color;
|
||||
uniform sampler2D alphaTex;
|
||||
uniform float globalAlpha;
|
||||
void main() {
|
||||
vec4 col = color;
|
||||
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var linearGradientAlphaVS = `
|
||||
attribute vec2 vertex, alphaTexCoord;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_cp;
|
||||
varying vec2 v_atc;
|
||||
void main() {
|
||||
v_cp = vertex;
|
||||
v_atc = alphaTexCoord;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var linearGradientAlphaFS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_cp;
|
||||
varying vec2 v_atc;
|
||||
varying vec2 v_texCoord;
|
||||
uniform sampler2D gradient;
|
||||
uniform vec2 from, dir;
|
||||
uniform float len;
|
||||
uniform sampler2D alphaTex;
|
||||
uniform float globalAlpha;
|
||||
void main() {
|
||||
vec2 v = v_cp - from;
|
||||
float r = dot(v, dir) / len;
|
||||
r = clamp(r, 0.0, 1.0);
|
||||
vec4 col = texture2D(gradient, vec2(r, 0.0));
|
||||
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
|
||||
var radialGradientAlphaVS = `
|
||||
attribute vec2 vertex, alphaTexCoord;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_cp;
|
||||
varying vec2 v_atc;
|
||||
void main() {
|
||||
v_cp = vertex;
|
||||
v_atc = alphaTexCoord;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var radialGradientAlphaFS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_cp;
|
||||
varying vec2 v_atc;
|
||||
uniform sampler2D gradient;
|
||||
uniform vec2 from, to;
|
||||
uniform float radFrom, radTo;
|
||||
uniform sampler2D alphaTex;
|
||||
uniform float globalAlpha;
|
||||
bool isNaN(float v) {
|
||||
return v < 0.0 || 0.0 < v || v == 0.0 ? false : true;
|
||||
}
|
||||
void main() {
|
||||
float o_a = 0.5 * sqrt(
|
||||
pow(-2.0*from.x*from.x+2.0*from.x*to.x+2.0*from.x*v_cp.x-2.0*to.x*v_cp.x-2.0*from.y*from.y+2.0*from.y*to.y+2.0*from.y*v_cp.y-2.0*to.y*v_cp.y+2.0*radFrom*radFrom-2.0*radFrom*radTo, 2.0)
|
||||
-4.0*(from.x*from.x-2.0*from.x*v_cp.x+v_cp.x*v_cp.x+from.y*from.y-2.0*from.y*v_cp.y+v_cp.y*v_cp.y-radFrom*radFrom)
|
||||
*(from.x*from.x-2.0*from.x*to.x+to.x*to.x+from.y*from.y-2.0*from.y*to.y+to.y*to.y-radFrom*radFrom+2.0*radFrom*radTo-radTo*radTo)
|
||||
);
|
||||
float o_b = (from.x*from.x-from.x*to.x-from.x*v_cp.x+to.x*v_cp.x+from.y*from.y-from.y*to.y-from.y*v_cp.y+to.y*v_cp.y-radFrom*radFrom+radFrom*radTo);
|
||||
float o_c = (from.x*from.x-2.0*from.x*to.x+to.x*to.x+from.y*from.y-2.0*from.y*to.y+to.y*to.y-radFrom*radFrom+2.0*radFrom*radTo-radTo*radTo);
|
||||
float o1 = (-o_a + o_b) / o_c;
|
||||
float o2 = (o_a + o_b) / o_c;
|
||||
if (isNaN(o1) && isNaN(o2)) {
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
return;
|
||||
}
|
||||
float o = max(o1, o2);
|
||||
//float r = radFrom + o * (radTo - radFrom);
|
||||
vec4 col = texture2D(gradient, vec2(o, 0.0));
|
||||
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
`
|
||||
|
||||
var imagePatternAlphaVS = `
|
||||
attribute vec2 vertex, alphaTexCoord;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_cp;
|
||||
varying vec2 v_atc;
|
||||
void main() {
|
||||
v_cp = vertex;
|
||||
v_atc = alphaTexCoord;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var imagePatternAlphaFS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_cp;
|
||||
varying vec2 v_atc;
|
||||
uniform vec2 imageSize;
|
||||
uniform sampler2D image;
|
||||
uniform mat3 imageTransform;
|
||||
uniform vec2 repeat;
|
||||
uniform sampler2D alphaTex;
|
||||
uniform float globalAlpha;
|
||||
void main() {
|
||||
vec3 tfpt = vec3(v_cp, 1.0) * imageTransform;
|
||||
vec2 imgpt = tfpt.xy / imageSize;
|
||||
vec4 col = texture2D(image, mod(imgpt, 1.0));
|
||||
if (imgpt.x < 0.0 || imgpt.x > 1.0) {
|
||||
col *= repeat.x;
|
||||
}
|
||||
if (imgpt.y < 0.0 || imgpt.y > 1.0) {
|
||||
col *= repeat.y;
|
||||
}
|
||||
col.a *= texture2D(alphaTex, v_atc).a * globalAlpha;
|
||||
gl_FragColor = col;
|
||||
}`
|
||||
const (
|
||||
shdFuncSolid int = iota
|
||||
shdFuncLinearGradient
|
||||
shdFuncRadialGradient
|
||||
shdFuncImagePattern
|
||||
shdFuncImage
|
||||
shdFuncBoxBlur
|
||||
)
|
||||
|
||||
var gaussian15VS = `
|
||||
attribute vec2 vertex, texCoord;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_texCoord;
|
||||
void main() {
|
||||
v_texCoord = texCoord;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var gaussian15FS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_texCoord;
|
||||
uniform vec2 kernelScale;
|
||||
uniform sampler2D image;
|
||||
uniform float kernel[15];
|
||||
void main() {
|
||||
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
_SUM_
|
||||
gl_FragColor = color;
|
||||
}`
|
||||
|
||||
var gaussian63VS = `
|
||||
attribute vec2 vertex, texCoord;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_texCoord;
|
||||
void main() {
|
||||
v_texCoord = texCoord;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var gaussian63FS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_texCoord;
|
||||
uniform vec2 kernelScale;
|
||||
uniform sampler2D image;
|
||||
uniform float kernel[63];
|
||||
void main() {
|
||||
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
_SUM_
|
||||
gl_FragColor = color;
|
||||
}`
|
||||
|
||||
var gaussian127VS = `
|
||||
attribute vec2 vertex, texCoord;
|
||||
uniform vec2 canvasSize;
|
||||
varying vec2 v_texCoord;
|
||||
void main() {
|
||||
v_texCoord = texCoord;
|
||||
vec2 glp = vertex * 2.0 / canvasSize - 1.0;
|
||||
gl_Position = vec4(glp.x, -glp.y, 0.0, 1.0);
|
||||
}`
|
||||
var gaussian127FS = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec2 v_texCoord;
|
||||
uniform vec2 kernelScale;
|
||||
uniform sampler2D image;
|
||||
uniform float kernel[127];
|
||||
void main() {
|
||||
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
_SUM_
|
||||
gl_FragColor = color;
|
||||
}`
|
||||
|
||||
func init() {
|
||||
fstr := "\tcolor += texture2D(image, v_texCoord + vec2(%.1f * kernelScale.x, %.1f * kernelScale.y)) * kernel[%d];\n"
|
||||
bb := bytes.Buffer{}
|
||||
for i := 0; i < 127; i++ {
|
||||
off := float64(i) - 63
|
||||
fmt.Fprintf(&bb, fstr, off, off, i)
|
||||
}
|
||||
gaussian127FS = strings.Replace(gaussian127FS, "_SUM_", bb.String(), -1)
|
||||
bb.Reset()
|
||||
for i := 0; i < 63; i++ {
|
||||
off := float64(i) - 31
|
||||
fmt.Fprintf(&bb, fstr, off, off, i)
|
||||
}
|
||||
gaussian63FS = strings.Replace(gaussian63FS, "_SUM_", bb.String(), -1)
|
||||
bb.Reset()
|
||||
for i := 0; i < 15; i++ {
|
||||
off := float64(i) - 7
|
||||
fmt.Fprintf(&bb, fstr, off, off, i)
|
||||
}
|
||||
gaussian15FS = strings.Replace(gaussian15FS, "_SUM_", bb.String(), -1)
|
||||
}
|
||||
|
||||
type solidShader struct {
|
||||
type unifiedShader struct {
|
||||
shaderProgram
|
||||
Vertex gl.Attrib
|
||||
|
||||
Vertex gl.Attrib
|
||||
TexCoord gl.Attrib
|
||||
|
||||
CanvasSize gl.Uniform
|
||||
Color gl.Uniform
|
||||
GlobalAlpha gl.Uniform
|
||||
}
|
||||
|
||||
type imageShader struct {
|
||||
shaderProgram
|
||||
Vertex gl.Attrib
|
||||
TexCoord gl.Attrib
|
||||
CanvasSize gl.Uniform
|
||||
Image gl.Uniform
|
||||
GlobalAlpha gl.Uniform
|
||||
}
|
||||
Func gl.Uniform
|
||||
|
||||
type linearGradientShader struct {
|
||||
shaderProgram
|
||||
Vertex gl.Attrib
|
||||
CanvasSize gl.Uniform
|
||||
Gradient gl.Uniform
|
||||
From gl.Uniform
|
||||
Dir gl.Uniform
|
||||
Len gl.Uniform
|
||||
GlobalAlpha gl.Uniform
|
||||
}
|
||||
UseAlphaTex gl.Uniform
|
||||
AlphaTex gl.Uniform
|
||||
|
||||
type radialGradientShader struct {
|
||||
shaderProgram
|
||||
Vertex gl.Attrib
|
||||
CanvasSize gl.Uniform
|
||||
Gradient gl.Uniform
|
||||
From gl.Uniform
|
||||
To gl.Uniform
|
||||
RadFrom gl.Uniform
|
||||
RadTo gl.Uniform
|
||||
GlobalAlpha gl.Uniform
|
||||
}
|
||||
Gradient gl.Uniform
|
||||
From, To, Dir gl.Uniform
|
||||
Len gl.Uniform
|
||||
RadFrom, RadTo gl.Uniform
|
||||
|
||||
type imagePatternShader struct {
|
||||
shaderProgram
|
||||
Vertex gl.Attrib
|
||||
CanvasSize gl.Uniform
|
||||
ImageSize gl.Uniform
|
||||
Image gl.Uniform
|
||||
ImageTransform gl.Uniform
|
||||
Repeat gl.Uniform
|
||||
GlobalAlpha gl.Uniform
|
||||
}
|
||||
|
||||
type solidAlphaShader struct {
|
||||
shaderProgram
|
||||
Vertex gl.Attrib
|
||||
AlphaTexCoord gl.Attrib
|
||||
CanvasSize gl.Uniform
|
||||
Color gl.Uniform
|
||||
AlphaTex gl.Uniform
|
||||
GlobalAlpha gl.Uniform
|
||||
}
|
||||
|
||||
type linearGradientAlphaShader struct {
|
||||
shaderProgram
|
||||
Vertex gl.Attrib
|
||||
AlphaTexCoord gl.Attrib
|
||||
CanvasSize gl.Uniform
|
||||
Gradient gl.Uniform
|
||||
From gl.Uniform
|
||||
Dir gl.Uniform
|
||||
Len gl.Uniform
|
||||
AlphaTex gl.Uniform
|
||||
GlobalAlpha gl.Uniform
|
||||
}
|
||||
|
||||
type radialGradientAlphaShader struct {
|
||||
shaderProgram
|
||||
Vertex gl.Attrib
|
||||
AlphaTexCoord gl.Attrib
|
||||
CanvasSize gl.Uniform
|
||||
Gradient gl.Uniform
|
||||
From gl.Uniform
|
||||
To gl.Uniform
|
||||
RadFrom gl.Uniform
|
||||
RadTo gl.Uniform
|
||||
AlphaTex gl.Uniform
|
||||
GlobalAlpha gl.Uniform
|
||||
}
|
||||
|
||||
type imagePatternAlphaShader struct {
|
||||
shaderProgram
|
||||
Vertex gl.Attrib
|
||||
AlphaTexCoord gl.Attrib
|
||||
CanvasSize gl.Uniform
|
||||
ImageSize gl.Uniform
|
||||
Image gl.Uniform
|
||||
ImageTransform gl.Uniform
|
||||
Repeat gl.Uniform
|
||||
AlphaTex gl.Uniform
|
||||
GlobalAlpha gl.Uniform
|
||||
}
|
||||
|
||||
type gaussianShader struct {
|
||||
shaderProgram
|
||||
Vertex gl.Attrib
|
||||
TexCoord gl.Attrib
|
||||
CanvasSize gl.Uniform
|
||||
KernelScale gl.Uniform
|
||||
Image gl.Uniform
|
||||
Kernel gl.Uniform
|
||||
BoxSize gl.Uniform
|
||||
BoxVertical gl.Uniform
|
||||
BoxScale gl.Uniform
|
||||
BoxOffset gl.Uniform
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package xmobilebackend
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
"math"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
@ -24,18 +23,7 @@ type GLContext struct {
|
|||
shadowBuf gl.Buffer
|
||||
alphaTex gl.Texture
|
||||
|
||||
sr solidShader
|
||||
lgr linearGradientShader
|
||||
rgr radialGradientShader
|
||||
ipr imagePatternShader
|
||||
sar solidAlphaShader
|
||||
rgar radialGradientAlphaShader
|
||||
lgar linearGradientAlphaShader
|
||||
ipar imagePatternAlphaShader
|
||||
ir imageShader
|
||||
gauss15r gaussianShader
|
||||
gauss63r gaussianShader
|
||||
gauss127r gaussianShader
|
||||
shd unifiedShader
|
||||
|
||||
offscr1 offscreenBuffer
|
||||
offscr2 offscreenBuffer
|
||||
|
@ -64,110 +52,11 @@ func NewGLContext(glctx gl.Context) (*GLContext, error) {
|
|||
|
||||
b.glctx.GetError() // clear error state
|
||||
|
||||
err = loadShader(b, solidVS, solidFS, &ctx.sr.shaderProgram)
|
||||
err = loadShader(b, unifiedVS, unifiedFS, &ctx.shd.shaderProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.sr.shaderProgram.mustLoadLocations(&ctx.sr)
|
||||
if err = glError(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = loadShader(b, linearGradientVS, linearGradientFS, &ctx.lgr.shaderProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.lgr.shaderProgram.mustLoadLocations(&ctx.lgr)
|
||||
if err = glError(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = loadShader(b, radialGradientVS, radialGradientFS, &ctx.rgr.shaderProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.rgr.shaderProgram.mustLoadLocations(&ctx.rgr)
|
||||
if err = glError(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = loadShader(b, imagePatternVS, imagePatternFS, &ctx.ipr.shaderProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.ipr.shaderProgram.mustLoadLocations(&ctx.ipr)
|
||||
if err = glError(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = loadShader(b, solidAlphaVS, solidAlphaFS, &ctx.sar.shaderProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.sar.shaderProgram.mustLoadLocations(&ctx.sar)
|
||||
if err = glError(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = loadShader(b, linearGradientAlphaVS, linearGradientFS, &ctx.lgar.shaderProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.lgar.shaderProgram.mustLoadLocations(&ctx.lgar)
|
||||
if err = glError(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = loadShader(b, radialGradientAlphaVS, radialGradientAlphaFS, &ctx.rgar.shaderProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.rgar.shaderProgram.mustLoadLocations(&ctx.rgar)
|
||||
if err = glError(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = loadShader(b, imagePatternAlphaVS, imagePatternAlphaFS, &ctx.ipar.shaderProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.ipar.shaderProgram.mustLoadLocations(&ctx.ipar)
|
||||
if err = glError(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = loadShader(b, imageVS, imageFS, &ctx.ir.shaderProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.ir.shaderProgram.mustLoadLocations(&ctx.ir)
|
||||
if err = glError(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = loadShader(b, gaussian15VS, gaussian15FS, &ctx.gauss15r.shaderProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.gauss15r.shaderProgram.mustLoadLocations(&ctx.gauss15r)
|
||||
if err = glError(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = loadShader(b, gaussian63VS, gaussian63FS, &ctx.gauss63r.shaderProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.gauss63r.shaderProgram.mustLoadLocations(&ctx.gauss63r)
|
||||
if err = glError(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = loadShader(b, gaussian127VS, gaussian127FS, &ctx.gauss127r.shaderProgram)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.gauss127r.shaderProgram.mustLoadLocations(&ctx.gauss127r)
|
||||
ctx.shd.shaderProgram.mustLoadLocations(&ctx.shd)
|
||||
if err = glError(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -244,6 +133,7 @@ func New(x, y, w, h int, ctx *GLContext) (*XMobileBackend, error) {
|
|||
}
|
||||
b.disableTextureRenderTarget = func() {
|
||||
b.glctx.BindFramebuffer(gl.FRAMEBUFFER, gl.Framebuffer{Value: 0})
|
||||
b.glctx.Viewport(b.x, b.y, b.w, b.h)
|
||||
}
|
||||
|
||||
return b, nil
|
||||
|
@ -377,163 +267,81 @@ func (b *XMobileBackendOffscreen) AsImage() backendbase.Image {
|
|||
return &b.offscrImg
|
||||
}
|
||||
|
||||
type glColor struct {
|
||||
r, g, b, a float64
|
||||
}
|
||||
func (b *XMobileBackend) useShader(style *backendbase.FillStyle, useAlpha bool, alphaTexSlot int) (vertexLoc, alphaTexCoordLoc gl.Attrib) {
|
||||
b.glctx.UseProgram(b.shd.ID)
|
||||
b.glctx.Uniform2f(b.shd.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
if useAlpha {
|
||||
b.glctx.Uniform1i(b.shd.UseAlphaTex, 1)
|
||||
b.glctx.Uniform1i(b.shd.AlphaTex, alphaTexSlot)
|
||||
} else {
|
||||
b.glctx.Uniform1i(b.shd.UseAlphaTex, 0)
|
||||
}
|
||||
b.glctx.Uniform1f(b.shd.GlobalAlpha, float32(style.Color.A)/255)
|
||||
|
||||
func colorGoToGL(c color.RGBA) glColor {
|
||||
var glc glColor
|
||||
glc.r = float64(c.R) / 255
|
||||
glc.g = float64(c.G) / 255
|
||||
glc.b = float64(c.B) / 255
|
||||
glc.a = float64(c.A) / 255
|
||||
return glc
|
||||
}
|
||||
|
||||
func (b *XMobileBackend) useShader(style *backendbase.FillStyle) (vertexLoc gl.Attrib) {
|
||||
if lg := style.LinearGradient; lg != nil {
|
||||
lg := lg.(*LinearGradient)
|
||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, lg.tex)
|
||||
b.glctx.UseProgram(b.lgr.ID)
|
||||
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)
|
||||
b.glctx.Uniform2f(b.lgr.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform2f(b.lgr.From, float32(from[0]), float32(from[1]))
|
||||
b.glctx.Uniform2f(b.lgr.Dir, float32(dir[0]), float32(dir[1]))
|
||||
b.glctx.Uniform1f(b.lgr.Len, float32(length))
|
||||
b.glctx.Uniform1i(b.lgr.Gradient, 0)
|
||||
b.glctx.Uniform1f(b.lgr.GlobalAlpha, float32(style.Color.A)/255)
|
||||
return b.lgr.Vertex
|
||||
b.glctx.Uniform2f(b.shd.From, float32(from[0]), float32(from[1]))
|
||||
b.glctx.Uniform2f(b.shd.Dir, float32(dir[0]), float32(dir[1]))
|
||||
b.glctx.Uniform1f(b.shd.Len, float32(length))
|
||||
b.glctx.Uniform1i(b.shd.Gradient, 0)
|
||||
b.glctx.Uniform1i(b.shd.Func, shdFuncLinearGradient)
|
||||
return b.shd.Vertex, b.shd.TexCoord
|
||||
}
|
||||
if rg := style.RadialGradient; rg != nil {
|
||||
rg := rg.(*RadialGradient)
|
||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, rg.tex)
|
||||
b.glctx.UseProgram(b.rgr.ID)
|
||||
from := vec{style.Gradient.X0, style.Gradient.Y0}
|
||||
to := vec{style.Gradient.X1, style.Gradient.Y1}
|
||||
b.glctx.Uniform2f(b.rgr.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform2f(b.rgr.From, float32(from[0]), float32(from[1]))
|
||||
b.glctx.Uniform2f(b.rgr.To, float32(to[0]), float32(to[1]))
|
||||
b.glctx.Uniform1f(b.rgr.RadFrom, float32(style.Gradient.RadFrom))
|
||||
b.glctx.Uniform1f(b.rgr.RadTo, float32(style.Gradient.RadTo))
|
||||
b.glctx.Uniform1i(b.rgr.Gradient, 0)
|
||||
b.glctx.Uniform1f(b.rgr.GlobalAlpha, float32(style.Color.A)/255)
|
||||
return b.rgr.Vertex
|
||||
b.glctx.Uniform2f(b.shd.From, float32(from[0]), float32(from[1]))
|
||||
b.glctx.Uniform2f(b.shd.To, float32(to[0]), float32(to[1]))
|
||||
b.glctx.Uniform1f(b.shd.RadFrom, float32(style.Gradient.RadFrom))
|
||||
b.glctx.Uniform1f(b.shd.RadTo, float32(style.Gradient.RadTo))
|
||||
b.glctx.Uniform1i(b.shd.Gradient, 0)
|
||||
b.glctx.Uniform1i(b.shd.Func, shdFuncRadialGradient)
|
||||
return b.shd.Vertex, b.shd.TexCoord
|
||||
}
|
||||
if ip := style.ImagePattern; ip != nil {
|
||||
ipd := ip.(*ImagePattern).data
|
||||
img := ipd.Image.(*Image)
|
||||
b.glctx.UseProgram(b.ipr.ID)
|
||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, img.tex)
|
||||
b.glctx.Uniform2f(b.ipr.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform2f(b.ipr.ImageSize, float32(img.w), float32(img.h))
|
||||
b.glctx.Uniform1i(b.ipr.Image, 0)
|
||||
b.glctx.Uniform2f(b.shd.ImageSize, float32(img.w), float32(img.h))
|
||||
b.glctx.Uniform1i(b.shd.Image, 0)
|
||||
var f32mat [9]float32
|
||||
for i, v := range ipd.Transform {
|
||||
f32mat[i] = float32(v)
|
||||
}
|
||||
b.glctx.UniformMatrix3fv(b.ipr.ImageTransform, f32mat[:])
|
||||
b.glctx.UniformMatrix3fv(b.shd.ImageTransform, f32mat[:])
|
||||
switch ipd.Repeat {
|
||||
case backendbase.Repeat:
|
||||
b.glctx.Uniform2f(b.ipr.Repeat, 1, 1)
|
||||
b.glctx.Uniform2f(b.shd.Repeat, 1, 1)
|
||||
case backendbase.RepeatX:
|
||||
b.glctx.Uniform2f(b.ipr.Repeat, 1, 0)
|
||||
b.glctx.Uniform2f(b.shd.Repeat, 1, 0)
|
||||
case backendbase.RepeatY:
|
||||
b.glctx.Uniform2f(b.ipr.Repeat, 0, 1)
|
||||
b.glctx.Uniform2f(b.shd.Repeat, 0, 1)
|
||||
case backendbase.NoRepeat:
|
||||
b.glctx.Uniform2f(b.ipr.Repeat, 0, 0)
|
||||
b.glctx.Uniform2f(b.shd.Repeat, 0, 0)
|
||||
}
|
||||
b.glctx.Uniform1f(b.ipr.GlobalAlpha, float32(style.Color.A)/255)
|
||||
return b.ipr.Vertex
|
||||
b.glctx.Uniform1i(b.shd.Func, shdFuncImagePattern)
|
||||
return b.shd.Vertex, b.shd.TexCoord
|
||||
}
|
||||
|
||||
b.glctx.UseProgram(b.sr.ID)
|
||||
b.glctx.Uniform2f(b.sr.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
c := colorGoToGL(style.Color)
|
||||
b.glctx.Uniform4f(b.sr.Color, float32(c.r), float32(c.g), float32(c.b), float32(c.a))
|
||||
b.glctx.Uniform1f(b.sr.GlobalAlpha, 1)
|
||||
return b.sr.Vertex
|
||||
}
|
||||
|
||||
func (b *XMobileBackend) useAlphaShader(style *backendbase.FillStyle, alphaTexSlot int) (vertexLoc, alphaTexCoordLoc gl.Attrib) {
|
||||
if lg := style.LinearGradient; lg != nil {
|
||||
lg := lg.(*LinearGradient)
|
||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, lg.tex)
|
||||
b.glctx.UseProgram(b.lgar.ID)
|
||||
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)
|
||||
b.glctx.Uniform2f(b.lgar.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform2f(b.lgar.From, float32(from[0]), float32(from[1]))
|
||||
b.glctx.Uniform2f(b.lgar.Dir, float32(dir[0]), float32(dir[1]))
|
||||
b.glctx.Uniform1f(b.lgar.Len, float32(length))
|
||||
b.glctx.Uniform1i(b.lgar.Gradient, 0)
|
||||
b.glctx.Uniform1i(b.lgar.AlphaTex, alphaTexSlot)
|
||||
b.glctx.Uniform1f(b.lgar.GlobalAlpha, float32(style.Color.A)/255)
|
||||
return b.lgar.Vertex, b.lgar.AlphaTexCoord
|
||||
}
|
||||
if rg := style.RadialGradient; rg != nil {
|
||||
rg := rg.(*RadialGradient)
|
||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, rg.tex)
|
||||
b.glctx.UseProgram(b.rgar.ID)
|
||||
from := vec{style.Gradient.X0, style.Gradient.Y0}
|
||||
to := vec{style.Gradient.X1, style.Gradient.Y1}
|
||||
b.glctx.Uniform2f(b.rgar.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform2f(b.rgar.From, float32(from[0]), float32(from[1]))
|
||||
b.glctx.Uniform2f(b.rgar.To, float32(to[0]), float32(to[1]))
|
||||
b.glctx.Uniform1f(b.rgar.RadFrom, float32(style.Gradient.RadFrom))
|
||||
b.glctx.Uniform1f(b.rgar.RadTo, float32(style.Gradient.RadTo))
|
||||
b.glctx.Uniform1i(b.rgar.Gradient, 0)
|
||||
b.glctx.Uniform1i(b.rgar.AlphaTex, alphaTexSlot)
|
||||
b.glctx.Uniform1f(b.rgar.GlobalAlpha, float32(style.Color.A)/255)
|
||||
return b.rgar.Vertex, b.rgar.AlphaTexCoord
|
||||
}
|
||||
if ip := style.ImagePattern; ip != nil {
|
||||
ipd := ip.(*ImagePattern).data
|
||||
img := ipd.Image.(*Image)
|
||||
b.glctx.UseProgram(b.ipar.ID)
|
||||
b.glctx.ActiveTexture(gl.TEXTURE0)
|
||||
b.glctx.BindTexture(gl.TEXTURE_2D, img.tex)
|
||||
b.glctx.Uniform2f(b.ipar.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
b.glctx.Uniform2f(b.ipar.ImageSize, float32(img.w), float32(img.h))
|
||||
b.glctx.Uniform1i(b.ipar.Image, 0)
|
||||
var f32mat [9]float32
|
||||
for i, v := range ipd.Transform {
|
||||
f32mat[i] = float32(v)
|
||||
}
|
||||
b.glctx.UniformMatrix3fv(b.ipr.ImageTransform, f32mat[:])
|
||||
switch ipd.Repeat {
|
||||
case backendbase.Repeat:
|
||||
b.glctx.Uniform2f(b.ipr.Repeat, 1, 1)
|
||||
case backendbase.RepeatX:
|
||||
b.glctx.Uniform2f(b.ipr.Repeat, 1, 0)
|
||||
case backendbase.RepeatY:
|
||||
b.glctx.Uniform2f(b.ipr.Repeat, 0, 1)
|
||||
case backendbase.NoRepeat:
|
||||
b.glctx.Uniform2f(b.ipr.Repeat, 0, 0)
|
||||
}
|
||||
b.glctx.Uniform1i(b.ipar.AlphaTex, alphaTexSlot)
|
||||
b.glctx.Uniform1f(b.ipar.GlobalAlpha, float32(style.Color.A)/255)
|
||||
return b.ipar.Vertex, b.ipar.AlphaTexCoord
|
||||
}
|
||||
|
||||
b.glctx.UseProgram(b.sar.ID)
|
||||
b.glctx.Uniform2f(b.sar.CanvasSize, float32(b.fw), float32(b.fh))
|
||||
c := colorGoToGL(style.Color)
|
||||
b.glctx.Uniform4f(b.sar.Color, float32(c.r), float32(c.g), float32(c.b), float32(c.a))
|
||||
b.glctx.Uniform1i(b.sar.AlphaTex, alphaTexSlot)
|
||||
b.glctx.Uniform1f(b.sar.GlobalAlpha, 1)
|
||||
return b.sar.Vertex, b.sar.AlphaTexCoord
|
||||
cr := float32(style.Color.R) / 255
|
||||
cg := float32(style.Color.G) / 255
|
||||
cb := float32(style.Color.B) / 255
|
||||
ca := float32(style.Color.A) / 255
|
||||
b.glctx.Uniform4f(b.shd.Color, cr, cg, cb, ca)
|
||||
b.glctx.Uniform1f(b.shd.GlobalAlpha, 1)
|
||||
b.glctx.Uniform1i(b.shd.Func, shdFuncSolid)
|
||||
return b.shd.Vertex, b.shd.TexCoord
|
||||
}
|
||||
|
||||
func (b *XMobileBackend) enableTextureRenderTarget(offscr *offscreenBuffer) {
|
||||
|
|
Loading…
Reference in a new issue