MyGUI
3.0.3
|
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 _firstQueue = _item->castType<ISubWidgetText>(false) == nullptr; 00154 // для первичной очереди нужен порядок 00155 if (_firstQueue) 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 // либо с нужной текстурой за пустым 00169 VectorRenderItem::reverse_iterator iter = mFirstRenderItems.rbegin(); 00170 if ((*iter)->getNeedVertexCount() == 0) 00171 { 00172 while (true) 00173 { 00174 VectorRenderItem::reverse_iterator next = iter + 1; 00175 if (next != mFirstRenderItems.rend()) 00176 { 00177 if ((*next)->getNeedVertexCount() == 0) 00178 { 00179 iter = next; 00180 continue; 00181 } 00182 else if ((*next)->getTexture() == _texture) 00183 iter = next; 00184 } 00185 00186 break; 00187 } 00188 00189 (*iter)->setTexture(_texture); 00190 return (*iter); 00191 } 00192 // последний буфер с нужной текстурой 00193 else if ((*iter)->getTexture() == _texture) 00194 { 00195 return *iter; 00196 } 00197 00198 // создаем новый буфер 00199 RenderItem* item = new RenderItem(); 00200 item->setTexture(_texture); 00201 mFirstRenderItems.push_back(item); 00202 00203 return item; 00204 } 00205 00206 // для второй очереди порядок неважен 00207 for (VectorRenderItem::iterator iter = mSecondRenderItems.begin(); iter != mSecondRenderItems.end(); ++iter) 00208 { 00209 // либо такая же текстура, либо пустой буфер 00210 if ((*iter)->getTexture() == _texture) 00211 { 00212 return (*iter); 00213 } 00214 else if ((*iter)->getNeedVertexCount() == 0) 00215 { 00216 (*iter)->setTexture(_texture); 00217 return (*iter); 00218 } 00219 00220 } 00221 // не найденно создадим новый 00222 RenderItem* item = new RenderItem(); 00223 item->setTexture(_texture); 00224 00225 mSecondRenderItems.push_back(item); 00226 return mSecondRenderItems.back(); 00227 } 00228 00229 void LayerNode::attachLayerItem(ILayerItem* _item) 00230 { 00231 mLayerItems.push_back(_item); 00232 _item->attachItemToNode(mLayer, this); 00233 } 00234 00235 void LayerNode::detachLayerItem(ILayerItem* _item) 00236 { 00237 for (VectorLayerItem::iterator iter=mLayerItems.begin(); iter!=mLayerItems.end(); ++iter) 00238 { 00239 if ((*iter) == _item) 00240 { 00241 (*iter) = mLayerItems.back(); 00242 mLayerItems.pop_back(); 00243 return; 00244 } 00245 } 00246 MYGUI_EXCEPT("layer item not found"); 00247 } 00248 00249 void LayerNode::outOfDate(RenderItem* _item) 00250 { 00251 mOutOfDate = true; 00252 if (_item) 00253 _item->outOfDate(); 00254 } 00255 00256 EnumeratorILayerNode LayerNode::getEnumerator() 00257 { 00258 return EnumeratorILayerNode(mChildItems); 00259 } 00260 00261 void LayerNode::updateCompression() 00262 { 00263 // буферы освобождаются по одному всегда 00264 if (mFirstRenderItems.size() > 1) 00265 { 00266 // пытаемся поднять пустой буфер выше полных 00267 VectorRenderItem::iterator iter1 = mFirstRenderItems.begin(); 00268 VectorRenderItem::iterator iter2 = iter1 + 1; 00269 while (iter2 != mFirstRenderItems.end()) 00270 { 00271 if ((*iter1)->getNeedVertexCount() == 0) 00272 { 00273 RenderItem * tmp = (*iter1); 00274 (*iter1) = (*iter2); 00275 (*iter2) = tmp; 00276 } 00277 iter1 = iter2; 00278 ++iter2; 00279 } 00280 } 00281 } 00282 00283 void LayerNode::dumpStatisticToLog(size_t _level) 00284 { 00285 static const char* spacer = " "; 00286 std::string offset(" ", _level); 00287 MYGUI_LOG(Info, offset << " - Node batch_count='" << mFirstRenderItems.size() + mSecondRenderItems.size() << spacer); 00288 00289 for (VectorRenderItem::iterator iter=mFirstRenderItems.begin(); iter!=mFirstRenderItems.end(); ++iter) 00290 { 00291 MYGUI_LOG(Info, offset << " * Batch texture='" << ((*iter)->getTexture() == nullptr ? "nullptr" : (*iter)->getTexture()->getName()) << "' vertex_count='" << (*iter)->getVertexCount() << "'" << spacer); 00292 } 00293 for (VectorRenderItem::iterator iter=mSecondRenderItems.begin(); iter!=mSecondRenderItems.end(); ++iter) 00294 { 00295 MYGUI_LOG(Info, offset << " * Batch texture='" << ((*iter)->getTexture() == nullptr ? "nullptr" : (*iter)->getTexture()->getName()) << "' vertex_count='" << (*iter)->getVertexCount() << "'" << spacer); 00296 } 00297 00298 for (VectorILayerNode::iterator iter = mChildItems.begin(); iter!=mChildItems.end(); ++iter) 00299 { 00300 (*iter)->dumpStatisticToLog(_level + 1); 00301 } 00302 } 00303 00304 } // namespace MyGUI