2012-02-25 5 views
3

OpengGLで描画する必要のあるアプリケーションでは、少なくともリフレッシュレートをモニタのリフレッシュレート以上にする必要があります。また、私は描画を別のスレッドで実行する必要があります。そのため、強力なUIアクションによって描画がロックされることはありません。NSOpenGLLayerとは別のスレッドから描画します

実際には私はと組み合わせてNSOpenGLViewを使用していますが、60-80FPSは問題なく使用できます。

私はこのビューの上にいくつかのココアコントロールを表示する必要があるので、NSOpenGLViewサブクラス化し、レイヤーバックにしました。LayerBackedOpenGLViewアップルの例に従います。

結果は満足のいくものではなく、多くのアーチファクトがあります。

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

私はこのソリューションを汚れたハックのように思っていますので、私は必要なものを満たすための代替的かつよりクリーンな方法を探しています。

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

最後に、このすべてのプリアンブルの後に、私の質問になります:コールバックを使用して別のスレッドからNSOpenGLLayerに描画することは可能ですか。

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

私はこれを見つけたところで、ユーザーがの中でのみライオンの下で起こると主張する投稿をthisで見つけました。

私は現在、Snow Leopardにいますが、アプリはLionでも完璧に動作するはずです。

何か不足していますか?

答えて

4

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

レイヤーを非同期にし、メインスレッド上でOpenGLコンテキストをレンダリングすることをお勧めします。このように良いフレームレートを達成できない場合は、メインスレッドが他の場所でビジー状態になっているため、他のスレッド(Grand Central Dispatchなど)に他のもの(ほとんどすべてのアプリケーションロジック)を移動し、メインスレッドの描画コード。あなたのウィンドウが非常に大きい場合でも、30 FPS(1フレームは2回のスクリーンリフレッシュ)より優れたものはまだ得られないかもしれませんが、それはCALayerの構成がかなり高価に見え、多かれ少なかれ最適化されています静的レイヤー(例えば、画像を含むレイヤー)であり、60FPS自体を更新するレイヤーではない。

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

最後に、2つのウインドウアプローチは、VLC(ビデオプレーヤー)がビデオ画像(MacではOpenGLによってレンダリングされる)に対してどのように制御を引き出すかについて、エキゾチックではありません。

+0

ありがとうございました!現在のアプリもビデオプレーヤーです。私は、VLCがそのコントロールに子ウィンドウを使用していることを知らなかった。私はそのソースコードを見たことがない。一方、子供のウィンドウのソリューションは、iMac上で正常に動作するようだが、それは2009年のMacBookにいくつかのグラフィックの問題を与えるようだ。しかし、それらの問題が子ウィンドウや他のものに関係しているかどうかはわかりません。あなたが私の他の質問で提案した解決策を試してみましょう。もしそれがより良い性能を与えないなら、私はコントロールのために子供のウィンドウに固執します。どうもありがとうございました!! – Andrea3000

+0

私はCVDisplayLinkと組み合わせてperformSelectorOnMainThreadを使用しました。それは素晴らしい作品です。 CATransaction .Flushを使用すると、ユーザインタラクションとフレームアニメーションを組み合わせようとすると問題が発生します。それは使用できますが、将来のすべてのコードでそれを考慮する必要があります。 performSelectorOnMainThreadメソッドを使いやすくする。ここに私とMeckiとの間のconvoと、この件に関する私の所見もあります:http://chat.stackoverflow.com/rooms/104337/opengl-on-macos-x-and-threadingまた、このMeckiに対するあなたの最終的なコメントが大好きです。再度、感謝します。 – eonist

関連する問題