简述CCNode和Sprite的渲染过程

页面导航:首页 > 软件编程 > Java编程 > 简述CCNode和Sprite的渲染过程

简述CCNode和Sprite的渲染过程

来源: 作者: 时间:2016-01-18 15:52 【

Sprite创建时,加载纹理,产生纹理id。Sprite重写(override)Node中的drawvoid Sprite::draw(Renderer *renderer, const Mat4 transform, uint32_t flags){ // Don#39;t do calculate the c...
Sprite创建时,加载纹理,产生纹理id。Sprite重写(override)Node中的draw
void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
    // Don't do calculate the culling if the transform was not updated
    _insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;

    if(_insideBounds)
    {
        _quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform);
        renderer->addCommand(&_quadCommand);
#if CC_SPRITE_DEBUG_DRAW
        _debugDrawNode->clear();
        Vec2 vertices[4] = {
            Vec2( _quad.bl.vertices.x, _quad.bl.vertices.y ),
            Vec2( _quad.br.vertices.x, _quad.br.vertices.y ),
            Vec2( _quad.tr.vertices.x, _quad.tr.vertices.y ),
            Vec2( _quad.tl.vertices.x, _quad.tl.vertices.y ),
        };
        _debugDrawNode->drawPoly(vertices, 4, true, Color4F(1.0, 1.0, 1.0, 1.0));
#endif //CC_SPRITE_DEBUG_DRAW
    }
}

 

将对应的顶点信息,纹理id,视图矩阵加入render队列。
draw函数在什么时候被调用?
请看Node中的visit函数
void Node::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t parentFlags)
{
    // quick return if not visible. children won't be drawn.
    if (!_visible)
    {
        return;
    }

    uint32_t flags = processParentFlags(parentTransform, parentFlags);

    // IMPORTANT:
    // To ease the migration to v3.0, we still support the Mat4 stack,
    // but it is deprecated and your code should not rely on it
    Director* director = Director::getInstance();
    director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
    
    bool visibleByCamera = isVisitableByVisitingCamera();

    int i = 0;

    if(!_children.empty())
    {
        sortAllChildren();
        // draw children zOrder < 0
        for( ; i < _children.size(); i++ )
        {
            auto node = _children.at(i);

            if ( node && node->_localZOrder < 0 )
                node->visit(renderer, _modelViewTransform, flags);
            else
                break;
        }
        // self draw
        if (visibleByCamera)
            this->draw(renderer, _modelViewTransform, flags);

        for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
            (*it)->visit(renderer, _modelViewTransform, flags);
    }
    else if (visibleByCamera)
    {
        this->draw(renderer, _modelViewTransform, flags);
    }

    director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    
    // FIX ME: Why need to set _orderOfArrival to 0??
    // Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920
    // reset for next frame
    // _orderOfArrival = 0;
}

 

visit首先根据zorder排列子节点,先调用zorder大于0的子节点的draw函数,再调用自身的draw,接着再调用zorder小于0的子节点的draw函数,最后渲染时,按照render中队列的先后顺序,渲染所有节点。
void Director::drawScene()
{
  if (_runningScene)
    {
        //clear draw stats
        _renderer->clearDrawStats();
        
        //render the scene
        _runningScene->render(_renderer);---------调用所有节点的visit和draw函数,添加节点渲染信息到渲染队列中
        
        _eventDispatcher->dispatchEvent(_eventAfterVisit);
    }

    // draw the notifications node
    if (_notificationNode)
    {
        _notificationNode->visit(_renderer, Mat4::IDENTITY, 0);
    }

    if (_displayStats)
    {
        showStats();
    }
    _renderer->render();------------------渲染所有节点

 


Tags:

文章评论

最 近 更 新
热 点 排 行
Js与CSS工具
代码转换工具

<