MyGUI  3.2.0
MyGUI_RenderItem.cpp
Go to the documentation of this file.
00001 
00006 /*
00007     This file is part of MyGUI.
00008 
00009     MyGUI is free software: you can redistribute it and/or modify
00010     it under the terms of the GNU Lesser General Public License as published by
00011     the Free Software Foundation, either version 3 of the License, or
00012     (at your option) any later version.
00013 
00014     MyGUI is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
00021 */
00022 #include "MyGUI_Precompiled.h"
00023 #include "MyGUI_RenderItem.h"
00024 #include "MyGUI_LayerNode.h"
00025 #include "MyGUI_LayerManager.h"
00026 #include "MyGUI_Gui.h"
00027 #include "MyGUI_RenderManager.h"
00028 #include "MyGUI_DataManager.h"
00029 #include "MyGUI_RenderManager.h"
00030 
00031 namespace MyGUI
00032 {
00033 
00034     RenderItem::RenderItem() :
00035         mTexture(nullptr),
00036         mNeedVertexCount(0),
00037         mOutOfDate(false),
00038         mCountVertex(0),
00039         mCurrentUpdate(true),
00040         mCurrentVertex(nullptr),
00041         mLastVertexCount(0),
00042         mVertexBuffer(nullptr),
00043         mRenderTarget(nullptr),
00044         mCompression(false),
00045         mManualRender(false)
00046     {
00047         mVertexBuffer = RenderManager::getInstance().createVertexBuffer();
00048     }
00049 
00050     RenderItem::~RenderItem()
00051     {
00052         RenderManager::getInstance().destroyVertexBuffer(mVertexBuffer);
00053         mVertexBuffer = nullptr;
00054     }
00055 
00056     void RenderItem::renderToTarget(IRenderTarget* _target, bool _update)
00057     {
00058         if (mTexture == nullptr)
00059             return;
00060 
00061         mRenderTarget = _target;
00062 
00063         mCurrentUpdate = _update;
00064 
00065         if (mOutOfDate || _update)
00066         {
00067             mCountVertex = 0;
00068             Vertex* buffer = (Vertex*)mVertexBuffer->lock();
00069 
00070             for (VectorDrawItem::iterator iter = mDrawItems.begin(); iter != mDrawItems.end(); ++iter)
00071             {
00072                 // перед вызовом запоминаем позицию в буфере
00073                 mCurrentVertex = buffer;
00074                 mLastVertexCount = 0;
00075 
00076                 (*iter).first->doRender();
00077 
00078                 // колличество отрисованных вершин
00079                 MYGUI_DEBUG_ASSERT(mLastVertexCount <= (*iter).second, "It is too much vertexes");
00080                 buffer += mLastVertexCount;
00081                 mCountVertex += mLastVertexCount;
00082             }
00083 
00084             mVertexBuffer->unlock();
00085 
00086             mOutOfDate = false;
00087         }
00088 
00089         // хоть с 0 не выводиться батч, но все равно не будем дергать стейт и операцию
00090         if (0 != mCountVertex)
00091         {
00092 #if MYGUI_DEBUG_MODE == 1
00093             if (!RenderManager::getInstance().checkTexture(mTexture))
00094             {
00095                 mTexture = nullptr;
00096                 MYGUI_EXCEPT("texture pointer is not valid, texture name '" << mTextureName << "'");
00097                 return;
00098             }
00099 #endif
00100             // непосредственный рендринг
00101             if (mManualRender)
00102             {
00103                 for (VectorDrawItem::iterator iter = mDrawItems.begin(); iter != mDrawItems.end(); ++iter)
00104                     (*iter).first->doManualRender(mVertexBuffer, mTexture, mCountVertex);
00105             }
00106             else
00107             {
00108                 _target->doRender(mVertexBuffer, mTexture, mCountVertex);
00109             }
00110         }
00111     }
00112 
00113     void RenderItem::removeDrawItem(ISubWidget* _item)
00114     {
00115         for (VectorDrawItem::iterator iter = mDrawItems.begin(); iter != mDrawItems.end(); ++iter)
00116         {
00117             if ((*iter).first == _item)
00118             {
00119                 mNeedVertexCount -= (*iter).second;
00120                 mDrawItems.erase(iter);
00121                 mOutOfDate = true;
00122 
00123                 mVertexBuffer->setVertexCount(mNeedVertexCount);
00124 
00125                 // если все отдетачились, расскажем отцу
00126                 if (mDrawItems.empty())
00127                 {
00128                     mTexture = nullptr;
00129                     mCompression = true;
00130                 }
00131 
00132                 return;
00133             }
00134         }
00135         MYGUI_EXCEPT("DrawItem not found");
00136     }
00137 
00138     void RenderItem::addDrawItem(ISubWidget* _item, size_t _count)
00139     {
00140 
00141 // проверяем только в дебаге
00142 #if MYGUI_DEBUG_MODE == 1
00143         for (VectorDrawItem::iterator iter = mDrawItems.begin(); iter != mDrawItems.end(); ++iter)
00144         {
00145             MYGUI_ASSERT((*iter).first != _item, "DrawItem exist");
00146         }
00147 #endif
00148 
00149         mDrawItems.push_back(DrawItemInfo(_item, _count));
00150         mNeedVertexCount += _count;
00151         mOutOfDate = true;
00152 
00153         mVertexBuffer->setVertexCount(mNeedVertexCount);
00154     }
00155 
00156     void RenderItem::reallockDrawItem(ISubWidget* _item, size_t _count)
00157     {
00158         for (VectorDrawItem::iterator iter = mDrawItems.begin(); iter != mDrawItems.end(); ++iter)
00159         {
00160             if ((*iter).first == _item)
00161             {
00162                 // если нужно меньше, то ниче не делаем
00163                 if ((*iter).second < _count)
00164                 {
00165                     mNeedVertexCount -= (*iter).second;
00166                     mNeedVertexCount += _count;
00167                     (*iter).second = _count;
00168                     mOutOfDate = true;
00169 
00170                     mVertexBuffer->setVertexCount(mNeedVertexCount);
00171                 }
00172                 return;
00173             }
00174         }
00175         MYGUI_EXCEPT("DrawItem not found");
00176     }
00177 
00178     void RenderItem::setTexture(ITexture* _value)
00179     {
00180         if (mTexture == _value)
00181             return;
00182 
00183         //MYGUI_DEBUG_ASSERT(mVertexBuffer->getVertexCount() == 0, "change texture only empty buffer");
00184         MYGUI_DEBUG_ASSERT(mNeedVertexCount == 0, "change texture only empty buffer");
00185 
00186         mTexture = _value;
00187 
00188 #if MYGUI_DEBUG_MODE == 1
00189         mTextureName = mTexture == nullptr ? "" : mTexture->getName();
00190 #endif
00191     }
00192 
00193     ITexture* RenderItem::getTexture()
00194     {
00195         return mTexture;
00196     }
00197 
00198     bool RenderItem::getCompression()
00199     {
00200         bool result = mCompression;
00201         mCompression = false;
00202         return result;
00203     }
00204 
00205     void RenderItem::setManualRender(bool _value)
00206     {
00207         mManualRender = _value;
00208     }
00209 
00210     bool RenderItem::getManualRender() const
00211     {
00212         return mManualRender;
00213     }
00214 
00215     void RenderItem::outOfDate()
00216     {
00217         mOutOfDate = true;
00218     }
00219 
00220     bool RenderItem::isOutOfDate() const
00221     {
00222         return mOutOfDate;
00223     }
00224 
00225     size_t RenderItem::getNeedVertexCount() const
00226     {
00227         return mNeedVertexCount;
00228     }
00229 
00230     size_t RenderItem::getVertexCount() const
00231     {
00232         return mCountVertex;
00233     }
00234 
00235     bool RenderItem::getCurrentUpdate() const
00236     {
00237         return mCurrentUpdate;
00238     }
00239 
00240     Vertex* RenderItem::getCurrentVertexBuffer() const
00241     {
00242         return mCurrentVertex;
00243     }
00244 
00245     void RenderItem::setLastVertexCount(size_t _count)
00246     {
00247         mLastVertexCount = _count;
00248     }
00249 
00250     IRenderTarget* RenderItem::getRenderTarget()
00251     {
00252         return mRenderTarget;
00253     }
00254 
00255 } // namespace MyGUI