LayerManager 渲染:
1渲染是從Layer開始:逐層傳遞
void LayerManager::renderToTarget(IRenderTarget* _target, bool _update)
{
for (VectorLayer::iterator iter=mLayerNodes.begin(); iter!=mLayerNodes.end(); ++iter)
{
(*iter)->renderToTarget(_target, _update);
}
}
2具體的Layer(over)
void OverlappedLayer::renderToTarget(IRenderTarget* _target, bool _update)
{
for (VectorILayerNode::iterator iter=mChildItems.begin(); iter!=mChildItems.end(); ++iter)
{
(*iter)->renderToTarget(_target, _update);
}
}
3傳遞LayerNode:
void LayerNode::renderToTarget(IRenderTarget* _target, bool _update)
{
// проверяем на сжатие пустот
bool need_compression = false;
for (VectorRenderItem::iterator iter=mFirstRenderItems.begin(); iter!=mFirstRenderItems.end(); ++iter)
{
if ((*iter)->getCompression())
{
need_compression = true;
break;
}
}
if (need_compression)
updateCompression();
// сначала отрисовываем свое
for (VectorRenderItem::iterator iter=mFirstRenderItems.begin(); iter!=mFirstRenderItems.end(); ++iter)
{
(*iter)->renderToTarget(_target, _update);
}
for (VectorRenderItem::iterator iter=mSecondRenderItems.begin(); iter!=mSecondRenderItems.end(); ++iter)
{
(*iter)->renderToTarget(_target, _update);
}
// теперь отрисовываем дочерние узлы
for (VectorILayerNode::iterator iter = mChildItems.begin(); iter!=mChildItems.end(); ++iter)
{
(*iter)->renderToTarget(_target, _update);
}
mOutOfDate = false;
}
4傳遞RenderItem
void RenderItem::renderToTarget(IRenderTarget* _target, bool _update)
{
if (mTexture == nullptr)
return;
mRenderTarget = _target;
mCurrentUpdate = _update;
if (mOutDate || _update)
{
mCountVertex = 0;
Vertex * buffer = (Vertex*)mVertexBuffer->lock();
for (VectorDrawItem::iterator iter=mDrawItems.begin(); iter!=mDrawItems.end(); ++iter)
{
// перед вызовом запоминаем позицию в буфере
mCurrentVertext = buffer;
mLastVertextCount = 0;
(*iter).first->doRender();
// колличество отрисованных вершин
MYGUI_DEBUG_ASSERT(mLastVertextCount <= (*iter).second, "It is too much vertexes");
buffer += mLastVertextCount;
mCountVertex += mLastVertextCount;
}
mVertexBuffer->unlock();
mOutDate = false;
}
// хоть с 0 не выводиться батч, но все равно не будем дергать стейт и операцию
if (0 != mCountVertex)
{
#if MYGUI_DEBUG_MODE == 1
if (!RenderManager::getInstance().checkTexture(mTexture))
{
mTexture = nullptr;
MYGUI_EXCEPT("texture pointer is not valid, texture name '" << mTextureName << "'");
return;
}
#endif
// непосредственный рендринг
_target->doRender(mVertexBuffer, mTexture, mCountVertex);
}
}
DrawItem:
終於出來ISubWidget
typedef std::pair<ISubWidget*, size_t> DrawItemInfo;
typedef std::vector<DrawItemInfo> VectorDrawItem;
傳遞:
5ISubWidget 真實的Render在這裏:
void RenderItem::renderToTarget(IRenderTarget* _target, bool _update)
{
if (mTexture == nullptr)
return;
mRenderTarget = _target;
mCurrentUpdate = _update;
if (mOutDate || _update)
{
mCountVertex = 0;
Vertex * buffer = (Vertex*)mVertexBuffer->lock();
for (VectorDrawItem::iterator iter=mDrawItems.begin(); iter!=mDrawItems.end(); ++iter)
{
// перед вызовом запоминаем позицию в буфере
mCurrentVertext = buffer;
mLastVertextCount = 0;
(*iter).first->doRender();
// колличество отрисованных вершин
MYGUI_DEBUG_ASSERT(mLastVertextCount <= (*iter).second, "It is too much vertexes");
buffer += mLastVertextCount;
mCountVertex += mLastVertextCount;
}
mVertexBuffer->unlock();
mOutDate = false;
}
// хоть с 0 не выводиться батч, но все равно не будем дергать стейт и операцию
if (0 != mCountVertex)
{
#if MYGUI_DEBUG_MODE == 1
if (!RenderManager::getInstance().checkTexture(mTexture))
{
mTexture = nullptr;
MYGUI_EXCEPT("texture pointer is not valid, texture name '" << mTextureName << "'");
return;
}
#endif
// непосредственный рендринг
_target->doRender(mVertexBuffer, mTexture, mCountVertex);
}
}
在第4步時,應該注意到有一個cast:
Vertex * buffer = (Vertex*)mVertexBuffer->lock();
這就是爲什麼DrawItem 可以繪製vertex!
之後再有的就是對渲染屬性的設置,無外乎Vertex 和 Texture 的賦值。