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