osgWidget::Window数量较多时性能问题

2019-11-05

  项目对三维显示功能提出了一项性能要求:在三维窗口上显示2000左右的overlay 控件。在OSG中,就是定制osgWidget::Window了,但是,OSG似乎并没有考虑这样数量的需求,而且osgWidget::Window构造2000个会非常慢,极其慢,十几分钟。另外,超过1800个数后,渲染的overlay 文字会重叠错误,显示模糊。
  针对问题一,很容易确定了性能瓶颈是渲染文字使用的Label。由于其只能通过传入font 文件名来构造,导致会重复读取font文件,这很傻。只是以前没有考虑到这个需求,也没有人修改吧。所以,我们需要定制Label,class Label : public osgWidget::Label,增加传入font 对象的构造。
  针对问题二,这是由于OSG对每个overlay控件给与了一个unsigned int 序号,用于控件遮挡排序,但是,这个值范围小了。修改很容易,在定制的Label中重写:

void Label::positioned() {
            XYCoord    size = getTextSize();
            point_type x = osg::round(((getWidth() - size.x()) / 2.0f) + getX());
            point_type y = osg::round(((getHeight() - size.y()) / 2.0f) + getY());
            point_type z = _calculateZ(getLayer() + 1);

            const WindowManager* wm = _getWindowManager();
         
            int binNum = static_cast<int>(z * 10000);             //OSGWIDGET_RENDERBIN_MOD
            if (wm && wm->isUsingRenderBins()) {
                _text->getOrCreateStateSet()->setRenderBinDetails(
                    binNum,
                    "RenderBin"
                    );
                z = 0.0f;
            }

            _text->setPosition(osg::Vec3(x, y, z));
        }

   OSG中对于overlay层的实现并不是很全面,可能这方面的需求并不多,所提供的功能相对较原始,也较少。由于其代码容易阅读并修改,我们很容易实现自己的需求。

如果有任何意见,欢迎留言讨论。


[ 主页 ]
COMMENTS
POST A COMMENT

(optional)



(optional)