c++ - 在 Windows 上共享 OpenGL 上下文
问题描述
我正在为用 OpenGL 编写的图形引擎编写一个插件(即 .dll)。我的目标是在第二个窗口上镜像该窗口上的内容。好消息是图形引擎向设备上下文 (hDC)、渲染上下文 (hRC) 和渲染窗口 (hWnd) 公开句柄。另一个好消息(我认为)是,由于我的插件是作为 .dll 加载的,因此它被加载到相同的地址空间中,因此我想要实现的目标不会有任何访问冲突。
我的目标是从图形引擎捕获像素并将它们绘制到一个单独的窗口中,从而镜像显示(例如 SDL2、glfw,甚至只是一个普通的 Win32 窗口)。我的理解是我需要使用图形引擎的上下文,然后我可以做一些事情,比如从图形引擎的帧缓冲区中读取,以将第二个窗口上的像素镜像到单独的纹理中。
但是我如何去共享上下文以便我可以访问纹理等?
我正在研究这个可能有一些有用的函数(wglmakecurrent、wglGetCurrentContext 等)来完成这个任务。
谁能确认我走在正确的轨道上,或者向我指出一些解释这个想法的资源?
其他相关资料:
- 在 Windows 10 中工作
- 用 C 和 C++ 编程
编辑
这是我在加载的 .dll 中尝试的,以便从主应用程序帧缓冲区中捕获像素:
// Make the current context available
wglMakeCurrent(mainApplication.hDC, mainApplication.hRC);
glReadBuffer(GL_BACK);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, framebufferCapture);
不幸的是,我只是得到了垃圾数据。我在正确的轨道上吗?我尝试在下一个上下文中创建纹理只是为了查看它的值是否大于 1,但事实并非如此,我认为这告诉我上下文没有被共享(否则会返回一个唯一的纹理 ID)。
解决方案
我能够弄清楚,并且我正在发布解决方案,因为我还没有看到其他人发布工作片段或正确的顺序。也许有一个更精简的解决方案,但这适用于在 Windows 10 上的另一个应用程序中加载插件(作为 .dll)。
// I had to use some of the wgl functions.
// Note that I wrote my own and added an '_' in front of each of the commands.
HGLRC beforeHGLRC = _wglGetCurrentContext("before glfwMakeContextCurrent");
HDC beforeHDC = _wglGetCurrentDC("before glfwMakeContextCurrent");
// Setting an error callback in front of glfw was useful just to make sure
// the setup worked.
glfwSetErrorCallback(errorCallback);
// Here I initialized glfw
// I knew from my source application the version was 4.6, so
// I set the window to match.
// I think I could probably otherwise query from the context the
// version if I was not sure, but I have yet to do that.
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
glfwWindowHint(GLFW_CENTER_CURSOR, false);
// Now I can create my openGL window from glfw.
GLFWwindow* window = glfwCreateWindow(400, 400, "test window", NULL, NULL);
if (window == NULL){
glfwTerminate();
}
// Now I can make a new context at this point
glfwMakeContextCurrent(window);
// Now I should see a different context at this point
HGLRC afterHGLRC = _wglGetCurrentContext("after glfwMakeContextCurrent");
HDC afterHDC = _wglGetCurrentDC("after glfwMakeContextCurrent");
// And finally, I can share the lists.
_wglShareLists(beforeHGLRC,afterHGLRC);
// I was able to further debug to see that I had in fact shared the
// contexts by simply creating a texture (glGenTexture). The value
// returned was greater than 1 (in fact it was 28), so then I iterated
// through each of the 28 textures and output the pixels (glGetTexImage) and
// output the textures from the original application to .ppm images.
推荐阅读
- swift - 如何将 Swift 字符串与 NSLineSeparatorCharacter 常量连接起来
- javascript - Javascript检查JSON数组中是否存在数组所有项目
- swiftui - SwiftUI Picker and NavigationLink Gesture Conflicts
- sql - 过滤 PIVOT 信息
- selenium - Selenium - 上传多个文件会导致上传重复文件(第一个文件一次又一次)
- reactjs - React 站点 - 刷新时,Auth Route 无权访问 auth 上下文数据
- python - 如何将元组保存到 sys.stdin 中的某个变量
- javascript - JS - 如何在同一选项卡中打开一个 url,然后在 3 秒后重定向到另一个 url
- python - 创建一个 numpy 数组的置换浅表副本
- python - 从 tkinter 中删除多个标签