Skip to content

Commit d8cd5c4

Browse files
authored
Implement fallback scissor in CCClippingNode::visit (#1556)
Added fallback scissor rendering when stencil buffer is disabled.
1 parent ef401d5 commit d8cd5c4

File tree

1 file changed

+42
-8
lines changed

1 file changed

+42
-8
lines changed

loader/src/cocos2d-ext/CCClippingNode.cpp

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,6 @@ void CCClippingNode::onExit()
116116

117117
void CCClippingNode::visit()
118118
{
119-
// if stencil buffer disabled
120-
if (g_sStencilBits < 1)
121-
{
122-
// draw everything, as if there where no stencil
123-
CCNode::visit();
124-
return;
125-
}
126-
127119
// return fast (draw nothing, or draw everything if in inverted mode) if:
128120
// - nil stencil node
129121
// - or stencil node invisible:
@@ -137,6 +129,48 @@ void CCClippingNode::visit()
137129
return;
138130
}
139131

132+
// if stencil buffer disabled, we will instead scissor as fallback
133+
if (g_sStencilBits < 1)
134+
{
135+
CCRect rect = m_pStencil->boundingBox();
136+
// on the rare occassion that its 0,0
137+
if (rect.size.width <= 0 || rect.size.width <= 0) {
138+
CCSize size = this->getContentSize();
139+
CCPoint pos = m_pStencil->getPosition();
140+
if (size.width <= 0 || size.height <= 0) {
141+
if (this->getParent()) {
142+
size = this->getParent()->getContentSize();
143+
pos = this->getPosition();
144+
}
145+
}
146+
rect = CCRectMake(pos.x, pos.y, size.width, size.height);
147+
}
148+
if (rect.size.width <= 0 || rect.size.width <= 0) {
149+
// we cannot properly render it, so we will fallback to rendering all of it
150+
CCNode::visit();
151+
return;
152+
}
153+
154+
int previousRect[4];
155+
bool previousScissor = glIsEnabled(GL_SCISSOR_TEST);
156+
if (previousScissor) {
157+
glGetIntegerv(GL_SCISSOR_BOX, previousRect);
158+
} else {
159+
glEnable(GL_SCISSOR_TEST);
160+
}
161+
auto const bottomLeft = this->convertToWorldSpace(rect.origin);
162+
auto const topRight = this->convertToWorldSpace(ccp(rect.getMaxX(), rect.getMaxY()));
163+
CCSize const size = topRight - bottomLeft;
164+
CCEGLView::get()->setScissorInPoints(bottomLeft.x, bottomLeft.y, size.width, size.height);
165+
CCNode::visit();
166+
if (previousScissor) {
167+
glScissor(previousRect[0], previousRect[1], previousRect[2], previousRect[3]);
168+
} else {
169+
glDisable(GL_SCISSOR_TEST);
170+
}
171+
return;
172+
}
173+
140174
// store the current stencil layer (position in the stencil buffer),
141175
// this will allow nesting up to n CCClippingNode,
142176
// where n is the number of bits of the stencil buffer.

0 commit comments

Comments
 (0)