Пример #1
0
/*!
    \since 4.8

    Returns a platform window format for the OpenGL format specified by \a format.
*/
QPlatformWindowFormat QGLFormat::toPlatformWindowFormat(const QGLFormat &format)
{
    QPlatformWindowFormat retFormat;
    retFormat.setAccum(format.accum());
    if (format.accumBufferSize() >= 0)
        retFormat.setAccumBufferSize(format.accumBufferSize());
    retFormat.setAlpha(format.alpha());
    if (format.alphaBufferSize() >= 0)
        retFormat.setAlphaBufferSize(format.alphaBufferSize());
    if (format.blueBufferSize() >= 0)
        retFormat.setBlueBufferSize(format.blueBufferSize());
    retFormat.setDepth(format.depth());
    if (format.depthBufferSize() >= 0)
        retFormat.setDepthBufferSize(format.depthBufferSize());
    retFormat.setDirectRendering(format.directRendering());
    retFormat.setDoubleBuffer(format.doubleBuffer());
    if (format.greenBufferSize() >= 0)
        retFormat.setGreenBufferSize(format.greenBufferSize());
    if (format.redBufferSize() >= 0)
        retFormat.setRedBufferSize(format.redBufferSize());
    retFormat.setRgba(format.rgba());
    retFormat.setSampleBuffers(format.sampleBuffers());
    if (format.samples() >= 0)
        retFormat.setSamples(format.samples());
    retFormat.setStencil(format.stencil());
    if (format.stencilBufferSize() >= 0)
        retFormat.setStencilBufferSize(format.stencilBufferSize());
    retFormat.setStereo(format.stereo());
    retFormat.setSwapInterval(format.swapInterval());
    return retFormat;
}
Пример #2
0
inline void GL3DShaderWidget::checkOpenGLPixelFormat(const QGLFormat &fmt)
{
    QGLFormat lRealFormat = format();

    if(fmt.depth() && !lRealFormat.depth()) printf("OpenGL Buffer Warning: depth buffer requested but NOT granted.\n");
    if(fmt.alpha() && !lRealFormat.alpha()) printf("OpenGL Buffer Warning: alpha buffer requested but not granted.\n");

    if(!fmt.doubleBuffer() && lRealFormat.doubleBuffer()) printf("OpenGL Buffer Warning: single buffer requested but NOT granted.\n");
    if(fmt.doubleBuffer() && !lRealFormat.doubleBuffer()) printf("OpenGL Buffer Warning: double buffer requested but NOT granted.\n");
    if(fmt.stereo() && !lRealFormat.stereo()) printf("OpenGL Buffer Warning: stereo buffer requested but NOT granted.\n");

    if(!fmt.rgba() && lRealFormat.rgba()) printf("OpenGL Buffer Warning: indexed color mode requested but NOT granted.\n");
    if(fmt.rgba() && !lRealFormat.rgba()) printf("OpenGL Buffer Warning: RGBA color mode requested but NOT granted.\n");
    if(fmt.sampleBuffers() && !lRealFormat.sampleBuffers()) printf("OpenGL Buffer Warning: multisample buffers requested but NOT granted.\n");

    if(fmt.accum() && !lRealFormat.accum()) printf("OpenGL Buffer Warning: accumulation buffer requested but not granted.\n");
    if(fmt.stencil() && !lRealFormat.stencil()) printf("OpenGL Buffer Warning: stencil buffer requested but not granted.\n");
    fflush(stdout);
}
Пример #3
0
void *QGLContext::chooseVisual()
{
    static int bufDepths[] = { 8, 4, 2, 1 };	// Try 16, 12 also?
    //todo: if pixmap, also make sure that vi->depth == pixmap->depth
    void* vis = 0;
    int i = 0;
    bool fail = FALSE;
    QGLFormat fmt = format();
    bool tryDouble = !fmt.doubleBuffer();  // Some GL impl's only have double
    bool triedDouble = FALSE;
    while( !fail && !( vis = tryVisual( fmt, bufDepths[i] ) ) ) {
	if ( !fmt.rgba() && bufDepths[i] > 1 ) {
	    i++;
	    continue;
	}
	if ( tryDouble ) {
	    fmt.setDoubleBuffer( TRUE );
	    tryDouble = FALSE;
	    triedDouble = TRUE;
	    continue;
	}
	else if ( triedDouble ) {
	    fmt.setDoubleBuffer( FALSE );
	    triedDouble = FALSE;
	}
	if ( fmt.stereo() ) {
	    fmt.setStereo( FALSE );
	    continue;
	}
	if ( fmt.accum() ) {
	    fmt.setAccum( FALSE );
	    continue;
	}
	if ( fmt.stencil() ) {
	    fmt.setStencil( FALSE );
	    continue;
	}
	if ( fmt.alpha() ) {
	    fmt.setAlpha( FALSE );
	    continue;
	}
	if ( fmt.depth() ) {
	    fmt.setDepth( FALSE );
	    continue;
	}
	if ( fmt.doubleBuffer() ) {
	    fmt.setDoubleBuffer( FALSE );
	    continue;
	}
	fail = TRUE;
    }
    glFormat = fmt;
    return vis;
}
Пример #4
0
static void qt_format_to_attrib_list(const QGLFormat &f, int attribs[])
{
    int i = 0;
    attribs[i++] = GLX_RENDER_TYPE;
    attribs[i++] = GLX_RGBA_BIT;
    attribs[i++] = GLX_DRAWABLE_TYPE;
    attribs[i++] = GLX_PBUFFER_BIT;
    attribs[i++] = GLX_RED_SIZE;
    attribs[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize();
    attribs[i++] = GLX_GREEN_SIZE;
    attribs[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize();
    attribs[i++] = GLX_BLUE_SIZE;
    attribs[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize();
    if (f.doubleBuffer()) {
        attribs[i++] = GLX_DOUBLEBUFFER;
        attribs[i++] = true;
    }
    if (f.depth()) {
        attribs[i++] = GLX_DEPTH_SIZE;
        attribs[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize();
    }
    if (f.stereo()) {
        attribs[i++] = GLX_STEREO;
        attribs[i++] = true;
    }
    if (f.stencil()) {
        attribs[i++] = GLX_STENCIL_SIZE;
        attribs[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize();
    }
    if (f.alpha()) {
        attribs[i++] = GLX_ALPHA_SIZE;
        attribs[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize();
    }
    if (f.accum()) {
        attribs[i++] = GLX_ACCUM_RED_SIZE;
        attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
        attribs[i++] = GLX_ACCUM_GREEN_SIZE;
        attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
        attribs[i++] = GLX_ACCUM_BLUE_SIZE;
        attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
        if (f.alpha()) {
            attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
            attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
        }
    }
    if (f.sampleBuffers()) {
        attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
        attribs[i++] = 1;
        attribs[i++] = GLX_SAMPLES_ARB;
        attribs[i++] = f.samples() == -1 ? 4 : f.samples();
    }

    attribs[i] = XNone;
}
Пример #5
0
string glinfo::
        pretty_format(const QGLFormat& f)
{
    QGLFormat::OpenGLVersionFlags flag = f.openGLVersionFlags();

    stringstream s;
    s << "accum=" << f.accum() << endl
      << "accumBufferSize=" << f.accumBufferSize() << endl
      << "alpha=" << f.alpha() << endl
      << "alphaBufferSize=" << f.alphaBufferSize() << endl
      << "blueBufferSize=" << f.blueBufferSize() << endl
      << "depth=" << f.depth() << endl
      << "depthBufferSize=" << f.depthBufferSize() << endl
      << "directRendering=" << f.directRendering() << endl
      << "doubleBuffer=" << f.doubleBuffer() << endl
      << "greenBufferSize=" << f.greenBufferSize() << endl
      << "hasOverlay=" << f.hasOverlay() << endl
      << "redBufferSize=" << f.redBufferSize() << endl
      << "rgba=" << f.rgba() << endl
      << "sampleBuffers=" << f.sampleBuffers() << endl
      << "samples=" << f.samples() << endl
      << "stencil=" << f.stencil() << endl
      << "stencilBufferSize=" << f.stencilBufferSize() << endl
      << "stereo=" << f.stereo() << endl
      << "swapInterval=" << f.swapInterval() << endl
      << "" << endl
      << "hasOpenGL=" << f.hasOpenGL() << endl
      << "hasOpenGLOverlays=" << f.hasOpenGLOverlays() << endl
      << "OpenGL_Version_None=" << (QGLFormat::OpenGL_Version_None == flag) << endl
      << "OpenGL_Version_1_1=" << (QGLFormat::OpenGL_Version_1_1 & flag) << endl
      << "OpenGL_Version_1_2=" << (QGLFormat::OpenGL_Version_1_2 & flag) << endl
      << "OpenGL_Version_1_3=" << (QGLFormat::OpenGL_Version_1_3 & flag) << endl
      << "OpenGL_Version_1_4=" << (QGLFormat::OpenGL_Version_1_4 & flag) << endl
      << "OpenGL_Version_1_5=" << (QGLFormat::OpenGL_Version_1_5 & flag) << endl
      << "OpenGL_Version_2_0=" << (QGLFormat::OpenGL_Version_2_0 & flag) << endl
      << "OpenGL_Version_2_1=" << (QGLFormat::OpenGL_Version_2_1 & flag) << endl
      << "OpenGL_Version_3_0=" << (QGLFormat::OpenGL_Version_3_0 & flag) << endl
      << "OpenGL_ES_CommonLite_Version_1_0=" << (QGLFormat::OpenGL_ES_CommonLite_Version_1_0 & flag) << endl
      << "OpenGL_ES_Common_Version_1_0=" << (QGLFormat::OpenGL_ES_Common_Version_1_0 & flag) << endl
      << "OpenGL_ES_CommonLite_Version_1_1=" << (QGLFormat::OpenGL_ES_CommonLite_Version_1_1 & flag) << endl
      << "OpenGL_ES_Common_Version_1_1=" << (QGLFormat::OpenGL_ES_Common_Version_1_1 & flag) << endl
      << "OpenGL_ES_Version_2_0=" << (QGLFormat::OpenGL_ES_Version_2_0 & flag) << endl;

    return s.str();
}
Пример #6
0
QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL)
    : QGraphicsSystem(), m_useX11GL(useX11GL)
{
#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)
    // only override the system defaults if the user hasn't already
    // picked a visual
    if (X11->visual == 0 && X11->visual_id == -1 && X11->visual_class == -1) {
        // find a double buffered, RGBA visual that supports OpenGL
        // and set that as the default visual for windows in Qt
        int i = 0;
        int spec[16];
        spec[i++] = GLX_RGBA;
        spec[i++] = GLX_DOUBLEBUFFER;

        if (!qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull()) {
            spec[i++] = GLX_DEPTH_SIZE;
            spec[i++] = 8;
            spec[i++] = GLX_STENCIL_SIZE;
            spec[i++] = 8;
            spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
            spec[i++] = 1;
            spec[i++] = GLX_SAMPLES_ARB;
            spec[i++] = 4;
        }

        spec[i++] = XNone;

        XVisualInfo *vi = glXChooseVisual(X11->display, X11->defaultScreen, spec);
        if (vi) {
            X11->visual_id = vi->visualid;
            X11->visual_class = vi->c_class;

            QGLFormat format;
            int res;
            glXGetConfig(X11->display, vi, GLX_LEVEL, &res);
            format.setPlane(res);
            glXGetConfig(X11->display, vi, GLX_DOUBLEBUFFER, &res);
            format.setDoubleBuffer(res);
            glXGetConfig(X11->display, vi, GLX_DEPTH_SIZE, &res);
            format.setDepth(res);
            if (format.depth())
                format.setDepthBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_RGBA, &res);
            format.setRgba(res);
            glXGetConfig(X11->display, vi, GLX_RED_SIZE, &res);
            format.setRedBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_GREEN_SIZE, &res);
            format.setGreenBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_BLUE_SIZE, &res);
            format.setBlueBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_ALPHA_SIZE, &res);
            format.setAlpha(res);
            if (format.alpha())
                format.setAlphaBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_ACCUM_RED_SIZE, &res);
            format.setAccum(res);
            if (format.accum())
                format.setAccumBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_STENCIL_SIZE, &res);
            format.setStencil(res);
            if (format.stencil())
                format.setStencilBufferSize(res);
            glXGetConfig(X11->display, vi, GLX_STEREO, &res);
            format.setStereo(res);
            glXGetConfig(X11->display, vi, GLX_SAMPLE_BUFFERS_ARB, &res);
            format.setSampleBuffers(res);
            if (format.sampleBuffers()) {
                glXGetConfig(X11->display, vi, GLX_SAMPLES_ARB, &res);
                format.setSamples(res);
            }

            QGLWindowSurface::surfaceFormat = format;
            XFree(vi);

            printf("using visual class %x, id %x\n", X11->visual_class, X11->visual_id);
        }
    }
