3

我目前有一个适用于除 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在开始加载纹理之前预先应用这些窗口,对吗?

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

4

1 回答 1

1

首先,让我告诉你它有多棒,你的目标是上下文重用。但是,如果您需要解决驱动程序错误(也就是说,您遇到的问题,您所做的事情绝不能使程序崩溃。最坏的情况只会产生错误),那么请使用 wglShareLists 解决它。

只要没有对象 ID 冲突,合并两个上下文的命名空间就很好。这意味着,您的主要上下文已经可以加载纹理和资产,只要您将命名空间合并到的上下文是“处女”。然后,“旧”上下文的所有现有资产也将出现在新的上下文中。


我注意到您的代码:您写道:wglMakeCurrent(sDC, NULL)这表明您有这样的概念,即 OpenGL RC 以某种方式“绑定”到可绘制 DC。这不是发生的事情。该关联实际上是在上下文和线程之间。推荐的调用是wglMakeCurrent(NULL, NULL),坦率地说,我什至不知道 a 的结果wglMakeCurrent(<someDC not NULL>, NULL)是否真的被定义了。也许这实际上是你麻烦的原因。

于 2014-07-25T09:19:02.623 回答