gpu,gpu/gl: implement shader uniform buffers

Emulate them for the OpenGL ES backend because 2.0 doesn't support uniform
buffers. The future d3d backend only supports uniform (constant) buffers.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-02-19 21:06:30 +01:00
parent ef3e94e7a7
commit 646a767665
12 changed files with 504 additions and 252 deletions
+4 -3
View File
@@ -44,6 +44,7 @@ type ShaderSources struct {
GLES2 string
HLSL []byte
Uniforms []UniformLocation
UniformSize int
Inputs []InputLocation
}
@@ -106,11 +107,10 @@ type Caps struct {
type Program interface {
Bind()
Release()
SetVertexUniforms(buf Buffer)
SetFragmentUniforms(buf Buffer)
UniformFor(uniform string) Uniform
Uniform1i(u Uniform, v int)
Uniform1f(u Uniform, v float32)
Uniform2f(u Uniform, v0, v1 float32)
Uniform4f(u Uniform, v0, v1, v2, v3 float32)
}
type Uniform interface{}
@@ -161,6 +161,7 @@ const (
const (
BufferTypeIndices BufferType = iota
BufferTypeVertices
BufferTypeUniforms
)
const (
+14 -9
View File
@@ -90,11 +90,12 @@ func generate() error {
hlsl []byte
inputs []InputLocation
uniforms []UniformLocation
uniformSize int
}
args := [nvariants]shaderArgs{
{
FetchColorExpr: `color.color`,
Header: `layout(binding=0) uniform Color { vec4 color; } color;`,
FetchColorExpr: `_color`,
Header: `layout(binding=0) uniform Color { vec4 _color; };`,
},
{
FetchColorExpr: `texture(tex, vUV)`,
@@ -108,7 +109,7 @@ func generate() error {
}
// Make the GL ES 2 source compatible with desktop GL 3.
gles2 = "#version 100\n" + gles2
inputs, uniforms, err := parseReflection(reflect)
inputs, uniforms, uniformSize, err := parseReflection(reflect)
if err != nil {
return err
}
@@ -137,6 +138,7 @@ func generate() error {
variants[i].hlsl = hlslc
variants[i].inputs = inputs
variants[i].uniforms = uniforms
variants[i].uniformSize = uniformSize
}
name := filepath.Base(shader)
name = strings.ReplaceAll(name, ".", "_")
@@ -163,6 +165,7 @@ func generate() error {
fmt.Fprintf(&out, "{Name: %q, Type: %d, Size: %d, Offset: %d},\n", u.Name, u.Type, u.Size, u.Offset)
}
fmt.Fprintf(&out, "},\n")
fmt.Fprintf(&out, "UniformSize: %d,\n", src.uniformSize)
}
fmt.Fprintf(&out, "GLES2: %#v,\n", src.gles2)
fmt.Fprintf(&out, "/*\n%s\n*/\n", src.hlslSrc)
@@ -188,7 +191,7 @@ func generate() error {
return ioutil.WriteFile("shaders.go", gosrc, 0644)
}
func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, error) {
func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, int, error) {
type InputReflection struct {
ID int `json:"id"`
Name string `json:"name"`
@@ -221,14 +224,14 @@ func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, error
}
var reflect shaderMetadata
if err := json.Unmarshal(jsonData, &reflect); err != nil {
return nil, nil, fmt.Errorf("parseReflection: %v", err)
return nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
}
var inputs []InputLocation
inputRef := reflect.VS.Inputs
for _, input := range inputRef {
dataType, dataSize, err := parseDataType(input.Type)
if err != nil {
return nil, nil, err
return nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
}
inputs = append(inputs, InputLocation{
Name: input.Name,
@@ -247,22 +250,24 @@ func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, error
if len(shaderBlocks) == 0 {
shaderBlocks = reflect.FS.UniformBuffers
}
blockOffset := 0
for _, block := range shaderBlocks {
for _, member := range block.Members {
dataType, size, err := parseDataType(member.Type)
if err != nil {
return nil, nil, err
return nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
}
ublocks = append(ublocks, UniformLocation{
// Synthetic name generated by glslcc.
Name: fmt.Sprintf("_%d.%s", block.ID, member.Name),
Type: dataType,
Size: size,
Offset: member.Offset,
Offset: blockOffset + member.Offset,
})
}
blockOffset += block.Size
}
return inputs, ublocks, nil
return inputs, ublocks, blockOffset, nil
}
func parseDataType(t string) (DataType, int, error) {
+129 -20
View File
@@ -8,6 +8,7 @@ import (
"image"
"strings"
"time"
"unsafe"
"gioui.org/gpu"
)
@@ -65,12 +66,31 @@ type gpuBuffer struct {
typ Enum
size int
immutable bool
version int
// For emulation of uniform buffers.
data []byte
}
type gpuProgram struct {
backend *Backend
obj Program
nattr int
vertUniforms uniformsTracker
fragUniforms uniformsTracker
}
type uniformsTracker struct {
locs []uniformLocation
size int
buf *gpuBuffer
version int
}
type uniformLocation struct {
uniform Uniform
offset int
typ gpu.DataType
size int
}
type gpuInputLayout struct {
@@ -165,9 +185,16 @@ func (b *Backend) NewTexture(minFilter, magFilter gpu.TextureFilter) gpu.Texture
}
func (b *Backend) NewBuffer(typ gpu.BufferType, size int) gpu.Buffer {
obj := b.funcs.CreateBuffer()
gltyp := toBufferType(typ)
return &gpuBuffer{backend: b, obj: obj, typ: gltyp, size: size}
buf := &gpuBuffer{backend: b, typ: gltyp, size: size}
switch typ {
case gpu.BufferTypeUniforms:
// GLES 2 doesn't support uniform buffers.
buf.data = make([]byte, size)
default:
buf.obj = b.funcs.CreateBuffer()
}
return buf
}
func (b *Backend) NewImmutableBuffer(typ gpu.BufferType, data []byte) gpu.Buffer {
@@ -246,15 +273,22 @@ func (b *Backend) SetBlend(enable bool) {
}
func (b *Backend) DrawElements(mode gpu.DrawMode, off, count int) {
b.setupVertexArrays()
b.prepareDraw()
b.funcs.DrawElements(toGLDrawMode(mode), count, UNSIGNED_SHORT, off)
}
func (b *Backend) DrawArrays(mode gpu.DrawMode, off, count int) {
b.setupVertexArrays()
b.prepareDraw()
b.funcs.DrawArrays(toGLDrawMode(mode), off, count)
}
func (b *Backend) prepareDraw() {
b.setupVertexArrays()
if p := b.state.prog; p != nil {
p.updateUniforms()
}
}
func toGLDrawMode(mode gpu.DrawMode) Enum {
switch mode {
case gpu.DrawModeTriangleStrip:
@@ -325,7 +359,32 @@ func (b *Backend) NewProgram(vssrc, fssrc gpu.ShaderSources) (gpu.Program, error
if err != nil {
return nil, err
}
return &gpuProgram{backend: b, obj: p, nattr: len(attr)}, nil
gpuProg := &gpuProgram{
backend: b,
obj: p,
nattr: len(attr),
}
gpuProg.vertUniforms.setup(b.funcs, p, vssrc.UniformSize, vssrc.Uniforms)
gpuProg.fragUniforms.setup(b.funcs, p, fssrc.UniformSize, fssrc.Uniforms)
return gpuProg, nil
}
func lookupUniform(funcs Functions, p Program, loc gpu.UniformLocation) uniformLocation {
u := GetUniformLocation(funcs, p, loc.Name)
return uniformLocation{uniform: u, offset: loc.Offset, typ: loc.Type, size: loc.Size}
}
func (p *gpuProgram) SetVertexUniforms(buffer gpu.Buffer) {
p.vertUniforms.setBuffer(buffer)
}
func (p *gpuProgram) SetFragmentUniforms(buffer gpu.Buffer) {
p.fragUniforms.setBuffer(buffer)
}
func (p *gpuProgram) updateUniforms() {
p.vertUniforms.update(p.backend.funcs)
p.fragUniforms.update(p.backend.funcs)
}
func (p *gpuProgram) Uniform1i(u gpu.Uniform, v int) {
@@ -333,21 +392,6 @@ func (p *gpuProgram) Uniform1i(u gpu.Uniform, v int) {
p.backend.funcs.Uniform1i(u.(Uniform), v)
}
func (p *gpuProgram) Uniform1f(u gpu.Uniform, v0 float32) {
p.Bind()
p.backend.funcs.Uniform1f(u.(Uniform), v0)
}
func (p *gpuProgram) Uniform2f(u gpu.Uniform, v0, v1 float32) {
p.Bind()
p.backend.funcs.Uniform2f(u.(Uniform), v0, v1)
}
func (p *gpuProgram) Uniform4f(u gpu.Uniform, v0, v1, v2, v3 float32) {
p.Bind()
p.backend.funcs.Uniform4f(u.(Uniform), v0, v1, v2, v3)
}
func (p *gpuProgram) Bind() {
p.backend.useProgram(p)
p.backend.enableVertexArrays(p.nattr)
@@ -362,6 +406,59 @@ func (p *gpuProgram) Release() {
p.backend.funcs.DeleteProgram(p.obj)
}
func (u *uniformsTracker) setup(funcs Functions, p Program, uniformSize int, uniforms []gpu.UniformLocation) {
u.locs = make([]uniformLocation, len(uniforms))
for i, uniform := range uniforms {
u.locs[i] = lookupUniform(funcs, p, uniform)
}
u.size = uniformSize
}
func (u *uniformsTracker) setBuffer(buffer gpu.Buffer) {
buf := buffer.(*gpuBuffer)
if buf.typ != UNIFORM_BUFFER {
panic("not a uniform buffer")
}
if buf.size < u.size {
panic(fmt.Errorf("uniform buffer too small, got %d need %d", buf.size, u.size))
}
u.buf = buf
// Force update.
u.version = buf.version - 1
}
func (p *uniformsTracker) update(funcs Functions) {
b := p.buf
if b == nil || b.version == p.version {
return
}
p.version = b.version
data := b.data
for _, u := range p.locs {
data := data[u.offset:]
switch {
case u.typ == gpu.DataTypeFloat && u.size == 1:
data := data[:4]
v := *(*[1]float32)(unsafe.Pointer(&data[0]))
funcs.Uniform1f(u.uniform, v[0])
case u.typ == gpu.DataTypeFloat && u.size == 2:
data := data[:8]
v := *(*[2]float32)(unsafe.Pointer(&data[0]))
funcs.Uniform2f(u.uniform, v[0], v[1])
case u.typ == gpu.DataTypeFloat && u.size == 3:
data := data[:12]
v := *(*[3]float32)(unsafe.Pointer(&data[0]))
funcs.Uniform3f(u.uniform, v[0], v[1], v[2])
case u.typ == gpu.DataTypeFloat && u.size == 4:
data := data[:16]
v := *(*[4]float32)(unsafe.Pointer(&data[0]))
funcs.Uniform4f(u.uniform, v[0], v[1], v[2], v[3])
default:
panic("unsupported uniform data type or size")
}
}
}
func (b *gpuBuffer) Upload(data []byte) {
if b.immutable {
panic("immutable buffer")
@@ -369,12 +466,22 @@ func (b *gpuBuffer) Upload(data []byte) {
if len(data) > b.size {
panic("buffer size overflow")
}
b.version++
switch b.typ {
case UNIFORM_BUFFER:
copy(b.data, data)
default:
b.backend.funcs.BindBuffer(b.typ, b.obj)
b.backend.funcs.BufferData(b.typ, data, STATIC_DRAW)
}
}
func (b *gpuBuffer) Release() {
switch b.typ {
case UNIFORM_BUFFER:
default:
b.backend.funcs.DeleteBuffer(b.obj)
}
}
func (b *gpuBuffer) BindVertex(stride, offset int) {
@@ -585,6 +692,8 @@ func toBufferType(typ gpu.BufferType) Enum {
return ARRAY_BUFFER
case gpu.BufferTypeIndices:
return ELEMENT_ARRAY_BUFFER
case gpu.BufferTypeUniforms:
return UNIFORM_BUFFER
default:
panic("unsupported buffer type")
}
+1
View File
@@ -71,6 +71,7 @@ const (
TRIANGLE_STRIP = 0x5
TRIANGLES = 0x4
TRUE = 1
UNIFORM_BUFFER = 0x8A11
UNPACK_ALIGNMENT = 0xcf5
UNSIGNED_BYTE = 0x1401
UNSIGNED_SHORT = 0x1403
+148 -48
View File
@@ -13,6 +13,7 @@ import (
"image"
"image/color"
"math"
"reflect"
"time"
"unsafe"
@@ -211,17 +212,50 @@ type texture struct {
type blitter struct {
ctx Backend
viewport image.Point
prog [2]Program
prog [2]*program
layout InputLayout
vars [2]struct {
z Uniform
uScale, uOffset Uniform
uUVScale, uUVOffset Uniform
uColor Uniform
colUniforms struct {
vert struct {
blitUniforms
_ [8]byte // Padding to a multiple of 16.
}
frag struct {
colorUniforms
}
}
texUniforms struct {
vert struct {
blitUniforms
_ [8]byte // Padding to a multiple of 16.
}
}
quadVerts Buffer
}
type uniformBuffer struct {
buf Buffer
ptr []byte
}
type program struct {
prog Program
vertUniforms *uniformBuffer
fragUniforms *uniformBuffer
}
type blitUniforms struct {
z float32
_ float32 // Padding.
scale [2]float32
offset [2]float32
uvScale [2]float32
uvOffset [2]float32
}
type colorUniforms struct {
color [4]float32
}
type materialType uint8
const (
@@ -372,10 +406,6 @@ func (r *renderer) release() {
}
func newBlitter(ctx Backend) *blitter {
prog, layout, err := createColorPrograms(ctx, shader_blit_vert, shader_blit_frag)
if err != nil {
panic(err)
}
quadVerts := ctx.NewImmutableBuffer(BufferTypeVertices,
gunsafe.BytesView([]float32{
-1, +1, 0, 0,
@@ -386,24 +416,17 @@ func newBlitter(ctx Backend) *blitter {
)
b := &blitter{
ctx: ctx,
prog: prog,
layout: layout,
quadVerts: quadVerts,
}
for i, prog := range prog {
switch materialType(i) {
case materialTexture:
uTex := prog.UniformFor("tex")
prog.Uniform1i(uTex, 0)
b.vars[i].uUVScale = prog.UniformFor("uniforms.uvScale")
b.vars[i].uUVOffset = prog.UniformFor("uniforms.uvOffset")
case materialColor:
b.vars[i].uColor = prog.UniformFor("color.color")
}
b.vars[i].z = prog.UniformFor("uniforms.z")
b.vars[i].uScale = prog.UniformFor("uniforms.scale")
b.vars[i].uOffset = prog.UniformFor("uniforms.offset")
prog, layout, err := createColorPrograms(ctx, shader_blit_vert, shader_blit_frag,
[2]interface{}{&b.colUniforms.vert, &b.texUniforms.vert}, [2]interface{}{&b.colUniforms.frag, nil})
if err != nil {
panic(err)
}
b.prog = prog
b.layout = layout
texProg := b.prog[materialTexture].prog
texProg.Uniform1i(texProg.UniformFor("tex"), 0)
return b
}
@@ -415,28 +438,47 @@ func (b *blitter) release() {
b.layout.Release()
}
func createColorPrograms(ctx Backend, vsSrc ShaderSources, fsSrc [2]ShaderSources) ([2]Program, InputLayout, error) {
var prog [2]Program
var err error
prog[materialTexture], err = ctx.NewProgram(vsSrc, fsSrc[materialTexture])
func createColorPrograms(b Backend, vsSrc ShaderSources, fsSrc [2]ShaderSources, vertUniforms, fragUniforms [2]interface{}) ([2]*program, InputLayout, error) {
var progs [2]*program
prog, err := b.NewProgram(vsSrc, fsSrc[materialTexture])
if err != nil {
return prog, nil, err
return progs, nil, err
}
prog[materialColor], err = ctx.NewProgram(vsSrc, fsSrc[materialColor])
var vertBuffer *uniformBuffer
if u := vertUniforms[materialTexture]; u != nil {
vertBuffer = newUniformBuffer(b, u)
prog.SetVertexUniforms(vertBuffer.buf)
}
var fragBuffer *uniformBuffer
if u := fragUniforms[materialTexture]; u != nil {
fragBuffer = newUniformBuffer(b, u)
prog.SetFragmentUniforms(fragBuffer.buf)
}
progs[materialTexture] = newProgram(prog, vertBuffer, fragBuffer)
prog, err = b.NewProgram(vsSrc, fsSrc[materialColor])
if err != nil {
prog[materialTexture].Release()
return prog, nil, err
progs[materialTexture].Release()
return progs, nil, err
}
layout, err := ctx.NewInputLayout(vsSrc, []InputDesc{
if u := vertUniforms[materialColor]; u != nil {
vertBuffer = newUniformBuffer(b, u)
prog.SetVertexUniforms(vertBuffer.buf)
}
if u := fragUniforms[materialColor]; u != nil {
fragBuffer = newUniformBuffer(b, u)
prog.SetFragmentUniforms(fragBuffer.buf)
}
progs[materialColor] = newProgram(prog, vertBuffer, fragBuffer)
layout, err := b.NewInputLayout(vsSrc, []InputDesc{
{Type: DataTypeFloat, Size: 2, Offset: 0},
{Type: DataTypeFloat, Size: 2, Offset: 4 * 2},
})
if err != nil {
prog[materialTexture].Release()
prog[materialColor].Release()
return prog, nil, err
progs[materialTexture].Release()
progs[materialColor].Release()
return progs, nil, err
}
return prog, layout, nil
return progs, layout, nil
}
func (r *renderer) stencilClips(pathCache *opCache, ops []*pathOp) {
@@ -465,7 +507,7 @@ func (r *renderer) intersect(ops []imageOp) {
fbo := -1
r.pather.stenciler.beginIntersect(r.intersections.sizes)
r.blitter.quadVerts.BindVertex(4*4, 0)
r.pather.stenciler.iprogLayout.Bind()
r.pather.stenciler.iprog.layout.Bind()
for _, img := range ops {
if img.clipType != clipTypeIntersection {
continue
@@ -497,8 +539,9 @@ func (r *renderer) intersectPath(p *pathOp, clip image.Rectangle) {
fbo := r.pather.stenciler.cover(p.place.Idx)
fbo.tex.Bind(0)
coverScale, coverOff := texSpaceTransform(toRectF(uv), fbo.size)
r.pather.stenciler.iprog.Uniform2f(r.pather.stenciler.uIntersectUVScale, coverScale.X, coverScale.Y)
r.pather.stenciler.iprog.Uniform2f(r.pather.stenciler.uIntersectUVOffset, coverOff.X, coverOff.Y)
r.pather.stenciler.iprog.uniforms.vert.uvScale = [2]float32{coverScale.X, coverScale.Y}
r.pather.stenciler.iprog.uniforms.vert.uvOffset = [2]float32{coverOff.X, coverOff.Y}
r.pather.stenciler.iprog.prog.UploadUniforms()
r.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4)
}
@@ -846,20 +889,77 @@ func gamma(r, g, b, a uint32) [4]float32 {
func (b *blitter) blit(z float32, mat materialType, col [4]float32, scale, off, uvScale, uvOff f32.Point) {
p := b.prog[mat]
p.Bind()
p.prog.Bind()
var uniforms *blitUniforms
switch mat {
case materialColor:
p.Uniform4f(b.vars[mat].uColor, col[0], col[1], col[2], col[3])
b.colUniforms.frag.color = col
uniforms = &b.colUniforms.vert.blitUniforms
case materialTexture:
p.Uniform2f(b.vars[mat].uUVScale, uvScale.X, uvScale.Y)
p.Uniform2f(b.vars[mat].uUVOffset, uvOff.X, uvOff.Y)
b.texUniforms.vert.uvScale = [2]float32{uvScale.X, uvScale.Y}
b.texUniforms.vert.uvOffset = [2]float32{uvOff.X, uvOff.Y}
uniforms = &b.texUniforms.vert.blitUniforms
}
p.Uniform1f(b.vars[mat].z, z)
p.Uniform2f(b.vars[mat].uScale, scale.X, scale.Y)
p.Uniform2f(b.vars[mat].uOffset, off.X, off.Y)
uniforms.z = z
uniforms.scale = [2]float32{scale.X, scale.Y}
uniforms.offset = [2]float32{off.X, off.Y}
p.UploadUniforms()
b.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4)
}
// newUniformBuffer creates a new GPU uniform buffer backed by the
// structure uniformBlock points to.
func newUniformBuffer(b Backend, uniformBlock interface{}) *uniformBuffer {
ref := reflect.ValueOf(uniformBlock)
// Determine the size of the uniforms structure, *uniforms.
size := ref.Elem().Type().Size()
// Map the uniforms structure as a byte slice.
ptr := (*[1 << 30]byte)(unsafe.Pointer(ref.Pointer()))[:size:size]
ubuf := b.NewBuffer(BufferTypeUniforms, len(ptr))
return &uniformBuffer{buf: ubuf, ptr: ptr}
}
func (u *uniformBuffer) Upload() {
u.buf.Upload(u.ptr)
}
func (u *uniformBuffer) Release() {
u.buf.Release()
u.buf = nil
}
func newProgram(prog Program, vertUniforms, fragUniforms *uniformBuffer) *program {
if vertUniforms != nil {
prog.SetVertexUniforms(vertUniforms.buf)
}
if fragUniforms != nil {
prog.SetFragmentUniforms(fragUniforms.buf)
}
return &program{prog: prog, vertUniforms: vertUniforms, fragUniforms: fragUniforms}
}
func (p *program) UploadUniforms() {
if p.vertUniforms != nil {
p.vertUniforms.Upload()
}
if p.fragUniforms != nil {
p.fragUniforms.Upload()
}
}
func (p *program) Release() {
p.prog.Release()
p.prog = nil
if p.vertUniforms != nil {
p.vertUniforms.Release()
p.vertUniforms = nil
}
if p.fragUniforms != nil {
p.fragUniforms.Release()
p.fragUniforms = nil
}
}
// texSpaceTransform return the scale and offset that transforms the given subimage
// into quad texture coordinates.
func texSpaceTransform(r f32.Rectangle, bounds image.Point) (f32.Point, f32.Point) {
+104 -78
View File
@@ -25,30 +25,63 @@ type pather struct {
type coverer struct {
ctx Backend
prog [2]Program
layout InputLayout
vars [2]struct {
z Uniform
uScale, uOffset Uniform
uUVScale, uUVOffset Uniform
uCoverUVScale, uCoverUVOffset Uniform
uColor Uniform
prog [2]*program
texUniforms struct {
vert struct {
coverUniforms
_ [8]byte // Padding to multiple of 16.
}
}
colUniforms struct {
vert struct {
coverUniforms
_ [8]byte // Padding to multiple of 16.
}
frag struct {
colorUniforms
}
}
layout InputLayout
}
type coverUniforms struct {
z float32
_ float32 // Padding.
scale [2]float32
offset [2]float32
uvCoverScale [2]float32
uvCoverOffset [2]float32
uvScale [2]float32
uvOffset [2]float32
}
type stenciler struct {
ctx Backend
defFBO Framebuffer
prog Program
progLayout InputLayout
iprog Program
iprogLayout InputLayout
prog struct {
prog *program
uniforms struct {
vert struct {
scale [2]float32
offset [2]float32
pathOffset [2]float32
_ [8]byte // Padding to multiple of 16.
}
}
layout InputLayout
}
iprog struct {
prog *program
uniforms struct {
vert struct {
uvScale [2]float32
uvOffset [2]float32
}
}
layout InputLayout
}
fbos fboSet
intersections fboSet
uScale, uOffset Uniform
uPathOffset Uniform
uIntersectUVOffset Uniform
uIntersectUVScale Uniform
indexBuf Buffer
}
@@ -89,48 +122,28 @@ func newPather(ctx Backend) *pather {
}
func newCoverer(ctx Backend) *coverer {
prog, layout, err := createColorPrograms(ctx, shader_cover_vert, shader_cover_frag)
c := &coverer{
ctx: ctx,
}
prog, layout, err := createColorPrograms(ctx, shader_cover_vert, shader_cover_frag,
[2]interface{}{&c.colUniforms.vert, &c.texUniforms.vert},
[2]interface{}{&c.colUniforms.frag, nil},
)
if err != nil {
panic(err)
}
c := &coverer{
ctx: ctx,
prog: prog,
layout: layout,
}
for i, prog := range prog {
switch materialType(i) {
case materialTexture:
uTex := prog.UniformFor("tex")
prog.Uniform1i(uTex, 0)
c.vars[i].uUVScale = prog.UniformFor("uniforms.uvScale")
c.vars[i].uUVOffset = prog.UniformFor("uniforms.uvOffset")
case materialColor:
c.vars[i].uColor = prog.UniformFor("color.color")
}
uCover := prog.UniformFor("cover")
prog.Uniform1i(uCover, 1)
c.vars[i].z = prog.UniformFor("uniforms.z")
c.vars[i].uScale = prog.UniformFor("uniforms.scale")
c.vars[i].uOffset = prog.UniformFor("uniforms.offset")
c.vars[i].uCoverUVScale = prog.UniformFor("uniforms.uvCoverScale")
c.vars[i].uCoverUVOffset = prog.UniformFor("uniforms.uvCoverOffset")
c.prog = prog
c.layout = layout
texProg := prog[materialTexture].prog
texProg.Uniform1i(texProg.UniformFor("tex"), 0)
for _, p := range prog {
p.prog.Uniform1i(p.prog.UniformFor("cover"), 1)
}
return c
}
func newStenciler(ctx Backend) *stenciler {
defFBO := ctx.DefaultFramebuffer()
prog, err := ctx.NewProgram(shader_stencil_vert, shader_stencil_frag)
if err != nil {
panic(err)
}
iprog, err := ctx.NewProgram(shader_intersect_vert, shader_intersect_frag)
if err != nil {
panic(err)
}
coverLoc := iprog.UniformFor("cover")
iprog.Uniform1i(coverLoc, 0)
// Allocate a suitably large index buffer for drawing paths.
indices := make([]uint16, pathBatchSize*6)
for i := 0; i < pathBatchSize; i++ {
@@ -160,20 +173,28 @@ func newStenciler(ctx Backend) *stenciler {
if err != nil {
panic(err)
}
return &stenciler{
st := &stenciler{
ctx: ctx,
defFBO: defFBO,
prog: prog,
progLayout: progLayout,
iprog: iprog,
iprogLayout: iprogLayout,
uScale: prog.UniformFor("uniforms.scale"),
uOffset: prog.UniformFor("uniforms.offset"),
uPathOffset: prog.UniformFor("uniforms.pathOffset"),
uIntersectUVScale: iprog.UniformFor("uvparams.scale"),
uIntersectUVOffset: iprog.UniformFor("uvparams.offset"),
indexBuf: indexBuf,
}
prog, err := ctx.NewProgram(shader_stencil_vert, shader_stencil_frag)
if err != nil {
panic(err)
}
vertUniforms := newUniformBuffer(ctx, &st.prog.uniforms.vert)
st.prog.prog = newProgram(prog, vertUniforms, nil)
st.prog.layout = progLayout
iprog, err := ctx.NewProgram(shader_intersect_vert, shader_intersect_frag)
if err != nil {
panic(err)
}
vertUniforms = newUniformBuffer(ctx, &st.iprog.uniforms.vert)
coverLoc := iprog.UniformFor("cover")
iprog.Uniform1i(coverLoc, 0)
st.iprog.prog = newProgram(iprog, vertUniforms, nil)
st.iprog.layout = iprogLayout
return st
}
func (s *fboSet) resize(ctx Backend, sizes []image.Point) {
@@ -219,10 +240,10 @@ func (s *fboSet) delete(ctx Backend, idx int) {
func (s *stenciler) release() {
s.fbos.delete(s.ctx, 0)
s.progLayout.Release()
s.prog.Release()
s.iprogLayout.Release()
s.iprog.Release()
s.prog.layout.Release()
s.prog.prog.Release()
s.iprog.layout.Release()
s.iprog.prog.Release()
s.indexBuf.Release()
}
@@ -270,7 +291,7 @@ func (s *stenciler) beginIntersect(sizes []image.Point) {
// no floating point support is available.
s.intersections.resize(s.ctx, sizes)
s.ctx.ClearColor(1.0, 0.0, 0.0, 0.0)
s.iprog.Bind()
s.iprog.prog.prog.Bind()
}
func (s *stenciler) endIntersect() {
@@ -292,8 +313,8 @@ func (s *stenciler) begin(sizes []image.Point) {
s.ctx.BlendFunc(BlendFactorOne, BlendFactorOne)
s.fbos.resize(s.ctx, sizes)
s.ctx.ClearColor(0.0, 0.0, 0.0, 0.0)
s.prog.Bind()
s.progLayout.Bind()
s.prog.prog.prog.Bind()
s.prog.layout.Bind()
s.indexBuf.BindIndex()
}
@@ -303,9 +324,10 @@ func (s *stenciler) stencilPath(bounds image.Rectangle, offset f32.Point, uv ima
texSize := f32.Point{X: float32(bounds.Dx()), Y: float32(bounds.Dy())}
scale := f32.Point{X: 2 / texSize.X, Y: 2 / texSize.Y}
orig := f32.Point{X: -1 - float32(bounds.Min.X)*2/texSize.X, Y: -1 - float32(bounds.Min.Y)*2/texSize.Y}
s.prog.Uniform2f(s.uScale, scale.X, scale.Y)
s.prog.Uniform2f(s.uOffset, orig.X, orig.Y)
s.prog.Uniform2f(s.uPathOffset, offset.X, offset.Y)
s.prog.uniforms.vert.scale = [2]float32{scale.X, scale.Y}
s.prog.uniforms.vert.offset = [2]float32{orig.X, orig.Y}
s.prog.uniforms.vert.pathOffset = [2]float32{offset.X, offset.Y}
s.prog.prog.UploadUniforms()
// Draw in batches that fit in uint16 indices.
start := 0
nquads := data.ncurves / 4
@@ -331,18 +353,22 @@ func (p *pather) cover(z float32, mat materialType, col [4]float32, scale, off,
func (c *coverer) cover(z float32, mat materialType, col [4]float32, scale, off, uvScale, uvOff, coverScale, coverOff f32.Point) {
p := c.prog[mat]
p.Bind()
p.prog.Bind()
var uniforms *coverUniforms
switch mat {
case materialColor:
p.Uniform4f(c.vars[mat].uColor, col[0], col[1], col[2], col[3])
c.colUniforms.frag.color = col
uniforms = &c.colUniforms.vert.coverUniforms
case materialTexture:
p.Uniform2f(c.vars[mat].uUVScale, uvScale.X, uvScale.Y)
p.Uniform2f(c.vars[mat].uUVOffset, uvOff.X, uvOff.Y)
c.texUniforms.vert.uvScale = [2]float32{uvScale.X, uvScale.Y}
c.texUniforms.vert.uvOffset = [2]float32{uvOff.X, uvOff.Y}
uniforms = &c.texUniforms.vert.coverUniforms
}
p.Uniform1f(c.vars[mat].z, z)
p.Uniform2f(c.vars[mat].uScale, scale.X, scale.Y)
p.Uniform2f(c.vars[mat].uOffset, off.X, off.Y)
p.Uniform2f(c.vars[mat].uCoverUVScale, coverScale.X, coverScale.Y)
p.Uniform2f(c.vars[mat].uCoverUVOffset, coverOff.X, coverOff.Y)
uniforms.z = z
uniforms.scale = [2]float32{scale.X, scale.Y}
uniforms.offset = [2]float32{off.X, off.Y}
uniforms.uvCoverScale = [2]float32{coverScale.X, coverScale.Y}
uniforms.uvCoverOffset = [2]float32{coverOff.X, coverOff.Y}
p.UploadUniforms()
c.ctx.DrawArrays(DrawModeTriangleStrip, 0, 4)
}
+53 -47
View File
@@ -6,13 +6,14 @@ var (
shader_blit_frag = [...]ShaderSources{
ShaderSources{
Uniforms: []UniformLocation{
{Name: "_12.color", Type: 0, Size: 4, Offset: 0},
{Name: "_12._color", Type: 0, Size: 4, Offset: 0},
},
GLES2: "#version 100\nprecision mediump float;\nprecision highp int;\n\nstruct Color\n{\n vec4 color;\n};\n\nuniform Color color;\n\nvarying vec2 vUV;\n\nvoid main()\n{\n gl_FragData[0] = color.color;\n}\n\n",
UniformSize: 16,
GLES2: "#version 100\nprecision mediump float;\nprecision highp int;\n\nstruct Color\n{\n vec4 _color;\n};\n\nuniform Color _12;\n\nvarying vec2 vUV;\n\nvoid main()\n{\n gl_FragData[0] = _12._color;\n}\n\n",
/*
cbuffer Color : register(b0)
{
float4 color_color : packoffset(c0);
float4 _12_color : packoffset(c0);
};
@@ -31,7 +32,7 @@ var (
void frag_main()
{
fragColor = color_color;
fragColor = _12_color;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
@@ -95,15 +96,16 @@ var (
{Name: "_15.uvScale", Type: 0, Size: 2, Offset: 24},
{Name: "_15.uvOffset", Type: 0, Size: 2, Offset: 32},
},
GLES2: "#version 100\n\nstruct Block\n{\n float z;\n vec2 scale;\n vec2 offset;\n vec2 uvScale;\n vec2 uvOffset;\n};\n\nuniform Block uniforms;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\n\nvoid main()\n{\n vec2 p = pos;\n p *= uniforms.scale;\n p += uniforms.offset;\n gl_Position = vec4(p, uniforms.z, 1.0);\n vUV = (uv * uniforms.uvScale) + uniforms.uvOffset;\n}\n\n",
UniformSize: 40,
GLES2: "#version 100\n\nstruct Block\n{\n float z;\n vec2 scale;\n vec2 offset;\n vec2 uvScale;\n vec2 uvOffset;\n};\n\nuniform Block _15;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\n\nvoid main()\n{\n vec2 p = pos;\n p *= _15.scale;\n p += _15.offset;\n gl_Position = vec4(p, _15.z, 1.0);\n vUV = (uv * _15.uvScale) + _15.uvOffset;\n}\n\n",
/*
cbuffer Block : register(b0)
{
float uniforms_z : packoffset(c0);
float2 uniforms_scale : packoffset(c0.z);
float2 uniforms_offset : packoffset(c1);
float2 uniforms_uvScale : packoffset(c1.z);
float2 uniforms_uvOffset : packoffset(c2);
float _15_z : packoffset(c0);
float2 _15_scale : packoffset(c0.z);
float2 _15_offset : packoffset(c1);
float2 _15_uvScale : packoffset(c1.z);
float2 _15_uvOffset : packoffset(c2);
};
@@ -127,10 +129,10 @@ var (
void vert_main()
{
float2 p = pos;
p *= uniforms_scale;
p += uniforms_offset;
gl_Position = float4(p, uniforms_z, 1.0f);
vUV = (uv * uniforms_uvScale) + uniforms_uvOffset;
p *= _15_scale;
p += _15_offset;
gl_Position = float4(p, _15_z, 1.0f);
vUV = (uv * _15_uvScale) + _15_uvOffset;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
@@ -150,13 +152,14 @@ var (
shader_cover_frag = [...]ShaderSources{
ShaderSources{
Uniforms: []UniformLocation{
{Name: "_12.color", Type: 0, Size: 4, Offset: 0},
{Name: "_12._color", Type: 0, Size: 4, Offset: 0},
},
GLES2: "#version 100\nprecision mediump float;\nprecision highp int;\n\nstruct Color\n{\n vec4 color;\n};\n\nuniform Color color;\n\nuniform mediump sampler2D cover;\n\nvarying highp vec2 vCoverUV;\nvarying vec2 vUV;\n\nvoid main()\n{\n gl_FragData[0] = color.color;\n float cover_1 = abs(texture2D(cover, vCoverUV).x);\n gl_FragData[0] *= cover_1;\n}\n\n",
UniformSize: 16,
GLES2: "#version 100\nprecision mediump float;\nprecision highp int;\n\nstruct Color\n{\n vec4 _color;\n};\n\nuniform Color _12;\n\nuniform mediump sampler2D cover;\n\nvarying highp vec2 vCoverUV;\nvarying vec2 vUV;\n\nvoid main()\n{\n gl_FragData[0] = _12._color;\n float cover_1 = abs(texture2D(cover, vCoverUV).x);\n gl_FragData[0] *= cover_1;\n}\n\n",
/*
cbuffer Color : register(b0)
{
float4 color_color : packoffset(c0);
float4 _12_color : packoffset(c0);
};
Texture2D<float4> cover : register(t1);
@@ -179,7 +182,7 @@ var (
void frag_main()
{
fragColor = color_color;
fragColor = _12_color;
float cover_1 = abs(cover.Sample(_cover_sampler, vCoverUV).x);
fragColor *= cover_1;
}
@@ -250,22 +253,23 @@ var (
{Name: "_19.z", Type: 0, Size: 1, Offset: 0},
{Name: "_19.scale", Type: 0, Size: 2, Offset: 8},
{Name: "_19.offset", Type: 0, Size: 2, Offset: 16},
{Name: "_19.uvScale", Type: 0, Size: 2, Offset: 24},
{Name: "_19.uvOffset", Type: 0, Size: 2, Offset: 32},
{Name: "_19.uvCoverScale", Type: 0, Size: 2, Offset: 40},
{Name: "_19.uvCoverOffset", Type: 0, Size: 2, Offset: 48},
{Name: "_19.uvCoverScale", Type: 0, Size: 2, Offset: 24},
{Name: "_19.uvCoverOffset", Type: 0, Size: 2, Offset: 32},
{Name: "_19.uvScale", Type: 0, Size: 2, Offset: 40},
{Name: "_19.uvOffset", Type: 0, Size: 2, Offset: 48},
},
GLES2: "#version 100\n\nstruct Block\n{\n float z;\n vec2 scale;\n vec2 offset;\n vec2 uvScale;\n vec2 uvOffset;\n vec2 uvCoverScale;\n vec2 uvCoverOffset;\n};\n\nuniform Block uniforms;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\nvarying vec2 vCoverUV;\n\nvoid main()\n{\n gl_Position = vec4((pos * uniforms.scale) + uniforms.offset, uniforms.z, 1.0);\n vUV = (uv * uniforms.uvScale) + uniforms.uvOffset;\n vCoverUV = (uv * uniforms.uvCoverScale) + uniforms.uvCoverOffset;\n}\n\n",
UniformSize: 56,
GLES2: "#version 100\n\nstruct Block\n{\n float z;\n vec2 scale;\n vec2 offset;\n vec2 uvCoverScale;\n vec2 uvCoverOffset;\n vec2 uvScale;\n vec2 uvOffset;\n};\n\nuniform Block _19;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\nvarying vec2 vCoverUV;\n\nvoid main()\n{\n gl_Position = vec4((pos * _19.scale) + _19.offset, _19.z, 1.0);\n vUV = (uv * _19.uvScale) + _19.uvOffset;\n vCoverUV = (uv * _19.uvCoverScale) + _19.uvCoverOffset;\n}\n\n",
/*
cbuffer Block : register(b0)
{
float uniforms_z : packoffset(c0);
float2 uniforms_scale : packoffset(c0.z);
float2 uniforms_offset : packoffset(c1);
float2 uniforms_uvScale : packoffset(c1.z);
float2 uniforms_uvOffset : packoffset(c2);
float2 uniforms_uvCoverScale : packoffset(c2.z);
float2 uniforms_uvCoverOffset : packoffset(c3);
float _19_z : packoffset(c0);
float2 _19_scale : packoffset(c0.z);
float2 _19_offset : packoffset(c1);
float2 _19_uvCoverScale : packoffset(c1.z);
float2 _19_uvCoverOffset : packoffset(c2);
float2 _19_uvScale : packoffset(c2.z);
float2 _19_uvOffset : packoffset(c3);
};
@@ -290,9 +294,9 @@ var (
void vert_main()
{
gl_Position = float4((pos * uniforms_scale) + uniforms_offset, uniforms_z, 1.0f);
vUV = (uv * uniforms_uvScale) + uniforms_uvOffset;
vCoverUV = (uv * uniforms_uvCoverScale) + uniforms_uvCoverOffset;
gl_Position = float4((pos * _19_scale) + _19_offset, _19_z, 1.0f);
vUV = (uv * _19_uvScale) + _19_uvOffset;
vCoverUV = (uv * _19_uvCoverScale) + _19_uvCoverOffset;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
@@ -356,12 +360,13 @@ var (
{Name: "_40.scale", Type: 0, Size: 2, Offset: 0},
{Name: "_40.offset", Type: 0, Size: 2, Offset: 8},
},
GLES2: "#version 100\n\nstruct Block\n{\n vec2 scale;\n vec2 offset;\n};\n\nuniform Block uvparams;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\n\nvoid main()\n{\n vec2 p = pos;\n p.y = -p.y;\n gl_Position = vec4(p, 0.0, 1.0);\n vUV = (uv * uvparams.scale) + uvparams.offset;\n}\n\n",
UniformSize: 16,
GLES2: "#version 100\n\nstruct Block\n{\n vec2 scale;\n vec2 offset;\n};\n\nuniform Block _40;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\n\nvoid main()\n{\n vec2 p = pos;\n p.y = -p.y;\n gl_Position = vec4(p, 0.0, 1.0);\n vUV = (uv * _40.scale) + _40.offset;\n}\n\n",
/*
cbuffer Block : register(b0)
{
float2 uvparams_scale : packoffset(c0);
float2 uvparams_offset : packoffset(c0.z);
float2 _40_scale : packoffset(c0);
float2 _40_offset : packoffset(c0.z);
};
@@ -387,7 +392,7 @@ var (
float2 p = pos;
p.y = -p.y;
gl_Position = float4(p, 0.0f, 1.0f);
vUV = (uv * uvparams_scale) + uvparams_offset;
vUV = (uv * _40_scale) + _40_offset;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
@@ -484,13 +489,14 @@ var (
{Name: "_15.offset", Type: 0, Size: 2, Offset: 8},
{Name: "_15.pathOffset", Type: 0, Size: 2, Offset: 16},
},
GLES2: "#version 100\n\nstruct Block\n{\n vec2 scale;\n vec2 offset;\n vec2 pathOffset;\n};\n\nuniform Block uniforms;\n\nattribute vec2 from;\nattribute vec2 ctrl;\nattribute vec2 to;\nattribute float maxy;\nattribute vec2 corner;\nvarying vec2 vFrom;\nvarying vec2 vCtrl;\nvarying vec2 vTo;\n\nvoid main()\n{\n vec2 from_1 = from + uniforms.pathOffset;\n vec2 ctrl_1 = ctrl + uniforms.pathOffset;\n vec2 to_1 = to + uniforms.pathOffset;\n float maxy_1 = maxy + uniforms.pathOffset.y;\n vec2 pos;\n if (corner.x > 0.0)\n {\n pos.x = max(max(from_1.x, ctrl_1.x), to_1.x) + 1.0;\n }\n else\n {\n pos.x = min(min(from_1.x, ctrl_1.x), to_1.x) - 1.0;\n }\n if (corner.y > 0.0)\n {\n pos.y = maxy_1 + 1.0;\n }\n else\n {\n pos.y = min(min(from_1.y, ctrl_1.y), to_1.y) - 1.0;\n }\n vFrom = from_1 - pos;\n vCtrl = ctrl_1 - pos;\n vTo = to_1 - pos;\n pos *= uniforms.scale;\n pos += uniforms.offset;\n gl_Position = vec4(pos, 1.0, 1.0);\n}\n\n",
UniformSize: 24,
GLES2: "#version 100\n\nstruct Block\n{\n vec2 scale;\n vec2 offset;\n vec2 pathOffset;\n};\n\nuniform Block _15;\n\nattribute vec2 from;\nattribute vec2 ctrl;\nattribute vec2 to;\nattribute float maxy;\nattribute vec2 corner;\nvarying vec2 vFrom;\nvarying vec2 vCtrl;\nvarying vec2 vTo;\n\nvoid main()\n{\n vec2 from_1 = from + _15.pathOffset;\n vec2 ctrl_1 = ctrl + _15.pathOffset;\n vec2 to_1 = to + _15.pathOffset;\n float maxy_1 = maxy + _15.pathOffset.y;\n vec2 pos;\n if (corner.x > 0.0)\n {\n pos.x = max(max(from_1.x, ctrl_1.x), to_1.x) + 1.0;\n }\n else\n {\n pos.x = min(min(from_1.x, ctrl_1.x), to_1.x) - 1.0;\n }\n if (corner.y > 0.0)\n {\n pos.y = maxy_1 + 1.0;\n }\n else\n {\n pos.y = min(min(from_1.y, ctrl_1.y), to_1.y) - 1.0;\n }\n vFrom = from_1 - pos;\n vCtrl = ctrl_1 - pos;\n vTo = to_1 - pos;\n pos *= _15.scale;\n pos += _15.offset;\n gl_Position = vec4(pos, 1.0, 1.0);\n}\n\n",
/*
cbuffer Block : register(b0)
{
float2 uniforms_scale : packoffset(c0);
float2 uniforms_offset : packoffset(c0.z);
float2 uniforms_pathOffset : packoffset(c1);
float2 _15_scale : packoffset(c0);
float2 _15_offset : packoffset(c0.z);
float2 _15_pathOffset : packoffset(c1);
};
@@ -523,10 +529,10 @@ var (
void vert_main()
{
float2 from_1 = from + uniforms_pathOffset;
float2 ctrl_1 = ctrl + uniforms_pathOffset;
float2 to_1 = to + uniforms_pathOffset;
float maxy_1 = maxy + uniforms_pathOffset.y;
float2 from_1 = from + _15_pathOffset;
float2 ctrl_1 = ctrl + _15_pathOffset;
float2 to_1 = to + _15_pathOffset;
float maxy_1 = maxy + _15_pathOffset.y;
float2 pos;
if (corner.x > 0.0f)
{
@@ -547,8 +553,8 @@ var (
vFrom = from_1 - pos;
vCtrl = ctrl_1 - pos;
vTo = to_1 - pos;
pos *= uniforms_scale;
pos += uniforms_offset;
pos *= _15_scale;
pos += _15_offset;
gl_Position = float4(pos, 1.0f, 1.0f);
}
+5 -5
View File
@@ -10,7 +10,7 @@ layout(binding = 0) uniform Block {
vec2 offset;
vec2 uvScale;
vec2 uvOffset;
} uniforms;
};
layout(location = 0) in vec2 pos;
@@ -20,8 +20,8 @@ layout(location = 0) out vec2 vUV;
void main() {
vec2 p = pos;
p *= uniforms.scale;
p += uniforms.offset;
gl_Position = vec4(p, uniforms.z, 1);
vUV = uv*uniforms.uvScale + uniforms.uvOffset;
p *= scale;
p += offset;
gl_Position = vec4(p, z, 1);
vUV = uv*uvScale + uvOffset;
}
+4
View File
@@ -0,0 +1,4 @@
#version 310 es
void blah() {
}
+6 -6
View File
@@ -8,11 +8,11 @@ layout(binding = 0) uniform Block {
float z;
vec2 scale;
vec2 offset;
vec2 uvScale;
vec2 uvOffset;
vec2 uvCoverScale;
vec2 uvCoverOffset;
} uniforms;
vec2 uvScale;
vec2 uvOffset;
};
layout(location = 0) in vec2 pos;
@@ -22,7 +22,7 @@ layout(location = 1) in vec2 uv;
layout(location = 1) out vec2 vUV;
void main() {
gl_Position = vec4(pos*uniforms.scale + uniforms.offset, uniforms.z, 1);
vUV = uv*uniforms.uvScale + uniforms.uvOffset;
vCoverUV = uv*uniforms.uvCoverScale+uniforms.uvCoverOffset;
gl_Position = vec4(pos*scale + offset, z, 1);
vUV = uv*uvScale + uvOffset;
vCoverUV = uv*uvCoverScale+uvCoverOffset;
}
+2 -2
View File
@@ -10,7 +10,7 @@ layout(location = 1) in vec2 uv;
layout(binding = 0) uniform Block {
vec2 scale;
vec2 offset;
} uvparams;
};
layout(location = 0) out vec2 vUV;
@@ -18,5 +18,5 @@ void main() {
vec2 p = pos;
p.y = -p.y;
gl_Position = vec4(p, 0, 1);
vUV = uv*uvparams.scale + uvparams.offset;
vUV = uv*scale + offset;
}
+7 -7
View File
@@ -8,7 +8,7 @@ layout(binding = 0) uniform Block {
vec2 scale;
vec2 offset;
vec2 pathOffset;
} uniforms;
};
layout(location=0) in vec2 corner;
layout(location=1) in float maxy;
@@ -24,10 +24,10 @@ void main() {
// Add a one pixel overlap so curve quads cover their
// entire curves. Could use conservative rasterization
// if available.
vec2 from = from + uniforms.pathOffset;
vec2 ctrl = ctrl + uniforms.pathOffset;
vec2 to = to + uniforms.pathOffset;
float maxy = maxy + uniforms.pathOffset.y;
vec2 from = from + pathOffset;
vec2 ctrl = ctrl + pathOffset;
vec2 to = to + pathOffset;
float maxy = maxy + pathOffset.y;
vec2 pos;
if (corner.x > 0.0) {
// East.
@@ -46,8 +46,8 @@ void main() {
vFrom = from-pos;
vCtrl = ctrl-pos;
vTo = to-pos;
pos *= uniforms.scale;
pos += uniforms.offset;
pos *= scale;
pos += offset;
gl_Position = vec4(pos, 1, 1);
}