Beispiel #1
0
static unsigned GetFakeWindowExtensions(void)
{
    WNDCLASSEX wc;
    PIXELFORMATDESCRIPTOR pfd;
    int pixelformat;
    HWND wnd;
    HDC dc;
    HGLRC rc;
    unsigned extensions = 0;

    memset(&wc, 0, sizeof(wc));
    wc.cbSize = sizeof(wc);
    wc.lpfnWndProc = DefWindowProc;
    wc.hInstance = hGlobalInstance;
    wc.lpszClassName = FAKE_WINDOW_CLASS;

    if (!RegisterClassEx(&wc))
        goto fail0;

    wnd = CreateWindow(
        FAKE_WINDOW_CLASS,
        FAKE_WINDOW_NAME,
        0,
        0, 0, 0, 0,
        NULL,
        NULL,
        hGlobalInstance,
        NULL);
    if (!wnd)
        goto fail1;

    if ((dc = GetDC(wnd)) == NULL)
        goto fail2;

    memset(&pfd, 0, 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 = 24;
    pfd.cDepthBits = 24;
    pfd.cStencilBits = 8;
    pfd.iLayerType = PFD_MAIN_PLANE;

    if (glw.minidriver) {
        if ((pixelformat = qwglChoosePixelFormat(dc, &pfd)) == 0)
            goto fail3;

        if (qwglSetPixelFormat(dc, pixelformat, &pfd) == FALSE)
            goto fail3;
    } else {
        if ((pixelformat = ChoosePixelFormat(dc, &pfd)) == 0)
            goto fail3;

        if (SetPixelFormat(dc, pixelformat, &pfd) == FALSE)
            goto fail3;
    }

    if ((rc = qwglCreateContext(dc)) == NULL)
        goto fail3;

    if (qwglMakeCurrent(dc, rc) == FALSE)
        goto fail4;

    WGL_InitExtensions(QWGL_ARB_extensions_string);

    if (!qwglGetExtensionsStringARB)
        goto fail5;

    extensions = WGL_ParseExtensionString(qwglGetExtensionsStringARB(dc));

    if (extensions & QWGL_ARB_pixel_format) {
        Com_Printf("...enabling WGL_ARB_pixel_format\n");
        WGL_InitExtensions(QWGL_ARB_pixel_format);
    }

fail5:
    qwglMakeCurrent(NULL, NULL);
fail4:
    qwglDeleteContext(rc);
fail3:
    ReleaseDC(wnd, dc);
fail2:
    DestroyWindow(wnd);
fail1:
    UnregisterClass(FAKE_WINDOW_CLASS, hGlobalInstance);
fail0:
    return extensions;
}
Beispiel #2
0
/*
VID_Init

This routine is responsible for initializing the OS specific portions
of OpenGL.  Under Win32 this means dealing with the pixelformats and
doing the wgl interface stuff.
*/
qboolean VID_Init(void)
{
    const char *extensions;
    int ret;

    gl_driver = Cvar_Get("gl_driver", "opengl32", CVAR_ARCHIVE | CVAR_REFRESH);
    gl_drawbuffer = Cvar_Get("gl_drawbuffer", "GL_BACK", 0);
    gl_swapinterval = Cvar_Get("gl_swapinterval", "1", CVAR_ARCHIVE);
    gl_allow_software = Cvar_Get("gl_allow_software", "0", 0);
    gl_colorbits = Cvar_Get("gl_colorbits", "0", CVAR_REFRESH);
    gl_depthbits = Cvar_Get("gl_depthbits", "0", CVAR_REFRESH);
    gl_stencilbits = Cvar_Get("gl_stencilbits", "8", CVAR_REFRESH);
    gl_multisamples = Cvar_Get("gl_multisamples", "0", CVAR_REFRESH);

    // don't allow absolute or relative paths
    FS_SanitizeFilenameVariable(gl_driver);

    // load and initialize the OpenGL driver
    ret = LoadGL(gl_driver->string);

    // attempt to recover if this was a minidriver
    if (ret == FAIL_SOFT && glw.minidriver) {
        Com_Printf("...falling back to opengl32\n");
        Cvar_Reset(gl_driver);
        ret = LoadGL(gl_driver->string);
    }

    // it failed, abort
    if (ret)
        return qfalse;

    // initialize WGL extensions
    WGL_InitExtensions(QWGL_ARB_extensions_string);

    if (qwglGetExtensionsStringARB)
        extensions = qwglGetExtensionsStringARB(win.dc);
    else
        extensions = NULL;

    // fall back to GL_EXTENSIONS for legacy drivers
    if (!extensions || !*extensions)
        extensions = (const char *)qwglGetString(GL_EXTENSIONS);

    glw.extensions = WGL_ParseExtensionString(extensions);

    if (glw.extensions & QWGL_EXT_swap_control) {
        if (glw.extensions & QWGL_EXT_swap_control_tear)
            Com_Printf("...enabling WGL_EXT_swap_control(_tear)\n");
        else
            Com_Printf("...enabling WGL_EXT_swap_control\n");
        WGL_InitExtensions(QWGL_EXT_swap_control);
        gl_swapinterval->changed = gl_swapinterval_changed;
        gl_swapinterval_changed(gl_swapinterval);
    } else {
        Com_Printf("WGL_EXT_swap_control not found\n");
        Cvar_Set("gl_swapinterval", "0");
    }

    gl_drawbuffer->changed = gl_drawbuffer_changed;
    gl_drawbuffer_changed(gl_drawbuffer);

    VID_SetMode();

    return qtrue;
}
Beispiel #3
0
static int LoadGL(const char *driver)
{
    int colorbits = Cvar_ClampInteger(gl_colorbits, 0, 32);
    int depthbits = Cvar_ClampInteger(gl_depthbits, 0, 32);
    int stencilbits = Cvar_ClampInteger(gl_stencilbits, 0, 8);
    int multisamples = Cvar_ClampInteger(gl_multisamples, 0, 32);
    int ret;

    // figure out if we're running on a minidriver or not
    if (!Q_stricmp(driver, "opengl32") ||
        !Q_stricmp(driver, "opengl32.dll")) {
        glw.minidriver = qfalse;
    } else {
        Com_Printf("...running a minidriver: %s\n", driver);
        glw.minidriver = qtrue;
    }

    // load the OpenGL library and bind to it
    if (!WGL_Init(driver)) {
        ReportLastError("WGL_Init");
        return FAIL_SOFT;
    }

    // check if basic WGL entry points are present
    if (!qwglCreateContext || !qwglMakeCurrent || !qwglDeleteContext) {
        Com_EPrintf("Required WGL entry points are missing\n");
        goto fail;
    }

    if (glw.minidriver) {
        // check if MCD entry points are present if using a minidriver
        if (!qwglChoosePixelFormat || !qwglSetPixelFormat ||
            !qwglDescribePixelFormat || !qwglSwapBuffers) {
            Com_EPrintf("Required MCD entry points are missing\n");
            goto fail;
        }
    }

    // check for WGL_ARB_multisample by creating a fake window
    if (multisamples > 1) {
        unsigned extensions = GetFakeWindowExtensions();

        if (extensions & QWGL_ARB_multisample) {
            if (extensions & QWGL_ARB_pixel_format) {
                Com_Printf("...enabling WGL_ARB_pixel_format\n");
                Com_Printf("...enabling WGL_ARB_multisample\n");
                WGL_InitExtensions(QWGL_ARB_pixel_format);
            } else {
                Com_Printf("...ignoring WGL_ARB_multisample, WGL_ARB_pixel_format not found\n");
                Cvar_Set("gl_multisamples", "0");
                multisamples = 0;
            }
        } else {
            Com_Printf("WGL_ARB_multisample not found\n");
            Cvar_Set("gl_multisamples", "0");
            multisamples = 0;
        }
    }

    // create window, choose PFD, setup OpenGL context
    ret = SetupGL(colorbits, depthbits, stencilbits, multisamples);

    // attempt to recover
    if (ret == FAIL_SOFT && (colorbits || depthbits || stencilbits || multisamples > 1))
        ret = SetupGL(0, 0, 0, 0);

    if (ret)
        goto fail;

    return FAIL_OK;

fail:
    // it failed, clean up
    WGL_Shutdown();
    return FAIL_SOFT;
}