cocos2dx 3.2 渲染(Director::drawScene 在游戏loop里每帧调用。 内部实际通过调用场景内每个node的 visit方法完成渲染)

Cocos2d-x 3.2与OpenGL渲染总结(一):Cocos2d-x 3.2的渲染流程

Node

    /**

     * Override this method to draw your own node.

     * The following GL states will be enabled by default:

     * - `glEnableClientState(GL_VERTEX_ARRAY);`

     * - `glEnableClientState(GL_COLOR_ARRAY);`

     * - `glEnableClientState(GL_TEXTURE_COORD_ARRAY);`

     * - `glEnable(GL_TEXTURE_2D);`

     * AND YOU SHOULD NOT DISABLE THEM AFTER DRAWING YOUR NODE

     * But if you enable any other GL state, you should disable it after drawing your node.

     */

   virtual void Node::draw(Renderer *renderer, constMat4& transform,uint32_t flags);

{

    auto renderer = Director::getInstance()->getRenderer();

    draw(renderer, _modelViewTransform, true);

}


    virtual voidNode::draw() final;

{

}


    /**

     * Visits this node's children and draw them recursively.

     */

    virtual voidNode::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);

/

 &按位与 | 按位或  


uint32_t Node::processParentFlags(const Mat4& parentTransform, uint32_t parentFlags)

{

    uint32_t flags = parentFlags;

    flags |= (_transformUpdated ? FLAGS_TRANSFORM_DIRTY : 0);

    flags |= (_contentSizeDirty ? FLAGS_CONTENT_SIZE_DIRTY : 0);


    if(_usingNormalizedPosition && (flags & FLAGS_CONTENT_SIZE_DIRTY)) {

        CCASSERT(_parent, "setNormalizedPosition() doesn't work with orphan nodes");

        auto s = _parent->getContentSize();

        _position.x = _normalizedPosition.x * s.width;

        _position.y = _normalizedPosition.y * s.height;

        _transformUpdated = _transformDirty = _inverseDirty = true;

    }


    if(flags & FLAGS_DIRTY_MASK)

        _modelViewTransform = this->transform(parentTransform);


    _transformUpdated = false;

    _contentSizeDirty = false;


    return flags;

}


/


    // 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);


    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

        this->draw(renderer, _modelViewTransform, flags);


        for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)

            (*it)->visit(renderer, _modelViewTransform, flags);

    }

    else

    {

        this->draw(renderer, _modelViewTransform, flags);

    }


    director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);

}



   virtual voidNode::visit() final;

{

    auto renderer = Director::getInstance()->getRenderer();

    Mat4 parentTransform = Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);

    visit(renderer, parentTransform, true);

}



    /*

     * Update method will be called automatically every frame if "scheduleUpdate" is called, and the node is "live"

     */


virtual voidNode::update(float delta);

{

#if CC_ENABLE_SCRIPT_BINDING

    if (0 != _updateScriptHandler)

    {

        //only lua use

        SchedulerScriptData data(_updateScriptHandler,fDelta);

        ScriptEvent event(kScheduleEvent,&data);

        ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);

    }

#endif

    

    if (_componentContainer && !_componentContainer->isEmpty())

    {

        _componentContainer->visit(fDelta);  //node update 1   更新组件事件状态  

    }

}


    voidNode::scheduleUpdate(void);

    voidNode::scheduleUpdateWithPriority(int priority);




    Component* getComponent(const std::string& name);


virtual  bool Node::addComponent(Component *component)

{

    // lazy alloc

    if( !_componentContainer )

        _componentContainer = new ComponentContainer(this);

    return _componentContainer->add(component);

}


    virtual bool removeComponent(const std::string& name);


    virtual void removeAllComponents();

protected:

ComponentContainer *_componentContainer;  


————————————————————————————————————————————————————————————————————————————————————ponent

ComponentContainer


ComponentContainer::ComponentContainer(Node *pNode);


virtual void ComponentContainer::visit(float delta);  //node update 2

{

    if (_components != nullptr)

    {

        CC_SAFE_RETAIN(_owner);

        for (auto iter = _components->begin(); iter != _components->end(); ++iter)

        {

            iter->second->update(delta);    //node update 3 

        }

        CC_SAFE_RELEASE(_owner);

    }

}


