1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the opengl module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "qplatformdefs.h"
35
#include <private/qpaintengine_opengl_p.h>
36
#include "qcolormap.h"
40
Q_GLOBAL_STATIC(QGLFormat, qgl_default_format)
42
class QGLDefaultOverlayFormat: public QGLFormat
45
inline QGLDefaultOverlayFormat()
47
setOption(QGL::DirectRendering);
50
Q_GLOBAL_STATIC(QGLDefaultOverlayFormat, instance)
53
QGLExtensions::Extensions QGLExtensions::glExtensions = 0;
57
typedef void (APIENTRY *pfn_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei,
58
GLsizei, GLint, GLsizei, const GLvoid *);
59
static pfn_glCompressedTexImage2DARB qt_glCompressedTexImage2DARB = 0;
62
#include "private/qt_x11_p.h"
63
#define INT32 dummy_INT32
64
#define INT8 dummy_INT8
68
#include "qx11info_x11.h"
69
#elif defined(Q_WS_MAC)
70
# include <private/qt_mac_p.h>
73
#include <stdlib.h> // malloc
82
\brief The QGL namespace specifies miscellaneous identifiers used
83
in the Qt OpenGL module.
89
\enum QGL::FormatOption
91
This enum specifies the format options.
100
\value DirectRendering
106
\value NoAlphaChannel
108
\value NoStencilBuffer
109
\value NoStereoBuffers
110
\value IndirectRendering
112
\value NoSampleBuffers
115
/*****************************************************************************
116
QGLFormat implementation
117
*****************************************************************************/
122
\brief The QGLFormat class specifies the display format of an OpenGL
127
A display format has several characteristics:
129
\i \link setDoubleBuffer() Double or single buffering.\endlink
130
\i \link setDepth() Depth buffer.\endlink
131
\i \link setRgba() RGBA or color index mode.\endlink
132
\i \link setAlpha() Alpha channel.\endlink
133
\i \link setAccum() Accumulation buffer.\endlink
134
\i \link setStencil() Stencil buffer.\endlink
135
\i \link setStereo() Stereo buffers.\endlink
136
\i \link setDirectRendering() Direct rendering.\endlink
137
\i \link setOverlay() Presence of an overlay.\endlink
138
\i \link setPlane() The plane of an overlay format.\endlink
139
\i \link setSampleBuffers() Multisample buffers.\endlink
142
You can also specify preferred bit depths for the depth buffer,
143
alpha buffer, accumulation buffer and the stencil buffer with the
144
functions: setDepthBufferSize(), setAlphaBufferSize(),
145
setAccumBufferSize() and setStencilBufferSize().
147
Note that even if you specify that you prefer a 32 bit depth
148
buffer (e.g. with setDepthBufferSize(32)), the format that is
149
chosen may not have a 32 bit depth buffer, even if there is a
150
format available with a 32 bit depth buffer. The main reason for
151
this is how the system dependant picking algorithms work on the
152
different platforms, and some format options may have higher
153
precedence than others.
155
You create and tell a QGLFormat object what rendering options you
158
OpenGL is a trademark of Silicon Graphics, Inc. in the
159
United States and other countries.
163
OpenGL drivers or accelerated hardware may or may not support
164
advanced features such as alpha channel or stereographic viewing.
165
If you request some features that the driver/hardware does not
166
provide when you create a QGLWidget, you will get a rendering
167
context with the nearest subset of features.
169
There are different ways to define the display characteristics of
170
a rendering context. One is to create a QGLFormat and make it the
171
default for the entire application:
176
QGLFormat::setDefaultFormat(fmt);
179
Or you can specify the desired format when creating an object of
180
your QGLWidget subclass:
183
fmt.setDoubleBuffer(false); // single buffer
184
fmt.setDirectRendering(false); // software rendering
185
MyGLWidget* myWidget = new MyGLWidget(fmt, ...);
188
After the widget has been created, you can find out which of the
189
requested features the system was able to provide:
192
fmt.setOverlay(true);
194
MyGLWidget* myWidget = new MyGLWidget(fmt, ...);
195
if (!myWidget->format().stereo()) {
197
if (!myWidget->format().hasOverlay()) {
198
qFatal("Cool hardware required");
203
\sa QGLContext, QGLWidget
208
Constructs a QGLFormat object with the factory default settings:
210
\i \link setDoubleBuffer() Double buffer:\endlink Enabled.
211
\i \link setDepth() Depth buffer:\endlink Enabled.
212
\i \link setRgba() RGBA:\endlink Enabled (i.e., color index disabled).
213
\i \link setAlpha() Alpha channel:\endlink Disabled.
214
\i \link setAccum() Accumulator buffer:\endlink Disabled.
215
\i \link setStencil() Stencil buffer:\endlink Disabled.
216
\i \link setStereo() Stereo:\endlink Disabled.
217
\i \link setDirectRendering() Direct rendering:\endlink Enabled.
218
\i \link setOverlay() Overlay:\endlink Disabled.
219
\i \link setPlane() Plane:\endlink 0 (i.e., normal plane).
220
\i \link setSampleBuffers() Multisample buffers:\endlink Disabled.
224
QGLFormat::QGLFormat()
226
d = new QGLFormatPrivate;
231
Creates a QGLFormat object that is a copy of the current \link
232
defaultFormat() application default format\endlink.
234
If \a options is not 0, this copy is modified by these format
235
options. The \a options parameter should be \c FormatOption values
238
This constructor makes it easy to specify a certain desired format
239
in classes derived from QGLWidget, for example:
241
// The rendering in MyGLWidget depends on using
242
// stencil buffer and alpha channel
243
MyGLWidget::MyGLWidget(QWidget* parent)
244
: QGLWidget(QGLFormat(QGL::StencilBuffer | QGL::AlphaChannel), parent)
246
if (!format().stencil())
247
qWarning("Could not get stencil buffer; results will be suboptimal");
248
if (!format().alphaChannel())
249
qWarning("Could not get alpha channel; results will be suboptimal");
254
Note that there are \c FormatOption values to turn format settings
255
both on and off, e.g. \c DepthBuffer and \c NoDepthBuffer,
256
\c DirectRendering and \c IndirectRendering, etc.
258
The \a plane parameter defaults to 0 and is the plane which this
259
format should be associated with. Not all OpenGL implementations
260
supports overlay/underlay rendering planes.
262
\sa defaultFormat(), setOption()
265
QGLFormat::QGLFormat(QGL::FormatOptions options, int plane)
267
d = new QGLFormatPrivate;
268
QGL::FormatOptions newOpts = options;
269
d->opts = defaultFormat().d->opts;
270
d->opts |= (newOpts & 0xffff);
271
d->opts &= ~(newOpts >> 16);
276
Constructs a copy of \a other.
279
QGLFormat::QGLFormat(const QGLFormat &other)
281
d = new QGLFormatPrivate;
286
Assigns \a other to this object.
289
QGLFormat &QGLFormat::operator=(const QGLFormat &other)
296
Destroys the QGLFormat.
298
QGLFormat::~QGLFormat()
304
\fn bool QGLFormat::doubleBuffer() const
306
Returns true if double buffering is enabled; otherwise returns
307
false. Double buffering is enabled by default.
309
\sa setDoubleBuffer()
313
If \a enable is true sets double buffering; otherwise sets single
316
Double buffering is enabled by default.
318
Double buffering is a technique where graphics are rendered on an
319
off-screen buffer and not directly to the screen. When the drawing
320
has been completed, the program calls a swapBuffers() function to
321
exchange the screen contents with the buffer. The result is
322
flicker-free drawing and often better performance.
324
\sa doubleBuffer(), QGLContext::swapBuffers(),
325
QGLWidget::swapBuffers()
328
void QGLFormat::setDoubleBuffer(bool enable)
330
setOption(enable ? QGL::DoubleBuffer : QGL::SingleBuffer);
335
\fn bool QGLFormat::depth() const
337
Returns true if the depth buffer is enabled; otherwise returns
338
false. The depth buffer is enabled by default.
340
\sa setDepth(), setDepthBufferSize()
344
If \a enable is true enables the depth buffer; otherwise disables
347
The depth buffer is enabled by default.
349
The purpose of a depth buffer (or Z-buffering) is to remove hidden
350
surfaces. Pixels are assigned Z values based on the distance to
351
the viewer. A pixel with a high Z value is closer to the viewer
352
than a pixel with a low Z value. This information is used to
353
decide whether to draw a pixel or not.
355
\sa depth(), setDepthBufferSize()
358
void QGLFormat::setDepth(bool enable)
360
setOption(enable ? QGL::DepthBuffer : QGL::NoDepthBuffer);
365
\fn bool QGLFormat::rgba() const
367
Returns true if RGBA color mode is set. Returns false if color
368
index mode is set. The default color mode is RGBA.
374
If \a enable is true sets RGBA mode. If \a enable is false sets
377
The default color mode is RGBA.
379
RGBA is the preferred mode for most OpenGL applications. In RGBA
380
color mode you specify colors as red + green + blue + alpha
383
In color index mode you specify an index into a color lookup
389
void QGLFormat::setRgba(bool enable)
391
setOption(enable ? QGL::Rgba : QGL::ColorIndex);
396
\fn bool QGLFormat::alpha() const
398
Returns true if the alpha buffer in the framebuffer is enabled;
399
otherwise returns false. The alpha buffer is disabled by default.
401
\sa setAlpha(), setAlphaBufferSize()
405
If \a enable is true enables the alpha buffer; otherwise disables
408
The alpha buffer is disabled by default.
410
The alpha buffer is typically used for implementing transparency
411
or translucency. The A in RGBA specifies the transparency of a
414
\sa alpha(), setAlphaBufferSize()
417
void QGLFormat::setAlpha(bool enable)
419
setOption(enable ? QGL::AlphaChannel : QGL::NoAlphaChannel);
424
\fn bool QGLFormat::accum() const
426
Returns true if the accumulation buffer is enabled; otherwise
427
returns false. The accumulation buffer is disabled by default.
429
\sa setAccum(), setAccumBufferSize()
433
If \a enable is true enables the accumulation buffer; otherwise
434
disables the accumulation buffer.
436
The accumulation buffer is disabled by default.
438
The accumulation buffer is used to create blur effects and
441
\sa accum(), setAccumBufferSize()
444
void QGLFormat::setAccum(bool enable)
446
setOption(enable ? QGL::AccumBuffer : QGL::NoAccumBuffer);
451
\fn bool QGLFormat::stencil() const
453
Returns true if the stencil buffer is enabled; otherwise returns
454
false. The stencil buffer is disabled by default.
456
\sa setStencil(), setStencilBufferSize()
460
If \a enable is true enables the stencil buffer; otherwise
461
disables the stencil buffer.
463
The stencil buffer is disabled by default.
465
The stencil buffer masks certain parts of the drawing area so that
466
masked parts are not drawn on.
468
\sa stencil(), setStencilBufferSize()
471
void QGLFormat::setStencil(bool enable)
473
setOption(enable ? QGL::StencilBuffer: QGL::NoStencilBuffer);
478
\fn bool QGLFormat::stereo() const
480
Returns true if stereo buffering is enabled; otherwise returns
481
false. Stereo buffering is disabled by default.
487
If \a enable is true enables stereo buffering; otherwise disables
490
Stereo buffering is disabled by default.
492
Stereo buffering provides extra color buffers to generate left-eye
493
and right-eye images.
498
void QGLFormat::setStereo(bool enable)
500
setOption(enable ? QGL::StereoBuffers : QGL::NoStereoBuffers);
505
\fn bool QGLFormat::directRendering() const
507
Returns true if direct rendering is enabled; otherwise returns
510
Direct rendering is enabled by default.
512
\sa setDirectRendering()
516
If \a enable is true enables direct rendering; otherwise disables
519
Direct rendering is enabled by default.
521
Enabling this option will make OpenGL bypass the underlying window
522
system and render directly from hardware to the screen, if this is
523
supported by the system.
525
\sa directRendering()
528
void QGLFormat::setDirectRendering(bool enable)
530
setOption(enable ? QGL::DirectRendering : QGL::IndirectRendering);
534
\fn bool QGLFormat::sampleBuffers() const
536
Returns true if multisample buffer support is enabled; otherwise
539
The multisample buffer is disabled by default.
541
\sa setSampleBuffers()
545
If \a enable is true, a GL context with multisample buffer support
546
is picked; otherwise ignored.
548
\sa sampleBuffers(), setSamples(), samples()
550
void QGLFormat::setSampleBuffers(bool enable)
552
setOption(enable ? QGL::SampleBuffers : QGL::NoSampleBuffers);
556
Returns the number of samples per pixel when multisampling is
557
enabled. By default, the highest number of samples that is
560
\sa setSampleBuffers(), sampleBuffers(), setSamples()
562
int QGLFormat::samples() const
564
return d->numSamples;
568
Set the preferred number of samples per pixel when multisampling
569
is enabled to \a numSamples. By default, the highest number of
570
samples available is used.
572
\sa setSampleBuffers(), sampleBuffers(), samples()
574
void QGLFormat::setSamples(int numSamples)
576
d->numSamples = numSamples;
580
\fn bool QGLFormat::hasOverlay() const
582
Returns true if overlay plane is enabled; otherwise returns false.
584
Overlay is disabled by default.
590
If \a enable is true enables an overlay plane; otherwise disables
593
Enabling the overlay plane will cause QGLWidget to create an
594
additional context in an overlay plane. See the QGLWidget
595
documentation for further information.
600
void QGLFormat::setOverlay(bool enable)
602
setOption(enable ? QGL::HasOverlay : QGL::NoOverlay);
606
Returns the plane of this format. The default for normal formats
607
is 0, which means the normal plane. The default for overlay
608
formats is 1, which is the first overlay plane.
612
int QGLFormat::plane() const
618
Sets the requested plane to \a plane. 0 is the normal plane, 1 is
619
the first overlay plane, 2 is the second overlay plane, etc.; -1,
620
-2, etc. are underlay planes.
622
Note that in contrast to other format specifications, the plane
623
specifications will be matched exactly. This means that if you
624
specify a plane that the underlying OpenGL system cannot provide,
625
an \link QGLWidget::isValid() invalid\endlink QGLWidget will be
630
void QGLFormat::setPlane(int plane)
636
Sets the format option to \a opt.
641
void QGLFormat::setOption(QGL::FormatOptions opt)
646
d->opts &= ~(opt >> 16);
652
Returns true if format option \a opt is set; otherwise returns false.
657
bool QGLFormat::testOption(QGL::FormatOptions opt) const
660
return (d->opts & opt) != 0;
662
return (d->opts & (opt >> 16)) == 0;
666
Set the preferred depth buffer size to \a size.
668
\sa depthBufferSize(), setDepth(), depth()
670
void QGLFormat::setDepthBufferSize(int size)
676
Returns the depth buffer size.
678
\sa depth(), setDepth(), setDepthBufferSize()
680
int QGLFormat::depthBufferSize() const
686
Set the preferred alpha buffer size to \a size.
688
\sa alpha(), setAlpha(), alphaBufferSize()
690
void QGLFormat::setAlphaBufferSize(int size)
696
Returns the alpha buffer size.
698
\sa alpha(), setAlpha(), setAlphaBufferSize()
700
int QGLFormat::alphaBufferSize() const
706
Set the preferred accumulation buffer size, where \a size is the
707
bit depth for each RGBA component.
709
\sa accum(), setAccum(), accumBufferSize()
711
void QGLFormat::setAccumBufferSize(int size)
717
Returns the accumulation buffer size.
719
\sa setAccumBufferSize(), accum(), setAccum()
721
int QGLFormat::accumBufferSize() const
727
Set the preferred stencil buffer size to \a size.
729
\sa stencilBufferSize(), setStencil(), stencil()
731
void QGLFormat::setStencilBufferSize(int size)
733
d->stencilSize = size;
737
Returns the stencil buffer size.
739
\sa stencil(), setStencil(), setStencilBufferSize()
741
int QGLFormat::stencilBufferSize() const
743
return d->stencilSize;
747
\fn bool QGLFormat::hasOpenGL()
749
Returns true if the window system has any OpenGL support;
750
otherwise returns false.
752
\warning This function must not be called until the QApplication
753
object has been created.
759
\fn bool QGLFormat::hasOpenGLOverlays()
761
Returns true if the window system supports OpenGL overlays;
762
otherwise returns false.
764
\warning This function must not be called until the QApplication
765
object has been created.
769
Returns the default QGLFormat for the application. All QGLWidgets
770
that are created use this format unless another format is
771
specified, e.g. when they are constructed.
773
If no special default format has been set using
774
setDefaultFormat(), the default format is the same as that created
777
\sa setDefaultFormat()
780
QGLFormat QGLFormat::defaultFormat()
782
return *qgl_default_format();
786
Sets a new default QGLFormat for the application to \a f. For
787
example, to set single buffering as the default instead of double
788
buffering, your main() might contain code like this:
790
QApplication a(argc, argv);
792
f.setDoubleBuffer(false);
793
QGLFormat::setDefaultFormat(f);
799
void QGLFormat::setDefaultFormat(const QGLFormat &f)
801
*qgl_default_format() = f;
806
Returns the default QGLFormat for overlay contexts.
808
The factory default overlay format is:
810
\i \link setDoubleBuffer() Double buffer:\endlink Disabled.
811
\i \link setDepth() Depth buffer:\endlink Disabled.
812
\i \link setRgba() RGBA:\endlink Disabled (i.e., color index enabled).
813
\i \link setAlpha() Alpha channel:\endlink Disabled.
814
\i \link setAccum() Accumulator buffer:\endlink Disabled.
815
\i \link setStencil() Stencil buffer:\endlink Disabled.
816
\i \link setStereo() Stereo:\endlink Disabled.
817
\i \link setDirectRendering() Direct rendering:\endlink Enabled.
818
\i \link setOverlay() Overlay:\endlink Disabled.
819
\i \link setPlane() Plane:\endlink 1 (i.e., first overlay plane).
822
\sa setDefaultFormat()
825
QGLFormat QGLFormat::defaultOverlayFormat()
827
return *QGLDefaultOverlayFormat::instance();
831
Sets a new default QGLFormat for overlay contexts to \a f. This
832
format is used whenever a QGLWidget is created with a format that
833
hasOverlay() enabled.
835
For example, to get a double buffered overlay context (if
836
available), use code like this:
839
QGLFormat f = QGLFormat::defaultOverlayFormat();
840
f.setDoubleBuffer(true);
841
QGLFormat::setDefaultOverlayFormat(f);
844
As usual, you can find out after widget creation whether the
845
underlying OpenGL system was able to provide the requested
849
// ...continued from above
850
MyGLWidget* myWidget = new MyGLWidget(QGLFormat(QGL::HasOverlay), ...);
851
if (myWidget->format().hasOverlay()) {
852
// Yes, we got an overlay, let's check _its_ format:
853
QGLContext* olContext = myWidget->overlayContext();
854
if (olContext->format().doubleBuffer())
855
; // yes, we got a double buffered overlay
857
; // no, only single buffered overlays are available
861
\sa defaultOverlayFormat()
864
void QGLFormat::setDefaultOverlayFormat(const QGLFormat &f)
866
QGLFormat *defaultFormat = QGLDefaultOverlayFormat::instance();
868
// Make sure the user doesn't request that the overlays themselves
869
// have overlays, since it is unlikely that the system supports
870
// infinitely many planes...
871
defaultFormat->setOverlay(false);
876
Returns true if all the options of the two QGLFormats are equal;
877
otherwise returns false.
880
bool operator==(const QGLFormat& a, const QGLFormat& b)
882
return (int) a.d->opts == (int) b.d->opts && a.d->pln == b.d->pln && a.d->alphaSize == b.d->alphaSize
883
&& a.d->accumSize == b.d->accumSize && a.d->stencilSize == b.d->stencilSize
884
&& a.d->depthSize == b.d->depthSize;
889
Returns false if all the options of the two QGLFormats are equal;
890
otherwise returns true.
893
bool operator!=(const QGLFormat& a, const QGLFormat& b)
898
/*****************************************************************************
899
QGLContext implementation
900
*****************************************************************************/
902
void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
905
glFormat = reqFormat = format;
908
#if defined(Q_WS_X11)
911
#if defined(Q_WS_WIN)
924
QGLContext* QGLContext::currentCtx = 0;
926
// returns the highest number closest to v, which is a power of 2
927
// NB! assumes 32 bit ints
928
static int nearest_gl_texture_size(int v)
931
for (int s = 0; s < 32; ++s) {
932
if (((v>>s) & 1) == 1) {
938
return 1 << (last+1);
944
QGLTexture(const QGLContext *ctx, GLuint tx_id) : context(ctx), id(tx_id) {}
946
if (!context->isSharing())
947
glDeleteTextures(1, &id);
950
const QGLContext *context;
954
typedef QCache<QString, QGLTexture> QGLTextureCache;
955
static int qt_tex_cache_limit = 64*1024; // cache ~64 MB worth of textures - this is not accurate though
956
static QGLTextureCache *qt_tex_cache = 0;
958
// DDS format structure
964
quint32 dwLinearSize;
966
quint32 dwMipMapCount;
975
// compressed texture pixel formats
976
#define FOURCC_DXT1 0x31545844
977
#define FOURCC_DXT2 0x32545844
978
#define FOURCC_DXT3 0x33545844
979
#define FOURCC_DXT4 0x34545844
980
#define FOURCC_DXT5 0x35545844
982
#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
983
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
984
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
985
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
986
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
989
#ifndef GL_GENERATE_MIPMAP_SGIS
990
#define GL_GENERATE_MIPMAP_SGIS 0x8191
991
#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
996
\brief The QGLContext class encapsulates an OpenGL rendering context.
1002
OpenGL is a trademark of Silicon Graphics, Inc. in the
1003
United States and other countries.
1005
rendering context is a complete set of OpenGL state variables.
1007
The context's \link QGL::FormatOption format\endlink is set in the
1008
constructor or later with setFormat(). The format options that are
1009
actually set are returned by format(); the options you asked for
1010
are returned by requestedFormat(). Note that after a QGLContext
1011
object has been constructed, the actual OpenGL context must be
1012
created by explicitly calling the \link create() create()\endlink
1013
function. The makeCurrent() function makes this context the
1014
current rendering context. You can make \e no context current
1015
using doneCurrent(). The reset() function will reset the context
1016
and make it invalid.
1018
You can examine properties of the context with, e.g. isValid(),
1019
isSharing(), initialized(), windowCreated() and
1020
overlayTransparentColor().
1022
If you're using double buffering you can swap the screen contents
1023
with the off-screen buffer using swapBuffers().
1025
Please note that QGLContext is not thread safe.
1030
Constructs an OpenGL context for the paint device \a device, which
1031
can be a widget or a pixmap. The \a format specifies several
1032
display options for the context.
1034
If the underlying OpenGL/Window system cannot satisfy all the
1035
features requested in \a format, the nearest subset of features
1036
will be used. After creation, the format() method will return the
1037
actual format obtained.
1039
Note that after a QGLContext object has been constructed, \link
1040
create() create()\endlink must be called explicitly to create
1041
the actual OpenGL context. The context will be \link isValid()
1042
invalid\endlink if it was not possible to obtain a GL context at
1045
\sa format(), isValid()
1048
QGLContext::QGLContext(const QGLFormat &format, QPaintDevice *device)
1050
d_ptr = new QGLContextPrivate(this);
1052
d->init(device, format);
1059
QGLContext::QGLContext(const QGLFormat &format)
1061
d_ptr = new QGLContextPrivate(this);
1067
Destroys the OpenGL context and frees its resources.
1070
QGLContext::~QGLContext()
1073
// remove any textures cached in this context
1075
QList<QString> keys = qt_tex_cache->keys();
1076
for (int i = 0; i < keys.size(); ++i) {
1077
const QString &key = keys.at(i);
1078
if (qt_tex_cache->object(key)->context == this)
1079
qt_tex_cache->remove(key);
1081
// ### thread safety
1082
if (qt_tex_cache->size() == 0) {
1083
delete qt_tex_cache;
1094
Reads the DirectDrawSurface (DDS) compressed file \a fileName and
1095
generates a 2D GL texture from it.
1097
Only the DXT1, DXT3 and DXT5 DDS formats are supported.
1099
Note that this will only work if the implementation supports the
1100
\c GL_ARB_texture_compression and \c GL_EXT_texture_compression_s3tc
1105
GLuint QGLContext::bindTexture(const QString &fileName)
1107
if (!qt_glCompressedTexImage2DARB) {
1108
qWarning("QGLContext::bindTexture(): The GL implementation does not support texture"
1109
"compression extensions.");
1114
qt_tex_cache = new QGLTextureCache(qt_tex_cache_limit);
1116
QString key(fileName);
1117
QGLTexture *texture = qt_tex_cache->object(key);
1119
if (texture && texture->context == this) {
1120
glBindTexture(GL_TEXTURE_2D, texture->id);
1125
f.open(QIODevice::ReadOnly);
1129
if (strncmp(tag,"DDS ", 4) != 0) {
1130
qWarning("QGLContext::bindTexture(): not a DDS image file.");
1134
DDSFormat ddsHeader;
1135
f.read((char *) &ddsHeader, sizeof(DDSFormat));
1137
if (!ddsHeader.dwLinearSize) {
1138
qWarning("QGLContext::bindTexture() DDS image size is not valid.");
1147
switch(ddsHeader.ddsPixelFormat.dwFourCC) {
1149
format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
1154
format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
1157
format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
1160
qWarning("QGLContext::bindTexture() DDS image format not supported.");
1164
if (ddsHeader.dwMipMapCount > 1)
1165
bufferSize = ddsHeader.dwLinearSize * factor;
1167
bufferSize = ddsHeader.dwLinearSize;
1169
GLubyte *pixels = (GLubyte *) malloc(bufferSize*sizeof(GLubyte));
1170
f.seek(ddsHeader.dwSize + 4);
1171
f.read((char *) pixels, bufferSize);
1175
glGenTextures(1, &tx_id);
1176
glBindTexture(GL_TEXTURE_2D, tx_id);
1177
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1181
int w = ddsHeader.dwWidth;
1182
int h = ddsHeader.dwHeight;
1185
for(int i = 0; i < (int) ddsHeader.dwMipMapCount; ++i) {
1189
size = ((w+3)/4) * ((h+3)/4) * blockSize;
1190
qt_glCompressedTexImage2DARB(GL_TEXTURE_2D, i, format, w, h, 0,
1191
size, pixels + offset);
1194
// half size for each mip-map level
1201
int cost = bufferSize/1024;
1202
qt_tex_cache->insert(key, new QGLTexture(this, tx_id), cost);
1206
GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format, const QString &key)
1211
qt_tex_cache = new QGLTextureCache(qt_tex_cache_limit);
1213
// Scale the pixmap if needed. GL textures needs to have the
1214
// dimensions 2^n+2(border) x 2^m+2(border).
1216
int tx_w = nearest_gl_texture_size(image.width());
1217
int tx_h = nearest_gl_texture_size(image.height());
1218
if (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height()))
1219
tx = QGLWidget::convertToGLFormat(image.scaled(tx_w, tx_h));
1221
tx = QGLWidget::convertToGLFormat(image);
1224
glGenTextures(1, &tx_id);
1225
glBindTexture(target, tx_id);
1226
glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1227
if (QGLExtensions::glExtensions & QGLExtensions::GenerateMipmap
1228
&& target == GL_TEXTURE_2D)
1230
glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
1231
glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
1232
glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1234
glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1237
glTexImage2D(target, 0, format, tx.width(), tx.height(), 0, GL_RGBA,
1238
GL_UNSIGNED_BYTE, tx.bits());
1240
// this assumes the size of a texture is always smaller than the max cache size
1241
int cost = tx.width()*tx.height()*4/1024;
1242
qt_tex_cache->insert(key, new QGLTexture(q, tx_id), cost);
1247
Generates and binds a 2D GL texture to the current context, based
1248
on \a image. The generated texture id is returned and can be used
1249
in later \c glBindTexture() calls.
1251
The \a target parameter specifies the texture target. The default
1252
target is \c GL_TEXTURE_2D.
1254
The \a format parameter sets the internal format for the
1255
texture. The default format is \c GL_RGBA8.
1257
If the GL implementation supports the \c GL_SGIS_generate_mipmap
1258
extension, mipmaps will be automatically generated for the
1259
texture. Mipmap generation is only supported for the \c
1260
GL_TEXTURE_2D target.
1262
The texture that is generated is cached, so multiple calls to
1263
bindTexture() with the same QImage will return the same texture
1268
GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format)
1271
const QString key = QString("%1_%2_%3").arg(image.serialNumber()).arg(target).arg(format);
1273
QGLTexture *texture = qt_tex_cache->object(key);
1274
if (texture && texture->context == this) {
1275
glBindTexture(target, texture->id);
1279
return d->bindTexture(image, target, format, key);
1284
Generates and binds a 2D GL texture based on \a pixmap.
1286
GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint format)
1289
const QString key = QString("%1_%2_%3").arg(pixmap.serialNumber()).arg(target).arg(format);
1292
QGLTexture *texture = qt_tex_cache->object(key);
1293
if (texture && texture->context == this) {
1294
glBindTexture(target, texture->id);
1298
return d->bindTexture(pixmap.toImage(), target, format, key);
1302
Removes the texture identified by \a id from the texture cache. If
1303
the context is not shared by any other QGLContext,
1304
glDeleteTextures() will be called to delete the texture from the
1309
void QGLContext::deleteTexture(GLuint id)
1314
QList<QString> keys = qt_tex_cache->keys();
1315
for (int i = 0; i < keys.size(); ++i) {
1316
QGLTexture *tex = qt_tex_cache->object(keys.at(i));
1317
if (tex->id == id && tex->context == this) {
1318
qt_tex_cache->remove(keys.at(i));
1325
This function sets the limit for the texture cache to \a size,
1326
expressed in kilobytes.
1328
By default, the cache limit is approximately 64 MB.
1330
\sa textureCacheLimit()
1332
void QGLContext::setTextureCacheLimit(int size)
1334
qt_tex_cache_limit = size;
1336
qt_tex_cache->setMaxCost(qt_tex_cache_limit);
1340
Returns the current texture cache limit in kilobytes.
1342
\sa setTextureCacheLimit()
1344
int QGLContext::textureCacheLimit()
1346
return qt_tex_cache_limit;
1350
\fn QGLFormat QGLContext::format() const
1352
Returns the frame buffer format that was obtained (this may be a
1353
subset of what was requested).
1355
\sa requestedFormat()
1359
\fn QGLFormat QGLContext::requestedFormat() const
1361
Returns the frame buffer format that was originally requested in
1362
the constructor or setFormat().
1368
Sets a \a format for this context. The context is \link reset()
1371
Call create() to create a new GL context that tries to match the
1381
exit(); // no OpenGL support, or cannot render on the specified paintdevice
1382
if (!cx->format().stereo())
1383
exit(); // could not create stereo context
1386
\sa format(), reset(), create()
1389
void QGLContext::setFormat(const QGLFormat &format)
1393
d->glFormat = d->reqFormat = format;
1399
void QGLContext::setDevice(QPaintDevice *pDev)
1404
d->paintDevice = pDev;
1405
if (d->paintDevice && (d->paintDevice->devType() != QInternal::Widget
1406
&& d->paintDevice->devType() != QInternal::Pixmap)) {
1407
qWarning("QGLContext: Unsupported paint device type");
1412
\fn bool QGLContext::isValid() const
1414
Returns true if a GL rendering context has been successfully
1415
created; otherwise returns false.
1419
\fn void QGLContext::setValid(bool valid)
1422
Forces the GL rendering context to be valid.
1426
\fn bool QGLContext::isSharing() const
1428
Returns true if this context is sharing its GL context with
1429
another QGLContext, otherwise false is returned. Note that context
1430
sharing might not be supported between contexts with different
1435
\fn bool QGLContext::deviceIsPixmap() const
1437
Returns true if the paint device of this context is a pixmap;
1438
otherwise returns false.
1442
\fn bool QGLContext::windowCreated() const
1444
Returns true if a window has been created for this context;
1445
otherwise returns false.
1447
\sa setWindowCreated()
1451
\fn void QGLContext::setWindowCreated(bool on)
1453
If \a on is true the context has had a window created for it. If
1454
\a on is false no window has been created for the context.
1460
\fn uint QGLContext::colorIndex(const QColor& c) const
1464
Returns a colormap index for the color c, in ColorIndex mode. Used
1465
by qglColor() and qglClearColor().
1470
\fn bool QGLContext::initialized() const
1472
Returns true if this context has been initialized, i.e. if
1473
QGLWidget::initializeGL() has been performed on it; otherwise
1476
\sa setInitialized()
1480
\fn void QGLContext::setInitialized(bool on)
1482
If \a on is true the context has been initialized, i.e.
1483
QGLContext::setInitialized() has been called on it. If \a on is
1484
false the context has not been initialized.
1490
\fn const QGLContext* QGLContext::currentContext()
1492
Returns the current context, i.e. the context to which any OpenGL
1493
commands will currently be directed. Returns 0 if no context is
1500
\fn QColor QGLContext::overlayTransparentColor() const
1502
If this context is a valid context in an overlay plane, returns
1503
the plane's transparent color. Otherwise returns an \link
1504
QColor::isValid() invalid \endlink color.
1506
The returned color's \link QColor::pixel() pixel \endlink value is
1507
the index of the transparent color in the colormap of the overlay
1508
plane. (Naturally, the color's RGB values are meaningless.)
1510
The returned QColor object will generally work as expected only
1511
when passed as the argument to QGLWidget::qglColor() or
1512
QGLWidget::qglClearColor(). Under certain circumstances it can
1513
also be used to draw transparent graphics with a QPainter. See the
1514
examples/opengl/overlay_x11 example for details.
1519
Creates the GL context. Returns true if it was successful in
1520
creating a valid GL rendering context on the paint device
1521
specified in the constructor; otherwise returns false (i.e. the
1522
context is invalid).
1524
After successful creation, format() returns the set of features of
1525
the created GL rendering context.
1527
If \a shareContext points to a valid QGLContext, this method will
1528
try to establish OpenGL display list sharing between this context
1529
and the \a shareContext. Note that this may fail if the two
1530
contexts have different formats. Use isSharing() to see if sharing
1533
\warning Implementation note: initialization of C++ class
1534
members usually takes place in the class constructor. QGLContext
1535
is an exception because it must be simple to customize. The
1536
virtual functions chooseContext() (and chooseVisual() for X11) can
1537
be reimplemented in a subclass to select a particular context. The
1538
problem is that virtual functions are not properly called during
1539
construction (even though this is correct C++) because C++
1540
constructs class hierarchies from the bottom up. For this reason
1541
we need a create() function.
1543
\sa chooseContext(), format(), isValid()
1546
bool QGLContext::create(const QGLContext* shareContext)
1550
d->valid = chooseContext(shareContext);
1554
bool QGLContext::isValid() const
1556
Q_D(const QGLContext);
1560
void QGLContext::setValid(bool valid)
1566
bool QGLContext::isSharing() const
1568
Q_D(const QGLContext);
1572
QGLFormat QGLContext::format() const
1574
Q_D(const QGLContext);
1578
QGLFormat QGLContext::requestedFormat() const
1580
Q_D(const QGLContext);
1581
return d->reqFormat;
1584
QPaintDevice* QGLContext::device() const
1586
Q_D(const QGLContext);
1587
return d->paintDevice;
1590
bool QGLContext::deviceIsPixmap() const
1592
Q_D(const QGLContext);
1593
return d->paintDevice->devType() == QInternal::Pixmap;
1597
bool QGLContext::windowCreated() const
1599
Q_D(const QGLContext);
1604
void QGLContext::setWindowCreated(bool on)
1610
bool QGLContext::initialized() const
1612
Q_D(const QGLContext);
1616
void QGLContext::setInitialized(bool on)
1622
const QGLContext* QGLContext::currentContext()
1628
\fn bool QGLContext::chooseContext(const QGLContext* shareContext = 0)
1630
This semi-internal function is called by create(). It creates a
1631
system-dependent OpenGL handle that matches the format() of \a
1632
shareContext as closely as possible.
1634
On Windows, it calls the virtual function choosePixelFormat(),
1635
which finds a matching pixel format identifier. On X11, it calls
1636
the virtual function chooseVisual() which finds an appropriate X
1637
visual. On other platforms it may work differently.
1642
\fn void QGLContext::reset()
1644
Resets the context and makes it invalid.
1646
\sa create(), isValid()
1651
\fn void QGLContext::makeCurrent()
1653
Makes this context the current OpenGL rendering context. All GL
1654
functions you call operate on this context until another context
1657
In some very rare cases the underlying call may fail. If this
1658
occurs an error message is output to stderr.
1663
\fn void QGLContext::swapBuffers() const
1665
Swaps the screen contents with an off-screen buffer. Only works if
1666
the context is in double buffer mode.
1668
\sa QGLFormat::setDoubleBuffer()
1673
\fn void QGLContext::doneCurrent()
1675
Makes no GL context the current context. Normally, you do not need
1676
to call this function; QGLContext calls it as necessary.
1681
\fn QPaintDevice* QGLContext::device() const
1683
Returns the paint device set for this context.
1685
\sa QGLContext::QGLContext()
1689
\fn void QGLContext::generateFontDisplayLists(const QFont& font, int listBase)
1691
Generates a set of 256 display lists for the 256 first characters
1692
in the font \a font. The first list will start at index \a listBase.
1694
\sa QGLWidget::renderText()
1698
/*****************************************************************************
1699
QGLWidget implementation
1700
*****************************************************************************/
1705
\brief The QGLWidget class is a widget for rendering OpenGL graphics.
1710
QGLWidget provides functionality for displaying OpenGL
1712
OpenGL is a trademark of Silicon Graphics, Inc. in the
1713
United States and other countries.
1715
graphics integrated into a Qt application. It is very simple to
1716
use. You inherit from it and use the subclass like any other
1717
QWidget, except that instead of drawing the widget's contents
1718
using QPainter etc. you use the standard OpenGL rendering
1721
QGLWidget provides three convenient virtual functions that you can
1722
reimplement in your subclass to perform the typical OpenGL tasks:
1725
\i paintGL() - Renders the OpenGL scene. Gets called whenever the widget
1726
needs to be updated.
1727
\i resizeGL() - Sets up the OpenGL viewport, projection, etc. Gets
1728
called whenever the the widget has been resized (and also when it
1729
is shown for the first time because all newly created widgets get a
1730
resize event automatically).
1731
\i initializeGL() - Sets up the OpenGL rendering context, defines display
1732
lists, etc. Gets called once before the first time resizeGL() or
1733
paintGL() is called.
1736
Here is a rough outline of how a QGLWidget subclass might look:
1739
class MyGLDrawer : public QGLWidget
1741
Q_OBJECT // must include this if you use Qt signals/slots
1744
MyGLDrawer(QWidget *parent)
1745
: QGLWidget(parent) {}
1751
// Set up the rendering context, define display lists etc.:
1753
glClearColor(0.0, 0.0, 0.0, 0.0);
1754
glEnable(GL_DEPTH_TEST);
1758
void resizeGL(int w, int h)
1760
// setup viewport, projection etc.:
1761
glViewport(0, 0, (GLint)w, (GLint)h);
1784
If you need to trigger a repaint from places other than paintGL()
1785
(a typical example is when using \link QTimer timers\endlink to
1786
animate scenes), you should call the widget's updateGL() function.
1788
Your widget's OpenGL rendering context is made current when
1789
paintGL(), resizeGL(), or initializeGL() is called. If you need to
1790
call the standard OpenGL API functions from other places (e.g. in
1791
your widget's constructor or in your own paint functions), you
1792
must call makeCurrent() first.
1794
QGLWidget provides functions for requesting a new display \link
1795
QGLFormat format\endlink and you can also create widgets with
1796
customized rendering \link QGLContext contexts\endlink.
1798
You can also share OpenGL display lists between QGLWidgets (see
1799
the documentation of the QGLWidget constructors for details).
1803
The QGLWidget creates a GL overlay context in addition to the
1804
normal context if overlays are supported by the underlying system.
1806
If you want to use overlays, you specify it in the \link QGLFormat
1807
format\endlink. (Note: Overlay must be requested in the format
1808
passed to the QGLWidget constructor.) Your GL widget should also
1809
implement some or all of these virtual methods:
1813
\i resizeOverlayGL()
1814
\i initializeOverlayGL()
1817
These methods work in the same way as the normal paintGL() etc.
1818
functions, except that they will be called when the overlay
1819
context is made current. You can explicitly make the overlay
1820
context current by using makeOverlayCurrent(), and you can access
1821
the overlay context directly (e.g. to ask for its transparent
1822
color) by calling overlayContext().
1824
On X servers in which the default visual is in an overlay plane,
1825
non-GL Qt windows can also be used for overlays.
1829
Constructs an OpenGL widget with a \a parent widget.
1831
The \link QGLFormat::defaultFormat() default format\endlink is
1832
used. The widget will be \link isValid() invalid\endlink if the
1833
system has no \link QGLFormat::hasOpenGL() OpenGL support\endlink.
1835
The \a parent and widget flag, \a f, arguments are passed
1836
to the QWidget constructor.
1838
If the \a shareWidget parameter points to a valid QGLWidget, this
1839
widget will share OpenGL display lists with \a shareWidget. If
1840
this widget and \a shareWidget have different \link format()
1841
formats\endlink, display list sharing may fail. You can check
1842
whether display list sharing succeeded by calling isSharing().
1844
The initialization of OpenGL rendering state, etc. should be done
1845
by overriding the initializeGL() function, rather than in the
1846
constructor of your QGLWidget subclass.
1848
\sa QGLFormat::defaultFormat()
1851
QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WFlags f)
1852
: QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
1855
setAttribute(Qt::WA_PaintOnScreen);
1856
setAttribute(Qt::WA_NoSystemBackground);
1857
d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget);
1862
Constructs an OpenGL widget with parent \a parent.
1864
The \a format argument specifies the desired \link QGLFormat
1865
rendering options \endlink. If the underlying OpenGL/Window system
1866
cannot satisfy all the features requested in \a format, the
1867
nearest subset of features will be used. After creation, the
1868
format() method will return the actual format obtained.
1870
The widget will be \link isValid() invalid\endlink if the system
1871
has no \link QGLFormat::hasOpenGL() OpenGL support\endlink.
1873
The \a parent and widget flag, \a f, arguments are passed
1874
to the QWidget constructor.
1876
If the \a shareWidget parameter points to a valid QGLWidget, this
1877
widget will share OpenGL display lists with \a shareWidget. If
1878
this widget and \a shareWidget have different \link format()
1879
formats\endlink, display list sharing may fail. You can check
1880
whether display list sharing succeeded by calling isSharing().
1882
The initialization of OpenGL rendering state, etc. should be done
1883
by overriding the initializeGL() function, rather than in the
1884
constructor of your QGLWidget subclass.
1886
\sa QGLFormat::defaultFormat(), isValid()
1889
QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget* shareWidget,
1891
: QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
1894
setAttribute(Qt::WA_PaintOnScreen);
1895
setAttribute(Qt::WA_NoSystemBackground);
1896
d->init(new QGLContext(format, this), shareWidget);
1900
Constructs an OpenGL widget with parent \a parent.
1902
The \a context argument is a pointer to the QGLContext that
1903
you wish to be bound to this widget. This allows you to pass in
1904
your own QGLContext sub-classes.
1906
The widget will be \link isValid() invalid\endlink if the system
1907
has no \link QGLFormat::hasOpenGL() OpenGL support\endlink.
1909
The \a parent and widget flag, \a f, arguments are passed
1910
to the QWidget constructor.
1912
If the \a shareWidget parameter points to a valid QGLWidget, this
1913
widget will share OpenGL display lists with \a shareWidget. If
1914
this widget and \a shareWidget have different \link format()
1915
formats\endlink, display list sharing may fail. You can check
1916
whether display list sharing succeeded by calling isSharing().
1918
The initialization of OpenGL rendering state, etc. should be done
1919
by overriding the initializeGL() function, rather than in the
1920
constructor of your QGLWidget subclass.
1922
\sa QGLFormat::defaultFormat(), isValid()
1924
QGLWidget::QGLWidget(QGLContext *context, QWidget *parent, const QGLWidget *shareWidget,
1926
: QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
1929
setAttribute(Qt::WA_PaintOnScreen);
1930
setAttribute(Qt::WA_NoSystemBackground);
1931
d->init(context, shareWidget);
1935
Destroys the widget.
1938
QGLWidget::~QGLWidget()
1941
#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
1942
bool doRelease = (glcx && glcx->windowCreated());
1952
#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
1954
glXReleaseBuffersMESA(x11Display(), winId());
1956
d->cleanupColormaps();
1960
\fn QGLFormat QGLWidget::format() const
1962
Returns the format of the contained GL rendering context.
1966
\fn bool QGLWidget::doubleBuffer() const
1968
Returns true if the contained GL rendering context has double
1969
buffering; otherwise returns false.
1971
\sa QGLFormat::doubleBuffer()
1975
\fn void QGLWidget::setAutoBufferSwap(bool on)
1977
If \a on is true automatic GL buffer swapping is switched on;
1978
otherwise it is switched off.
1980
If \a on is true and the widget is using a double-buffered format,
1981
the background and foreground GL buffers will automatically be
1982
swapped after each paintGL() call.
1984
The buffer auto-swapping is on by default.
1986
\sa autoBufferSwap(), doubleBuffer(), swapBuffers()
1990
\fn bool QGLWidget::autoBufferSwap() const
1992
Returns true if the widget is doing automatic GL buffer swapping;
1993
otherwise returns false.
1995
\sa setAutoBufferSwap()
1999
\fn bool QGLWidget::isValid() const
2001
Returns true if the widget has a valid GL rendering context;
2002
otherwise returns false. A widget will be invalid if the system
2003
has no \link QGLFormat::hasOpenGL() OpenGL support\endlink.
2006
bool QGLWidget::isValid() const
2008
Q_D(const QGLWidget);
2009
return d->glcx->isValid();
2013
\fn bool QGLWidget::isSharing() const
2015
Returns true if this widget's GL context is shared with another GL
2016
context, otherwise false is returned. The GL system may fail to
2017
provide context sharing if the two QGLWidgets use different
2023
bool QGLWidget::isSharing() const
2025
Q_D(const QGLWidget);
2026
return d->glcx->isSharing();
2030
\fn void QGLWidget::makeCurrent()
2032
Makes this widget the current widget for OpenGL operations, i.e.
2033
makes the widget's rendering context the current OpenGL rendering
2037
void QGLWidget::makeCurrent()
2040
d->glcx->makeCurrent();
2044
\fn void QGLWidget::doneCurrent()
2046
Makes no GL context the current context. Normally, you do not need
2047
to call this function; QGLContext calls it as necessary. However,
2048
it may be useful in multithreaded environments.
2051
void QGLWidget::doneCurrent()
2054
d->glcx->doneCurrent();
2058
\fn void QGLWidget::swapBuffers()
2060
Swaps the screen contents with an off-screen buffer. This only
2061
works if the widget's format specifies double buffer mode.
2063
Normally, there is no need to explicitly call this function
2064
because it is done automatically after each widget repaint, i.e.
2065
each time after paintGL() has been executed.
2067
\sa doubleBuffer(), setAutoBufferSwap(), QGLFormat::setDoubleBuffer()
2070
void QGLWidget::swapBuffers()
2073
d->glcx->swapBuffers();
2078
\fn const QGLContext* QGLWidget::overlayContext() const
2080
Returns the overlay context of this widget, or 0 if this widget
2089
\fn void QGLWidget::makeOverlayCurrent()
2091
Makes the overlay context of this widget current. Use this if you
2092
need to issue OpenGL commands to the overlay context outside of
2093
initializeOverlayGL(), resizeOverlayGL(), and paintOverlayGL().
2095
Does nothing if this widget has no overlay.
2104
Sets a new format for this widget.
2106
If the underlying OpenGL/Window system cannot satisfy all the
2107
features requested in \a format, the nearest subset of features will
2108
be used. After creation, the format() method will return the actual
2109
rendering context format obtained.
2111
The widget will be assigned a new QGLContext, and the initializeGL()
2112
function will be executed for this new context before the first
2113
resizeGL() or paintGL().
2115
This method will try to keep any existing display list sharing with
2116
other QGLWidgets, but it may fail. Use isSharing() to test.
2118
\sa format(), isSharing(), isValid()
2121
void QGLWidget::setFormat(const QGLFormat &format)
2123
setContext(new QGLContext(format,this));
2130
\fn const QGLContext *QGLWidget::context() const
2132
Returns the context of this widget.
2134
It is possible that the context is not valid (see isValid()), for
2135
example, if the underlying hardware does not support the format
2136
attributes that were requested.
2142
\fn void QGLWidget::setContext(QGLContext *context,
2143
const QGLContext* shareContext,
2144
bool deleteOldContext)
2146
Sets a new context for this widget. The QGLContext \a context must
2147
be created using \e new. QGLWidget will delete \a context when
2148
another context is set or when the widget is destroyed.
2150
If \a context is invalid, QGLContext::create() is performed on
2151
it. The initializeGL() function will then be executed for the new
2152
context before the first resizeGL() or paintGL().
2154
If \a context is invalid, this method will try to keep any existing
2155
display list sharing with other QGLWidgets this widget currently
2156
has, or (if \a shareContext points to a valid context) start display
2157
list sharing with that context, but it may fail. Use isSharing() to
2160
If \a deleteOldContext is true (the default), the existing context
2161
will be deleted. You may use false here if you have kept a pointer
2162
to the old context (as returned by context()), and want to restore
2165
\sa context(), isSharing()
2171
\fn void QGLWidget::updateGL()
2173
Updates the widget by calling glDraw().
2176
void QGLWidget::updateGL()
2183
\fn void QGLWidget::updateOverlayGL()
2185
Updates the widget's overlay (if any). Will cause the virtual
2186
function paintOverlayGL() to be executed.
2188
The widget's rendering context will become the current context and
2189
initializeGL() will be called if it hasn't already been called.
2194
This virtual function is called once before the first call to
2195
paintGL() or resizeGL(), and then once whenever the widget has
2196
been assigned a new QGLContext. Reimplement it in a subclass.
2198
This function should set up any required OpenGL context rendering
2199
flags, defining display lists, etc.
2201
There is no need to call makeCurrent() because this has already
2202
been done when this function is called.
2205
void QGLWidget::initializeGL()
2211
This virtual function is called whenever the widget needs to be
2212
painted. Reimplement it in a subclass.
2214
There is no need to call makeCurrent() because this has already
2215
been done when this function is called.
2218
void QGLWidget::paintGL()
2224
\fn void QGLWidget::resizeGL(int width , int height)
2226
This virtual function is called whenever the widget has been
2227
resized. The new size is passed in \a width and \a height.
2228
Reimplement it in a subclass.
2230
There is no need to call makeCurrent() because this has already
2231
been done when this function is called.
2234
void QGLWidget::resizeGL(int, int)
2241
This virtual function is used in the same manner as initializeGL()
2242
except that it operates on the widget's overlay context instead of
2243
the widget's main context. This means that initializeOverlayGL()
2244
is called once before the first call to paintOverlayGL() or
2245
resizeOverlayGL(). Reimplement it in a subclass.
2247
This function should set up any required OpenGL context rendering
2248
flags, defining display lists, etc. for the overlay context.
2250
There is no need to call makeOverlayCurrent() because this has
2251
already been done when this function is called.
2254
void QGLWidget::initializeOverlayGL()
2260
This virtual function is used in the same manner as paintGL()
2261
except that it operates on the widget's overlay context instead of
2262
the widget's main context. This means that paintOverlayGL() is
2263
called whenever the widget's overlay needs to be painted.
2264
Reimplement it in a subclass.
2266
There is no need to call makeOverlayCurrent() because this has
2267
already been done when this function is called.
2270
void QGLWidget::paintOverlayGL()
2276
\fn void QGLWidget::resizeOverlayGL(int width , int height)
2278
This virtual function is used in the same manner as paintGL()
2279
except that it operates on the widget's overlay context instead of
2280
the widget's main context. This means that resizeOverlayGL() is
2281
called whenever the widget has been resized. The new size is
2282
passed in \a width and \a height. Reimplement it in a subclass.
2284
There is no need to call makeOverlayCurrent() because this has
2285
already been done when this function is called.
2288
void QGLWidget::resizeOverlayGL(int, int)
2296
\fn void QGLWidget::paintEvent(QPaintEvent *event)
2298
Handles paint events passed in the \a event parameter. Will cause
2299
the virtual paintGL() function to be called.
2301
The widget's rendering context will become the current context and
2302
initializeGL() will be called if it hasn't already been called.
2305
void QGLWidget::paintEvent(QPaintEvent *)
2313
\fn void QGLWidget::resizeEvent(QResizeEvent *event)
2315
Handles resize events that are passed in the \a event parameter.
2316
Calls the virtual function resizeGL().
2321
\fn void QGLWidget::setMouseTracking(bool enable)
2323
If \a enable is true then mouse tracking is enabled; otherwise it
2329
Renders the current scene on a pixmap and returns the pixmap.
2331
You can use this method on both visible and invisible QGLWidgets.
2333
This method will create a pixmap and a temporary QGLContext to
2334
render on the pixmap. It will then call initializeGL(),
2335
resizeGL(), and paintGL() on this context. Finally, the widget's
2336
original GL context is restored.
2338
The size of the pixmap will be \a w pixels wide and \a h pixels
2339
high unless one of these parameters is 0 (the default), in which
2340
case the pixmap will have the same size as the widget.
2342
If \a useContext is true, this method will try to be more
2343
efficient by using the existing GL context to render the pixmap.
2344
The default is false. Only use true if you understand the risks.
2346
Overlays are not rendered onto the pixmap.
2348
If the GL rendering context and the desktop have different bit
2349
depths, the result will most likely look surprising.
2351
Note that the creation of display lists, modifications of the view
2352
frustum etc. should be done from within initializeGL(). If this is
2353
not done, the temporary QGLContext will not be initialized
2354
properly, and the rendered pixmap may be incomplete/corrupted.
2357
QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
2361
if ((w > 0) && (h > 0))
2364
#if defined(Q_WS_X11)
2365
// If we are using OpenGL widgets under X11 we HAVE to make sure
2366
// that the default visual is GL enabled, and that the Pixmap has
2367
// the same depth as the GL window.
2369
extern int qt_x11_preferred_pixmap_depth;
2370
int old_depth = qt_x11_preferred_pixmap_depth;
2371
qt_x11_preferred_pixmap_depth = x11Info().depth();
2373
qt_x11_preferred_pixmap_depth = old_depth;
2374
Visual *gl_visual = (Visual *) d->glcx->d_func()->vi;
2375
Visual *gl_pixmap_visual = 0;
2377
if (gl_visual != QX11Info::appVisual()) {
2379
XVisualInfo visInfo;
2380
memset(&visInfo, 0, sizeof(XVisualInfo));
2381
visInfo.visualid = XVisualIDFromVisual(gl_visual);
2382
visInfo.screen = QX11Info::appScreen();
2383
XVisualInfo *vi = XGetVisualInfo(QX11Info::display(),
2384
VisualIDMask | VisualScreenMask,
2386
gl_pixmap_visual = vi->visual;
2388
QX11InfoData* xd = pm.x11Info().getX11Data(true);
2389
xd->depth = vi->depth;
2390
xd->visual = (Visual *) vi->visual;
2391
const_cast<QX11Info &>(pm.x11Info()).setX11Data(xd);
2400
d->glcx->doneCurrent();
2402
bool success = true;
2404
if (useContext && isValid() && d->renderCxPm(&pm))
2407
QGLFormat fmt = d->glcx->requestedFormat();
2408
fmt.setDirectRendering(false); // Direct is unlikely to work
2409
fmt.setDoubleBuffer(false); // We don't need dbl buf
2411
QGLContext* ocx = d->glcx;
2412
bool wasCurrent = (QGLContext::currentContext() == ocx);
2414
d->glcx = new QGLContext(fmt, &pm);
2417
if (d->glcx->isValid())
2422
#if defined(Q_WS_WIN)
2423
pm = QPixmap::fromWinHBITMAP(d->glcx->d_func()->hbitmap);
2433
#if defined(Q_WS_X11)
2434
if (gl_pixmap_visual) {
2435
QImage image = pm.toImage();
2436
QPixmap p = QPixmap::fromImage(image);
2448
Returns an image of the frame buffer. If \a withAlpha is true the
2449
alpha channel is included.
2451
Depending on your hardware, you can explicitly select which color
2452
buffer to grab with a glReadBuffer() call before calling this
2455
QImage QGLWidget::grabFrameBuffer(bool withAlpha)
2461
if (format().rgba()) {
2462
res = QImage(w, h, withAlpha ? QImage::Format_ARGB32 : QImage::Format_RGB32);
2463
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, res.bits());
2464
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
2465
// OpenGL gives RGBA; Qt wants ARGB
2466
uint *p = (uint*)res.bits();
2467
uint *end = p + w*h;
2468
if (withAlpha && format().alpha()) {
2476
*p = 0xFF000000 | (*p>>8);
2481
// OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB
2482
res = res.rgbSwapped();
2485
#if defined (Q_WS_WIN)
2486
res = QImage(w, h, QImage::Format_Indexed8);
2487
glReadPixels(0, 0, w, h, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, res.bits());
2488
const QVector<QColor> pal = QColormap::instance().colormap();
2490
res.setNumColors(pal.size());
2491
for (int i = 0; i < pal.size(); i++)
2492
res.setColor(i, pal.at(i).rgb());
2497
return res.mirrored();
2503
Initializes OpenGL for this widget's context. Calls the virtual
2504
function initializeGL().
2507
void QGLWidget::glInit()
2514
d->glcx->setInitialized(true);
2519
Executes the virtual function paintGL().
2521
The widget's rendering context will become the current context and
2522
initializeGL() will be called if it hasn't already been called.
2525
void QGLWidget::glDraw()
2531
if (d->glcx->deviceIsPixmap())
2532
glDrawBuffer(GL_FRONT);
2533
if (!d->glcx->initialized()) {
2535
resizeGL(d->glcx->device()->width(), d->glcx->device()->height()); // New context needs this "resize"
2538
if (doubleBuffer()) {
2548
Convenience function for specifying a drawing color to OpenGL.
2549
Calls glColor4 (in RGBA mode) or glIndex (in color-index mode)
2550
with the color \a c. Applies to the current GL context.
2552
\sa qglClearColor(), QGLContext::currentContext(), QColor
2555
void QGLWidget::qglColor(const QColor& c) const
2557
Q_D(const QGLWidget);
2558
const QGLContext* ctx = QGLContext::currentContext();
2560
if (ctx->format().rgba())
2561
glColor4ub(c.red(), c.green(), c.blue(), c.alpha());
2562
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
2563
int i = d->cmap.find(c.rgb());
2565
i = d->cmap.findNearest(c.rgb());
2568
glIndexi(ctx->colorIndex(c));
2573
Convenience function for specifying the clearing color to OpenGL.
2574
Calls glClearColor (in RGBA mode) or glClearIndex (in color-index
2575
mode) with the color \a c. Applies to the current GL context.
2577
\sa qglColor(), QGLContext::currentContext(), QColor
2580
void QGLWidget::qglClearColor(const QColor& c) const
2582
Q_D(const QGLWidget);
2583
const QGLContext* ctx = QGLContext::currentContext();
2585
if (ctx->format().rgba())
2586
glClearColor((GLfloat)c.red() / 255.0, (GLfloat)c.green() / 255.0,
2587
(GLfloat)c.blue() / 255.0, (GLfloat) c.alpha() / 255.0);
2588
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
2589
int i = d->cmap.find(c.rgb());
2591
i = d->cmap.findNearest(c.rgb());
2594
glClearIndex(ctx->colorIndex(c));
2600
Converts the image \a img into the unnamed format expected by
2601
OpenGL functions such as glTexImage2D(). The returned image is not
2602
usable as a QImage, but QImage::width(), QImage::height() and
2603
QImage::bits() may be used with OpenGL.
2607
\l opengl/texture example
2608
The following few lines are from the texture example. Most of the
2609
code is irrelevant, so we just quote the relevant bits:
2611
\quotefromfile opengl/texture/gltexobj.cpp
2614
\printline gllogo.bmp
2616
We create \e tex1 (and another variable) for OpenGL, and load a real
2619
\skipto convertToGLFormat
2620
\printline convertToGLFormat
2622
A few lines later, we convert \e buf into OpenGL format and store it
2625
\skipto glTexImage2D
2626
\printline glTexImage2D
2627
\printline tex1.bits
2629
Note the dimension restrictions for texture images as described in
2630
the glTexImage2D() documentation. The width must be 2^m + 2*border
2631
and the height 2^n + 2*border where m and n are integers and
2632
border is either 0 or 1.
2634
Another function in the same example uses \e tex1 with OpenGL.
2639
QImage QGLWidget::convertToGLFormat(const QImage& img)
2641
QImage res = img.convertToFormat(QImage::Format_ARGB32);
2642
res = res.mirrored();
2644
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
2645
// Qt has ARGB; OpenGL wants RGBA
2646
for (int i=0; i < res.height(); i++) {
2647
uint *p = (uint*)res.scanLine(i);
2648
uint *end = p + res.width();
2650
*p = (*p << 8) | ((*p >> 24) & 0xFF);
2656
// Qt has ARGB; OpenGL wants ABGR (i.e. RGBA backwards)
2657
res = res.rgbSwapped();
2664
\fn QGLColormap & QGLWidget::colormap() const
2666
Returns the colormap for this widget.
2668
Usually it is only top-level widgets that can have different
2669
colormaps installed. Asking for the colormap of a child widget
2670
will return the colormap for the child's top-level widget.
2672
If no colormap has been set for this widget, the QColormap
2673
returned will be empty.
2679
\fn void QGLWidget::setColormap(const QGLColormap & cmap)
2681
Set the colormap for this widget to \a cmap. Usually it is only
2682
top-level widgets that can have colormaps installed.
2689
Returns the value of the first display list that is generated for
2690
the characters in font \a fnt. \a listBase indicates the base
2691
value used when generating the display lists for the font. The
2692
default value is 2000.
2694
int QGLWidget::fontDisplayListBase(const QFont & fnt, int listBase)
2699
if (!d->glcx) { // this can't happen unless we run out of mem
2703
// always regenerate font disp. lists for pixmaps - hw accelerated
2704
// contexts can't handle this otherwise
2705
bool regenerate = d->glcx->deviceIsPixmap();
2706
#ifndef QT_NO_FONTCONFIG
2707
// font color needs to be part of the font cache key when using
2708
// antialiased fonts since one set of glyphs needs to be generated
2709
// for each font color
2711
if (fnt.styleStrategy() != QFont::NoAntialias) {
2713
glGetFloatv(GL_CURRENT_COLOR, color);
2714
color_key.sprintf("%f_%f_%f",color[0], color[1], color[2]);
2716
QString key = fnt.key() + color_key + QString::number((int) regenerate);
2718
QString key = fnt.key() + QString::number((int) regenerate);
2720
if (!regenerate && (d->displayListCache.find(key) != d->displayListCache.end())) {
2721
base = d->displayListCache[key];
2723
int maxBase = listBase - 256;
2724
QMap<QString,int>::ConstIterator it;
2725
for (it = d->displayListCache.constBegin(); it != d->displayListCache.constEnd(); ++it) {
2726
if (maxBase < it.value()) {
2727
maxBase = it.value();
2731
d->glcx->generateFontDisplayLists(fnt, maxBase);
2732
d->displayListCache[key] = maxBase;
2739
Renders the string \a str into the GL context of this widget.
2741
\a x and \a y are specified in window coordinates, with the origin
2742
in the upper left-hand corner of the window. If \a fnt is not
2743
specified, the currently set application font will be used to
2744
render the string. To change the color of the rendered text you can
2745
use the glColor() call (or the qglColor() convenience function),
2746
just before the renderText() call. Note that if you have
2747
GL_LIGHTING enabled, the string will not appear in the color you
2748
want. You should therefore switch lighting off before using
2751
\a listBase specifies the index of the first display list that is
2752
generated by this function. The default value is 2000. 256 display
2753
lists will be generated, one for each of the first 256 characters
2754
in the font that is used to render the string. If several fonts are
2755
used in the same widget, the display lists for these fonts will
2756
follow the last generated list. You would normally not have to
2757
change this value unless you are using lists in the same range. The
2758
lists are deleted when the widget is destroyed.
2761
void QGLWidget::renderText(int x, int y, const QString & str, const QFont & fnt, int listBase)
2764
glPushAttrib(GL_TRANSFORM_BIT | GL_VIEWPORT_BIT | GL_LIST_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT);
2765
glMatrixMode(GL_PROJECTION);
2768
glOrtho(0, width(), height(), 0, -1, 1);
2769
glMatrixMode(GL_MODELVIEW);
2773
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2775
glRasterPos2i(0, 0);
2776
glBitmap(0, 0, 0, 0, x, -y, NULL);
2777
glListBase(fontDisplayListBase(fnt, listBase));
2778
glCallLists(str.length(), GL_UNSIGNED_BYTE, str.toLocal8Bit());
2781
glMatrixMode(GL_PROJECTION);
2788
\a x, \a y and \a z are specified in scene or object coordinates
2789
relative to the currently set projection and model matrices. This
2790
can be useful if you want to annotate models with text labels and
2791
have the labels move with the model as it is rotated etc.
2793
void QGLWidget::renderText(double x, double y, double z, const QString & str, const QFont & fnt,
2797
glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT);
2798
glRasterPos3d(x, y, z);
2799
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2801
glListBase(fontDisplayListBase(fnt, listBase));
2802
glCallLists(str.length(), GL_UNSIGNED_BYTE, str.toLocal8Bit());
2806
QGLFormat QGLWidget::format() const
2808
Q_D(const QGLWidget);
2809
return d->glcx->format();
2812
const QGLContext *QGLWidget::context() const
2814
Q_D(const QGLWidget);
2818
bool QGLWidget::doubleBuffer() const
2820
Q_D(const QGLWidget);
2821
return d->glcx->format().doubleBuffer();
2824
void QGLWidget::setAutoBufferSwap(bool on)
2830
bool QGLWidget::autoBufferSwap() const
2832
Q_D(const QGLWidget);
2837
Calls QGLContext:::bindTexture(\a image, \a target, \a format) on the currently
2842
GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format)
2845
return d->glcx->bindTexture(image, target, format);
2849
Calls QGLContext:::bindTexture(\a pixmap, \a target, \a format) on the currently
2854
GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format)
2857
return d->glcx->bindTexture(pixmap, target, format);
2862
Calls QGLContext::bindTexture(\a fileName) on the currently set context.
2866
GLuint QGLWidget::bindTexture(const QString &fileName)
2869
return d->glcx->bindTexture(fileName);
2873
Calls QGLContext::deleteTexture(\a id) on the currently set
2878
void QGLWidget::deleteTexture(GLuint id)
2881
d->glcx->deleteTexture(id);
2884
Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_widget_paintengine)
2888
Returns the GL widget's paint engine. This is normally a
2891
QPaintEngine *QGLWidget::paintEngine() const
2893
return qt_widget_paintengine();
2901
QGLWidget::QGLWidget(QWidget *parent, const char *name,
2902
const QGLWidget* shareWidget, Qt::WFlags f)
2903
: QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
2907
setObjectName(name);
2908
setAttribute(Qt::WA_PaintOnScreen);
2909
setAttribute(Qt::WA_NoSystemBackground);
2910
d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget);
2917
QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent,
2918
const char *name, const QGLWidget* shareWidget,
2920
: QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
2924
setObjectName(name);
2925
setAttribute(Qt::WA_PaintOnScreen);
2926
setAttribute(Qt::WA_NoSystemBackground);
2927
d->init(new QGLContext(format, this), shareWidget);
2934
QGLWidget::QGLWidget(QGLContext *context, QWidget *parent,
2935
const char *name, const QGLWidget *shareWidget, Qt::WFlags f)
2936
: QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
2940
setObjectName(name);
2941
setAttribute(Qt::WA_PaintOnScreen);
2942
setAttribute(Qt::WA_NoSystemBackground);
2943
d->init(context, shareWidget);
2946
#endif // QT3_SUPPORT
2948
void QGLExtensions::init_extensions()
2950
QString extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
2951
if (extensions.contains("texture_rectangle"))
2952
glExtensions |= TextureRectangle;
2953
if (extensions.contains("multisample"))
2954
glExtensions |= SampleBuffers;
2955
if (extensions.contains("generate_mipmap"))
2956
glExtensions |= GenerateMipmap;
2957
if (extensions.contains("texture_compression_s3tc"))
2958
glExtensions |= TextureCompression;
2960
QGLContext cx(QGLFormat::defaultFormat());
2961
if (glExtensions & TextureCompression) {
2962
qt_glCompressedTexImage2DARB = (pfn_glCompressedTexImage2DARB) cx.getProcAddress("glCompressedTexImage2DARB");