Cocos2d-x Source Code read UI tree 2, cocos2d-x source code ui tree
The UI of the Cocos2d-x is organized according to the tree structure.
If you have learned the data structure, you will know what a tree is.
A tree has only one root node. The root node does not have a parent node. Other nodes have a parent node and a child node. A leaf node does not have a child node. A leaf node is a node without a child node.
Here, both the parent and the child are opposite.
We know that there are three ways to traverse the tree structure, that is, to traverse is to find the meaning of each node, forward, middle, and backward.
The so-called "front" and "back" refer to the root node. traverse the root node first is the front node, then traverse is the final root node, and "middle traversal" is the middle traversal.
Therefore, the first traversal is 0,-1,-3, 3, 2,-4, 4.
If the traversal in the middle order is-3,-, 0,-4, 2, 4
Post-order traversal is-3, 3,-1-4, 4, 2, 0
Cocos2dx adopts the Middle-order traversal.
UI coordinates, colors, and bending are required when the UI is drawn.
The coordinates required for drawing the UI are the world coordinates. But we provide a local coordinate system, so we need to convert it into a world coordinate system. Use a transformation matrix. Provided to shader.
The visit function is used for plotting.
Void Node: visit ()
{
Auto renderer = Director: getInstance ()-> getRenderer (); // get the renderer
Mat4 parentTransform = Director: getInstance ()-> getMatrix (MATRIX_STACK_TYPE: MATRIX_STACK_MODELVIEW); // obtain the transformation matrix of the world coordinate system
Visit (renderer, parentTransform, true); // Rendering
}
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); // here processParentFlags is passed into the function as a parameter. It must be processed. If you see the red parameter, it is processed here.
// IMPORTANT:
// To handle the migration to v3.0, we still support the Mat4 stack,
// But it is deprecated and your code shocould not rely on it
Director * director = Director: getInstance ();
Director-> pushMatrix (MATRIX_STACK_TYPE: MATRIX_STACK_MODELVIEW); // push
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); // Recursion
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); // Recursion
}
Else if (visibleByCamera)
{
This-> draw (renderer, _ modelViewTransform, flags );
}
Director-> popMatrix (MATRIX_STACK_TYPE: MATRIX_STACK_MODELVIEW); // pop
// 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;
}
Uint32_t Node: processParentFlags (const Mat4 & parentTransform, uint32_t parentFlags)
{
If (_ usingNormalizedPosition ){
CCASSERT (_ parent, "setNormalizedPosition () doesn't work with orphan nodes ");
If (parentFlags & FLAGS_CONTENT_SIZE_DIRTY) | _ normalizedPositionDirty ){
Auto s = _ parent-> getContentSize ();
_ Position. x = _ normalizedPosition. x * s. width;
_ Position. y = _ normalizedPosition. y * s. height;
_ TransformUpdated = _ transformDirty = _ inverseDirty = true;
_ NormalizedPositionDirty = false;
}
}
Uint32_t flags = parentFlags;
Flags | = (_ transformUpdated? FLAGS_TRANSFORM_DIRTY: 0 );
Flags | = (_ contentSizeDirty? FLAGS_CONTENT_SIZE_DIRTY: 0 );
If (flags & FLAGS_DIRTY_MASK)
_ ModelViewTransform = this-> transform (parentTransform); // Conversion
_ TransformUpdated = false;
_ ContentSizeDirty = false;
Return flags;
}
Mat4 Node: transform (const Mat4 & parentTransform)
{
Mat4 ret = this-> getNodeToParentTransform ();
Ret = parentTransform * ret;
Return ret;
}
The color and bending effect are not involved here, and only the position is related.