現在、次の問題に直面しています。さまざまな Qt ウィジェットで多数の個別の OpenSceneGraph シーンを表示する必要があるアプリケーションがあります。たとえば、1 つの Qt ウィジェットが球体を表し、別のウィジェットが 20 面体を表す場合があります。OpenSceneGraph 3.0.1 を使用しているため、これを実装するために公式ドキュメントの osgViewerQt の例に従いました。
サンプル コードではQTimer
、ビューア ウィジェットの更新を強制するために を使用しています。
connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );
_timer.start( 10 );
問題は、複数のウィジェットを作成して表示したいときに始まります。各ウィジェットには独自のタイマーが付属しているため、開いているウィジェットの数に応じてパフォーマンスが急速に低下します。OSG ウィジェットとの対話が非常に遅いだけでなく、他のQt ウィジェットとの対話も著しく遅くなります。最近の中途半端なクアッドコア システムでさえ、約 5 つのウィンドウが開いているとほとんど圧倒されます。この問題は、グラフィック ハードウェアとはまったく関係ありません。他のアプリケーション (Blender、Meshlab など) は、パフォーマンスに悪影響を与えることなく、より大きなシーンをレンダリングできます。
要約すると、パフォーマンスに影響を与えることなく、異なる OpenSceneGraph シーンを表示する複数の Qt ウィジェットを作成する最良の方法は何でしょうか?
すでに試したこと:
- すべてのシーン オブジェクト
osgViewer::CompositeViewer
のレンダリングに 1 つの を使用することは既に検討しました。ただし、単一のウィジェットとのやり取りが非常に複雑になる可能性があるため、このアイデアは今のところ破棄しました。 - osgQtWidgets の例で詳しく説明されているように、それぞれのレンダリング部分を
osgViewer::CompositeViewer
別のスレッドに入れてみました。
2 回目の試行 (スレッドを使用) は、おおよそ次のようになります。
class ViewerFrameThread : public OpenThreads::Thread
{
public:
ViewerFrameThread(osgViewer::ViewerBase* viewerBase):
_viewerBase(viewerBase) {}
~ViewerFrameThread()
{
cancel();
while(isRunning())
{
OpenThreads::Thread::YieldCurrentThread();
}
}
int cancel()
{
_viewerBase->setDone(true);
return 0;
}
void run()
{
int result = _viewerBase->run();
}
osg::ref_ptr<osgViewer::ViewerBase> _viewerBase;
};
ただし、これによりパフォーマンスが大幅に低下しました。各スレッドは依然として多くの CPU 時間を必要とします (基本的な対話は依然としてタイマーで処理されるため、これは驚くべきことではありません)。このアプローチの唯一の利点は、少なくとも他のQt ウィジェットとの対話が可能であることです。
私たちにとって理想的な解決策は、ユーザーがクリック、ダブルクリック、スクロールなどの操作を行うたびに再描画リクエストのみを起動するウィジェットです。より正確には、このウィジェットは更新が必要になるまでアイドル状態のままにする必要があります。これに似たことがまったく可能ですか?ご提案をお待ちしております。