热门IT资讯网

简述CCNode和Sprite的渲染过程

发表于:2024-11-25 作者:热门IT资讯网编辑
编辑最后更新 2024年11月25日,Sprite创建时,加载纹理,产生纹理id。Sprite重写(override)Node中的drawvoid Sprite::draw(Renderer *renderer, const Mat4 &

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();------------------渲染所有节点

0