由于
OpenGL只是负责显示3D的内容,并没有相应的UI实现,因此第二人生里就采用类LLView来实现一个窗口的显示,在这个窗口里可以显示任何其它的窗口,达到递归显示窗口的内容。下面就来仔细地分析它的显示函数,如下:
#001 void LLView::draw()
#002 {
如果设置调试窗口显示,就显示调试窗口。
#003
if (sDebugRects)
#004
{
#005
drawDebugRect();
#006
#007
// Check for bogus rectangle
#008
if (getRect().mRight <= getRect().mLeft
#009
|| getRect().mTop <= getRect().mBottom)
#010
{
#011
llwarns << "Bogus rectangle for " << getName() << " with " << mRect << llendl;
#012
}
#013
}
#014
获取根窗口拥有的窗口大小。
#015
LLRect rootRect = getRootView()->getRect();
#016
LLRect screenRect;
#017
查看这个窗口是否有输入焦点。
#018
// draw focused control on top of everything else
#019
LLView* focus_view = gFocusMgr.getKeyboardFocus();
#020
if (focus_view && focus_view->getParent() != this)
#021
{
#022
focus_view = NULL;
#023
}
#024
开始显示所有子窗口,
mChildList列表里保存了所有子窗口。
#025
++sDepth;
#026
for (child_list_reverse_iter_t child_iter = mChildList.rbegin(); child_iter != mChildList.rend(); ++child_iter)
#027
{
#028
LLView *viewp = *child_iter;
#029
窗口有可见属性,并且没有焦点的窗口显示。
#030
if (viewp->getVisible() && viewp != focus_view)
#031
{
#032
// Only draw views that are within the root view
获取仅能显示在根窗口里的大小。
#033
localRectToScreen(viewp->getRect(),&screenRect);
#034
if ( rootRect.rectInRect(&screenRect) )
#035
{
指明
OPENGL里当前矩阵是GL_MODELVIEW矩阵。
#036
glMatrixMode(GL_MODELVIEW);
保存矩阵。
#037
LLUI::pushMatrix();
#038
{
开始显示窗口。
#039
LLUI::translate((F32)viewp->getRect().mLeft, (F32)viewp->getRect().mBottom, 0.f);
#040
viewp->draw();
#041
}
恢复刚才的矩阵。
#042
LLUI::popMatrix();
#043
}
#044
}
#045
#046
}
#047
--sDepth;
#048
显示有焦点输入的窗口。
#049
if (focus_view && focus_view->getVisible())
#050
{
#051
drawChild(focus_view);
#052
}
#053
显示输出调试窗口。
#054
// HACK
#055
if (sEditingUI && this == sEditingUIView)
#056
{
#057
drawDebugRect();
#058
}
#059 }
在这个函数里,主要通过遍历子窗口列表,把所有窗口渲染到
OPENGL窗口里。