Skip to content

Commit 816289c

Browse files
Mee-guminggo
authored andcommitted
fix clipping node issue (#20100)
Children are not correctly clipped.
1 parent d1abfd8 commit 816289c

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

cocos/2d/CCClippingNode.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,10 @@ void ClippingNode::visit(Renderer *renderer, const Mat4 &parentTransform, uint32
199199
if (alphaThreshold < 1)
200200
{
201201
auto programState = new (std::nothrow) backend::ProgramState(positionTextureColor_vert, positionTextureColorAlphaTest_frag);
202-
_stencil->setProgramState(programState);
203202
auto alphaLocation = programState->getUniformLocation("u_alpha_value");
204203
programState->setUniform(alphaLocation, &alphaThreshold, sizeof(alphaThreshold));
204+
setProgramStateRecursively(_stencil, programState);
205+
205206
CC_SAFE_RELEASE_NULL(programState);
206207
}
207208
_stencil->visit(renderer, _modelViewTransform, flags);
@@ -309,7 +310,13 @@ void ClippingNode::setStencil(Node *stencil)
309310
}
310311

311312
if (_stencil != nullptr)
312-
_originalStencilProgramState = _stencil->getProgramState();
313+
{
314+
_originalStencilProgramState[_stencil] = _stencil->getProgramState();
315+
auto& children = _stencil->getChildren();
316+
for (const auto &child : children) {
317+
_originalStencilProgramState[child] = child->getProgramState();
318+
}
319+
}
313320
}
314321

315322
bool ClippingNode::hasContent() const
@@ -328,7 +335,7 @@ void ClippingNode::setAlphaThreshold(float alphaThreshold)
328335
{
329336
// should reset program used by _stencil
330337
if (_stencil)
331-
_stencil->setProgramState(_originalStencilProgramState);
338+
restoreAllProgramStates();
332339
}
333340
_stencilStateManager->setAlphaThreshold(alphaThreshold);
334341
}
@@ -343,5 +350,26 @@ void ClippingNode::setInverted(bool inverted)
343350
_stencilStateManager->setInverted(inverted);
344351
}
345352

353+
void ClippingNode::setProgramStateRecursively(Node* node, backend::ProgramState* programState)
354+
{
355+
_originalStencilProgramState[node] = node->getProgramState();
356+
node->setProgramState(programState);
357+
358+
auto& children = node->getChildren();
359+
for (const auto &child : children) {
360+
setProgramStateRecursively(child, programState);
361+
}
362+
}
363+
364+
void ClippingNode::restoreAllProgramStates()
365+
{
366+
for (auto item : _originalStencilProgramState)
367+
{
368+
auto node = item.first;
369+
auto programState = item.second;
370+
node->setProgramState(programState);
371+
}
372+
}
373+
346374

347375
NS_CC_END

cocos/2d/CCClippingNode.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#include "renderer/CCGroupCommand.h"
3232
#include "renderer/CCCustomCommand.h"
3333
#include "renderer/CCCallbackCommand.h"
34-
34+
#include <unordered_map>
3535
NS_CC_BEGIN
3636

3737
class StencilStateManager;
@@ -154,14 +154,17 @@ class CC_DLL ClippingNode : public Node
154154
virtual bool init(Node *stencil);
155155

156156
protected:
157+
void setProgramStateRecursively(Node* node, backend::ProgramState* programState);
158+
void restoreAllProgramStates();
159+
157160
Node* _stencil = nullptr;
158161
StencilStateManager* _stencilStateManager = nullptr;
159162

160163
GroupCommand _groupCommandStencil;
161164
GroupCommand _groupCommandChildren;
162165
CallbackCommand _afterDrawStencilCmd;
163166
CallbackCommand _afterVisitCmd;
164-
backend::ProgramState* _originalStencilProgramState = nullptr;
167+
std::unordered_map<Node*, backend::ProgramState*> _originalStencilProgramState;
165168

166169
private:
167170
CC_DISALLOW_COPY_AND_ASSIGN(ClippingNode);

0 commit comments

Comments
 (0)