626 return fmt; |
626 return fmt; |
627 } |
627 } |
628 |
628 |
629 |
629 |
630 /* |
630 /* |
631 Creates a temporary GL context and makes it current |
631 QGLTemporaryContext implementation |
632 - cleans up when the object is destructed. |
|
633 */ |
632 */ |
634 |
633 |
635 Q_GUI_EXPORT const QString qt_getRegisteredWndClass(); |
634 Q_GUI_EXPORT const QString qt_getRegisteredWndClass(); |
636 |
635 |
637 class QGLTempContext |
636 class QGLTemporaryContextPrivate |
638 { |
637 { |
639 public: |
638 public: |
640 QGLTempContext(bool directRendering, QWidget *parent = 0) |
|
641 { |
|
642 QString windowClassName = qt_getRegisteredWndClass(); |
|
643 if (parent && !parent->internalWinId()) |
|
644 parent = parent->nativeParentWidget(); |
|
645 |
|
646 dmy_id = CreateWindow((const wchar_t *)windowClassName.utf16(), |
|
647 0, 0, 0, 0, 1, 1, |
|
648 parent ? parent->winId() : 0, 0, qWinAppInst(), 0); |
|
649 |
|
650 dmy_pdc = GetDC(dmy_id); |
|
651 PIXELFORMATDESCRIPTOR dmy_pfd; |
|
652 memset(&dmy_pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); |
|
653 dmy_pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); |
|
654 dmy_pfd.nVersion = 1; |
|
655 dmy_pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; |
|
656 dmy_pfd.iPixelType = PFD_TYPE_RGBA; |
|
657 if (!directRendering) |
|
658 dmy_pfd.dwFlags |= PFD_GENERIC_FORMAT; |
|
659 |
|
660 int dmy_pf = ChoosePixelFormat(dmy_pdc, &dmy_pfd); |
|
661 SetPixelFormat(dmy_pdc, dmy_pf, &dmy_pfd); |
|
662 dmy_rc = wglCreateContext(dmy_pdc); |
|
663 old_dc = wglGetCurrentDC(); |
|
664 old_context = wglGetCurrentContext(); |
|
665 wglMakeCurrent(dmy_pdc, dmy_rc); |
|
666 } |
|
667 |
|
668 ~QGLTempContext() { |
|
669 wglMakeCurrent(dmy_pdc, 0); |
|
670 wglDeleteContext(dmy_rc); |
|
671 ReleaseDC(dmy_id, dmy_pdc); |
|
672 DestroyWindow(dmy_id); |
|
673 if (old_dc && old_context) |
|
674 wglMakeCurrent(old_dc, old_context); |
|
675 } |
|
676 |
|
677 HDC dmy_pdc; |
639 HDC dmy_pdc; |
678 HGLRC dmy_rc; |
640 HGLRC dmy_rc; |
679 HDC old_dc; |
641 HDC old_dc; |
680 HGLRC old_context; |
642 HGLRC old_context; |
681 WId dmy_id; |
643 WId dmy_id; |
682 }; |
644 }; |
|
645 |
|
646 QGLTemporaryContext::QGLTemporaryContext(bool directRendering, QWidget *parent) |
|
647 : d(new QGLTemporaryContextPrivate) |
|
648 { |
|
649 QString windowClassName = qt_getRegisteredWndClass(); |
|
650 if (parent && !parent->internalWinId()) |
|
651 parent = parent->nativeParentWidget(); |
|
652 |
|
653 d->dmy_id = CreateWindow((const wchar_t *)windowClassName.utf16(), |
|
654 0, 0, 0, 0, 1, 1, |
|
655 parent ? parent->winId() : 0, 0, qWinAppInst(), 0); |
|
656 |
|
657 d->dmy_pdc = GetDC(d->dmy_id); |
|
658 PIXELFORMATDESCRIPTOR dmy_pfd; |
|
659 memset(&dmy_pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); |
|
660 dmy_pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); |
|
661 dmy_pfd.nVersion = 1; |
|
662 dmy_pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; |
|
663 dmy_pfd.iPixelType = PFD_TYPE_RGBA; |
|
664 if (!directRendering) |
|
665 dmy_pfd.dwFlags |= PFD_GENERIC_FORMAT; |
|
666 |
|
667 int dmy_pf = ChoosePixelFormat(d->dmy_pdc, &dmy_pfd); |
|
668 SetPixelFormat(d->dmy_pdc, dmy_pf, &dmy_pfd); |
|
669 d->dmy_rc = wglCreateContext(d->dmy_pdc); |
|
670 d->old_dc = wglGetCurrentDC(); |
|
671 d->old_context = wglGetCurrentContext(); |
|
672 wglMakeCurrent(d->dmy_pdc, d->dmy_rc); |
|
673 } |
|
674 |
|
675 QGLTemporaryContext::~QGLTemporaryContext() |
|
676 { |
|
677 wglMakeCurrent(d->dmy_pdc, 0); |
|
678 wglDeleteContext(d->dmy_rc); |
|
679 ReleaseDC(d->dmy_id, d->dmy_pdc); |
|
680 DestroyWindow(d->dmy_id); |
|
681 if (d->old_dc && d->old_context) |
|
682 wglMakeCurrent(d->old_dc, d->old_context); |
|
683 } |
683 |
684 |
684 bool QGLContext::chooseContext(const QGLContext* shareContext) |
685 bool QGLContext::chooseContext(const QGLContext* shareContext) |
685 { |
686 { |
686 Q_D(QGLContext); |
687 Q_D(QGLContext); |
687 // workaround for matrox driver: |
688 // workaround for matrox driver: |
719 widget = static_cast<QWidget *>(d->paintDevice); |
720 widget = static_cast<QWidget *>(d->paintDevice); |
720 d->win = widget->winId(); |
721 d->win = widget->winId(); |
721 myDc = GetDC(d->win); |
722 myDc = GetDC(d->win); |
722 } |
723 } |
723 |
724 |
724 // NB! the QGLTempContext object is needed for the |
725 // NB! the QGLTemporaryContext object is needed for the |
725 // wglGetProcAddress() calls to succeed and are absolutely |
726 // wglGetProcAddress() calls to succeed and are absolutely |
726 // necessary - don't remove! |
727 // necessary - don't remove! |
727 QGLTempContext tmp_ctx(d->glFormat.directRendering(), widget); |
728 QGLTemporaryContext tmp_ctx(d->glFormat.directRendering(), widget); |
728 |
729 |
729 if (!myDc) { |
730 if (!myDc) { |
730 qWarning("QGLContext::chooseContext(): Paint device cannot be null"); |
731 qWarning("QGLContext::chooseContext(): Paint device cannot be null"); |
731 result = false; |
732 result = false; |
732 goto end; |
733 goto end; |
963 if (d->glFormat.hasOverlay()) { |
964 if (d->glFormat.hasOverlay()) { |
964 iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB; |
965 iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB; |
965 iAttributes[i++] = 1; |
966 iAttributes[i++] = 1; |
966 } |
967 } |
967 int si = 0; |
968 int si = 0; |
968 bool trySampleBuffers = QGLExtensions::glExtensions & QGLExtensions::SampleBuffers; |
969 bool trySampleBuffers = QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers; |
969 if (trySampleBuffers && d->glFormat.sampleBuffers()) { |
970 if (trySampleBuffers && d->glFormat.sampleBuffers()) { |
970 iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; |
971 iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; |
971 iAttributes[i++] = TRUE; |
972 iAttributes[i++] = TRUE; |
972 iAttributes[i++] = WGL_SAMPLES_ARB; |
973 iAttributes[i++] = WGL_SAMPLES_ARB; |
973 si = i; |
974 si = i; |