示例#1
0
bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
{
    QGLTemporaryContext tempContext;

    PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB =
        (PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB");
    PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB =
        (PFNWGLGETPBUFFERDCARBPROC) wglGetProcAddress("wglGetPbufferDCARB");
    PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB =
        (PFNWGLQUERYPBUFFERARBPROC) wglGetProcAddress("wglQueryPbufferARB");
    PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB =
        (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");

    if (!wglCreatePbufferARB) // assumes that if one can be resolved, all of them can
        return false;

    dc = wglGetCurrentDC();
    Q_ASSERT(dc);
    has_render_texture = false;

    // sample buffers doesn't work in conjunction with the render_texture extension
    if (!f.sampleBuffers()) {
        PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB =
                (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");

        if (wglGetExtensionsStringARB) {
            QString extensions(QLatin1String(wglGetExtensionsStringARB(dc)));
            has_render_texture = extensions.contains(QLatin1String("WGL_ARB_render_texture"));
        }
    }

    int attribs[40];
    qt_format_to_attrib_list(has_render_texture, f, attribs);

    // Find pbuffer capable pixel format.
    unsigned int num_formats = 0;
    int pixel_format;
    wglChoosePixelFormatARB(dc, attribs, 0, 1, &pixel_format, &num_formats);

    // some GL implementations don't support pbuffers with accum
    // buffers, so try that before we give up
    if (num_formats == 0 && f.accum()) {
        QGLFormat tmp = f;
        tmp.setAccum(false);
        qt_format_to_attrib_list(has_render_texture, tmp, attribs);
        wglChoosePixelFormatARB(dc, attribs, 0, 1, &pixel_format, &num_formats);
    }

    if (num_formats == 0) {
        qWarning("QGLPixelBuffer: Unable to find a pixel format with pbuffer  - giving up.");
        return false;
    }
    format = pfiToQGLFormat(dc, pixel_format);

    // NB! The below ONLY works if the width/height are powers of 2.
    // Set some pBuffer attributes so that we can use this pBuffer as
    // a 2D RGBA texture target.
    int pb_attribs[] = {WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
                        WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, 0};
    int pb_attribs_null[] = {0};

    pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(),
                               has_render_texture ? pb_attribs : pb_attribs_null);
    if (!pbuf) {
        // try again without the render_texture extension
        pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(), pb_attribs_null);
        has_render_texture = false;
        if (!pbuf) {
            qWarning("QGLPixelBuffer: Unable to create pbuffer [w=%d, h=%d] - giving up.", size.width(), size.height());
            return false;
        }
    }

    dc = wglGetPbufferDCARB(pbuf);
    ctx = wglCreateContext(dc);
    if (!dc || !ctx) {
        qWarning("QGLPixelBuffer: Unable to create pbuffer context - giving up.");
        return false;
    }

    // Explicitly disable the render_texture extension if we have a 
    // multi-sampled pbuffer context. This seems to be a problem only with 
    // ATI cards if multi-sampling is forced globally in the driver.
    wglMakeCurrent(dc, ctx);
    GLint samples = 0;
    glGetIntegerv(GL_SAMPLES_ARB, &samples);
    if (has_render_texture && samples != 0)
        has_render_texture = false;

    HGLRC share_ctx = shareWidget ? shareWidget->d_func()->glcx->d_func()->rc : 0;
    if (share_ctx && !wglShareLists(share_ctx, ctx))
        qWarning("QGLPixelBuffer: Unable to share display lists - with share widget.");

    int width, height;
    wglQueryPbufferARB(pbuf, WGL_PBUFFER_WIDTH_ARB, &width);
    wglQueryPbufferARB(pbuf, WGL_PBUFFER_HEIGHT_ARB, &height);
    return true;
}
bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
{
    QGLWidget dmy;
    dmy.makeCurrent(); // needed for wglGetProcAddress() to succeed

    PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB =
        (PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB");
    PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB =
        (PFNWGLGETPBUFFERDCARBPROC) wglGetProcAddress("wglGetPbufferDCARB");
    PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB =
        (PFNWGLQUERYPBUFFERARBPROC) wglGetProcAddress("wglQueryPbufferARB");
    PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB =
        (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");

    if (!wglCreatePbufferARB) // assumes that if one can be resolved, all of them can
        return false;

    dc = GetDC(dmy.winId());
    Q_ASSERT(dc);

    PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB =
        (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");

    if (wglGetExtensionsStringARB) {
        QString extensions(QLatin1String(wglGetExtensionsStringARB(dc)));
        has_render_texture = extensions.contains(QLatin1String("WGL_ARB_render_texture"));
    }

    int attribs[40];
    qt_format_to_attrib_list(has_render_texture, f, attribs);

    // Find pbuffer capable pixel format.
    unsigned int num_formats = 0;
    int pixel_format;
    wglChoosePixelFormatARB(dc, attribs, 0, 1, &pixel_format, &num_formats);

    // some GL implementations don't support pbuffers with accum
    // buffers, so try that before we give up
    if (num_formats == 0 && f.accum()) {
        QGLFormat tmp = f;
        tmp.setAccum(false);
        qt_format_to_attrib_list(has_render_texture, tmp, attribs);
        wglChoosePixelFormatARB(dc, attribs, 0, 1, &pixel_format, &num_formats);
    }

    if (num_formats == 0) {
        qWarning("QGLPixelBuffer: Unable to find a pixel format with pbuffer  - giving up.");
        ReleaseDC(dmy.winId(), dc);
        return false;
    }
    format = pfiToQGLFormat(dc, pixel_format);

    // NB! The below ONLY works if the width/height are powers of 2.
    // Set some pBuffer attributes so that we can use this pBuffer as
    // a 2D RGBA texture target.
    int pb_attribs[] = {WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
                        WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, 0};

    pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(),
                               has_render_texture ? pb_attribs : 0);
    if(!pbuf) {
        // try again without the render_texture extension
        pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(), 0);
        has_render_texture = false;
        if (!pbuf) {
            qWarning("QGLPixelBuffer: Unable to create pbuffer [w=%d, h=%d] - giving up.", size.width(), size.height());
            ReleaseDC(dmy.winId(), dc);
            return false;
        }
    }

    ReleaseDC(dmy.winId(), dc);
    dc = wglGetPbufferDCARB(pbuf);
    ctx = wglCreateContext(dc);

    if (!dc || !ctx) {
        qWarning("QGLPixelBuffer: Unable to create pbuffer context - giving up.");
        return false;
    }

    HGLRC share_ctx = shareWidget ? shareWidget->d_func()->glcx->d_func()->rc : 0;
    if (share_ctx && !wglShareLists(share_ctx, ctx))
        qWarning("QGLPixelBuffer: Unable to share display lists - with share widget.");

    int width, height;
    wglQueryPbufferARB(pbuf, WGL_PBUFFER_WIDTH_ARB, &width);
    wglQueryPbufferARB(pbuf, WGL_PBUFFER_HEIGHT_ARB, &height);
    return true;
}