summaryrefslogtreecommitdiffstats
path: root/src/opengl/qgl_win.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/qgl_win.cpp')
-rw-r--r--src/opengl/qgl_win.cpp1601
1 files changed, 0 insertions, 1601 deletions
diff --git a/src/opengl/qgl_win.cpp b/src/opengl/qgl_win.cpp
deleted file mode 100644
index 3b1643f4c2..0000000000
--- a/src/opengl/qgl_win.cpp
+++ /dev/null
@@ -1,1601 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <qgl.h>
-#include <qlist.h>
-#include <qmap.h>
-#include <qpixmap.h>
-#include <qevent.h>
-#include <private/qgl_p.h>
-#include <qcolormap.h>
-#include <qvarlengtharray.h>
-#include <qdebug.h>
-#include <qcolor.h>
-
-#include <qt_windows.h>
-
-typedef bool (APIENTRY *PFNWGLGETPIXELFORMATATTRIBIVARB)(HDC hdc,
- int iPixelFormat,
- int iLayerPlane,
- uint nAttributes,
- const int *piAttributes,
- int *piValues);
-typedef bool (APIENTRY *PFNWGLCHOOSEPIXELFORMATARB)(HDC hdc,
- const int *piAttribList,
- const float *pfAttribFList,
- uint nMaxFormats,
- int *piFormats,
- UINT *nNumFormats);
-#ifndef WGL_ARB_multisample
-#define WGL_SAMPLE_BUFFERS_ARB 0x2041
-#define WGL_SAMPLES_ARB 0x2042
-#endif
-
-#ifndef WGL_ARB_pixel_format
-#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
-#define WGL_DRAW_TO_WINDOW_ARB 0x2001
-#define WGL_DRAW_TO_BITMAP_ARB 0x2002
-#define WGL_ACCELERATION_ARB 0x2003
-#define WGL_NEED_PALETTE_ARB 0x2004
-#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
-#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
-#define WGL_SWAP_METHOD_ARB 0x2007
-#define WGL_NUMBER_OVERLAYS_ARB 0x2008
-#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
-#define WGL_TRANSPARENT_ARB 0x200A
-#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
-#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
-#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
-#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
-#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
-#define WGL_SHARE_DEPTH_ARB 0x200C
-#define WGL_SHARE_STENCIL_ARB 0x200D
-#define WGL_SHARE_ACCUM_ARB 0x200E
-#define WGL_SUPPORT_GDI_ARB 0x200F
-#define WGL_SUPPORT_OPENGL_ARB 0x2010
-#define WGL_DOUBLE_BUFFER_ARB 0x2011
-#define WGL_STEREO_ARB 0x2012
-#define WGL_PIXEL_TYPE_ARB 0x2013
-#define WGL_COLOR_BITS_ARB 0x2014
-#define WGL_RED_BITS_ARB 0x2015
-#define WGL_RED_SHIFT_ARB 0x2016
-#define WGL_GREEN_BITS_ARB 0x2017
-#define WGL_GREEN_SHIFT_ARB 0x2018
-#define WGL_BLUE_BITS_ARB 0x2019
-#define WGL_BLUE_SHIFT_ARB 0x201A
-#define WGL_ALPHA_BITS_ARB 0x201B
-#define WGL_ALPHA_SHIFT_ARB 0x201C
-#define WGL_ACCUM_BITS_ARB 0x201D
-#define WGL_ACCUM_RED_BITS_ARB 0x201E
-#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
-#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
-#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
-#define WGL_DEPTH_BITS_ARB 0x2022
-#define WGL_STENCIL_BITS_ARB 0x2023
-#define WGL_AUX_BUFFERS_ARB 0x2024
-#define WGL_NO_ACCELERATION_ARB 0x2025
-#define WGL_GENERIC_ACCELERATION_ARB 0x2026
-#define WGL_FULL_ACCELERATION_ARB 0x2027
-#define WGL_SWAP_EXCHANGE_ARB 0x2028
-#define WGL_SWAP_COPY_ARB 0x2029
-#define WGL_SWAP_UNDEFINED_ARB 0x202A
-#define WGL_TYPE_RGBA_ARB 0x202B
-#define WGL_TYPE_COLORINDEX_ARB 0x202C
-#endif
-
-#ifndef WGL_ARB_create_context
-#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
-#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
-#define WGL_CONTEXT_FLAGS_ARB 0x2094
-#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
-#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
-#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
-#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x0001
-#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x0002
-// Error codes returned by GetLastError().
-#define ERROR_INVALID_VERSION_ARB 0x2095
-#define ERROR_INVALID_PROFILE_ARB 0x2096
-#endif
-
-#ifndef GL_VERSION_3_2
-#define GL_CONTEXT_PROFILE_MASK 0x9126
-#define GL_MAJOR_VERSION 0x821B
-#define GL_MINOR_VERSION 0x821C
-#define GL_NUM_EXTENSIONS 0x821D
-#define GL_CONTEXT_FLAGS 0x821E
-#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QGLCmapPrivate
-{
-public:
- QGLCmapPrivate() : count(1) { }
- void ref() { ++count; }
- bool deref() { return !--count; }
- uint count;
-
- enum AllocState{ UnAllocated = 0, Allocated = 0x01, Reserved = 0x02 };
-
- int maxSize;
- QVector<uint> colorArray;
- QVector<quint8> allocArray;
- QVector<quint8> contextArray;
- QMap<uint,int> colorMap;
-};
-
-/*****************************************************************************
- QColorMap class - temporarily here, until it is ready for prime time
- *****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QColorMap class
-**
-****************************************************************************/
-
-class QGLCmapPrivate;
-
-class /*Q_EXPORT*/ QGLCmap
-{
-public:
- enum Flags { Reserved = 0x01 };
-
- QGLCmap(int maxSize = 256);
- QGLCmap(const QGLCmap& map);
- ~QGLCmap();
-
- QGLCmap& operator=(const QGLCmap& map);
-
- // isEmpty and/or isNull ?
- int size() const;
- int maxSize() const;
-
- void resize(int newSize);
-
- int find(QRgb color) const;
- int findNearest(QRgb color) const;
- int allocate(QRgb color, uint flags = 0, quint8 context = 0);
-
- void setEntry(int idx, QRgb color, uint flags = 0, quint8 context = 0);
-
- const QRgb* colors() const;
-
-private:
- void detach();
- QGLCmapPrivate* d;
-};
-
-
-QGLCmap::QGLCmap(int maxSize) // add a bool prealloc?
-{
- d = new QGLCmapPrivate;
- d->maxSize = maxSize;
-}
-
-
-QGLCmap::QGLCmap(const QGLCmap& map)
-{
- d = map.d;
- d->ref();
-}
-
-
-QGLCmap::~QGLCmap()
-{
- if (d && d->deref())
- delete d;
- d = 0;
-}
-
-
-QGLCmap& QGLCmap::operator=(const QGLCmap& map)
-{
- map.d->ref();
- if (d->deref())
- delete d;
- d = map.d;
- return *this;
-}
-
-
-int QGLCmap::size() const
-{
- return d->colorArray.size();
-}
-
-
-int QGLCmap::maxSize() const
-{
- return d->maxSize;
-}
-
-
-void QGLCmap::detach()
-{
- if (d->count != 1) {
- d->deref();
- QGLCmapPrivate* newd = new QGLCmapPrivate;
- newd->maxSize = d->maxSize;
- newd->colorArray = d->colorArray;
- newd->allocArray = d->allocArray;
- newd->contextArray = d->contextArray;
- newd->colorArray.detach();
- newd->allocArray.detach();
- newd->contextArray.detach();
- newd->colorMap = d->colorMap;
- d = newd;
- }
-}
-
-
-void QGLCmap::resize(int newSize)
-{
- if (newSize < 0 || newSize > d->maxSize) {
- qWarning("QGLCmap::resize(): size out of range");
- return;
- }
- int oldSize = size();
- detach();
- //if shrinking; remove the lost elems from colorMap
- d->colorArray.resize(newSize);
- d->allocArray.resize(newSize);
- d->contextArray.resize(newSize);
- if (newSize > oldSize) {
- memset(d->allocArray.data() + oldSize, 0, newSize - oldSize);
- memset(d->contextArray.data() + oldSize, 0, newSize - oldSize);
- }
-}
-
-
-int QGLCmap::find(QRgb color) const
-{
- QMap<uint,int>::ConstIterator it = d->colorMap.find(color);
- if (it != d->colorMap.end())
- return *it;
- return -1;
-}
-
-
-int QGLCmap::findNearest(QRgb color) const
-{
- int idx = find(color);
- if (idx >= 0)
- return idx;
- int mapSize = size();
- int mindist = 200000;
- int r = qRed(color);
- int g = qGreen(color);
- int b = qBlue(color);
- int rx, gx, bx, dist;
- for (int i=0; i < mapSize; i++) {
- if (!(d->allocArray[i] & QGLCmapPrivate::Allocated))
- continue;
- QRgb ci = d->colorArray[i];
- rx = r - qRed(ci);
- gx = g - qGreen(ci);
- bx = b - qBlue(ci);
- dist = rx*rx + gx*gx + bx*bx; // calculate distance
- if (dist < mindist) { // minimal?
- mindist = dist;
- idx = i;
- }
- }
- return idx;
-}
-
-
-
-
-// Does not always allocate; returns existing c idx if found
-
-int QGLCmap::allocate(QRgb color, uint flags, quint8 context)
-{
- int idx = find(color);
- if (idx >= 0)
- return idx;
-
- int mapSize = d->colorArray.size();
- int newIdx = d->allocArray.indexOf(QGLCmapPrivate::UnAllocated);
-
- if (newIdx < 0) { // Must allocate more room
- if (mapSize < d->maxSize) {
- newIdx = mapSize;
- mapSize++;
- resize(mapSize);
- }
- else {
- //# add a bool param that says what to do in case no more room -
- // fail (-1) or return nearest?
- return -1;
- }
- }
-
- d->colorArray[newIdx] = color;
- if (flags & QGLCmap::Reserved) {
- d->allocArray[newIdx] = QGLCmapPrivate::Reserved;
- }
- else {
- d->allocArray[newIdx] = QGLCmapPrivate::Allocated;
- d->colorMap.insert(color, newIdx);
- }
- d->contextArray[newIdx] = context;
- return newIdx;
-}
-
-
-void QGLCmap::setEntry(int idx, QRgb color, uint flags, quint8 context)
-{
- if (idx < 0 || idx >= d->maxSize) {
- qWarning("QGLCmap::set(): Index out of range");
- return;
- }
- detach();
- int mapSize = size();
- if (idx >= mapSize) {
- mapSize = idx + 1;
- resize(mapSize);
- }
- d->colorArray[idx] = color;
- if (flags & QGLCmap::Reserved) {
- d->allocArray[idx] = QGLCmapPrivate::Reserved;
- }
- else {
- d->allocArray[idx] = QGLCmapPrivate::Allocated;
- d->colorMap.insert(color, idx);
- }
- d->contextArray[idx] = context;
-}
-
-
-const QRgb* QGLCmap::colors() const
-{
- return d->colorArray.data();
-}
-
-
-
-/*****************************************************************************
- QGLFormat Win32/WGL-specific code
- *****************************************************************************/
-
-
-void qwglError(const char* method, const char* func)
-{
-#ifndef QT_NO_DEBUG
- char* lpMsgBuf;
- FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- 0, GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (char*) &lpMsgBuf, 0, 0);
- qWarning("%s : %s failed: %s", method, func, lpMsgBuf);
- LocalFree(lpMsgBuf);
-#else
- Q_UNUSED(method);
- Q_UNUSED(func);
-#endif
-}
-
-
-
-bool QGLFormat::hasOpenGL()
-{
- return true;
-}
-
-static bool opengl32dll = false;
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- // workaround for matrox driver:
- // make a cheap call to opengl to force loading of DLL
- if (!opengl32dll) {
- GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
- opengl32dll = true;
- }
-
- static bool checkDone = false;
- static bool hasOl = false;
-
- if (!checkDone) {
- checkDone = true;
- HDC display_dc = GetDC(0);
- int pfiMax = DescribePixelFormat(display_dc, 0, 0, NULL);
- PIXELFORMATDESCRIPTOR pfd;
- for (int pfi = 1; pfi <= pfiMax; pfi++) {
- DescribePixelFormat(display_dc, pfi, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
- if ((pfd.bReserved & 0x0f) && (pfd.dwFlags & PFD_SUPPORT_OPENGL)) {
- // This format has overlays/underlays
- LAYERPLANEDESCRIPTOR lpd;
- wglDescribeLayerPlane(display_dc, pfi, 1,
- sizeof(LAYERPLANEDESCRIPTOR), &lpd);
- if (lpd.dwFlags & LPD_SUPPORT_OPENGL) {
- hasOl = true;
- break;
- }
- }
- }
- ReleaseDC(0, display_dc);
- }
- return hasOl;
-}
-
-
-/*****************************************************************************
- QGLContext Win32/WGL-specific code
- *****************************************************************************/
-
-static uchar qgl_rgb_palette_comp(int idx, uint nbits, uint shift)
-{
- const uchar map_3_to_8[8] = {
- 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
- };
- const uchar map_2_to_8[4] = {
- 0, 0x55, 0xaa, 0xff
- };
- const uchar map_1_to_8[2] = {
- 0, 255
- };
-
- uchar val = (uchar) (idx >> shift);
- uchar res = 0;
- switch (nbits) {
- case 1:
- val &= 0x1;
- res = map_1_to_8[val];
- break;
- case 2:
- val &= 0x3;
- res = map_2_to_8[val];
- break;
- case 3:
- val &= 0x7;
- res = map_3_to_8[val];
- break;
- default:
- res = 0;
- }
- return res;
-}
-
-
-static QRgb* qgl_create_rgb_palette(const PIXELFORMATDESCRIPTOR* pfd)
-{
- if ((pfd->iPixelType != PFD_TYPE_RGBA) ||
- !(pfd->dwFlags & PFD_NEED_PALETTE) ||
- (pfd->cColorBits != 8))
- return 0;
- int numEntries = 1 << pfd->cColorBits;
- QRgb* pal = new QRgb[numEntries];
- for (int i = 0; i < numEntries; i++) {
- int r = qgl_rgb_palette_comp(i, pfd->cRedBits, pfd->cRedShift);
- int g = qgl_rgb_palette_comp(i, pfd->cGreenBits, pfd->cGreenShift);
- int b = qgl_rgb_palette_comp(i, pfd->cBlueBits, pfd->cBlueShift);
- pal[i] = qRgb(r, g, b);
- }
-
- const int syscol_indices[12] = {
- 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91
- };
-
- const uint syscols[20] = {
- 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080,
- 0x008080, 0xc0c0c0, 0xc0dcc0, 0xa6caf0, 0xfffbf0, 0xa0a0a4,
- 0x808080, 0xff0000, 0x00ff00, 0xffff00, 0x0000ff, 0xff00ff,
- 0x00ffff, 0xffffff
- }; // colors #1 - #12 are not present in pal; gets added below
-
- if ((pfd->cColorBits == 8) &&
- (pfd->cRedBits == 3) && (pfd->cRedShift == 0) &&
- (pfd->cGreenBits == 3) && (pfd->cGreenShift == 3) &&
- (pfd->cBlueBits == 2) && (pfd->cBlueShift == 6)) {
- for (int j = 0 ; j < 12 ; j++)
- pal[syscol_indices[j]] = QRgb(syscols[j+1]);
- }
-
- return pal;
-}
-
-static QGLFormat pfdToQGLFormat(const PIXELFORMATDESCRIPTOR* pfd)
-{
- QGLFormat fmt;
- fmt.setDoubleBuffer(pfd->dwFlags & PFD_DOUBLEBUFFER);
- fmt.setDepth(pfd->cDepthBits);
- if (fmt.depth())
- fmt.setDepthBufferSize(pfd->cDepthBits);
- fmt.setRgba(pfd->iPixelType == PFD_TYPE_RGBA);
- fmt.setRedBufferSize(pfd->cRedBits);
- fmt.setGreenBufferSize(pfd->cGreenBits);
- fmt.setBlueBufferSize(pfd->cBlueBits);
- fmt.setAlpha(pfd->cAlphaBits);
- if (fmt.alpha())
- fmt.setAlphaBufferSize(pfd->cAlphaBits);
- fmt.setAccum(pfd->cAccumBits);
- if (fmt.accum())
- fmt.setAccumBufferSize(pfd->cAccumRedBits);
- fmt.setStencil(pfd->cStencilBits);
- if (fmt.stencil())
- fmt.setStencilBufferSize(pfd->cStencilBits);
- fmt.setStereo(pfd->dwFlags & PFD_STEREO);
- fmt.setDirectRendering((pfd->dwFlags & PFD_GENERIC_ACCELERATED) ||
- !(pfd->dwFlags & PFD_GENERIC_FORMAT));
- fmt.setOverlay((pfd->bReserved & 0x0f) != 0);
- return fmt;
-}
-
-/*
- NB! requires a current GL context to work
-*/
-QGLFormat pfiToQGLFormat(HDC hdc, int pfi)
-{
- QGLFormat fmt;
- QVarLengthArray<int> iAttributes(40);
- QVarLengthArray<int> iValues(40);
- int i = 0;
- bool has_sample_buffers = QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers;
-
- iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; // 0
- iAttributes[i++] = WGL_DEPTH_BITS_ARB; // 1
- iAttributes[i++] = WGL_PIXEL_TYPE_ARB; // 2
- iAttributes[i++] = WGL_RED_BITS_ARB; // 3
- iAttributes[i++] = WGL_GREEN_BITS_ARB; // 4
- iAttributes[i++] = WGL_BLUE_BITS_ARB; // 5
- iAttributes[i++] = WGL_ALPHA_BITS_ARB; // 6
- iAttributes[i++] = WGL_ACCUM_BITS_ARB; // 7
- iAttributes[i++] = WGL_STENCIL_BITS_ARB; // 8
- iAttributes[i++] = WGL_STEREO_ARB; // 9
- iAttributes[i++] = WGL_ACCELERATION_ARB; // 10
- iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB; // 11
- if (has_sample_buffers) {
- iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; // 12
- iAttributes[i++] = WGL_SAMPLES_ARB; // 13
- }
- PFNWGLGETPIXELFORMATATTRIBIVARB wglGetPixelFormatAttribivARB =
- (PFNWGLGETPIXELFORMATATTRIBIVARB) wglGetProcAddress("wglGetPixelFormatAttribivARB");
-
- if (wglGetPixelFormatAttribivARB
- && wglGetPixelFormatAttribivARB(hdc, pfi, 0, i,
- iAttributes.constData(),
- iValues.data()))
- {
- fmt.setDoubleBuffer(iValues[0]);
- fmt.setDepth(iValues[1]);
- if (fmt.depth())
- fmt.setDepthBufferSize(iValues[1]);
- fmt.setRgba(iValues[2] == WGL_TYPE_RGBA_ARB);
- fmt.setRedBufferSize(iValues[3]);
- fmt.setGreenBufferSize(iValues[4]);
- fmt.setBlueBufferSize(iValues[5]);
- fmt.setAlpha(iValues[6]);
- if (fmt.alpha())
- fmt.setAlphaBufferSize(iValues[6]);
- fmt.setAccum(iValues[7]);
- if (fmt.accum())
- fmt.setAccumBufferSize(iValues[7]);
- fmt.setStencil(iValues[8]);
- if (fmt.stencil())
- fmt.setStencilBufferSize(iValues[8]);
- fmt.setStereo(iValues[9]);
- if (iValues[10] == WGL_FULL_ACCELERATION_ARB)
- fmt.setDirectRendering(true);
- else
- fmt.setDirectRendering(false);
- fmt.setOverlay(iValues[11]);
- if (has_sample_buffers) {
- fmt.setSampleBuffers(iValues[12]);
- if (fmt.sampleBuffers())
- fmt.setSamples(iValues[13]);
- }
- }
-#if 0
- qDebug() << "values for pfi:" << pfi;
- qDebug() << "doublebuffer 0:" << fmt.doubleBuffer();
- qDebug() << "depthbuffer 1:" << fmt.depthBufferSize();
- qDebug() << "rgba 2:" << fmt.rgba();
- qDebug() << "red size 3:" << fmt.redBufferSize();
- qDebug() << "green size 4:" << fmt.greenBufferSize();
- qDebug() << "blue size 5:" << fmt.blueBufferSize();
- qDebug() << "alpha size 6:" << fmt.alphaBufferSize();
- qDebug() << "accum size 7:" << fmt.accumBufferSize();
- qDebug() << "stencil size 8:" << fmt.stencilBufferSize();
- qDebug() << "stereo 9:" << fmt.stereo();
- qDebug() << "direct 10:" << fmt.directRendering();
- qDebug() << "has overlays 11:" << fmt.hasOverlay();
- qDebug() << "sample buff 12:" << fmt.sampleBuffers();
- qDebug() << "num samples 13:" << fmt.samples();
-#endif
- return fmt;
-}
-
-
-/*
- QGLTemporaryContext implementation
-*/
-
-Q_GUI_EXPORT const QString qt_getRegisteredWndClass();
-
-class QGLTemporaryContextPrivate
-{
-public:
- HDC dmy_pdc;
- HGLRC dmy_rc;
- HDC old_dc;
- HGLRC old_context;
- WId dmy_id;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool directRendering, QWidget *parent)
- : d(new QGLTemporaryContextPrivate)
-{
- QString windowClassName = qt_getRegisteredWndClass();
- if (parent && !parent->internalWinId())
- parent = parent->nativeParentWidget();
-
- d->dmy_id = CreateWindow((const wchar_t *)windowClassName.utf16(),
- 0, 0, 0, 0, 1, 1,
- parent ? parent->winId() : 0, 0, qWinAppInst(), 0);
-
- d->dmy_pdc = GetDC(d->dmy_id);
- PIXELFORMATDESCRIPTOR dmy_pfd;
- memset(&dmy_pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
- dmy_pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
- dmy_pfd.nVersion = 1;
- dmy_pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
- dmy_pfd.iPixelType = PFD_TYPE_RGBA;
- if (!directRendering)
- dmy_pfd.dwFlags |= PFD_GENERIC_FORMAT;
-
- int dmy_pf = ChoosePixelFormat(d->dmy_pdc, &dmy_pfd);
- SetPixelFormat(d->dmy_pdc, dmy_pf, &dmy_pfd);
- d->dmy_rc = wglCreateContext(d->dmy_pdc);
- d->old_dc = wglGetCurrentDC();
- d->old_context = wglGetCurrentContext();
- wglMakeCurrent(d->dmy_pdc, d->dmy_rc);
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- wglMakeCurrent(d->dmy_pdc, 0);
- wglDeleteContext(d->dmy_rc);
- ReleaseDC(d->dmy_id, d->dmy_pdc);
- DestroyWindow(d->dmy_id);
- if (d->old_dc && d->old_context)
- wglMakeCurrent(d->old_dc, d->old_context);
-}
-
-static bool qgl_create_context(HDC hdc, QGLContextPrivate *d, QGLContextPrivate *shareContext)
-{
- d->rc = 0;
-
- typedef HGLRC (APIENTRYP PFNWGLCREATECONTEXTATTRIBSARB)(HDC, HGLRC, const int *);
- PFNWGLCREATECONTEXTATTRIBSARB wglCreateContextAttribsARB =
- (PFNWGLCREATECONTEXTATTRIBSARB) wglGetProcAddress("wglCreateContextAttribsARB");
- if (wglCreateContextAttribsARB) {
- int attributes[11];
- int attribIndex = 0;
- const int major = d->reqFormat.majorVersion();
- const int minor = d->reqFormat.minorVersion();
- attributes[attribIndex++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
- attributes[attribIndex++] = major;
- attributes[attribIndex++] = WGL_CONTEXT_MINOR_VERSION_ARB;
- attributes[attribIndex++] = minor;
-
- if (major >= 3 && !d->reqFormat.testOption(QGL::DeprecatedFunctions)) {
- attributes[attribIndex++] = WGL_CONTEXT_FLAGS_ARB;
- attributes[attribIndex++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
- }
-
- if ((major == 3 && minor >= 2) || major > 3) {
- switch (d->reqFormat.profile()) {
- case QGLFormat::NoProfile:
- break;
- case QGLFormat::CoreProfile:
- attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB;
- attributes[attribIndex++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
- break;
- case QGLFormat::CompatibilityProfile:
- attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB;
- attributes[attribIndex++] = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
- break;
- default:
- qWarning("QGLContext::chooseContext(): Context profile not supported.");
- return false;
- }
- }
-
- if (d->reqFormat.plane() != 0) {
- attributes[attribIndex++] = WGL_CONTEXT_LAYER_PLANE_ARB;
- attributes[attribIndex++] = d->reqFormat.plane();
- }
-
- attributes[attribIndex++] = 0; // Terminate list.
- d->rc = wglCreateContextAttribsARB(hdc, shareContext && shareContext->valid
- ? shareContext->rc : 0, attributes);
- if (d->rc) {
- if (shareContext)
- shareContext->sharing = d->sharing = true;
- return true;
- }
- }
-
- d->rc = wglCreateLayerContext(hdc, d->reqFormat.plane());
- if (d->rc && shareContext && shareContext->valid)
- shareContext->sharing = d->sharing = wglShareLists(shareContext->rc, d->rc);
- return d->rc != 0;
-}
-
-void QGLContextPrivate::updateFormatVersion()
-{
- const GLubyte *s = glGetString(GL_VERSION);
-
- if (!(s && s[0] >= '0' && s[0] <= '9' && s[1] == '.' && s[2] >= '0' && s[2] <= '9')) {
- if (!s)
- qWarning("QGLContext::chooseContext(): OpenGL version string is null.");
- else
- qWarning("QGLContext::chooseContext(): Unexpected OpenGL version string format.");
- glFormat.setVersion(0, 0);
- glFormat.setProfile(QGLFormat::NoProfile);
- glFormat.setOption(QGL::DeprecatedFunctions);
- return;
- }
-
- int major = s[0] - '0';
- int minor = s[2] - '0';
- glFormat.setVersion(major, minor);
-
- if (major < 3) {
- glFormat.setProfile(QGLFormat::NoProfile);
- glFormat.setOption(QGL::DeprecatedFunctions);
- } else {
- GLint value = 0;
- if (major > 3 || minor >= 2)
- glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
-
- switch (value) {
- case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
- glFormat.setProfile(QGLFormat::CoreProfile);
- break;
- case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
- glFormat.setProfile(QGLFormat::CompatibilityProfile);
- break;
- default:
- glFormat.setProfile(QGLFormat::NoProfile);
- break;
- }
-
- glGetIntegerv(GL_CONTEXT_FLAGS, &value);
- if (value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
- glFormat.setOption(QGL::NoDeprecatedFunctions);
- else
- glFormat.setOption(QGL::DeprecatedFunctions);
- }
-}
-
-bool QGLContext::chooseContext(const QGLContext* shareContext)
-{
- QGLContextPrivate *share = shareContext ? const_cast<QGLContext *>(shareContext)->d_func() : 0;
-
- Q_D(QGLContext);
- // workaround for matrox driver:
- // make a cheap call to opengl to force loading of DLL
- if (!opengl32dll) {
- GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
- opengl32dll = true;
- }
-
- bool result = true;
- HDC myDc;
- QWidget *widget = 0;
-
- if (deviceIsPixmap()) {
- if (d->glFormat.plane())
- return false; // Pixmaps can't have overlay
- d->win = 0;
- HDC display_dc = GetDC(0);
- myDc = d->hbitmap_hdc = CreateCompatibleDC(display_dc);
- QPixmap *px = static_cast<QPixmap *>(d->paintDevice);
-
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = px->width();
- bmi.bmiHeader.biHeight = px->height();
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- d->hbitmap = CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, 0, 0, 0);
- SelectObject(myDc, d->hbitmap);
- ReleaseDC(0, display_dc);
- } else {
- widget = static_cast<QWidget *>(d->paintDevice);
- d->win = widget->winId();
- myDc = GetDC(d->win);
- }
-
- // NB! the QGLTemporaryContext object is needed for the
- // wglGetProcAddress() calls to succeed and are absolutely
- // necessary - don't remove!
- QGLTemporaryContext tmp_ctx(d->glFormat.directRendering(), widget);
-
- if (!myDc) {
- qWarning("QGLContext::chooseContext(): Paint device cannot be null");
- result = false;
- goto end;
- }
-
- if (d->glFormat.plane()) {
- d->pixelFormatId = ((QGLWidget*)d->paintDevice)->context()->d_func()->pixelFormatId;
- if (!d->pixelFormatId) { // I.e. the glwidget is invalid
- qWarning("QGLContext::chooseContext(): Cannot create overlay context for invalid widget");
- result = false;
- goto end;
- }
-
- if (!qgl_create_context(myDc, d, share)) {
- qwglError("QGLContext::chooseContext()", "CreateLayerContext");
- result = false;
- goto end;
- }
-
- LAYERPLANEDESCRIPTOR lpfd;
- wglDescribeLayerPlane(myDc, d->pixelFormatId, d->glFormat.plane(), sizeof(LAYERPLANEDESCRIPTOR), &lpfd);
- d->glFormat.setDoubleBuffer(lpfd.dwFlags & LPD_DOUBLEBUFFER);
- d->glFormat.setDepth(lpfd.cDepthBits);
- d->glFormat.setRgba(lpfd.iPixelType == PFD_TYPE_RGBA);
- if (d->glFormat.rgba()) {
- if (d->glFormat.redBufferSize() != -1)
- d->glFormat.setRedBufferSize(lpfd.cRedBits);
- if (d->glFormat.greenBufferSize() != -1)
- d->glFormat.setGreenBufferSize(lpfd.cGreenBits);
- if (d->glFormat.blueBufferSize() != -1)
- d->glFormat.setBlueBufferSize(lpfd.cBlueBits);
- }
- d->glFormat.setAlpha(lpfd.cAlphaBits);
- d->glFormat.setAccum(lpfd.cAccumBits);
- d->glFormat.setStencil(lpfd.cStencilBits);
- d->glFormat.setStereo(lpfd.dwFlags & LPD_STEREO);
- d->glFormat.setDirectRendering(false);
- if (d->glFormat.depth())
- d->glFormat.setDepthBufferSize(lpfd.cDepthBits);
- if (d->glFormat.alpha())
- d->glFormat.setAlphaBufferSize(lpfd.cAlphaBits);
- if (d->glFormat.accum())
- d->glFormat.setAccumBufferSize(lpfd.cAccumRedBits);
- if (d->glFormat.stencil())
- d->glFormat.setStencilBufferSize(lpfd.cStencilBits);
-
- if (d->glFormat.rgba()) {
- if (lpfd.dwFlags & LPD_TRANSPARENT)
- d->transpColor = QColor(lpfd.crTransparent & 0xff,
- (lpfd.crTransparent >> 8) & 0xff,
- (lpfd.crTransparent >> 16) & 0xff);
- else
- d->transpColor = QColor(0, 0, 0);
- }
- else {
- if (lpfd.dwFlags & LPD_TRANSPARENT)
- d->transpColor = QColor(qRgb(1, 2, 3));//, lpfd.crTransparent);
- else
- d->transpColor = QColor(qRgb(1, 2, 3));//, 0);
-
- d->cmap = new QGLCmap(1 << lpfd.cColorBits);
- d->cmap->setEntry(lpfd.crTransparent, qRgb(1, 2, 3));//, QGLCmap::Reserved);
- }
- } else {
- PIXELFORMATDESCRIPTOR pfd;
- PIXELFORMATDESCRIPTOR realPfd;
- d->pixelFormatId = choosePixelFormat(&pfd, myDc);
- if (d->pixelFormatId == 0) {
- qwglError("QGLContext::chooseContext()", "ChoosePixelFormat");
- result = false;
- goto end;
- }
-
- bool overlayRequested = d->glFormat.hasOverlay();
- DescribePixelFormat(myDc, d->pixelFormatId, sizeof(PIXELFORMATDESCRIPTOR), &realPfd);
-
- if (!deviceIsPixmap() && wglGetProcAddress("wglGetPixelFormatAttribivARB"))
- d->glFormat = pfiToQGLFormat(myDc, d->pixelFormatId);
- else
- d->glFormat = pfdToQGLFormat(&realPfd);
-
- d->glFormat.setOverlay(d->glFormat.hasOverlay() && overlayRequested);
-
- if (deviceIsPixmap() && !(realPfd.dwFlags & PFD_DRAW_TO_BITMAP)) {
- qWarning("QGLContext::chooseContext(): Failed to get pixmap rendering context.");
- result = false;
- goto end;
- }
-
- if (deviceIsPixmap() &&
- (((QPixmap*)d->paintDevice)->depth() != realPfd.cColorBits)) {
- qWarning("QGLContext::chooseContext(): Failed to get pixmap rendering context of suitable depth.");
- result = false;
- goto end;
- }
-
- if (!SetPixelFormat(myDc, d->pixelFormatId, &realPfd)) {
- qwglError("QGLContext::chooseContext()", "SetPixelFormat");
- result = false;
- goto end;
- }
-
- if (!qgl_create_context(myDc, d, share)) {
- qwglError("QGLContext::chooseContext()", "wglCreateContext");
- result = false;
- goto end;
- }
-
- if(!deviceIsPixmap()) {
- QRgb* pal = qgl_create_rgb_palette(&realPfd);
- if (pal) {
- QGLColormap cmap;
- cmap.setEntries(256, pal);
- ((QGLWidget*)d->paintDevice)->setColormap(cmap);
- delete[] pal;
- }
- }
- }
-
-end:
- // vblanking
- wglMakeCurrent(myDc, d->rc);
- if (d->rc)
- d->updateFormatVersion();
-
- typedef BOOL (APIENTRYP PFNWGLSWAPINTERVALEXT) (int interval);
- typedef int (APIENTRYP PFNWGLGETSWAPINTERVALEXT) (void);
- PFNWGLSWAPINTERVALEXT wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXT) wglGetProcAddress("wglSwapIntervalEXT");
- PFNWGLGETSWAPINTERVALEXT wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXT) wglGetProcAddress("wglGetSwapIntervalEXT");
- if (wglSwapIntervalEXT && wglGetSwapIntervalEXT) {
- if (d->reqFormat.swapInterval() != -1)
- wglSwapIntervalEXT(d->reqFormat.swapInterval());
- d->glFormat.setSwapInterval(wglGetSwapIntervalEXT());
- }
-
- if (d->win)
- ReleaseDC(d->win, myDc);
- return result;
-}
-
-
-
-static bool qLogEq(bool a, bool b)
-{
- return (((!a) && (!b)) || (a && b));
-}
-
-/*
- See qgl.cpp for qdoc comment.
- */
-int QGLContext::choosePixelFormat(void* dummyPfd, HDC pdc)
-{
- Q_D(QGLContext);
- // workaround for matrox driver:
- // make a cheap call to opengl to force loading of DLL
- if (!opengl32dll) {
- GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
- opengl32dll = true;
- }
-
- PFNWGLCHOOSEPIXELFORMATARB wglChoosePixelFormatARB =
- (PFNWGLCHOOSEPIXELFORMATARB) wglGetProcAddress("wglChoosePixelFormatARB");
- int chosenPfi = 0;
- if (!deviceIsPixmap() && wglChoosePixelFormatARB) {
- bool valid;
- int pixelFormat = 0;
- uint numFormats = 0;
- QVarLengthArray<int> iAttributes(40);
- int i = 0;
- iAttributes[i++] = WGL_ACCELERATION_ARB;
- if (d->glFormat.directRendering())
- iAttributes[i++] = WGL_FULL_ACCELERATION_ARB;
- else
- iAttributes[i++] = WGL_NO_ACCELERATION_ARB;
- iAttributes[i++] = WGL_SUPPORT_OPENGL_ARB;
- iAttributes[i++] = TRUE;
- iAttributes[i++] = WGL_DRAW_TO_WINDOW_ARB;
- iAttributes[i++] = TRUE;
- iAttributes[i++] = WGL_COLOR_BITS_ARB;
- iAttributes[i++] = 24;
- iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB;
- iAttributes[i++] = d->glFormat.doubleBuffer();
- if (d->glFormat.stereo()) {
- iAttributes[i++] = WGL_STEREO_ARB;
- iAttributes[i++] = TRUE;
- }
- if (d->glFormat.depth()) {
- iAttributes[i++] = WGL_DEPTH_BITS_ARB;
- iAttributes[i++] = d->glFormat.depthBufferSize() == -1 ? 24 : d->glFormat.depthBufferSize();
- }
- iAttributes[i++] = WGL_PIXEL_TYPE_ARB;
- if (d->glFormat.rgba()) {
- iAttributes[i++] = WGL_TYPE_RGBA_ARB;
- if (d->glFormat.redBufferSize() != -1) {
- iAttributes[i++] = WGL_RED_BITS_ARB;
- iAttributes[i++] = d->glFormat.redBufferSize();
- }
- if (d->glFormat.greenBufferSize() != -1) {
- iAttributes[i++] = WGL_GREEN_BITS_ARB;
- iAttributes[i++] = d->glFormat.greenBufferSize();
- }
- if (d->glFormat.blueBufferSize() != -1) {
- iAttributes[i++] = WGL_BLUE_BITS_ARB;
- iAttributes[i++] = d->glFormat.blueBufferSize();
- }
- } else {
- iAttributes[i++] = WGL_TYPE_COLORINDEX_ARB;
- }
- if (d->glFormat.alpha()) {
- iAttributes[i++] = WGL_ALPHA_BITS_ARB;
- iAttributes[i++] = d->glFormat.alphaBufferSize() == -1 ? 8 : d->glFormat.alphaBufferSize();
- }
- if (d->glFormat.accum()) {
- iAttributes[i++] = WGL_ACCUM_BITS_ARB;
- iAttributes[i++] = d->glFormat.accumBufferSize() == -1 ? 16 : d->glFormat.accumBufferSize();
- }
- if (d->glFormat.stencil()) {
- iAttributes[i++] = WGL_STENCIL_BITS_ARB;
- iAttributes[i++] = d->glFormat.stencilBufferSize() == -1 ? 8 : d->glFormat.stencilBufferSize();
- }
- if (d->glFormat.hasOverlay()) {
- iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB;
- iAttributes[i++] = 1;
- }
- int si = 0;
- bool trySampleBuffers = QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers;
- if (trySampleBuffers && d->glFormat.sampleBuffers()) {
- iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB;
- iAttributes[i++] = TRUE;
- iAttributes[i++] = WGL_SAMPLES_ARB;
- si = i;
- iAttributes[i++] = d->glFormat.samples() == -1 ? 4 : d->glFormat.samples();
- }
- iAttributes[i] = 0;
-
- do {
- valid = wglChoosePixelFormatARB(pdc, iAttributes.constData(), 0, 1,
- &pixelFormat, &numFormats);
- if (trySampleBuffers && (!valid || numFormats < 1) && d->glFormat.sampleBuffers())
- iAttributes[si] /= 2; // try different no. samples - we aim for the best one
- else
- break;
- } while ((!valid || numFormats < 1) && iAttributes[si] > 1);
- chosenPfi = pixelFormat;
- }
-
- if (!chosenPfi) { // fallback if wglChoosePixelFormatARB() failed
- int pmDepth = deviceIsPixmap() ? ((QPixmap*)d->paintDevice)->depth() : 0;
- PIXELFORMATDESCRIPTOR* p = (PIXELFORMATDESCRIPTOR*)dummyPfd;
- memset(p, 0, sizeof(PIXELFORMATDESCRIPTOR));
- p->nSize = sizeof(PIXELFORMATDESCRIPTOR);
- p->nVersion = 1;
- p->dwFlags = PFD_SUPPORT_OPENGL;
- if (deviceIsPixmap())
- p->dwFlags |= PFD_DRAW_TO_BITMAP;
- else
- p->dwFlags |= PFD_DRAW_TO_WINDOW;
- if (!d->glFormat.directRendering())
- p->dwFlags |= PFD_GENERIC_FORMAT;
- if (d->glFormat.doubleBuffer() && !deviceIsPixmap())
- p->dwFlags |= PFD_DOUBLEBUFFER;
- if (d->glFormat.stereo())
- p->dwFlags |= PFD_STEREO;
- if (d->glFormat.depth())
- p->cDepthBits = d->glFormat.depthBufferSize() == -1 ? 32 : d->glFormat.depthBufferSize();
- else
- p->dwFlags |= PFD_DEPTH_DONTCARE;
- if (d->glFormat.rgba()) {
- p->iPixelType = PFD_TYPE_RGBA;
- if (d->glFormat.redBufferSize() != -1)
- p->cRedBits = d->glFormat.redBufferSize();
- if (d->glFormat.greenBufferSize() != -1)
- p->cGreenBits = d->glFormat.greenBufferSize();
- if (d->glFormat.blueBufferSize() != -1)
- p->cBlueBits = d->glFormat.blueBufferSize();
- if (deviceIsPixmap())
- p->cColorBits = pmDepth;
- else
- p->cColorBits = 32;
- } else {
- p->iPixelType = PFD_TYPE_COLORINDEX;
- p->cColorBits = 8;
- }
- if (d->glFormat.alpha())
- p->cAlphaBits = d->glFormat.alphaBufferSize() == -1 ? 8 : d->glFormat.alphaBufferSize();
- if (d->glFormat.accum()) {
- p->cAccumRedBits = p->cAccumGreenBits = p->cAccumBlueBits = p->cAccumAlphaBits =
- d->glFormat.accumBufferSize() == -1 ? 16 : d->glFormat.accumBufferSize();
- }
- if (d->glFormat.stencil())
- p->cStencilBits = d->glFormat.stencilBufferSize() == -1 ? 8 : d->glFormat.stencilBufferSize();
- p->iLayerType = PFD_MAIN_PLANE;
- chosenPfi = ChoosePixelFormat(pdc, p);
-
- if (!chosenPfi)
- qErrnoWarning("QGLContext: ChoosePixelFormat failed");
-
- // Since the GDI function ChoosePixelFormat() does not handle
- // overlay and direct-rendering requests, we must roll our own here
-
- bool doSearch = chosenPfi <= 0;
- PIXELFORMATDESCRIPTOR pfd;
- QGLFormat fmt;
- if (!doSearch) {
- DescribePixelFormat(pdc, chosenPfi, sizeof(PIXELFORMATDESCRIPTOR),
- &pfd);
- fmt = pfdToQGLFormat(&pfd);
- if (d->glFormat.hasOverlay() && !fmt.hasOverlay())
- doSearch = true;
- else if (!qLogEq(d->glFormat.directRendering(), fmt.directRendering()))
- doSearch = true;
- else if (deviceIsPixmap() && (!(pfd.dwFlags & PFD_DRAW_TO_BITMAP) ||
- pfd.cColorBits != pmDepth))
- doSearch = true;
- else if (!deviceIsPixmap() && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))
- doSearch = true;
- else if (!qLogEq(d->glFormat.rgba(), fmt.rgba()))
- doSearch = true;
- }
-
- if (doSearch) {
- int pfiMax = DescribePixelFormat(pdc, 0, 0, NULL);
- int bestScore = -1;
- int bestPfi = -1;
- for (int pfi = 1; pfi <= pfiMax; pfi++) {
- DescribePixelFormat(pdc, pfi, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
- if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL))
- continue;
- if (deviceIsPixmap() && (!(pfd.dwFlags & PFD_DRAW_TO_BITMAP) ||
- pfd.cColorBits != pmDepth))
- continue;
- if (!deviceIsPixmap() && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))
- continue;
-
- fmt = pfdToQGLFormat(&pfd);
- if (d->glFormat.hasOverlay() && !fmt.hasOverlay())
- continue;
-
- int score = pfd.cColorBits;
- if (qLogEq(d->glFormat.depth(), fmt.depth()))
- score += pfd.cDepthBits;
- if (qLogEq(d->glFormat.alpha(), fmt.alpha()))
- score += pfd.cAlphaBits;
- if (qLogEq(d->glFormat.accum(), fmt.accum()))
- score += pfd.cAccumBits;
- if (qLogEq(d->glFormat.stencil(), fmt.stencil()))
- score += pfd.cStencilBits;
- if (qLogEq(d->glFormat.doubleBuffer(), fmt.doubleBuffer()))
- score += 1000;
- if (qLogEq(d->glFormat.stereo(), fmt.stereo()))
- score += 2000;
- if (qLogEq(d->glFormat.directRendering(), fmt.directRendering()))
- score += 4000;
- if (qLogEq(d->glFormat.rgba(), fmt.rgba()))
- score += 8000;
- if (score > bestScore) {
- bestScore = score;
- bestPfi = pfi;
- }
- }
-
- if (bestPfi > 0)
- chosenPfi = bestPfi;
- }
- }
- return chosenPfi;
-}
-
-
-
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- // workaround for matrox driver:
- // make a cheap call to opengl to force loading of DLL
- if (!opengl32dll) {
- GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
- opengl32dll = true;
- }
-
- if (!d->valid)
- return;
- d->cleanup();
- doneCurrent();
- if (d->rc)
- wglDeleteContext(d->rc);
- d->rc = 0;
- if (d->win && d->dc)
- ReleaseDC(d->win, d->dc);
- if (deviceIsPixmap()) {
- DeleteDC(d->hbitmap_hdc);
- DeleteObject(d->hbitmap);
- d->hbitmap_hdc = 0;
- d->hbitmap = 0;
- }
- d->dc = 0;
- d->win = 0;
- d->threadId = 0;
- d->pixelFormatId = 0;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- delete d->cmap;
- d->cmap = 0;
- d->initDone = false;
- QGLContextGroup::removeShare(this);
-}
-
-//
-// NOTE: In a multi-threaded environment, each thread has a current
-// context. If we want to make this code thread-safe, we probably
-// have to use TLS (thread local storage) for keeping current contexts.
-//
-
-void QGLContext::makeCurrent()
-{
- Q_D(QGLContext);
- if (d->rc == wglGetCurrentContext() || !d->valid) // already current
- return;
-
- if (d->win && (!d->dc || d->threadId != QThread::currentThreadId())) {
- d->dc = GetDC(d->win);
- d->threadId = QThread::currentThreadId();
- if (!d->dc) {
- qwglError("QGLContext::makeCurrent()", "GetDC()");
- return;
- }
- } else if (deviceIsPixmap()) {
- d->dc = d->hbitmap_hdc;
- }
-
- HPALETTE hpal = QColormap::hPal();
- if (hpal) {
- SelectPalette(d->dc, hpal, FALSE);
- RealizePalette(d->dc);
- }
- if (d->glFormat.plane()) {
- wglRealizeLayerPalette(d->dc, d->glFormat.plane(), TRUE);
- }
-
- if (wglMakeCurrent(d->dc, d->rc)) {
- QGLContextPrivate::setCurrentContext(this);
- } else {
- qwglError("QGLContext::makeCurrent()", "wglMakeCurrent");
- }
-}
-
-
-void QGLContext::doneCurrent()
-{
- Q_D(QGLContext);
- wglMakeCurrent(0, 0);
- QGLContextPrivate::setCurrentContext(0);
- if (deviceIsPixmap() && d->hbitmap) {
- QPixmap *pm = static_cast<QPixmap *>(d->paintDevice);
- *pm = QPixmap::fromWinHBITMAP(d->hbitmap);
- }
- if (d->win && d->dc) {
- ReleaseDC(d->win, d->dc);
- d->dc = 0;
- d->threadId = 0;
- }
-}
-
-void QGLContext::swapBuffers() const
-{
- Q_D(const QGLContext);
- if (d->dc && d->glFormat.doubleBuffer() && !deviceIsPixmap()) {
- if (d->glFormat.plane())
- wglSwapLayerBuffers(d->dc, WGL_SWAP_OVERLAY1);
- else {
- if (d->glFormat.hasOverlay())
- wglSwapLayerBuffers(d->dc, WGL_SWAP_MAIN_PLANE);
- else
- SwapBuffers(d->dc);
- }
- }
-}
-
-
-QColor QGLContext::overlayTransparentColor() const
-{
- return d_func()->transpColor;
-}
-
-
-uint QGLContext::colorIndex(const QColor& c) const
-{
- Q_D(const QGLContext);
- if (!isValid())
- return 0;
- if (d->cmap) {
- int idx = d->cmap->find(c.rgb());
- if (idx >= 0)
- return idx;
- if (d->dc && d->glFormat.plane()) {
- idx = d->cmap->allocate(c.rgb());
- if (idx >= 0) {
- COLORREF r = RGB(qRed(c.rgb()),qGreen(c.rgb()),qBlue(c.rgb()));
- wglSetLayerPaletteEntries(d->dc, d->glFormat.plane(), idx, 1, &r);
- wglRealizeLayerPalette(d->dc, d->glFormat.plane(), TRUE);
- return idx;
- }
- }
- return d->cmap->findNearest(c.rgb());
- }
- QColormap cmap = QColormap::instance();
- return cmap.pixel(c) & 0x00ffffff; // Assumes standard palette
-}
-
-void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
-{
- if (!isValid())
- return;
-
- HDC display_dc = GetDC(0);
- HDC tmp_dc = CreateCompatibleDC(display_dc);
- HGDIOBJ old_font = SelectObject(tmp_dc, fnt.handle());
-
- ReleaseDC(0, display_dc);
-
- if (!wglUseFontBitmaps(tmp_dc, 0, 256, listBase))
- qWarning("QGLContext::generateFontDisplayLists: Could not generate display lists for font '%s'", fnt.family().toLatin1().data());
-
- SelectObject(tmp_dc, old_font);
- DeleteDC(tmp_dc);
-}
-
-void *QGLContext::getProcAddress(const QString &proc) const
-{
- return (void *)wglGetProcAddress(proc.toLatin1());
-}
-
-/*****************************************************************************
- QGLWidget Win32/WGL-specific code
- *****************************************************************************/
-
-void QGLWidgetPrivate::init(QGLContext *ctx, const QGLWidget* shareWidget)
-{
- Q_Q(QGLWidget);
- olcx = 0;
- initContext(ctx, shareWidget);
-
- if (q->isValid() && q->context()->format().hasOverlay()) {
- olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), q);
- if (!olcx->create(shareWidget ? shareWidget->overlayContext() : 0)) {
- delete olcx;
- olcx = 0;
- glcx->d_func()->glFormat.setOverlay(false);
- }
- } else {
- olcx = 0;
- }
-}
-
-/*\internal
- Store color values in the given colormap.
-*/
-static void qStoreColors(HPALETTE cmap, const QGLColormap & cols)
-{
- QRgb color;
- PALETTEENTRY pe;
-
- for (int i = 0; i < cols.size(); i++) {
- color = cols.entryRgb(i);
- pe.peRed = qRed(color);
- pe.peGreen = qGreen(color);
- pe.peBlue = qBlue(color);
- pe.peFlags = 0;
-
- SetPaletteEntries(cmap, i, 1, &pe);
- }
-}
-
-void QGLWidgetPrivate::updateColormap()
-{
- Q_Q(QGLWidget);
- if (!cmap.handle())
- return;
- HDC hdc = GetDC(q->winId());
- SelectPalette(hdc, (HPALETTE) cmap.handle(), TRUE);
- qStoreColors((HPALETTE) cmap.handle(), cmap);
- RealizePalette(hdc);
- ReleaseDC(q->winId(), hdc);
-}
-
-void QGLWidget::setMouseTracking(bool enable)
-{
- QWidget::setMouseTracking(enable);
-}
-
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- resizeGL(width(), height());
- if (d->olcx) {
- makeOverlayCurrent();
- resizeOverlayGL(width(), height());
- }
-}
-
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return d_func()->olcx;
-}
-
-
-void QGLWidget::makeOverlayCurrent()
-{
- Q_D(QGLWidget);
- if (d->olcx) {
- d->olcx->makeCurrent();
- if (!d->olcx->initialized()) {
- initializeOverlayGL();
- d->olcx->setInitialized(true);
- }
- }
-}
-
-
-void QGLWidget::updateOverlayGL()
-{
- Q_D(QGLWidget);
- if (d->olcx) {
- makeOverlayCurrent();
- paintOverlayGL();
- if (d->olcx->format().doubleBuffer()) {
- if (d->autoSwap)
- d->olcx->swapBuffers();
- }
- else {
- glFlush();
- }
- }
-}
-
-
-void QGLWidget::setContext(QGLContext *context,
- const QGLContext* shareContext,
- bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- bool doShow = false;
- if (oldcx && oldcx->d_func()->win == winId() && !d->glcx->deviceIsPixmap()) {
- // We already have a context and must therefore create a new
- // window since Windows does not permit setting a new OpenGL
- // context for a window that already has one set.
- doShow = isVisible();
- QWidget *pW = static_cast<QWidget *>(parent());
- QPoint pos = geometry().topLeft();
- setParent(pW, windowFlags());
- move(pos);
- }
-
- if (!d->glcx->isValid()) {
- bool wasSharing = shareContext || (oldcx && oldcx->isSharing());
- d->glcx->create(shareContext ? shareContext : oldcx);
- // the above is a trick to keep disp lists etc when a
- // QGLWidget has been reparented, so remove the sharing
- // flag if we don't actually have a sharing context.
- if (!wasSharing)
- d->glcx->d_ptr->sharing = false;
- }
-
- if (deleteOldContext)
- delete oldcx;
-
- if (doShow)
- show();
-}
-
-
-bool QGLWidgetPrivate::renderCxPm(QPixmap*)
-{
- return false;
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
- Q_Q(QGLWidget);
- if (cmap.handle()) {
- HDC hdc = GetDC(q->winId());
- SelectPalette(hdc, (HPALETTE) GetStockObject(DEFAULT_PALETTE), FALSE);
- DeleteObject((HPALETTE) cmap.handle());
- ReleaseDC(q->winId(), hdc);
- cmap.setHandle(0);
- }
- return;
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap & c)
-{
- Q_D(QGLWidget);
- d->cmap = c;
-
- if (d->cmap.handle()) { // already have an allocated cmap
- d->updateColormap();
- } else {
- LOGPALETTE *lpal = (LOGPALETTE *) malloc(sizeof(LOGPALETTE)
- +c.size()*sizeof(PALETTEENTRY));
- lpal->palVersion = 0x300;
- lpal->palNumEntries = c.size();
- d->cmap.setHandle(CreatePalette(lpal));
- free(lpal);
- d->updateColormap();
- }
-}
-
-QT_END_NAMESPACE