-
Notifications
You must be signed in to change notification settings - Fork 52
/
stencil.go
133 lines (114 loc) · 3.91 KB
/
stencil.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2014 The Azul3D Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gfx
// StencilState represents the state to use when the stencil test occurs for a
// front or back facing pixel of an object during drawing. If written in Go
// it would look something like:
//
// if (s.Reference & s.ReadMask) s.Cmp (stencilValue & s.ReadMask) {
// if depthTestFailed {
// stencilValue = s.DepthFail() & s.WriteMask
// } else {
// stencilValue = s.DepthPass() & s.WriteMask
// }
// } else {
// stencilValue = s.Fail() & s.WriteMask
// }
//
type StencilState struct {
// A mask that will be AND'd with each pixel to be written to the stencil
// buffer, e.g. 0xFFFF would allow writing to the full range of every pixel
// in the stencil buffer when drawing the object.
WriteMask uint
// A mask that will be AND'd with each pixel to be read/compared to the
// existing value in the stencil buffer, e.g. 0xFFFF would disable the use
// of the mask altogether.
ReadMask uint
// The reference value that will be used to compare existing values in the
// stencil buffer against, e.g. if s.Reference == 2 and if s.Func ==
// GreaterOrEqual, then any value below 2 would not be affected.
Reference uint
// Fail specifies what stencil operation should occur when the stencil test
// fails.
//
// Any predefined StencilOp constant is accepted.
Fail StencilOp
// DepthFail specifies what stencil operation should occur when the stencil
// test passes but the depth test fails.
//
// Any predefined StencilOp constant is accepted.
DepthFail StencilOp
// DepthPass specifies what stencil operation should occur when the stencil
// test passes and the depth test passes.
//
// Any predefined StencilOp constant is accepted.
DepthPass StencilOp
// Cmp specifies the comparison operator to use when comparing stencil data
// with existing data in the stencil buffer.
//
// Any predefined Cmp constant is accepted.
Cmp Cmp
}
// Compare compares this state against the other one using DefaultStencilState
// as a reference when inequality occurs and returns whether or not this state
// should sort before the other one for purposes of state sorting.
func (s StencilState) Compare(other StencilState) bool {
if s == other {
return true
}
if s.WriteMask != other.WriteMask {
return s.WriteMask == DefaultStencilState.WriteMask
}
if s.ReadMask != other.ReadMask {
return s.ReadMask == DefaultStencilState.ReadMask
}
if s.Reference != other.Reference {
return s.Reference == DefaultStencilState.Reference
}
if s.Fail != other.Fail {
return s.Fail == DefaultStencilState.Fail
}
if s.DepthFail != other.DepthFail {
return s.DepthFail == DefaultStencilState.DepthFail
}
if s.DepthPass != other.DepthPass {
return s.DepthPass == DefaultStencilState.DepthPass
}
if s.Cmp != other.Cmp {
return s.Cmp == DefaultStencilState.Cmp
}
return true
}
// The default stencil state that should be used for graphics objects.
var DefaultStencilState = StencilState{
WriteMask: 0xFFFF,
Fail: SKeep,
DepthFail: SKeep,
DepthPass: SKeep,
Cmp: Always,
}
// StencilOp represents a single stencil operation to occur when the stencil
// function passes, like SKeep, SReplace, etc.
type StencilOp uint8
const (
// SKeep keeps the existing stencil data.
SKeep StencilOp = iota
// SZero sets the stencil data to zero.
SZero
// SReplace replaces the existing stencil data with the stencil reference
// value.
SReplace
// SIncr increments the stencil value by one and clamps the result.
SIncr
// SIncrWrap increments the stencil value by 1 and wraps the result if
// necessary.
SIncrWrap
// SDecr decrements the stencil value by one and clamps the result.
SDecr
// SDecrWrap decrements the stencil value by 1 and wraps the result if
// necessary.
SDecrWrap
// SInvert inverts the stencil data.
SInvert
)