#elif defined(Q_WS_WIN)
    QGLWindowSurface::surfaceFormat.setDoubleBuffer(true);

    qt_win_owndc_required = true;
#endif
}
Пример #7
0
/*
  See qgl.cpp for qdoc comment.
 */
void *QGLContext::chooseVisual()
{
    Q_D(QGLContext);
    static const int bufDepths[] = { 8, 4, 2, 1 };        // Try 16, 12 also?
    //todo: if pixmap, also make sure that vi->depth == pixmap->depth
    void* vis = 0;
    int i = 0;
    bool fail = false;
    QGLFormat fmt = format();
    bool tryDouble = !fmt.doubleBuffer();  // Some GL impl's only have double
    bool triedDouble = false;
    bool triedSample = false;
    if (fmt.sampleBuffers())
        fmt.setSampleBuffers(QGLExtensions::glExtensions & QGLExtensions::SampleBuffers);
    while(!fail && !(vis = tryVisual(fmt, bufDepths[i]))) {
        if (!fmt.rgba() && bufDepths[i] > 1) {
            i++;
            continue;
        }
        if (tryDouble) {
            fmt.setDoubleBuffer(true);
            tryDouble = false;
            triedDouble = true;
            continue;
        } else if (triedDouble) {
            fmt.setDoubleBuffer(false);
            triedDouble = false;
        }
        if (!triedSample && fmt.sampleBuffers()) {
            fmt.setSampleBuffers(false);
            triedSample = true;
            continue;
        }
        if (fmt.stereo()) {
            fmt.setStereo(false);
            continue;
        }
        if (fmt.accum()) {
            fmt.setAccum(false);
            continue;
        }
        if (fmt.stencil()) {
            fmt.setStencil(false);
            continue;
        }
        if (fmt.alpha()) {
            fmt.setAlpha(false);
            continue;
        }
        if (fmt.depth()) {
            fmt.setDepth(false);
            continue;
        }
        if (fmt.doubleBuffer()) {
            fmt.setDoubleBuffer(false);
            continue;
        }
        fail = true;
    }
    d->glFormat = fmt;
    return vis;
}
Пример #8
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;
}
Пример #9
0
static void qt_format_to_attrib_list(bool has_render_texture, const QGLFormat &f, int attribs[])
{
    int i = 0;
    attribs[i++] = WGL_SUPPORT_OPENGL_ARB;
    attribs[i++] = TRUE;
    attribs[i++] = WGL_DRAW_TO_PBUFFER_ARB;
    attribs[i++] = TRUE;

    if (has_render_texture) {
        attribs[i++] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
        attribs[i++] = TRUE;
    }

    attribs[i++] = WGL_COLOR_BITS_ARB;
    attribs[i++] = 32;
    attribs[i++] = WGL_DOUBLE_BUFFER_ARB;
    attribs[i++] = FALSE;

    if (f.stereo()) {
        attribs[i++] = WGL_STEREO_ARB;
        attribs[i++] = TRUE;
    }
    if (f.depth()) {
        attribs[i++] = WGL_DEPTH_BITS_ARB;
        attribs[i++] = f.depthBufferSize() == -1 ? 24 : f.depthBufferSize();
    }
    if (f.redBufferSize() != -1) {
        attribs[i++] = WGL_RED_BITS_ARB;
        attribs[i++] = f.redBufferSize();
    }
    if (f.greenBufferSize() != -1) {
        attribs[i++] = WGL_GREEN_BITS_ARB;
        attribs[i++] = f.greenBufferSize();
    }
    if (f.blueBufferSize() != -1) {
        attribs[i++] = WGL_BLUE_BITS_ARB;
        attribs[i++] = f.blueBufferSize();
    }
    if (f.alpha()) {
        attribs[i++] = WGL_ALPHA_BITS_ARB;
        attribs[i++] = f.alphaBufferSize() == -1 ? 8 : f.alphaBufferSize();
    }
    if (f.accum()) {
        attribs[i++] = WGL_ACCUM_BITS_ARB;
        attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
    }
    if (f.stencil()) {
        attribs[i++] = WGL_STENCIL_BITS_ARB;
        attribs[i++] = f.stencilBufferSize() == -1 ? 8 : f.stencilBufferSize();
    }
    if ((f.redBufferSize() > 8 || f.greenBufferSize() > 8
         || f.blueBufferSize() > 8 || f.alphaBufferSize() > 8)
        && (QGLExtensions::glExtensions() & QGLExtensions::NVFloatBuffer))
    {
        attribs[i++] = WGL_FLOAT_COMPONENTS_NV;
        attribs[i++] = TRUE;
    }
    if (f.sampleBuffers()) {
        attribs[i++] = WGL_SAMPLE_BUFFERS_ARB;
        attribs[i++] = 1;
        attribs[i++] = WGL_SAMPLES_ARB;
        attribs[i++] = f.samples() == -1 ? 16 : f.samples();
    }
    attribs[i] = 0;
}
Пример #10
0
AGLPixelFormat QGLContextPrivate::tryFormat(const QGLFormat &format)
{
    GLint attribs[40], cnt = 0;
    bool device_is_pixmap = (paintDevice->devType() == QInternal::Pixmap);

    attribs[cnt++] = AGL_RGBA;
    attribs[cnt++] = AGL_BUFFER_SIZE;
    attribs[cnt++] = device_is_pixmap ? static_cast<QPixmap *>(paintDevice)->depth() : 32;
    attribs[cnt++] = AGL_LEVEL;
    attribs[cnt++] = format.plane();

    if (format.redBufferSize() != -1) {
        attribs[cnt++] = AGL_RED_SIZE;
        attribs[cnt++] = format.redBufferSize();
    }
    if (format.greenBufferSize() != -1) {
        attribs[cnt++] = AGL_GREEN_SIZE;
        attribs[cnt++] = format.greenBufferSize();
    }
    if (format.blueBufferSize() != -1) {
        attribs[cnt++] = AGL_BLUE_SIZE;
        attribs[cnt++] = format.blueBufferSize();
    }
    if (device_is_pixmap) {
        attribs[cnt++] = AGL_PIXEL_SIZE;
        attribs[cnt++] = static_cast<QPixmap *>(paintDevice)->depth();
        attribs[cnt++] = AGL_OFFSCREEN;
        if(!format.alpha()) {
            attribs[cnt++] = AGL_ALPHA_SIZE;
            attribs[cnt++] = 8;
        }
    } else {
        if(format.doubleBuffer())
            attribs[cnt++] = AGL_DOUBLEBUFFER;
    }

    if(glFormat.stereo())
        attribs[cnt++] = AGL_STEREO;
    if(format.alpha()) {
        attribs[cnt++] = AGL_ALPHA_SIZE;
        attribs[cnt++] = format.alphaBufferSize() == -1 ? 8 : format.alphaBufferSize();
    }
    if(format.stencil()) {
        attribs[cnt++] = AGL_STENCIL_SIZE;
        attribs[cnt++] = format.stencilBufferSize() == -1 ? 8 : format.stencilBufferSize();
    }
    if(format.depth()) {
        attribs[cnt++] = AGL_DEPTH_SIZE;
        attribs[cnt++] = format.depthBufferSize() == -1 ? 32 : format.depthBufferSize();
    }
    if(format.accum()) {
        attribs[cnt++] = AGL_ACCUM_RED_SIZE;
        attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
        attribs[cnt++] = AGL_ACCUM_BLUE_SIZE;
        attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
        attribs[cnt++] = AGL_ACCUM_GREEN_SIZE;
        attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
        attribs[cnt++] = AGL_ACCUM_ALPHA_SIZE;
        attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
    }
    if(format.sampleBuffers()) {
        attribs[cnt++] = AGL_SAMPLE_BUFFERS_ARB;
        attribs[cnt++] = 1;
        attribs[cnt++] = AGL_SAMPLES_ARB;
        attribs[cnt++] = format.samples() == -1 ? 4 : format.samples();
    }

    attribs[cnt] = AGL_NONE;
    Q_ASSERT(cnt < 40);
    return aglChoosePixelFormat(0, 0, attribs);
}
Пример #11
0
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;
}