3.6.3同步修正

This commit is contained in:
lujun 2023-03-21 22:56:22 +08:00
parent d52561ee76
commit 76563d4c40
5 changed files with 174 additions and 122 deletions

View File

@ -125,7 +125,7 @@ UI.prototype.update = function() {
} }
} }
UI.prototype.walk = function(node: Node, level = 0, sortingPriority = 0){ UI.prototype.walk = function(node: Node, level = 0, sortingPriority = 0, sortingLevel = 0){
if (!node.activeInHierarchy) { if (!node.activeInHierarchy) {
return; return;
} }
@ -135,6 +135,9 @@ UI.prototype.walk = function(node: Node, level = 0, sortingPriority = 0){
const stencilEnterLevel = render && (render.stencilStage === _cocos_2d_renderer_stencil_manager__Stage.ENTER_LEVEL || render.stencilStage === _cocos_2d_renderer_stencil_manager__Stage.ENTER_LEVEL_INVERTED); const stencilEnterLevel = render && (render.stencilStage === _cocos_2d_renderer_stencil_manager__Stage.ENTER_LEVEL || render.stencilStage === _cocos_2d_renderer_stencil_manager__Stage.ENTER_LEVEL_INVERTED);
const transform = uiProps.uiTransformComp; const transform = uiProps.uiTransformComp;
sortingPriority = (transform && transform._sortingEnabled) ? transform._sortingPriority : sortingPriority; sortingPriority = (transform && transform._sortingEnabled) ? transform._sortingPriority : sortingPriority;
if((transform && transform._sortingEnabled)){
++sortingLevel;
}
// Save opacity // Save opacity
const parentOpacity = this._pOpacity; const parentOpacity = this._pOpacity;
@ -152,38 +155,49 @@ UI.prototype.walk = function(node: Node, level = 0, sortingPriority = 0){
// Render assembler update logic // Render assembler update logic
if (render && render.enabledInHierarchy) { if (render && render.enabledInHierarchy) {
if(stencilEnterLevel){ if(sortingLevel > 0){
this.flushRendererCache(); if(stencilEnterLevel){
this.flushRendererCache();
render.fillBuffers(this);// for rendering
render.fillBuffers(this);// for rendering
// Update cascaded opacity to vertex buffer
if (this._opacityDirty && render && !render.useVertexOpacity && render.renderData && render.renderData.vertexCount > 0) { // Update cascaded opacity to vertex buffer
// HARD COUPLING if (this._opacityDirty && render && !render.useVertexOpacity && render.renderData && render.renderData.vertexCount > 0) {
updateOpacity(render.renderData, opacity); // HARD COUPLING
updateOpacity(render.renderData, opacity);
const buffer = render.renderData.getMeshBuffer();
if (buffer) {
buffer.setDirty();
}
}
}else{
this.rendererCache.push(render);
render.renderPriority = sortingPriority;
if(sortingPriority != 0){
this.rendererOrder = true;
}
if (this._opacityDirty && render && !render.useVertexOpacity && render.renderData && render.renderData.vertexCount > 0) {
render.renderOpacity = opacity;
}else{
render.renderOpacity = -1;
}
}
}else{
render.fillBuffers(this);
if(render.renderOpacity >= 0){
updateOpacity(render.renderData, render.renderOpacity);
const buffer = render.renderData.getMeshBuffer(); const buffer = render.renderData.getMeshBuffer();
if (buffer) { if (buffer) {
buffer.setDirty(); buffer.setDirty();
} }
} }
}else{
this.rendererCache.push(render);
render.renderPriority = sortingPriority;
if(sortingPriority != 0){
this.rendererOrder = true;
}
if (this._opacityDirty && render && !render.useVertexOpacity && render.renderData && render.renderData.vertexCount > 0) {
render.renderOpacity = opacity;
}else{
render.renderOpacity = -1;
}
} }
} }
if (children.length > 0 && !node._static) { if (children.length > 0 && !node._static) {
for (let i = 0; i < children.length; ++i) { for (let i = 0; i < children.length; ++i) {
const child = children[i]; const child = children[i];
this.walk(child, level, sortingPriority); this.walk(child, level, sortingPriority, sortingLevel);
} }
} }
@ -210,5 +224,12 @@ UI.prototype.walk = function(node: Node, level = 0, sortingPriority = 0){
} }
} }
if((transform && transform._sortingEnabled)){
--sortingLevel;
if(sortingLevel <= 0){
this.flushRendererCache();
}
}
level += 1; level += 1;
}; };

