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
11
canvas.go
11
canvas.go
|
@ -38,7 +38,8 @@ type drawState struct {
|
|||
lineDashPoint int
|
||||
lineDashOffset float64
|
||||
|
||||
clip []pathPoint
|
||||
scissor scissor
|
||||
clip []pathPoint
|
||||
/*
|
||||
The current transformation matrix.
|
||||
The current clipping region.
|
||||
|
@ -57,6 +58,11 @@ type drawStyle struct {
|
|||
image *Image
|
||||
}
|
||||
|
||||
type scissor struct {
|
||||
on bool
|
||||
tl, br vec
|
||||
}
|
||||
|
||||
type lineJoin uint8
|
||||
type lineEnd uint8
|
||||
|
||||
|
@ -261,6 +267,8 @@ func LoadGL(glimpl GL) (err error) {
|
|||
gli.StencilOp(gl_KEEP, gl_KEEP, gl_KEEP)
|
||||
gli.StencilFunc(gl_EQUAL, 0, 0xFF)
|
||||
|
||||
gli.Enable(gl_SCISSOR_TEST)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -504,6 +512,7 @@ func (cv *Canvas) Restore() {
|
|||
}
|
||||
cv.state = cv.stateStack[l-1]
|
||||
cv.stateStack = cv.stateStack[:l-1]
|
||||
cv.applyScissor()
|
||||
}
|
||||
|
||||
// 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
|
||||
LinkProgram(program uint32)
|
||||
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)
|
||||
StencilFunc(xfunc uint32, ref int32, mask uint32)
|
||||
StencilMask(mask uint32)
|
||||
|
|
50
paths.go
50
paths.go
|
@ -17,6 +17,7 @@ type pathPointFlag uint8
|
|||
const (
|
||||
pathMove pathPointFlag = 1 << iota
|
||||
pathAttach
|
||||
pathIsRect
|
||||
)
|
||||
|
||||
func (cv *Canvas) BeginPath() {
|
||||
|
@ -497,10 +498,26 @@ func (cv *Canvas) Clip() {
|
|||
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) {
|
||||
if len(path) < 3 {
|
||||
return
|
||||
}
|
||||
if path[len(path)-1].flags&pathIsRect != 0 {
|
||||
cv.scissor(path)
|
||||
return
|
||||
}
|
||||
|
||||
cv.activate()
|
||||
|
||||
var triBuf [1000]float32
|
||||
|
@ -549,6 +566,35 @@ func (cv *Canvas) clip(path []pathPoint) {
|
|||
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
|
||||
func (cv *Canvas) Rect(x, y, w, h float64) {
|
||||
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, y+h)
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue