src/opengl/qgl_win.cpp
branchRCL_3
changeset 4 3b1da2848fc7
parent 0 1918ee327afb
equal deleted inserted replaced
3:41300fa6a67c 4:3b1da2848fc7
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtOpenGL module of the Qt Toolkit.
     7 ** This file is part of the QtOpenGL module of the Qt Toolkit.
     8 **
     8 **
   549 {
   549 {
   550     QGLFormat fmt;
   550     QGLFormat fmt;
   551     QVarLengthArray<int> iAttributes(40);
   551     QVarLengthArray<int> iAttributes(40);
   552     QVarLengthArray<int> iValues(40);
   552     QVarLengthArray<int> iValues(40);
   553     int i = 0;
   553     int i = 0;
   554     bool has_sample_buffers = QGLExtensions::glExtensions & QGLExtensions::SampleBuffers;
   554     bool has_sample_buffers = QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers;
   555 
   555 
   556     iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; // 0
   556     iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; // 0
   557     iAttributes[i++] = WGL_DEPTH_BITS_ARB; // 1
   557     iAttributes[i++] = WGL_DEPTH_BITS_ARB; // 1
   558     iAttributes[i++] = WGL_PIXEL_TYPE_ARB; // 2
   558     iAttributes[i++] = WGL_PIXEL_TYPE_ARB; // 2
   559     iAttributes[i++] = WGL_RED_BITS_ARB; // 3
   559     iAttributes[i++] = WGL_RED_BITS_ARB; // 3
   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;
  1143     d->valid = false;
  1144     d->valid = false;
  1144     d->transpColor = QColor();
  1145     d->transpColor = QColor();
  1145     delete d->cmap;
  1146     delete d->cmap;
  1146     d->cmap = 0;
  1147     d->cmap = 0;
  1147     d->initDone = false;
  1148     d->initDone = false;
  1148     qgl_share_reg()->removeShare(this);
  1149     QGLContextGroup::removeShare(this);
  1149 }
  1150 }
  1150 
  1151 
  1151 //
  1152 //
  1152 // NOTE: In a multi-threaded environment, each thread has a current
  1153 // NOTE: In a multi-threaded environment, each thread has a current
  1153 // context. If we want to make this code thread-safe, we probably
  1154 // context. If we want to make this code thread-safe, we probably
  1469         free(lpal);
  1470         free(lpal);
  1470         d->updateColormap();
  1471         d->updateColormap();
  1471     }
  1472     }
  1472 }
  1473 }
  1473 
  1474 
  1474 void QGLExtensions::init()
       
  1475 {
       
  1476     static bool init_done = false;
       
  1477 
       
  1478     if (init_done)
       
  1479         return;
       
  1480     init_done = true;
       
  1481     QGLTempContext temp_ctx(QGLFormat::defaultFormat().directRendering());
       
  1482     init_extensions();
       
  1483 }
       
  1484 
       
  1485 QT_END_NAMESPACE
  1475 QT_END_NAMESPACE