具有共享上下文的多个窗口

时间:2014-07-24 23:29:32

标签: winapi opengl wgl

我目前的实施适用于除Mobile Intel GM45之外的所有视频卡。不幸的是,当我试图在所述视频卡上呼叫wglMakeCurrent(sDC, sRC);时,它完全崩溃了。我没有物理访问此视频卡。

在我的方法中,我在第一个sRC的基础上重复使用相同的sDC

现在,我已经读过"如果两个窗口都使用相同的像素格式,则对两个窗口使用1个GL上下文" (http://www.opengl.org/wiki/Platform_specifics:_Windows#Multiple_Windows)您可以使用单个上下文和多个窗口(DC)执行此操作,并且如上所述,我的实现在所有其他视频卡上都能正常工作。

static HDC sDC = NULL;
static HGLRC sRC = NULL;
static HWND sOldWindow = NULL;

void GfxReset(HWND newWindow) {
    if (sCurrentWindow != newWindow) {
         if (sDC) {
            AssertWGL(wglMakeCurrent(sDC, NULL));
            AssertWGL(ReleaseDC(sCurrentWindow, sDC));
        }

        sDC = GetDC(newWindow);
        Assert(sDC);

        PrepareDC(sDC);

        //Create the render context.
        if (!sRC) {
            sRC = wglCreateContext(sDC);
            Assert(sRC);
        }

        AssertWGL(wglMakeCurrent(sDC, sRC)); // CRASH (not assertion)

        sCurrentWindow = newWindow;
    }
}

static void PrepareDC(HDC hDC) {
    PIXELFORMATDESCRIPTOR pfd;
    ZeroMemory(&pfd, sizeof(pfd));
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 32;
    pfd.cDepthBits = 16;
    pfd.cStencilBits = 8;
    pfd.iLayerType = PFD_MAIN_PLANE;
    int format = ChoosePixelFormat(hDC, &pfd);
    Assert(format);
    Assert(SetPixelFormat(hDC, format, &pfd));
}

我知道我可以使用多个上下文并使用wglShareLists来实现此功能。我不想采取这种方式,因为必须在资产加载和诸如此类的方面重构很多代码。

有没有办法在OpenGL中使用单个上下文实现多个窗口,从而大大简化了纹理创建。否则,我必须知道我的应用程序中的所有窗口,并在开始加载纹理之前预先应用wglShareLists,对吗?

编辑:我还尝试通过以下方式实现wglCreateContextAttribsARBhttp://www.opengl.org/wiki/Tutorial%3a_OpenGL_3.1_The_First_Triangle_%28C%2B%2B/Win%29但是,驱动程序在调用本身崩溃。

1 个答案:

答案 0 :(得分:1)

首先,让我告诉你它是多么伟大,你的目标是上下文重用。但是,如果您需要解决驱动程序错误(这就是您正在遇到的问题,您所做的事情必须永远不会使程序崩溃。最坏的情况只会产生错误),然后使用wglShareLists解决它。

只要没有对象ID冲突,合并两个上下文的命名空间就完全没问题了。这意味着,您的主要上下文已经可以加载纹理和资源,只要您将命名空间合并到的上下文是" virgin"。那么"年龄较大的现有资产"上下文也会出现在新的上下文中。


我注意到你的代码:你写道:wglMakeCurrent(sDC, NULL)表明你有一个概念,一个OpenGL RC以某种方式&#34;绑定&#34;一个可绘制的DC。这不是发生的事情。该关联实际上是在上下文和线程之间。建议的来电是wglMakeCurrent(NULL, NULL),坦率地说,我甚至不知道wglMakeCurrent(<someDC not NULL>, NULL)的结果是否实际定义了。也许这实际上是你麻烦的原因。