3

少なくともモニターのリフレッシュレートと同じリフレッシュレートでOpengGLを使用して描画する必要があるアプリに取り組んでいます。また、描画が激しいUIアクションによってロックされないように、別のスレッドで描画を実行する必要があります。

実はとNSOpenGLView組み合わせて使っておりCVDisplayLink、問題なく60-80FPSを達成することができます。

このビューの上にいくつかのココアコントロールも表示する必要があるため、 LayerBackedOpenGLView Appleの例NSOpenGLViewに従って、サブクラス化してレイヤーバックにしようとしました。

結果は満足のいくものではなく、多くのアーティファクトが発生します。

NSWindowしたがって、ココアコントロールをホストするために別のウィンドウを使用し、このウィンドウをを含むメインウィンドウの子ウィンドウとして追加することで問題を解決しましたNSOpenGLView。それは正常に動作し、最初の実装とまったく同じFPSを取得できます。

私はこのソリューションを汚いハックのように考えているので、必要なものを達成するための代替のよりクリーンな方法を探しています。

数日前に出くわしNSOpenGLLayer、それが私の問題の実行可能な解決策として使用できると思いました。

最後に、このすべての前文の後に、私の質問があります:コールバックNSOpenGLLayerを使用して別のスレッドからに描画することは可能ですCVDisplayLinkか?

CVDisplayLinkこれまでこれを実装しようとしましたが、コールバックから引き出すことができません。-setNeedsDisplay:TRUEコールバックNSOpenGLLayerからのみ実行でき、 cocoaによって自動的に呼び出されたときにCVDisplayLink描画を実行できます。-drawInOpenGLContext:pixelFormat:forLayerTime:displayTime:でも、このようにメインスレッドから描いていると思いますよね?

これをグーグルで調べた後、私はこの投稿を見つけました。この投稿では、Lionの下での描画は内部でのみ発生する可能性があるとユーザーが主張しています-drawInOpenGLContext:pixelFormat:forLayerTime:displayTime:

私は現在SnowLeopardを使用していますが、アプリはLionでも問題なく動作するはずです。

私は何かが足りないのですか?

4

1 に答える 1

4

はい、可能ですが、お勧めしません。displayCVDisplayLink 内からレイヤーを呼び出します。これによりcanDrawInContext:...が呼び出され、YES が返された場合drawInContext:...は が呼び出され、これらすべてが呼び出されたスレッドで呼び出されdisplayます。レンダリングされたイメージを画面に表示するには、 を呼び出す必要があります[CATransaction flush]。このメソッドは Apple メーリング リストで提案されていますが、完全に問題がないわけではありません (他のビューの表示メソッドがバックグラウンド スレッドでも呼び出される可能性があり、すべてのビューがバックグラウンド スレッドからのレンダリングをサポートしているわけではありません)。

推奨される方法は、レイヤーを非同期にし、メイン スレッドで OpenGL コンテキストをレンダリングすることです。メイン スレッドが別の場所で使用中であるために、この方法で適切なフレームレートを達成できない場合は、他のすべて (アプリケーション ロジックのほぼ全体) を他のスレッドに移動し (たとえば、Grand Central Dispatch を使用)、ユーザー入力とメインスレッドでコードを描画します。ウィンドウが非常に大きい場合でも、30 FPS (2 回の画面更新ごとに 1 フレーム) よりも優れたものは得られない可能性がありますが、これは、CALayer 合成がかなり高価なプロセスのように見え、多かれ少なかれ最適化されているという事実に由来します。静的レイヤー (例: 画像を含むレイヤー) であり、レイヤー自体を 60 FPS で更新するレイヤーではありません。

たとえば、3D ゲームを作成している場合は、CALayers と OpenGL コンテンツをまったく混在させないことをお勧めします。Cocoa UI 要素が必要な場合は、それらを OpenGL コンテンツから分離しておく (たとえば、ウィンドウを OpenGL のみを表示する部分とコントロールのみを表示する部分に水平に分割する) か、すべてのコントロールを自分で描画します (これはゲームではかなり一般的です)。

最後に大事なことを言い忘れましたが、2 つのウィンドウのアプローチは、あなたが思っているほど風変わりではありません。それは、VLC (ビデオ プレーヤー) がビデオ イメージ上にコントロールを描画する方法です (これは、Mac の OpenGL によってもレンダリングされます)。

于 2012-07-11T17:09:52.807 に答える