clipping with the rect function now uses scissor test instead of stencil
This commit is contained in:
parent
d5a4c0b4bb
commit
8502818b6f
3 changed files with 60 additions and 2 deletions
|
@ -38,6 +38,7 @@ type drawState struct {
|
||||||
lineDashPoint int
|
lineDashPoint int
|
||||||
lineDashOffset float64
|
lineDashOffset float64
|
||||||
|
|
||||||
|
scissor scissor
|
||||||
clip []pathPoint
|
clip []pathPoint
|
||||||
/*
|
/*
|
||||||
The current transformation matrix.
|
The current transformation matrix.
|
||||||
|
@ -57,6 +58,11 @@ type drawStyle struct {
|
||||||
image *Image
|
image *Image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type scissor struct {
|
||||||
|
on bool
|
||||||
|
tl, br vec
|
||||||
|
}
|
||||||
|
|
||||||
type lineJoin uint8
|
type lineJoin uint8
|
||||||
type lineEnd uint8
|
type lineEnd uint8
|
||||||
|
|
||||||
|
@ -261,6 +267,8 @@ func LoadGL(glimpl GL) (err error) {
|
||||||
gli.StencilOp(gl_KEEP, gl_KEEP, gl_KEEP)
|
gli.StencilOp(gl_KEEP, gl_KEEP, gl_KEEP)
|
||||||
gli.StencilFunc(gl_EQUAL, 0, 0xFF)
|
gli.StencilFunc(gl_EQUAL, 0, 0xFF)
|
||||||
|
|
||||||
|
gli.Enable(gl_SCISSOR_TEST)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,6 +512,7 @@ func (cv *Canvas) Restore() {
|
||||||
}
|
}
|
||||||
cv.state = cv.stateStack[l-1]
|
cv.state = cv.stateStack[l-1]
|
||||||
cv.stateStack = cv.stateStack[:l-1]
|
cv.stateStack = cv.stateStack[:l-1]
|
||||||
|
cv.applyScissor()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scale updates the current transformation with a scaling by the given values
|
// Scale updates the current transformation with a scaling by the given values
|
||||||
|
|
|
@ -826,6 +826,7 @@ type GL interface {
|
||||||
GetUniformLocation(program uint32, name *uint8) int32
|
GetUniformLocation(program uint32, name *uint8) int32
|
||||||
LinkProgram(program uint32)
|
LinkProgram(program uint32)
|
||||||
ReadPixels(x int32, y int32, width int32, height int32, format uint32, xtype uint32, pixels unsafe.Pointer)
|
ReadPixels(x int32, y int32, width int32, height int32, format uint32, xtype uint32, pixels unsafe.Pointer)
|
||||||
|
Scissor(x int32, y int32, width int32, height int32)
|
||||||
ShaderSource(shader uint32, count int32, xstring **uint8, length *int32)
|
ShaderSource(shader uint32, count int32, xstring **uint8, length *int32)
|
||||||
StencilFunc(xfunc uint32, ref int32, mask uint32)
|
StencilFunc(xfunc uint32, ref int32, mask uint32)
|
||||||
StencilMask(mask uint32)
|
StencilMask(mask uint32)
|
||||||
|
|
50
paths.go
50
paths.go
|
@ -17,6 +17,7 @@ type pathPointFlag uint8
|
||||||
const (
|
const (
|
||||||
pathMove pathPointFlag = 1 << iota
|
pathMove pathPointFlag = 1 << iota
|
||||||
pathAttach
|
pathAttach
|
||||||
|
pathIsRect
|
||||||
)
|
)
|
||||||
|
|
||||||
func (cv *Canvas) BeginPath() {
|
func (cv *Canvas) BeginPath() {
|
||||||
|
@ -497,10 +498,26 @@ func (cv *Canvas) Clip() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cv.clip(cv.polyPath)
|
path := cv.polyPath
|
||||||
|
for i := len(path) - 1; i >= 0; i-- {
|
||||||
|
if path[i].flags&pathMove != 0 {
|
||||||
|
path = path[i:]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cv.clip(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cv *Canvas) clip(path []pathPoint) {
|
func (cv *Canvas) clip(path []pathPoint) {
|
||||||
|
if len(path) < 3 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if path[len(path)-1].flags&pathIsRect != 0 {
|
||||||
|
cv.scissor(path)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
cv.activate()
|
cv.activate()
|
||||||
|
|
||||||
var triBuf [1000]float32
|
var triBuf [1000]float32
|
||||||
|
@ -549,6 +566,35 @@ func (cv *Canvas) clip(path []pathPoint) {
|
||||||
copy(cv.state.clip, cv.polyPath)
|
copy(cv.state.clip, cv.polyPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cv *Canvas) scissor(path []pathPoint) {
|
||||||
|
tl, br := vec{math.MaxFloat64, math.MaxFloat64}, vec{}
|
||||||
|
for _, p := range path {
|
||||||
|
tl[0] = math.Min(p.tf[0], tl[0])
|
||||||
|
tl[1] = math.Min(p.tf[1], tl[1])
|
||||||
|
br[0] = math.Max(p.tf[0], br[0])
|
||||||
|
br[1] = math.Max(p.tf[1], br[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
if cv.state.scissor.on {
|
||||||
|
tl[0] = math.Max(tl[0], cv.state.scissor.tl[0])
|
||||||
|
tl[1] = math.Max(tl[1], cv.state.scissor.tl[1])
|
||||||
|
br[0] = math.Min(br[0], cv.state.scissor.br[0])
|
||||||
|
br[1] = math.Min(br[1], cv.state.scissor.br[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
cv.state.scissor = scissor{tl: tl, br: br, on: true}
|
||||||
|
cv.applyScissor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cv *Canvas) applyScissor() {
|
||||||
|
s := &cv.state.scissor
|
||||||
|
if s.on {
|
||||||
|
gli.Scissor(int32(s.tl[0]+0.5), int32(cv.fh-s.br[1]+0.5), int32(s.br[0]-s.tl[0]+0.5), int32(s.br[1]-s.tl[1]+0.5))
|
||||||
|
} else {
|
||||||
|
gli.Scissor(0, 0, int32(cv.w), int32(cv.h))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Rect creates a closed rectangle path for stroking or filling
|
// Rect creates a closed rectangle path for stroking or filling
|
||||||
func (cv *Canvas) Rect(x, y, w, h float64) {
|
func (cv *Canvas) Rect(x, y, w, h float64) {
|
||||||
cv.MoveTo(x, y)
|
cv.MoveTo(x, y)
|
||||||
|
@ -556,6 +602,8 @@ func (cv *Canvas) Rect(x, y, w, h float64) {
|
||||||
cv.LineTo(x+w, y+h)
|
cv.LineTo(x+w, y+h)
|
||||||
cv.LineTo(x, y+h)
|
cv.LineTo(x, y+h)
|
||||||
cv.ClosePath()
|
cv.ClosePath()
|
||||||
|
cv.linePath[len(cv.linePath)-1].flags |= pathIsRect
|
||||||
|
cv.polyPath[len(cv.polyPath)-1].flags |= pathIsRect
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rect creates a closed rectangle path for stroking or filling
|
// Rect creates a closed rectangle path for stroking or filling
|
||||||
|
|
Loading…
Reference in a new issue