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,但我猜这是 NpApi 的东西,因为它在 Internet Explorer 中工作。

我相信发生的事情是,只要插件的可见尺寸发生变化,Chrome 就会发布并创建一个新的 HDC。这可能导致渲染上下文无效,但它仍在插件中使用并导致崩溃。

我注意到发生这种情况时会调用 NPP_SetWindow,但是在 NpapiPluginModule_NPP.cpp 中会忽略这些调用,因此我无法连接到此事件。

我已经谷歌了几个小时,但没有找到任何帮助。有没有人有这方面的经验?

我有一个想法,如果我创建我自己的子窗口到我可以处理我自己的 DC 的插件窗口,它可以工作。我做了一些失败的快速测试,这可能是因为我蹩脚的 Win32 技能。但这可以与更多的工作一起工作吗?我的另一个想法是以某种方式跟踪可见区域,但我还没有研究过。

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 回答