private:

    Map<std::string, Component*>* _components;

    Node *_owner;

    

    friend class Node;


————————————————————————————————————————————————————————————————————————————————————

Component


#if CC_ENABLE_SCRIPT_BINDING


static bool sendComponentEventToJS(Component* node, int action) //作用域文件内可用 生存期全局 

{

    auto scriptEngine = ScriptEngineManager::getInstance()->getScriptEngine();

    

    if (scriptEngine->isCalledFromScript())

    {

        scriptEngine->setCalledFromScript(false);

    }

    else

    {

        BasicScriptData data(node,(void*)&action);

        ScriptEvent scriptEvent(kComponentEvent,(void*)&data);

        if (scriptEngine->sendEvent(&scriptEvent))

            return true;

    }

    

    return false;

}


#endif

virtual void Component::update(float delta)  //node update 4 

{

#if CC_ENABLE_SCRIPT_BINDING

    if (_scriptType == kScriptTypeJavascript)

    {

        if (sendComponentEventToJS(this, kComponentOnUpdate)) //将组件绑定node 组件事件触发时通知js 有时间细看

            return;

    }

#endif

}

protected:

    Node *_owner;

    std::string _name;

    bool _enabled;


————————————————————————————————————————————————————————————————————————————————————

CCDirector(Director::drawScene 在游戏loop里每帧调用。 内部实际通过调用场景内每个node的 visit方法完成渲染

    /** Draw the scene.

    This method is called every frame. Don't call it manually.

    */

// Draw the Scene

void Director::drawScene()

{

    // calculate "global" dt

    calculateDeltaTime();

    

    // skip one flame when _deltaTime equal to zero.

    if(_deltaTime < FLT_EPSILON)

    {

        return;

    }


    if (_openGLView)

    {

       _openGLView->pollInputEvents(); 

    /**

     * Polls input events. Subclass must implement methods if platform

     * does not provide event callbacks.

     */

    virtual void pollInputEvents();

    }


    //tick before glClear: issue #533

    if (! _paused)                                //只要游戏没有暂停,调度器神马的就会在这里被执

    {

        _scheduler->update(_deltaTime);

        _eventDispatcher->dispatchEvent(_eventAfterUpdate);

    }


   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除指定的缓冲区 (颜色缓冲以及深度缓冲)


    /* to avoid flickr(网络相簿), nextScene MUST be here: after tick and before draw.

     XXX: Which bug is this one. It seems that it can't be reproduced(重现 重制的) with v0.9 */

    if (_nextScene)

    {

        setNextScene();

    }


    pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);//设置gl使用的矩阵类型

//

enum class MATRIX_STACK_TYPE

{

    MATRIX_STACK_MODELVIEW,

    MATRIX_STACK_PROJECTION,

    MATRIX_STACK_TEXTURE

};


  OpenGL 的ModelView矩阵 


/


    // draw the scene

    if (_runningScene)

    {

//visit() 这个函数在cocos3.2工程内部基本没用到了 被visit(_rendererMat4::IDENTITYfalse)取代

        _runningScene->visit(_renderer, Mat4::IDENTITY, false); 

    

/** Dispatches(调度) the event

     *  Also removes all EventListeners marked for deletion(删除) from the

     *  event dispatcher list.

     */

_eventDispatcher->dispatchEvent(_eventAfterVisit);//visit完成后调度事件  cocos3.2貌似什么都没做

    }


    // draw the notifications node

    if (_notificationNode)

    {

        _notificationNode->visit(_renderer, Mat4::IDENTITY, false);

    }


    if (_displayStats)

    {

        showStats();

    }


    _renderer->render();

    _eventDispatcher->dispatchEvent(_eventAfterDraw); //Draw完成后调度事件  cocos3.2貌似什么都没做


    popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);


    _totalFrames++;


    // swap buffers

    if (_openGLView)

    {

        _openGLView->swapBuffers();

    }


    if (_displayStats)

    {

        calculateMPF();

    }

}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值