Clipping issue migrating from CC2 to CC3

Hello there,

I’m using the C++ versions of cocos.
While migrating my project from cocos v2.x to cocos v3.1.1 I had an issue concerning clipping
and I’m not sure to completely understand the new cocos v3 rendering mechanics.

With cocos v2, I had a custom class inherited from CCNode having the ability to clip its children nodes.
To do that, I overrode the void visit() method of CCNode this way :

void CCCustomNode::visit()
        {
            if (_clipped)
            {
                glEnable(GL_SCISSOR_TEST);
                CCPoint p = this->convertToWorldSpace(_clip.origin);
                glScissor(p.x,p.y,_clip.size.width,_clip.size.height);
            }
            
            CCNode::visit();

            if (_clipped)
            {
                glDisable(GL_SCISSOR_TEST);
            }
        }

so the CCNode::visit() is called while GL_SCISSOR_TEST state is active.

With cocos v3, I did the same, but I see no clipping on the screen and I don’t understand why :

void CustomNodeCC3::visit(cocos2d::Renderer* renderer, const cocos2d::Mat4& parentTransform, bool parentTransformUpdated)
        {
            if (_clipped)
            {
                glEnable(GL_SCISSOR_TEST);
                cocos2d::Point p = this->convertToWorldSpace(_clip.origin);
                glScissor(p.x,p.y,_clip.size.width,_clip.size.height);
            }
            
            Node::visit(renderer, parentTransform, parentTransformUpdated);
            
            if (_clipped)
            {
                glDisable(GL_SCISSOR_TEST);
            }
        }

What is new in the rendering process to prevent this from working like before ?
I don’t know how the new parameters of visit() should be used.
Again, my CustomNode has no texture, but should clip its children.
Thank you for your help. :wink:

and you are not getting an GL_INVALID_VALUE error correct?

Correct.
glGetError() always returns me GL_NO_ERROR after each gl call of the code I posted.

Yes, I see the problem.
In v3.0 we decoupled the Scene Graph ( visit() ) from the RenderGraph ( draw() ).

So, it is no longer valid to call OpenGL commands in the Scene Graph. Basically if you call any OpenGL command at visit() time, it won’t work.

So, what you have to do is to put your OpenGL commands in draw(). And since you are changing the state of the children, what you need is a GroupCommand and/or use a CustomCommand that does that.

Thank you Ricardo for those explanations!
I didn’t find a lot of documentation on that but I had a look to the ClippingNode class and I did that :
(_beforeVisitCmd and _afterVisitCmd are CustomCommand objects)

void CustomNodeCC3::onBeforeVisit()
{
    if (_clipped)
    {
        cocos2d::Point p = this->convertToWorldSpace(_clip.origin);
        glEnable(GL_SCISSOR_TEST);
        glScissor(p.x,p.y,_clip.size.width,_clip.size.height);
    }
}

void CustomNodeCC3::onAfterVisit()
{
    if (_clipped)
    {
        glDisable(GL_SCISSOR_TEST);
    }
}

void CustomNodeCC3::visit(cocos2d::Renderer* renderer, const cocos2d::Mat4& parentTransform, bool parentTransformUpdated)
{
    _beforeVisitCmd.init(_globalZOrder);
    _beforeVisitCmd.func = CC_CALLBACK_0(CustomNodeCC3::onBeforeVisit, this);
    renderer->addCommand(&_beforeVisitCmd);
    
    Node::visit(renderer, parentTransform, parentTransformUpdated);
    
    _afterVisitCmd.init(_globalZOrder);
    _afterVisitCmd.func = CC_CALLBACK_0(CustomNodeCC3::onAfterVisit, this);
    renderer->addCommand(&_afterVisitCmd);
}

Can you confirm that this way of using CustomCommand objects is correct please?
And could you explain quickly the difference between GroupCommand and CustomCommand ?
Also it may be cool to have a RectClippingNode in cocos 3.
(Just saying, because that’s what my custom class is :smile: )

I think you have got it. There was also a discussion here: Can no longer override draw function?

Thanks! I’ll check that.

Btw it was for the game Grub, which is released today : http://appstore.com/grub

The first version uses cocos2d v2.x but the first update will probably use cocos2d v3.1.1