cegui渲染流程图
2016-08-10 10:44:21 0 举报
AI智能生成
cegui基本渲染流程,未完待续
作者其他创作
大纲/内容
GUIContext::draw()
Window::render()
getRenderingContext
获得一个绘制上下文(RnderingContext)
<div>struct RenderingContext :</div><div> public AllocatedObject<RenderingContext></div><div>{</div><div> RenderingSurface* surface;</div><div> const Window* owner;</div><div> Vector2f offset;</div><div> RenderQueueID queue;</div><div>};</div>
如果是rootwindow RnderSurface的类型为GUIContext
class CEGUIEXPORT GUIContext : public RenderingSurface
rootwindow下的子窗口,在绝大多数情况下都是RenderingWindow类型
class CEGUIEXPORT RenderingWindow : public RenderingSurface
drawSelf(ctx);//利用获得的上下文绘制控件自身的内容
bufferGeometry(ctx);
构建Window::d_geometry
GeometryBuffer* d_geometry;
queueGeometry(ctx);
添加到当前绘制上下文的surface中
ctx.surface->addGeometryBuffer(ctx.queue, *d_geometry);
绘制子窗口
<div> // render any child windows</div><div> for (ChildDrawList::iterator it = d_drawList.begin(); it != d_drawList.end(); ++it)</div><div> {</div><div> (*it)->render();</div><div> }</div>
如果当前上下文的所有者是自己,则进行绘制,这里执行真正的绘制操作
<div> // do final rendering for surface if it's ours</div><div> if (ctx.owner == this)</div><div> ctx.surface->draw();</div>
如果surface类型是RnderingWindow
<div>void RenderingWindow::draw()</div><div>{</div><div> // update geometry if needed.</div><div> if (!d_geometryValid)</div><div> realiseGeometry();</div><div><br></div><div> if (d_invalidated)</div><div> {</div><div> // base class will render out queues for us</div><div> RenderingSurface::draw();</div><div> // mark as no longer invalidated</div><div> d_invalidated = false;</div><div> }</div><div><br></div><div> // add our geometry to our owner for rendering</div><div> d_owner->addGeometryBuffer(RQ_BASE, *d_geometry);</div><div>}</div>
realiseGeometry(),提供了更改最终结果的可能,因为最终添加到父surface的是d_geometry,而这个函数能够改变这个
RenderingSurface::draw();
渲染到当前surface持有的纹理中
d_owner->addGeometryBuffer(RQ_BASE, *d_geometry);
这里可以看到蒋构造好的d_geometry添加到父surface中
这里的d_geometry默认情况下就是两个三角形,六个顶点组成的,纹理就是当前surface持有的纹理,这个纹理是作为上一步的 RnderTarget(这里的上一步指的是RenderingSurface::draw();)
如果surface类型是GUIContext
通过干扰渲染流程能够实现自绘的几种模式
realiseGeometry();
这个主要更改的是代表当前surface的纹理,可以参照cegui的例子EffectDemo
有一个前提就是Window::d_autoRenderingWindow为true
因为只有一个窗口单独自己持有一个纹理的时候,你设置的effect会被设置到自己的renderingwindow
Window::drawSelf(ctx);
这个需要自定义一个基于Window或者现有控件类型的类,并且重新实现Window::drawSelf
在drawself里将自己实现的geometrybuffer添加到surface的渲染队列里
响应一个事件,在绘制的时候直接绘制到对应的RenderingWindow上
CEGUI::System::getSingleton().getDefaultGUIContext().<br> subscribeEvent(CEGUI::RenderingSurface::EventRenderQueueStarted,
实现一个RenderEffect,重写performPreRenderFunctions或者performPostRenderFunctions
<p>void Direct3D9GeometryBuffer::draw() const<br>{<br> RECT saved_clip;<br> d_device->GetScissorRect(&saved_clip);</p><p> // setup clip region<br> RECT clip;<br> clip.left = static_cast<LONG>(d_clipRect.left());<br> clip.top = static_cast<LONG>(d_clipRect.top());<br> clip.right = static_cast<LONG>(d_clipRect.right());<br> clip.bottom = static_cast<LONG>(d_clipRect.bottom());</p><p> // apply the transformations we need to use.<br> if (!d_matrixValid)<br> updateMatrix();</p><p> d_device->SetTransform(D3DTS_WORLD, &d_matrix);</p><p> d_owner.setupRenderingBlendMode(d_blendMode);</p><p> const int pass_count = d_effect ? d_effect->getPassCount() : 1;<br> for (int pass = 0; pass < pass_count; ++pass)<br> {<br> // set up RenderEffect<br> if (d_effect)<br> d_effect->performPreRenderFunctions(pass);</p><p> // draw the batches<br> size_t pos = 0;<br> BatchList::const_iterator i = d_batches.begin();<br> for ( ; i != d_batches.end(); ++i)<br> {<br> if (i->clip)<br> d_device->SetScissorRect(&clip);</p><p> d_device->SetTexture(0, i->texture);<br> d_device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, i->vertexCount / 3,<br> &d_vertices[pos], sizeof(D3DVertex));<br> pos += i->vertexCount;</p><p> if (i->clip)<br> d_device->SetScissorRect(&saved_clip);<br> }<br> }</p><p> // clean up RenderEffect<br> if (d_effect)<br> d_effect->performPostRenderFunctions();<br>}</p><p></p>
实现 d_effect->performPreRenderFunctions(pass);影响的是前绘制
实现d_effect->performPostRenderFunctions();影响的是后绘制
这样的控件必须单独持有一个纹理,所以一定能够获得一个renderingwindow,setRenderEffect
void RenderingWindow::setRenderEffect(RenderEffect* effect)<br>{<br> d_geometry->setRenderEffect(effect);<br>}子主题
无论实现哪个函数<br>d_effect->performPreRenderFunctions(pass);还是<br>d_effect->performPostRenderFunctions();<br>他们本质上都是绘制到上一层renderwindowing上,如果你用固定管线绘制,不用设置矩阵,自然就可以默认绘制到当前纹理上,如果使用HLSL,千万记得获取设置矩阵<br>
收藏
0 条评论
下一页