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
+8 -7
View File
@@ -41,10 +41,11 @@ type Backend interface {
}
type ShaderSources struct {
GLES2 string
HLSL []byte
Uniforms []UniformLocation
Inputs []InputLocation
GLES2 string
HLSL []byte
Uniforms []UniformLocation
UniformSize int
Inputs []InputLocation
}
type UniformLocation struct {
@@ -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 (
+19 -14
View File
@@ -85,16 +85,17 @@ func generate() error {
for _, shader := range shaders {
const nvariants = 2
var variants [nvariants]struct {
gles2 string
hlslSrc string
hlsl []byte
inputs []InputLocation
uniforms []UniformLocation
gles2 string
hlslSrc string
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) {
+135 -26
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
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.backend.funcs.BindBuffer(b.typ, b.obj)
b.backend.funcs.BufferData(b.typ, data, STATIC_DRAW)
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() {
b.backend.funcs.DeleteBuffer(b.obj)
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
+151 -51
View File
@@ -13,6 +13,7 @@ import (
"image"
"image/color"
"math"
"reflect"
"time"
"unsafe"
@@ -209,19 +210,52 @@ type texture struct {
}
type blitter struct {
ctx Backend
viewport image.Point
prog [2]Program
layout InputLayout
vars [2]struct {
z Uniform
uScale, uOffset Uniform
uUVScale, uUVOffset Uniform
uColor Uniform
ctx Backend
viewport image.Point
prog [2]*program
layout InputLayout
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) {
+113 -87
View File
@@ -24,32 +24,65 @@ 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
ctx Backend
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
fbos fboSet
intersections fboSet
uScale, uOffset Uniform
uPathOffset Uniform
uIntersectUVOffset Uniform
uIntersectUVScale Uniform
indexBuf Buffer
ctx Backend
defFBO Framebuffer
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
indexBuf Buffer
}
type fboSet struct {
@@ -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{
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,
st := &stenciler{
ctx: ctx,
defFBO: defFBO,
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);
}