2

WindowsでFireBreathを使用してプラグインを開発しています(今のところ)、OpenGLを使用してウェブカメラフィードを表示しています。ウィンドウプラグインを使用しており、別のスレッドから描画しています。コードは次の場所で表示できます。

ヘッダーファイル

https://github.com/EvilTengil/kinect-at-home-plugin/blob/0007beecf136ff2e5e1aa50be94d4906447a8f43/Win/KinectAtHomeWin.h

ソースファイル

https://github.com/EvilTengil/kinect-at-home-plugin/blob/0007beecf136ff2e5e1aa50be94d4906447a8f43/Win/KinectAtHomeWin.cpp

(onWindowResized の奇妙なコードは無視してください。これは、コミットに残っているいくつかのテストです。)

問題は、ブラウザー ウィンドウのサイズが変更されてプラグインの表示領域が変更されるか、拡張機能が何らかの理由でスクロール ボックスの表示領域の外にスクロールされるとすぐに、Chrome でプラグインがクラッシュすることです。Firefox はインストールしていませんが、Internet Explorer で動作しているので、NpApi のことだと思います。

プラグインの表示サイズが変更されるたびに、Chrome が新しい HDC をリリースして作成することが起こっていると思います。これにより、レンダリング コンテキストが無効になる可能性がありますが、プラグインでまだ使用されているため、クラッシュが発生します。

これが発生したときに NPP_SetWindow get が呼び出されることに気付きましたが、これらの呼び出しは NpapiPluginModule_NPP.cpp で無視されるため、このイベントにフックする方法はありません。

私は数時間Googleを使っていますが、何の助けも見つかりません. 誰もこれを経験したことがありますか?

自分のDCを処理できるプラグインウィンドウに自分の子ウィンドウを作成すればうまくいくと思います。私は失敗した簡単なテストをいくつか行いました。しかし、これはもう少し作業を加えるとうまくいくでしょうか?私が持っている別のアイデアは、何らかの方法で可視領域を追跡することですが、まだ調べていません。

4

1 に答える 1

1

Windows ハンドルが無効になっても、プログラム自体がクラッシュすることはありません。ただし、OpenGL、つまりその拡張機能には、特にホスト プログラムが OpenGL も使用する場合に、特別な注意が必要です。

OpenGL を使用するあらゆる種類のプラグインまたは DLL は注意を払う必要があります。つまり、必要なリソースを使用する前に正常な状態にし、使用後に元に戻します。OpenGL の場合、これは、使用を開始する前に毎回コンテキストを再バインドする必要があることを意味します。

HDC hOldDC = wglGetCurrentDC();
HRC hOldContext = wglGetCurrentContext();

 // first unbind old context/DC from current thread
wglMakeCurrent(NULL, NULL);

 // then bind our context
wglMakeCurrent(hMyDC, hMyContext);

 // this is essential, as in Windows the addresses of extensions
 // may depend on the active context, so you must reinitialise
 // extension function pointers!
reinitialize_extensions();

/* NOW USE OPENGL FUNCTION

 // cleaning up once we're done:
wglMakeCurrent(NULL, NULL);
wglMakeCurrent(hOldDC, hOldRC);
// remember that we also need to reset extension
// function pointers to the other context
reinitialize_extensions();

Window 拡張関数ではポインターはコンテキストに依存するため、それらを構造体に入れ、その構造体を介して呼び出すことは理にかなっています。これにより、拡張機能の再初期化全体が保存されます。C++ では、このために OpenGL コンテキスト全体をクラスにラップできます。

プラグインが NP-API を介して呼び出されるたびに、このセットアップ/ティアダウンを実行する必要があることに注意してください。

于 2012-02-18T14:01:57.267 に答える