2011-12-18 15 views
0

NSOpenGLViewをサブクラス化していくつかのOpenGL図面を作成するアプリケーションを作成しています。今は、QuickTime Xに似たオーバレイコントロールを追加したいと思いました。最初に試したことは、NSOpenGLCPSurfaceOrderを-1に設定し、ウィンドウを非不透明にしました。それはうまくいったが、私は窓の影を失ったので、実行可能な解決策ではなかった。レイヤーバックアップNSOpenGLView +アニメーションタイマー=奇妙な描画動作ですか?

私は[setWantsLayer:YES]を呼び出し、サブビューとして自分のコントロールボックスを追加して、NSOpenGLViewサブクラスをレイヤーバックしました。それはうまくいったけど、パフォーマンスが大きく低下したことに気付いた。

NSTimerオブジェクトを使用して、[timerFired:]を1秒間に60回呼び出すことができます。完璧に動作します。レイヤーバックのOpenGLViewを使用するときに[drawRect:rect]メソッドをオーバーロードしてそこにすべてのOpenGL描画を行う必要があるため、このメソッド内で唯一行うのは[self setNeedsDisplay:YES]です。問題:[drawRect:rect]は、タイマーは起動しませんでしたが、しばしば呼び出されます。

最初は「もちろん、それはNSOpenGLViewを描画するので、ウィンドウマネージャなどで呼び出すことができる」と思っていました。だから[timerFired:]の呼び出しの間に呼び出された方法を決定するために私のタイマーオブジェクトを削除しました。結果:ウィンドウをサイズ変更したりドラッグしたりしていないときは、少なくとも呼び出されませんでした。

次に、私はタイマーの時間間隔を実験しました。 1秒間に55回、[drawRect:rect]が毎秒60〜70回呼び出され、1秒間に59回のタイマー間隔から、[drawRect:rect]が毎秒100〜120回呼び出されます。

私の描画が呼び出されるこの非常に予測できない方法は、不均等であるか、多くのOpenGL図面でスレッドを詰まらせ、実行する時間が足りないなどパフォーマンスが低下すると思われます。また、レイヤーバックのOpenGLViewはvsyncで動作しないと読んでいますが、これは確認できません。

誰か説明がありますか? OpenGLをタイマー・ファイアでしか描画しない方法について誰かが考えていますか?

私は既に素朴なアプローチを試みてブール値変数を追加しました。これは[timerFired:]でtrueに設定し、[drawRect:rect]は変数がtrueの場合にのみOpenGL描画メソッドを呼び出しました。結果は非常にちらつきがあり、不自然なアニメーションでした。

非同期アニメーションやCVDisplayLinkでCAOpenGLLayerを使用することはどうですか?いずれ助けるか?

編集役立つ情報かもしれない別の事:私はすでに私の見解は、層担保されることなく[setNeedsDisplay:YES]を使用し、私は簡単に層担保としませ層担保を切り替えることができ、私はいずれかを持っていませんでしたしたがって、私の見解がレイヤーバックされていることは間違いありません。 [setWantsLayer:YES]を呼び出すだけですべてが混乱します。

答えて

0

私はNSTimerオブジェクトをCVDisplayLinkに置き換えました。すべてが再び滑らかです。私は実際に理由を理解していませんが。バッキング層に垂直同期を壊すことを要求しているようだが、どこにも出現していないdrawRectへのランダム呼び出しは説明していない。

また、vsyncがNSOpenGLViewやCAOpenGLLayerをサポートしているレイヤーで動作しているかどうかは本当に気に入っています。私は正式な情報を見つけることができません。