View File

@ -4,15 +4,11 @@
*/ */
export enum SortingLayer { export enum SortingLayer {
//-- 自定义,在此之上,小于 DEFAULT 的层级
/** /**
* UI渲染上的默认层级 ** *
*/ */
DEFAULT = 0, DEFAULT = 0,
//-- 自定义,在此之下,大于 DEFAULT 的层级
// 测试定义,可以直接移除 // 测试定义,可以直接移除
TEST_LIST_ITEM = 1, TEST_LIST_ITEM = 1,
} }

View File

@ -27,11 +27,11 @@
"_active": true, "_active": true,
"_components": [], "_components": [],
"_prefab": { "_prefab": {
"__id__": 57 "__id__": 58
}, },
"autoReleaseAssets": false, "autoReleaseAssets": false,
"_globals": { "_globals": {
"__id__": 58 "__id__": 59
}, },
"_id": "b977450f-1cd5-49fa-a8db-db655012dcf5" "_id": "b977450f-1cd5-49fa-a8db-db655012dcf5"
}, },
@ -226,20 +226,17 @@
"__id__": 10 "__id__": 10
}, },
{ {
"__id__": 25 "__id__": 26
}, },
{ {
"__id__": 38 "__id__": 39
}, },
{ {
"__id__": 50 "__id__": 51
} }
], ],
"_active": true, "_active": true,
"_components": [ "_components": [
{
"__id__": 53
},
{ {
"__id__": 54 "__id__": 54
}, },
@ -248,6 +245,9 @@
}, },
{ {
"__id__": 56 "__id__": 56
},
{
"__id__": 57
} }
], ],
"_prefab": null, "_prefab": null,
@ -335,7 +335,7 @@
"_priority": 1073741824, "_priority": 1073741824,
"_fov": 45, "_fov": 45,
"_fovAxis": 0, "_fovAxis": 0,
"_orthoHeight": 540, "_orthoHeight": 572.2718446601942,
"_near": 1, "_near": 1,
"_far": 2000, "_far": 2000,
"_color": { "_color": {
@ -380,10 +380,10 @@
"_active": true, "_active": true,
"_components": [ "_components": [
{ {
"__id__": 23 "__id__": 24
}, },
{ {
"__id__": 24 "__id__": 25
} }
], ],
"_prefab": null, "_prefab": null,
@ -430,10 +430,10 @@
"_active": true, "_active": true,
"_components": [ "_components": [
{ {
"__id__": 21 "__id__": 22
}, },
{ {
"__id__": 22 "__id__": 23
} }
], ],
"_prefab": null, "_prefab": null,
@ -479,9 +479,6 @@
], ],
"_active": true, "_active": true,
"_components": [ "_components": [
{
"__id__": 17
},
{ {
"__id__": 18 "__id__": 18
}, },
@ -490,6 +487,9 @@
}, },
{ {
"__id__": 20 "__id__": 20
},
{
"__id__": 21
} }
], ],
"_prefab": null, "_prefab": null,
@ -539,6 +539,9 @@
}, },
{ {
"__id__": 16 "__id__": 16
},
{
"__id__": 17
} }
], ],
"_prefab": null, "_prefab": null,
@ -651,6 +654,19 @@
"_isAlign": false, "_isAlign": false,
"_id": "ffVfT/P5RIArEX2omGD0B6" "_id": "ffVfT/P5RIArEX2omGD0B6"
}, },
{
"__type__": "5c8c9BaV+VA1Z3pK+Zsi3Cb",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 13
},
"_enabled": false,
"__prefab": null,
"_sortingLayer": 1,
"_orderInLayer": 0,
"_id": "e8aq1C6uNAm4TPNL5F2hkn"
},
{ {
"__type__": "cc.UITransform", "__type__": "cc.UITransform",
"_name": "", "_name": "",
@ -868,22 +884,22 @@
}, },
"_children": [ "_children": [
{ {
"__id__": 26 "__id__": 27
}, },
{ {
"__id__": 30 "__id__": 31
}, },
{ {
"__id__": 33 "__id__": 34
} }
], ],
"_active": false, "_active": false,
"_components": [ "_components": [
{ {
"__id__": 36 "__id__": 37
}, },
{ {
"__id__": 37 "__id__": 38
} }
], ],
"_prefab": null, "_prefab": null,
@ -920,19 +936,19 @@
"_name": "Label", "_name": "Label",
"_objFlags": 0, "_objFlags": 0,
"_parent": { "_parent": {
"__id__": 25 "__id__": 26
}, },
"_children": [], "_children": [],
"_active": true, "_active": true,
"_components": [ "_components": [
{
"__id__": 27
},
{ {
"__id__": 28 "__id__": 28
}, },
{ {
"__id__": 29 "__id__": 29
},
{
"__id__": 30
} }
], ],
"_prefab": null, "_prefab": null,
@ -969,7 +985,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 26 "__id__": 27
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -990,7 +1006,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 26 "__id__": 27
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1028,7 +1044,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 26 "__id__": 27
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1041,16 +1057,16 @@
"_name": "SpriteSplash", "_name": "SpriteSplash",
"_objFlags": 0, "_objFlags": 0,
"_parent": { "_parent": {
"__id__": 25 "__id__": 26
}, },
"_children": [], "_children": [],
"_active": true, "_active": true,
"_components": [ "_components": [
{ {
"__id__": 31 "__id__": 32
}, },
{ {
"__id__": 32 "__id__": 33
} }
], ],
"_prefab": null, "_prefab": null,
@ -1087,7 +1103,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 30 "__id__": 31
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1108,7 +1124,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 30 "__id__": 31
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1146,16 +1162,16 @@
"_name": "Label-001", "_name": "Label-001",
"_objFlags": 0, "_objFlags": 0,
"_parent": { "_parent": {
"__id__": 25 "__id__": 26
}, },
"_children": [], "_children": [],
"_active": true, "_active": true,
"_components": [ "_components": [
{ {
"__id__": 34 "__id__": 35
}, },
{ {
"__id__": 35 "__id__": 36
} }
], ],
"_prefab": null, "_prefab": null,
@ -1192,7 +1208,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 33 "__id__": 34
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1213,7 +1229,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 33 "__id__": 34
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1251,7 +1267,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 25 "__id__": 26
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1272,7 +1288,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 25 "__id__": 26
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1289,22 +1305,22 @@
}, },
"_children": [ "_children": [
{ {
"__id__": 39 "__id__": 40
}, },
{ {
"__id__": 42 "__id__": 43
}, },
{ {
"__id__": 45 "__id__": 46
} }
], ],
"_active": false, "_active": false,
"_components": [ "_components": [
{ {
"__id__": 48 "__id__": 49
}, },
{ {
"__id__": 49 "__id__": 50
} }
], ],
"_prefab": null, "_prefab": null,
@ -1341,16 +1357,16 @@
"_name": "Label", "_name": "Label",
"_objFlags": 0, "_objFlags": 0,
"_parent": { "_parent": {
"__id__": 38 "__id__": 39
}, },
"_children": [], "_children": [],
"_active": true, "_active": true,
"_components": [ "_components": [
{ {
"__id__": 40 "__id__": 41
}, },
{ {
"__id__": 41 "__id__": 42
} }
], ],
"_prefab": null, "_prefab": null,
@ -1387,7 +1403,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 39 "__id__": 40
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1408,7 +1424,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 39 "__id__": 40
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1446,16 +1462,16 @@
"_name": "SpriteSplash", "_name": "SpriteSplash",
"_objFlags": 0, "_objFlags": 0,
"_parent": { "_parent": {
"__id__": 38 "__id__": 39
}, },
"_children": [], "_children": [],
"_active": true, "_active": true,
"_components": [ "_components": [
{ {
"__id__": 43 "__id__": 44
}, },
{ {
"__id__": 44 "__id__": 45
} }
], ],
"_prefab": null, "_prefab": null,
@ -1492,7 +1508,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 42 "__id__": 43
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1513,7 +1529,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 42 "__id__": 43
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1551,16 +1567,16 @@
"_name": "Label-001", "_name": "Label-001",
"_objFlags": 0, "_objFlags": 0,
"_parent": { "_parent": {
"__id__": 38 "__id__": 39
}, },
"_children": [], "_children": [],
"_active": true, "_active": true,
"_components": [ "_components": [
{ {
"__id__": 46 "__id__": 47
}, },
{ {
"__id__": 47 "__id__": 48
} }
], ],
"_prefab": null, "_prefab": null,
@ -1597,7 +1613,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 45 "__id__": 46
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1618,7 +1634,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 45 "__id__": 46
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1656,7 +1672,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 38 "__id__": 39
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1677,7 +1693,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 38 "__id__": 39
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1696,10 +1712,10 @@
"_active": false, "_active": false,
"_components": [ "_components": [
{ {
"__id__": 51 "__id__": 52
}, },
{ {
"__id__": 52 "__id__": 53
} }
], ],
"_prefab": null, "_prefab": null,
@ -1736,7 +1752,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 50 "__id__": 51
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1757,7 +1773,7 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 50 "__id__": 51
}, },
"_enabled": true, "_enabled": true,
"__prefab": null, "__prefab": null,
@ -1885,7 +1901,7 @@
"__expectedType__": "cc.SpriteFrame" "__expectedType__": "cc.SpriteFrame"
} }
], ],
"listItemMax": 200, "listItemMax": 20,
"_id": "9fuu+PfOFHPqnvdYJwsexB" "_id": "9fuu+PfOFHPqnvdYJwsexB"
}, },
{ {
@ -1895,19 +1911,19 @@
{ {
"__type__": "cc.SceneGlobals", "__type__": "cc.SceneGlobals",
"ambient": { "ambient": {
"__id__": 59
},
"shadows": {
"__id__": 60 "__id__": 60
}, },
"_skybox": { "shadows": {
"__id__": 61 "__id__": 61
}, },
"fog": { "_skybox": {
"__id__": 62 "__id__": 62
}, },
"octree": { "fog": {
"__id__": 63 "__id__": 63
},
"octree": {
"__id__": 64
} }
}, },
{ {

View File

@ -102,18 +102,21 @@ void Batcher2d::syncRootNodesToNative(ccstd::vector<Node*>&& rootNodes) {
void Batcher2d::fillBuffersAndMergeBatches() { void Batcher2d::fillBuffersAndMergeBatches() {
for (auto* rootNode : _rootNodeArr) { for (auto* rootNode : _rootNodeArr) {
walk(rootNode, 1, true, 0); walk(rootNode, 1, true, 0, 0);
// CC_LOG_INFO("-------------- flushRendererCache 1 -------------- %d", _rootNodeArr.size()); // CC_LOG_INFO("-------------- flushRendererCache 1 -------------- %d", _rootNodeArr.size());
flushRendererCache(); // LCC_UI_SORTING_GROUP flushRendererCache(); // LCC_UI_SORTING_GROUP
generateBatch(_currEntity, _currDrawInfo); generateBatch(_currEntity, _currDrawInfo);
} }
} }
void Batcher2d::walk(Node* node, float parentOpacity, bool cacheEnable, float sortingPriority) { // NOLINT(misc-no-recursion) void Batcher2d::walk(Node* node, float parentOpacity, bool cacheEnable, float sortingPriority, int sortingLevel) { // NOLINT(misc-no-recursion)
if (!node->isActiveInHierarchy()) { if (!node->isActiveInHierarchy()) {
return; return;
} }
sortingPriority = node->isUISortingEnabled() ? node->getUISortingPriority() : sortingPriority; sortingPriority = node->isUISortingEnabled() ? node->getUISortingPriority() : sortingPriority;
if(node->isUISortingEnabled()){
++sortingLevel;
}
bool breakWalk = false; bool breakWalk = false;
auto* entity = static_cast<RenderEntity*>(node->getUserData()); auto* entity = static_cast<RenderEntity*>(node->getUserData());
@ -128,22 +131,31 @@ void Batcher2d::walk(Node* node, float parentOpacity, bool cacheEnable, float so
// LCC_UI_SORTING_GROUP // LCC_UI_SORTING_GROUP
if (entity->isEnabled()) { if (entity->isEnabled()) {
if(entity->getIsMask() || !cacheEnable){ if(sortingLevel > 0){
// CC_LOG_INFO("-------------- flushRendererCache 2 --------------"); if(entity->getIsMask() || !cacheEnable){
flushRendererCache(); // CC_LOG_INFO("-------------- flushRendererCache 2 --------------");
uint32_t size = entity->getRenderDrawInfosSize(); flushRendererCache();
for (uint32_t i = 0; i < size; i++) { uint32_t size = entity->getRenderDrawInfosSize();
auto* drawInfo = entity->getRenderDrawInfoAt(i); for (uint32_t i = 0; i < size; i++) {
handleDrawInfo(entity, drawInfo, node); auto* drawInfo = entity->getRenderDrawInfoAt(i);
} handleDrawInfo(entity, drawInfo, node);
entity->setVBColorDirty(false); }
}else{ entity->setVBColorDirty(false);
rendererCache.push_back(entity); }else{
entity->setRenderPriority(sortingPriority); rendererCache.push_back(entity);
if(sortingPriority != 0){ entity->setRenderPriority(sortingPriority);
rendererOrder = true; if(sortingPriority != 0){
} rendererOrder = true;
} }
}
}else{
uint32_t size = entity->getRenderDrawInfosSize();
for (uint32_t i = 0; i < size; i++) {
auto* drawInfo = entity->getRenderDrawInfoAt(i);
handleDrawInfo(entity, drawInfo, node);
}
entity->setVBColorDirty(false);
}
} }
if (entity->getRenderEntityType() == RenderEntityType::CROSSED) { if (entity->getRenderEntityType() == RenderEntityType::CROSSED) {
@ -156,7 +168,7 @@ void Batcher2d::walk(Node* node, float parentOpacity, bool cacheEnable, float so
float thisOpacity = entity ? entity->getOpacity() : parentOpacity; float thisOpacity = entity ? entity->getOpacity() : parentOpacity;
for (const auto& child : children) { for (const auto& child : children) {
// we should find parent opacity recursively upwards if it doesn't have an entity. // we should find parent opacity recursively upwards if it doesn't have an entity.
walk(child, thisOpacity, cacheEnable, sortingPriority); walk(child, thisOpacity, cacheEnable, sortingPriority, sortingLevel);
} }
} }
@ -164,6 +176,13 @@ void Batcher2d::walk(Node* node, float parentOpacity, bool cacheEnable, float so
if (_stencilManager->getMaskStackSize() > 0 && entity && entity->isEnabled()) { if (_stencilManager->getMaskStackSize() > 0 && entity && entity->isEnabled()) {
handlePostRender(entity); handlePostRender(entity);
} }
if(node->isUISortingEnabled()){
--sortingLevel;
if(sortingLevel <= 0){
flushRendererCache();
}
}
} }
void Batcher2d::handlePostRender(RenderEntity* entity) { void Batcher2d::handlePostRender(RenderEntity* entity) {
@ -314,7 +333,7 @@ CC_FORCE_INLINE void Batcher2d::handleMiddlewareDraw(RenderEntity* entity, Rende
CC_FORCE_INLINE void Batcher2d::handleSubNode(RenderEntity* entity, RenderDrawInfo* drawInfo) { // NOLINT CC_FORCE_INLINE void Batcher2d::handleSubNode(RenderEntity* entity, RenderDrawInfo* drawInfo) { // NOLINT
if (drawInfo->getSubNode()) { if (drawInfo->getSubNode()) {
walk(drawInfo->getSubNode(), entity->getOpacity(), false, 0); walk(drawInfo->getSubNode(), entity->getOpacity(), false, 0, 0);
} }
} }

View File

@ -64,7 +64,7 @@ public:
void updateDescriptorSet(); void updateDescriptorSet();
void fillBuffersAndMergeBatches(); void fillBuffersAndMergeBatches();
void walk(Node* node, float parentOpacity, bool cacheEnable, float sortingPriority); void walk(Node* node, float parentOpacity, bool cacheEnable, float sortingPriority, int sortingLevel);
void handlePostRender(RenderEntity* entity); void handlePostRender(RenderEntity* entity);
void handleDrawInfo(RenderEntity* entity, RenderDrawInfo* drawInfo, Node* node); void handleDrawInfo(RenderEntity* entity, RenderDrawInfo* drawInfo, Node* node);
void handleComponentDraw(RenderEntity* entity, RenderDrawInfo* drawInfo, Node* node); void handleComponentDraw(RenderEntity* entity, RenderDrawInfo* drawInfo, Node* node);