COCOS2DX引擎深入三———渲染結構(3.0)

 3.0之前cocos2dx渲染機制上存在着一些弊端:不易擴展,不易針對繪製進行優化。

不易擴展:3.0之前每個元素的繪製邏輯全在元素元素內部的draw()方法裏。繪製順序緊密的依賴於UI樹。導致無法在多層級之間調整繪製順序。

不易針對繪製進行優化:各個繪製都分佈在每個元素內部,不利於針對繪製進行優化。

3.0新的繪製系統將繪製部分從UI樹的遍歷中分離出來了。使得繪製系統更靈活,更易於擴展。 

 

 新的繪製系統是怎麼將繪製部分分離出來的?

 3.0版本中多了一個RanderCommand類。另外draw接口也變了

 virtual void draw(Renderer *renderer, const Mat4& transform, uint32_t flags);

 Node類的draw是空實現,再看看sprite類裏的draw方法。

               

void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
    // 檢查是否在邊界內
    _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
        _customDebugDrawCommand.init(_globalZOrder);
        _customDebugDrawCommand.func = CC_CALLBACK_0(Sprite::drawDebugData, this);
        renderer->addCommand(&_customDebugDrawCommand);
#endif //CC_SPRITE_DEBUG_DRAW
    }
}


draw裏初始化了一條QuadCommand,他繼承於RanderCommand。之後再將這條命令加入到Render中。並沒有執行繪製相關操作。

 在看到Director類的drawScene()方法

               

    // draw the scene
    if (_runningScene)
    {
        _runningScene->visit(_renderer, Mat4::IDENTITY, false);
        _eventDispatcher->dispatchEvent(_eventAfterVisit);
    }

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

    if (_displayStats)
    {
        showStats();
    }

    _renderer->render();
    _eventDispatcher->dispatchEvent(_eventAfterDraw);


當調用完節點的visit   (visit裏面會調用節點的draw方法)後,就調用了Render的render方法。到這裏就可以看出,其實draw裏的繪製操作,統一的都以命令的形式統一的加入到render裏面,有render來統一處理。於是繪製部分的處理,就從UI樹的遍歷裏分離了出來,這樣如果想針對繪製進行優化,那麼直接操作幾個繪製類就行了。例如cocos2dx會對QuadCommand執行自動批繪製。

 

在看到Render的render方法裏具體做了什麼。

 

void Renderer::render()
{
    //Uncomment this once everything is rendered by new renderer
    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //TODO setup camera or MVP
    _isRendering = true;
    
    if (_glViewAssigned)
    {
        // cleanup
        _drawnBatches = _drawnVertices = 0;

        //Process render commands
        //1. Sort render commands based on ID
        for (auto &renderqueue : _renderGroups)
        {
            renderqueue.sort();
        }
        visitRenderQueue(_renderGroups[0]);
        flush();
    }
    clean();
    _isRendering = false;
}


 首先對命令進行了排序,之後纔是對節點進行繪製工作。

 

 

 

 

                 

               

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章