MyGUI
3.0.1
|
00001 00007 /* 00008 This file is part of MyGUI. 00009 00010 MyGUI is free software: you can redistribute it and/or modify 00011 it under the terms of the GNU Lesser General Public License as published by 00012 the Free Software Foundation, either version 3 of the License, or 00013 (at your option) any later version. 00014 00015 MyGUI is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public License 00021 along with MyGUI. If not, see <http://www.gnu.org/licenses/>. 00022 */ 00023 00024 #include "MyGUI_Precompiled.h" 00025 #include "MyGUI_LayerNode.h" 00026 #include "MyGUI_ILayerItem.h" 00027 #include "MyGUI_ITexture.h" 00028 #include "MyGUI_ISubWidget.h" 00029 #include "MyGUI_ISubWidgetText.h" 00030 00031 namespace MyGUI 00032 { 00033 00034 LayerNode::LayerNode(ILayer* _layer, ILayerNode* _parent) : 00035 mParent(_parent), 00036 mLayer(_layer), 00037 mOutOfDate(false) 00038 { 00039 } 00040 00041 LayerNode::~LayerNode() 00042 { 00043 for (VectorRenderItem::iterator iter=mFirstRenderItems.begin(); iter!=mFirstRenderItems.end(); ++iter) 00044 { 00045 delete (*iter); 00046 } 00047 mFirstRenderItems.clear(); 00048 00049 for (VectorRenderItem::iterator iter=mSecondRenderItems.begin(); iter!=mSecondRenderItems.end(); ++iter) 00050 { 00051 delete (*iter); 00052 } 00053 mSecondRenderItems.clear(); 00054 00055 // удаляем дочерние узлы 00056 for (VectorILayerNode::iterator iter = mChildItems.begin(); iter!=mChildItems.end(); ++iter) 00057 { 00058 delete (*iter); 00059 } 00060 mChildItems.clear(); 00061 } 00062 00063 ILayerNode* LayerNode::createChildItemNode() 00064 { 00065 LayerNode* layer = new LayerNode(mLayer, this); 00066 mChildItems.push_back(layer); 00067 return layer; 00068 } 00069 00070 void LayerNode::destroyChildItemNode(ILayerNode* _node) 00071 { 00072 for (VectorILayerNode::iterator iter=mChildItems.begin(); iter!=mChildItems.end(); ++iter) 00073 { 00074 if ((*iter) == _node) 00075 { 00076 delete _node; 00077 mChildItems.erase(iter); 00078 return; 00079 } 00080 } 00081 MYGUI_EXCEPT("item node not found"); 00082 } 00083 00084 void LayerNode::upChildItemNode(ILayerNode* _item) 00085 { 00086 for (VectorILayerNode::iterator iter=mChildItems.begin(); iter!=mChildItems.end(); ++iter) 00087 { 00088 if ((*iter) == _item) 00089 { 00090 mChildItems.erase(iter); 00091 mChildItems.push_back(_item); 00092 return; 00093 } 00094 } 00095 MYGUI_EXCEPT("item node not found"); 00096 } 00097 00098 void LayerNode::renderToTarget(IRenderTarget* _target, bool _update) 00099 { 00100 // проверяем на сжатие пустот 00101 bool need_compression = false; 00102 for (VectorRenderItem::iterator iter=mFirstRenderItems.begin(); iter!=mFirstRenderItems.end(); ++iter) 00103 { 00104 if ((*iter)->getCompression()) 00105 { 00106 need_compression = true; 00107 break; 00108 } 00109 } 00110 00111 if (need_compression) 00112 updateCompression(); 00113 00114 // сначала отрисовываем свое 00115 for (VectorRenderItem::iterator iter=mFirstRenderItems.begin(); iter!=mFirstRenderItems.end(); ++iter) 00116 { 00117 (*iter)->renderToTarget(_target, _update); 00118 } 00119 for (VectorRenderItem::iterator iter=mSecondRenderItems.begin(); iter!=mSecondRenderItems.end(); ++iter) 00120 { 00121 (*iter)->renderToTarget(_target, _update); 00122 } 00123 00124 // теперь отрисовываем дочерние узлы 00125 for (VectorILayerNode::iterator iter = mChildItems.begin(); iter!=mChildItems.end(); ++iter) 00126 { 00127 (*iter)->renderToTarget(_target, _update); 00128 } 00129 00130 mOutOfDate = false; 00131 } 00132 00133 ILayerItem* LayerNode::getLayerItemByPoint(int _left, int _top) 00134 { 00135 // сначала пикаем детей 00136 for (VectorILayerNode::iterator iter = mChildItems.begin(); iter!=mChildItems.end(); ++iter) 00137 { 00138 ILayerItem * item = (*iter)->getLayerItemByPoint(_left, _top); 00139 if (nullptr != item) return item; 00140 } 00141 00142 for (VectorLayerItem::iterator iter=mLayerItems.begin(); iter!=mLayerItems.end(); ++iter) 00143 { 00144 ILayerItem * item = (*iter)->getLayerItemByPoint(_left, _top); 00145 if (nullptr != item) return item; 00146 } 00147 00148 return nullptr; 00149 } 00150 00151 RenderItem* LayerNode::addToRenderItem(ITexture* _texture, ISubWidget* _item) 00152 { 00153 bool first = _item->castType<ISubWidgetText>(false) == nullptr; 00154 // для первичной очереди нужен порядок 00155 if (first) 00156 { 00157 if (mFirstRenderItems.empty()) 00158 { 00159 // создаем новый буфер 00160 RenderItem * item = new RenderItem(); 00161 item->setTexture(_texture); 00162 mFirstRenderItems.push_back(item); 00163 00164 return item; 00165 } 00166 00167 // если последний буфер пустой, то мона не создавать 00168 if (mFirstRenderItems.back()->getNeedVertexCount() == 0) 00169 { 00170 // пустых может быть сколько угодно, нужен самый первый из пустых 00171 for (VectorRenderItem::iterator iter=mFirstRenderItems.begin(); iter!=mFirstRenderItems.end(); ++iter) 00172 { 00173 if ((*iter)->getNeedVertexCount() == 0) 00174 { 00175 // а теперь внимание, если перед пустым наш, то его и юзаем 00176 if (iter != mFirstRenderItems.begin()) 00177 { 00178 VectorRenderItem::iterator prev = iter - 1; 00179 if ((*prev)->getTexture() == _texture) 00180 { 00181 return (*prev); 00182 } 00183 } 00184 (*iter)->setTexture(_texture); 00185 return (*iter); 00186 } 00187 } 00188 } 00189 00190 // та же текстура 00191 if (mFirstRenderItems.back()->getTexture() == _texture) 00192 { 00193 return mFirstRenderItems.back(); 00194 } 00195 00196 // создаем новый буфер 00197 RenderItem * item = new RenderItem(); 00198 item->setTexture(_texture); 00199 mFirstRenderItems.push_back(item); 00200 00201 return item; 00202 } 00203 00204 // для второй очереди порядок неважен 00205 for (VectorRenderItem::iterator iter=mSecondRenderItems.begin(); iter!=mSecondRenderItems.end(); ++iter) 00206 { 00207 // либо такая же текстура, либо пустой буфер 00208 if ((*iter)->getTexture() == _texture) 00209 { 00210 return (*iter); 00211 } 00212 else if ((*iter)->getNeedVertexCount() == 0) 00213 { 00214 (*iter)->setTexture(_texture); 00215 return (*iter); 00216 } 00217 00218 } 00219 // не найденно создадим новый 00220 RenderItem * item = new RenderItem(); 00221 item->setTexture(_texture); 00222 00223 mSecondRenderItems.push_back(item); 00224 return mSecondRenderItems.back(); 00225 } 00226 00227 void LayerNode::attachLayerItem(ILayerItem* _item) 00228 { 00229 mLayerItems.push_back(_item); 00230 _item->attachItemToNode(mLayer, this); 00231 } 00232 00233 void LayerNode::detachLayerItem(ILayerItem* _item) 00234 { 00235 for (VectorLayerItem::iterator iter=mLayerItems.begin(); iter!=mLayerItems.end(); ++iter) 00236 { 00237 if ((*iter) == _item) 00238 { 00239 (*iter) = mLayerItems.back(); 00240 mLayerItems.pop_back(); 00241 return; 00242 } 00243 } 00244 MYGUI_EXCEPT("layer item not found"); 00245 } 00246 00247 void LayerNode::outOfDate(RenderItem* _item) 00248 { 00249 mOutOfDate = true; 00250 if (_item) 00251 _item->outOfDate(); 00252 } 00253 00254 EnumeratorILayerNode LayerNode::getEnumerator() 00255 { 00256 return EnumeratorILayerNode(mChildItems); 00257 } 00258 00259 void LayerNode::updateCompression() 00260 { 00261 // буферы освобождаются по одному всегда 00262 if (mFirstRenderItems.size() > 1) 00263 { 00264 // пытаемся поднять пустой буфер выше полных 00265 VectorRenderItem::iterator iter1 = mFirstRenderItems.begin(); 00266 VectorRenderItem::iterator iter2 = iter1 + 1; 00267 while (iter2 != mFirstRenderItems.end()) 00268 { 00269 if ((*iter1)->getNeedVertexCount() == 0) 00270 { 00271 RenderItem * tmp = (*iter1); 00272 (*iter1) = (*iter2); 00273 (*iter2) = tmp; 00274 } 00275 iter1 = iter2; 00276 ++iter2; 00277 } 00278 } 00279 } 00280 00281 void LayerNode::dumpStatisticToLog(size_t _level) 00282 { 00283 static const char* spacer = " "; 00284 std::string offset(" ", _level); 00285 MYGUI_LOG(Info, offset << " - Node batch_count='" << mFirstRenderItems.size() + mSecondRenderItems.size() << spacer); 00286 00287 for (VectorRenderItem::iterator iter=mFirstRenderItems.begin(); iter!=mFirstRenderItems.end(); ++iter) 00288 { 00289 MYGUI_LOG(Info, offset << " * Batch texture='" << ((*iter)->getTexture() == nullptr ? "nullptr" : (*iter)->getTexture()->getName()) << "' vertex_count='" << (*iter)->getVertexCount() << "'" << spacer); 00290 } 00291 for (VectorRenderItem::iterator iter=mSecondRenderItems.begin(); iter!=mSecondRenderItems.end(); ++iter) 00292 { 00293 MYGUI_LOG(Info, offset << " * Batch texture='" << ((*iter)->getTexture() == nullptr ? "nullptr" : (*iter)->getTexture()->getName()) << "' vertex_count='" << (*iter)->getVertexCount() << "'" << spacer); 00294 } 00295 00296 for (VectorILayerNode::iterator iter = mChildItems.begin(); iter!=mChildItems.end(); ++iter) 00297 { 00298 (*iter)->dumpStatisticToLog(_level + 1); 00299 } 00300 } 00301 00302 } // namespace MyGUI