Why DrawNode outside of screen increase GL calls?

Why DrawNode outside of screen increase GL calls?
For below code I have “GL calls:1000” but only 7 draw node are on screen.

    float step = 100;
    for (int i = 0; i < 1000; ++i)
    {
        auto posXY = static_cast<float>(i);
        auto s1 = cocos2d::DrawNode::create();
        s1->drawDot({}, 1, cocos2d::Color4F::BLACK);
        s1->setPosition(cocos2d::Vec2{posXY, posXY} * step);
        auto s = s1->getContentSize();
        layer->addChild(s1);
    }

For the same code with Sprite everything works as expected “GL calls:14” (only 14 Sprite are drawn rest are outside of screen)

    float step = 100;
    for (int i = 0; i < 1000; ++i)
    {
        auto posXY = static_cast<float>(i) * step;
        auto s1 = cocos2d::Sprite::create("arrow.png");
        s1->setPosition(cocos2d::Vec2{posXY, posXY});
        layer->addChild(s1);
        // second sprite to break batching
        auto s2 = cocos2d::Sprite::create("back_button.png");
        s2->setPosition(cocos2d::Vec2{posXY, posXY});
        layer->addChild(s2);
    }

Regards,
Chp

Sprite nodes are culled (not drawn when off screen), but DrawNode nodes are probably not, probably because they don’t keep track of the area in which shapes are drawn. (DrawNode always has a content size of (0,0). A quick look at the cocos source code and it looks like it might only be Sprite and Label nodes that are culled.)

If you add 1 DrawNode to your scene and draw all your dots on it, then it seems to only use 1 draw call, e.g.

float step = 100;

auto s1 = cocos2d::DrawNode::create();
layer->addChild(s1);

for (int i = 0; i < 1000; ++i)
{
	auto posXY = static_cast<float>(i);		
	s1->drawDot(Vec2{posXY, posXY} * step, 1, cocos2d::Color4F::BLACK);
}
1 Like

@grimfate Thank you for answer.
One DrawNode it is not an option for me. I have to have many `DrawNode. I run different actions/animations on each.
I found workarund setVisible(false);

@zhangxm is it bug or feature that DrawNode is drawn even when off screen ?

Regards,
Chp

Yep, Sprite do culling as it is easy to do culling for Sprite. DrawNode can draw lines, circles, and many other different shapes. It is hard to do culling for DrawNode. Of course, you can do it yourself as you know the area of DrawNode.

Could you give me a hint, sample code how to do this if I know position and size?
I have already subclass
class MyDrawNode : public cocos2d::DrawNode
What should be implementation?
Regards,
Chp

You can refer to Renderer::checkVisibility. Just pass the size and transform to the function, it will return the result.

@zhangxm Thank you!

FYI. This is my implementation base on void Sprite::draw

void AwesomeNode::draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t flags)
{
    // Don't do calculate the culling if the transform was not updated
    bool transformUpdated = flags & FLAGS_TRANSFORM_DIRTY;
#if CC_USE_CULLING
    auto visitingCamera = cocos2d::Camera::getVisitingCamera();
    auto defaultCamera = cocos2d::Camera::getDefaultCamera();
    if (visitingCamera == defaultCamera)
    {
        _insideBounds = (transformUpdated || visitingCamera->isViewProjectionUpdated())
                            ? renderer->checkVisibility(transform, _contentSize)
                            : _insideBounds;
    }
    else
    {
        _insideBounds = renderer->checkVisibility(transform, _contentSize);
    }

    if (_insideBounds)
#endif
    {
        cocos2d::DrawNode::draw(renderer, transform, flags);
    }
}
1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.