~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/opengl/qgl.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the opengl module of the Qt Toolkit.
 
6
**
 
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.
 
10
**
 
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.
 
15
**
 
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.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
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.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qplatformdefs.h"
 
30
 
 
31
#include "qgl.h"
 
32
#include "qpixmap.h"
 
33
#include "qimage.h"
 
34
#include "qgl_p.h"
 
35
#include <private/qpaintengine_opengl_p.h>
 
36
#include "qcolormap.h"
 
37
#include "qcache.h"
 
38
#include "qfile.h"
 
39
 
 
40
Q_GLOBAL_STATIC(QGLFormat, qgl_default_format)
 
41
 
 
42
class QGLDefaultOverlayFormat: public QGLFormat
 
43
{
 
44
public:
 
45
    inline QGLDefaultOverlayFormat()
 
46
    {
 
47
        setOption(QGL::DirectRendering);
 
48
        setPlane(1);
 
49
    }
 
50
    Q_GLOBAL_STATIC(QGLDefaultOverlayFormat, instance)
 
51
};
 
52
 
 
53
QGLExtensions::Extensions QGLExtensions::glExtensions = 0;
 
54
#ifndef APIENTRY
 
55
# define APIENTRY
 
56
#endif
 
57
typedef void (APIENTRY *pfn_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei,
 
58
                                                        GLsizei, GLint, GLsizei, const GLvoid *);
 
59
static pfn_glCompressedTexImage2DARB qt_glCompressedTexImage2DARB = 0;
 
60
 
 
61
#if defined(Q_WS_X11)
 
62
#include "private/qt_x11_p.h"
 
63
#define INT32 dummy_INT32
 
64
#define INT8 dummy_INT8
 
65
#include <GL/glx.h>
 
66
#undef INT32
 
67
#undef INT8
 
68
#include "qx11info_x11.h"
 
69
#elif defined(Q_WS_MAC)
 
70
# include <private/qt_mac_p.h>
 
71
#endif
 
72
 
 
73
#include <stdlib.h> // malloc
 
74
 
 
75
#ifndef APIENTRY
 
76
#define APIENTRY
 
77
#endif
 
78
 
 
79
/*!
 
80
    \namespace QGL
 
81
 
 
82
    \brief The QGL namespace specifies miscellaneous identifiers used
 
83
    in the Qt OpenGL module.
 
84
 
 
85
    \ingroup multimedia
 
86
*/
 
87
 
 
88
/*!
 
89
    \enum QGL::FormatOption
 
90
 
 
91
    This enum specifies the format options.
 
92
 
 
93
    \value DoubleBuffer
 
94
    \value DepthBuffer
 
95
    \value Rgba
 
96
    \value AlphaChannel
 
97
    \value AccumBuffer
 
98
    \value StencilBuffer
 
99
    \value StereoBuffers
 
100
    \value DirectRendering
 
101
    \value HasOverlay
 
102
    \value SampleBuffers
 
103
    \value SingleBuffer
 
104
    \value NoDepthBuffer
 
105
    \value ColorIndex
 
106
    \value NoAlphaChannel
 
107
    \value NoAccumBuffer
 
108
    \value NoStencilBuffer
 
109
    \value NoStereoBuffers
 
110
    \value IndirectRendering
 
111
    \value NoOverlay
 
112
    \value NoSampleBuffers
 
113
*/
 
114
 
 
115
/*****************************************************************************
 
116
  QGLFormat implementation
 
117
 *****************************************************************************/
 
118
 
 
119
 
 
120
/*!
 
121
    \class QGLFormat
 
122
    \brief The QGLFormat class specifies the display format of an OpenGL
 
123
    rendering context.
 
124
 
 
125
    \ingroup multimedia
 
126
 
 
127
    A display format has several characteristics:
 
128
    \list
 
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
 
140
    \endlist
 
141
 
 
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().
 
146
 
 
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.
 
154
 
 
155
    You create and tell a QGLFormat object what rendering options you
 
156
    want from an OpenGL
 
157
    \footnote
 
158
        OpenGL is a trademark of Silicon Graphics, Inc. in the
 
159
        United States and other countries.
 
160
    \endfootnote
 
161
    rendering context.
 
162
 
 
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.
 
168
 
 
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:
 
172
    \code
 
173
    QGLFormat fmt;
 
174
    fmt.setAlpha(true);
 
175
    fmt.setStereo(true);
 
176
    QGLFormat::setDefaultFormat(fmt);
 
177
    \endcode
 
178
 
 
179
    Or you can specify the desired format when creating an object of
 
180
    your QGLWidget subclass:
 
181
    \code
 
182
    QGLFormat fmt;
 
183
    fmt.setDoubleBuffer(false);                 // single buffer
 
184
    fmt.setDirectRendering(false);              // software rendering
 
185
    MyGLWidget* myWidget = new MyGLWidget(fmt, ...);
 
186
    \endcode
 
187
 
 
188
    After the widget has been created, you can find out which of the
 
189
    requested features the system was able to provide:
 
190
    \code
 
191
    QGLFormat fmt;
 
192
    fmt.setOverlay(true);
 
193
    fmt.setStereo(true);
 
194
    MyGLWidget* myWidget = new MyGLWidget(fmt, ...);
 
195
    if (!myWidget->format().stereo()) {
 
196
        // ok, goggles off
 
197
        if (!myWidget->format().hasOverlay()) {
 
198
            qFatal("Cool hardware required");
 
199
        }
 
200
    }
 
201
    \endcode
 
202
 
 
203
    \sa QGLContext, QGLWidget
 
204
*/
 
205
 
 
206
 
 
207
/*!
 
208
    Constructs a QGLFormat object with the factory default settings:
 
209
    \list
 
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.
 
221
    \endlist
 
222
*/
 
223
 
 
224
QGLFormat::QGLFormat()
 
225
{
 
226
    d = new QGLFormatPrivate;
 
227
}
 
228
 
 
229
 
 
230
/*!
 
231
    Creates a QGLFormat object that is a copy of the current \link
 
232
    defaultFormat() application default format\endlink.
 
233
 
 
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
 
236
    OR'ed together.
 
237
 
 
238
    This constructor makes it easy to specify a certain desired format
 
239
    in classes derived from QGLWidget, for example:
 
240
    \code
 
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)
 
245
    {
 
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");
 
250
        ...
 
251
    }
 
252
    \endcode
 
253
 
 
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.
 
257
 
 
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.
 
261
 
 
262
    \sa defaultFormat(), setOption()
 
263
*/
 
264
 
 
265
QGLFormat::QGLFormat(QGL::FormatOptions options, int plane)
 
266
{
 
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);
 
272
    d->pln = plane;
 
273
}
 
274
 
 
275
/*!
 
276
    Constructs a copy of \a other.
 
277
*/
 
278
 
 
279
QGLFormat::QGLFormat(const QGLFormat &other)
 
280
{
 
281
    d = new QGLFormatPrivate;
 
282
    *d = *other.d;
 
283
}
 
284
 
 
285
/*!
 
286
    Assigns \a other to this object.
 
287
*/
 
288
 
 
289
QGLFormat &QGLFormat::operator=(const QGLFormat &other)
 
290
{
 
291
    *d = *other.d;
 
292
    return *this;
 
293
}
 
294
 
 
295
/*!
 
296
    Destroys the QGLFormat.
 
297
*/
 
298
QGLFormat::~QGLFormat()
 
299
{
 
300
    delete d;
 
301
}
 
302
 
 
303
/*!
 
304
    \fn bool QGLFormat::doubleBuffer() const
 
305
 
 
306
    Returns true if double buffering is enabled; otherwise returns
 
307
    false. Double buffering is enabled by default.
 
308
 
 
309
    \sa setDoubleBuffer()
 
310
*/
 
311
 
 
312
/*!
 
313
    If \a enable is true sets double buffering; otherwise sets single
 
314
    buffering.
 
315
 
 
316
    Double buffering is enabled by default.
 
317
 
 
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.
 
323
 
 
324
    \sa doubleBuffer(), QGLContext::swapBuffers(),
 
325
    QGLWidget::swapBuffers()
 
326
*/
 
327
 
 
328
void QGLFormat::setDoubleBuffer(bool enable)
 
329
{
 
330
    setOption(enable ? QGL::DoubleBuffer : QGL::SingleBuffer);
 
331
}
 
332
 
 
333
 
 
334
/*!
 
335
    \fn bool QGLFormat::depth() const
 
336
 
 
337
    Returns true if the depth buffer is enabled; otherwise returns
 
338
    false. The depth buffer is enabled by default.
 
339
 
 
340
    \sa setDepth(), setDepthBufferSize()
 
341
*/
 
342
 
 
343
/*!
 
344
    If \a enable is true enables the depth buffer; otherwise disables
 
345
    the depth buffer.
 
346
 
 
347
    The depth buffer is enabled by default.
 
348
 
 
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.
 
354
 
 
355
    \sa depth(), setDepthBufferSize()
 
356
*/
 
357
 
 
358
void QGLFormat::setDepth(bool enable)
 
359
{
 
360
    setOption(enable ? QGL::DepthBuffer : QGL::NoDepthBuffer);
 
361
}
 
362
 
 
363
 
 
364
/*!
 
365
    \fn bool QGLFormat::rgba() const
 
366
 
 
367
    Returns true if RGBA color mode is set. Returns false if color
 
368
    index mode is set. The default color mode is RGBA.
 
369
 
 
370
    \sa setRgba()
 
371
*/
 
372
 
 
373
/*!
 
374
    If \a enable is true sets RGBA mode. If \a enable is false sets
 
375
    color index mode.
 
376
 
 
377
    The default color mode is RGBA.
 
378
 
 
379
    RGBA is the preferred mode for most OpenGL applications. In RGBA
 
380
    color mode you specify colors as red + green + blue + alpha
 
381
    quadruplets.
 
382
 
 
383
    In color index mode you specify an index into a color lookup
 
384
    table.
 
385
 
 
386
    \sa rgba()
 
387
*/
 
388
 
 
389
void QGLFormat::setRgba(bool enable)
 
390
{
 
391
    setOption(enable ? QGL::Rgba : QGL::ColorIndex);
 
392
}
 
393
 
 
394
 
 
395
/*!
 
396
    \fn bool QGLFormat::alpha() const
 
397
 
 
398
    Returns true if the alpha buffer in the framebuffer is enabled;
 
399
    otherwise returns false. The alpha buffer is disabled by default.
 
400
 
 
401
    \sa setAlpha(), setAlphaBufferSize()
 
402
*/
 
403
 
 
404
/*!
 
405
    If \a enable is true enables the alpha buffer; otherwise disables
 
406
    the alpha buffer.
 
407
 
 
408
    The alpha buffer is disabled by default.
 
409
 
 
410
    The alpha buffer is typically used for implementing transparency
 
411
    or translucency. The A in RGBA specifies the transparency of a
 
412
    pixel.
 
413
 
 
414
    \sa alpha(), setAlphaBufferSize()
 
415
*/
 
416
 
 
417
void QGLFormat::setAlpha(bool enable)
 
418
{
 
419
    setOption(enable ? QGL::AlphaChannel : QGL::NoAlphaChannel);
 
420
}
 
421
 
 
422
 
 
423
/*!
 
424
    \fn bool QGLFormat::accum() const
 
425
 
 
426
    Returns true if the accumulation buffer is enabled; otherwise
 
427
    returns false. The accumulation buffer is disabled by default.
 
428
 
 
429
    \sa setAccum(), setAccumBufferSize()
 
430
*/
 
431
 
 
432
/*!
 
433
    If \a enable is true enables the accumulation buffer; otherwise
 
434
    disables the accumulation buffer.
 
435
 
 
436
    The accumulation buffer is disabled by default.
 
437
 
 
438
    The accumulation buffer is used to create blur effects and
 
439
    multiple exposures.
 
440
 
 
441
    \sa accum(), setAccumBufferSize()
 
442
*/
 
443
 
 
444
void QGLFormat::setAccum(bool enable)
 
445
{
 
446
    setOption(enable ? QGL::AccumBuffer : QGL::NoAccumBuffer);
 
447
}
 
448
 
 
449
 
 
450
/*!
 
451
    \fn bool QGLFormat::stencil() const
 
452
 
 
453
    Returns true if the stencil buffer is enabled; otherwise returns
 
454
    false. The stencil buffer is disabled by default.
 
455
 
 
456
    \sa setStencil(), setStencilBufferSize()
 
457
*/
 
458
 
 
459
/*!
 
460
    If \a enable is true enables the stencil buffer; otherwise
 
461
    disables the stencil buffer.
 
462
 
 
463
    The stencil buffer is disabled by default.
 
464
 
 
465
    The stencil buffer masks certain parts of the drawing area so that
 
466
    masked parts are not drawn on.
 
467
 
 
468
    \sa stencil(), setStencilBufferSize()
 
469
*/
 
470
 
 
471
void QGLFormat::setStencil(bool enable)
 
472
{
 
473
    setOption(enable ? QGL::StencilBuffer: QGL::NoStencilBuffer);
 
474
}
 
475
 
 
476
 
 
477
/*!
 
478
    \fn bool QGLFormat::stereo() const
 
479
 
 
480
    Returns true if stereo buffering is enabled; otherwise returns
 
481
    false. Stereo buffering is disabled by default.
 
482
 
 
483
    \sa setStereo()
 
484
*/
 
485
 
 
486
/*!
 
487
    If \a enable is true enables stereo buffering; otherwise disables
 
488
    stereo buffering.
 
489
 
 
490
    Stereo buffering is disabled by default.
 
491
 
 
492
    Stereo buffering provides extra color buffers to generate left-eye
 
493
    and right-eye images.
 
494
 
 
495
    \sa stereo()
 
496
*/
 
497
 
 
498
void QGLFormat::setStereo(bool enable)
 
499
{
 
500
    setOption(enable ? QGL::StereoBuffers : QGL::NoStereoBuffers);
 
501
}
 
502
 
 
503
 
 
504
/*!
 
505
    \fn bool QGLFormat::directRendering() const
 
506
 
 
507
    Returns true if direct rendering is enabled; otherwise returns
 
508
    false.
 
509
 
 
510
    Direct rendering is enabled by default.
 
511
 
 
512
    \sa setDirectRendering()
 
513
*/
 
514
 
 
515
/*!
 
516
    If \a enable is true enables direct rendering; otherwise disables
 
517
    direct rendering.
 
518
 
 
519
    Direct rendering is enabled by default.
 
520
 
 
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.
 
524
 
 
525
    \sa directRendering()
 
526
*/
 
527
 
 
528
void QGLFormat::setDirectRendering(bool enable)
 
529
{
 
530
    setOption(enable ? QGL::DirectRendering : QGL::IndirectRendering);
 
531
}
 
532
 
 
533
/*!
 
534
    \fn bool QGLFormat::sampleBuffers() const
 
535
 
 
536
    Returns true if multisample buffer support is enabled; otherwise
 
537
    returns false.
 
538
 
 
539
    The multisample buffer is disabled by default.
 
540
 
 
541
    \sa setSampleBuffers()
 
542
*/
 
543
 
 
544
/*!
 
545
    If \a enable is true, a GL context with multisample buffer support
 
546
    is picked; otherwise ignored.
 
547
 
 
548
    \sa sampleBuffers(), setSamples(), samples()
 
549
*/
 
550
void QGLFormat::setSampleBuffers(bool enable)
 
551
{
 
552
    setOption(enable ? QGL::SampleBuffers : QGL::NoSampleBuffers);
 
553
}
 
554
 
 
555
/*!
 
556
    Returns the number of samples per pixel when multisampling is
 
557
    enabled. By default, the highest number of samples that is
 
558
    available is used.
 
559
 
 
560
    \sa setSampleBuffers(), sampleBuffers(), setSamples()
 
561
*/
 
562
int QGLFormat::samples() const
 
563
{
 
564
   return d->numSamples;
 
565
}
 
566
 
 
567
/*!
 
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.
 
571
 
 
572
    \sa setSampleBuffers(), sampleBuffers(), samples()
 
573
*/
 
574
void QGLFormat::setSamples(int numSamples)
 
575
{
 
576
    d->numSamples = numSamples;
 
577
}
 
578
 
 
579
/*!
 
580
    \fn bool QGLFormat::hasOverlay() const
 
581
 
 
582
    Returns true if overlay plane is enabled; otherwise returns false.
 
583
 
 
584
    Overlay is disabled by default.
 
585
 
 
586
    \sa setOverlay()
 
587
*/
 
588
 
 
589
/*!
 
590
    If \a enable is true enables an overlay plane; otherwise disables
 
591
    the overlay plane.
 
592
 
 
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.
 
596
 
 
597
    \sa hasOverlay()
 
598
*/
 
599
 
 
600
void QGLFormat::setOverlay(bool enable)
 
601
{
 
602
    setOption(enable ? QGL::HasOverlay : QGL::NoOverlay);
 
603
}
 
604
 
 
605
/*!
 
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.
 
609
 
 
610
    \sa setPlane()
 
611
*/
 
612
int QGLFormat::plane() const
 
613
{
 
614
    return d->pln;
 
615
}
 
616
 
 
617
/*!
 
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.
 
621
 
 
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
 
626
    created.
 
627
 
 
628
    \sa plane()
 
629
*/
 
630
void QGLFormat::setPlane(int plane)
 
631
{
 
632
    d->pln = plane;
 
633
}
 
634
 
 
635
/*!
 
636
    Sets the format option to \a opt.
 
637
 
 
638
    \sa testOption()
 
639
*/
 
640
 
 
641
void QGLFormat::setOption(QGL::FormatOptions opt)
 
642
{
 
643
    if (opt & 0xffff)
 
644
        d->opts |= opt;
 
645
    else
 
646
       d->opts &= ~(opt >> 16);
 
647
}
 
648
 
 
649
 
 
650
 
 
651
/*!
 
652
    Returns true if format option \a opt is set; otherwise returns false.
 
653
 
 
654
    \sa setOption()
 
655
*/
 
656
 
 
657
bool QGLFormat::testOption(QGL::FormatOptions opt) const
 
658
{
 
659
    if (opt & 0xffff)
 
660
       return (d->opts & opt) != 0;
 
661
    else
 
662
       return (d->opts & (opt >> 16)) == 0;
 
663
}
 
664
 
 
665
/*!
 
666
    Set the preferred depth buffer size to \a size.
 
667
 
 
668
    \sa depthBufferSize(), setDepth(), depth()
 
669
*/
 
670
void QGLFormat::setDepthBufferSize(int size)
 
671
{
 
672
    d->depthSize = size;
 
673
}
 
674
 
 
675
/*!
 
676
    Returns the depth buffer size.
 
677
 
 
678
    \sa depth(), setDepth(), setDepthBufferSize()
 
679
*/
 
680
int QGLFormat::depthBufferSize() const
 
681
{
 
682
   return d->depthSize;
 
683
}
 
684
 
 
685
/*!
 
686
    Set the preferred alpha buffer size to \a size.
 
687
 
 
688
    \sa alpha(), setAlpha(), alphaBufferSize()
 
689
*/
 
690
void QGLFormat::setAlphaBufferSize(int size)
 
691
{
 
692
    d->alphaSize = size;
 
693
}
 
694
 
 
695
/*!
 
696
    Returns the alpha buffer size.
 
697
 
 
698
    \sa alpha(), setAlpha(), setAlphaBufferSize()
 
699
*/
 
700
int QGLFormat::alphaBufferSize() const
 
701
{
 
702
   return d->alphaSize;
 
703
}
 
704
 
 
705
/*!
 
706
    Set the preferred accumulation buffer size, where \a size is the
 
707
    bit depth for each RGBA component.
 
708
 
 
709
    \sa accum(), setAccum(), accumBufferSize()
 
710
*/
 
711
void QGLFormat::setAccumBufferSize(int size)
 
712
{
 
713
    d->accumSize = size;
 
714
}
 
715
 
 
716
/*!
 
717
    Returns the accumulation buffer size.
 
718
 
 
719
    \sa setAccumBufferSize(), accum(), setAccum()
 
720
*/
 
721
int QGLFormat::accumBufferSize() const
 
722
{
 
723
   return d->accumSize;
 
724
}
 
725
 
 
726
/*!
 
727
    Set the preferred stencil buffer size to \a size.
 
728
 
 
729
    \sa stencilBufferSize(), setStencil(), stencil()
 
730
*/
 
731
void QGLFormat::setStencilBufferSize(int size)
 
732
{
 
733
    d->stencilSize = size;
 
734
}
 
735
 
 
736
/*!
 
737
    Returns the stencil buffer size.
 
738
 
 
739
    \sa stencil(), setStencil(), setStencilBufferSize()
 
740
*/
 
741
int QGLFormat::stencilBufferSize() const
 
742
{
 
743
   return d->stencilSize;
 
744
}
 
745
 
 
746
/*!
 
747
    \fn bool QGLFormat::hasOpenGL()
 
748
 
 
749
    Returns true if the window system has any OpenGL support;
 
750
    otherwise returns false.
 
751
 
 
752
    \warning This function must not be called until the QApplication
 
753
    object has been created.
 
754
*/
 
755
 
 
756
 
 
757
 
 
758
/*!
 
759
    \fn bool QGLFormat::hasOpenGLOverlays()
 
760
 
 
761
    Returns true if the window system supports OpenGL overlays;
 
762
    otherwise returns false.
 
763
 
 
764
    \warning This function must not be called until the QApplication
 
765
    object has been created.
 
766
*/
 
767
 
 
768
/*!
 
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.
 
772
 
 
773
    If no special default format has been set using
 
774
    setDefaultFormat(), the default format is the same as that created
 
775
    with QGLFormat().
 
776
 
 
777
    \sa setDefaultFormat()
 
778
*/
 
779
 
 
780
QGLFormat QGLFormat::defaultFormat()
 
781
{
 
782
    return *qgl_default_format();
 
783
}
 
784
 
 
785
/*!
 
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:
 
789
    \code
 
790
    QApplication a(argc, argv);
 
791
    QGLFormat f;
 
792
    f.setDoubleBuffer(false);
 
793
    QGLFormat::setDefaultFormat(f);
 
794
    \endcode
 
795
 
 
796
    \sa defaultFormat()
 
797
*/
 
798
 
 
799
void QGLFormat::setDefaultFormat(const QGLFormat &f)
 
800
{
 
801
    *qgl_default_format() = f;
 
802
}
 
803
 
 
804
 
 
805
/*!
 
806
    Returns the default QGLFormat for overlay contexts.
 
807
 
 
808
    The factory default overlay format is:
 
809
    \list
 
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).
 
820
    \endlist
 
821
 
 
822
    \sa setDefaultFormat()
 
823
*/
 
824
 
 
825
QGLFormat QGLFormat::defaultOverlayFormat()
 
826
{
 
827
    return *QGLDefaultOverlayFormat::instance();
 
828
}
 
829
 
 
830
/*!
 
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.
 
834
 
 
835
    For example, to get a double buffered overlay context (if
 
836
    available), use code like this:
 
837
 
 
838
    \code
 
839
    QGLFormat f = QGLFormat::defaultOverlayFormat();
 
840
    f.setDoubleBuffer(true);
 
841
    QGLFormat::setDefaultOverlayFormat(f);
 
842
    \endcode
 
843
 
 
844
    As usual, you can find out after widget creation whether the
 
845
    underlying OpenGL system was able to provide the requested
 
846
    specification:
 
847
 
 
848
    \code
 
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
 
856
        else
 
857
            ; // no, only single buffered overlays are available
 
858
    }
 
859
    \endcode
 
860
 
 
861
    \sa defaultOverlayFormat()
 
862
*/
 
863
 
 
864
void QGLFormat::setDefaultOverlayFormat(const QGLFormat &f)
 
865
{
 
866
    QGLFormat *defaultFormat = QGLDefaultOverlayFormat::instance();
 
867
    *defaultFormat = f;
 
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);
 
872
}
 
873
 
 
874
 
 
875
/*!
 
876
    Returns true if all the options of the two QGLFormats are equal;
 
877
    otherwise returns false.
 
878
*/
 
879
 
 
880
bool operator==(const QGLFormat& a, const QGLFormat& b)
 
881
{
 
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;
 
885
}
 
886
 
 
887
 
 
888
/*!
 
889
    Returns false if all the options of the two QGLFormats are equal;
 
890
    otherwise returns true.
 
891
*/
 
892
 
 
893
bool operator!=(const QGLFormat& a, const QGLFormat& b)
 
894
{
 
895
    return !(a == b);
 
896
}
 
897
 
 
898
/*****************************************************************************
 
899
  QGLContext implementation
 
900
 *****************************************************************************/
 
901
 
 
902
void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
 
903
{
 
904
    Q_Q(QGLContext);
 
905
    glFormat = reqFormat = format;
 
906
    valid = false;
 
907
    q->setDevice(dev);
 
908
#if defined(Q_WS_X11)
 
909
    gpm = 0;
 
910
#endif
 
911
#if defined(Q_WS_WIN)
 
912
    dc = 0;
 
913
    win = 0;
 
914
    pixelFormatId = 0;
 
915
    cmap = 0;
 
916
    hbitmap = 0;
 
917
    hbitmap_hdc = 0;
 
918
#endif
 
919
    crWin = false;
 
920
    initDone = false;
 
921
    sharing = false;
 
922
}
 
923
 
 
924
QGLContext* QGLContext::currentCtx = 0;
 
925
 
 
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)
 
929
{
 
930
    int n = 0, last = 0;
 
931
    for (int s = 0; s < 32; ++s) {
 
932
        if (((v>>s) & 1) == 1) {
 
933
            ++n;
 
934
            last = s;
 
935
        }
 
936
    }
 
937
    if (n > 1)
 
938
        return 1 << (last+1);
 
939
    return 1 << last;
 
940
}
 
941
 
 
942
class QGLTexture {
 
943
public:
 
944
    QGLTexture(const QGLContext *ctx, GLuint tx_id) : context(ctx), id(tx_id) {}
 
945
    ~QGLTexture() {
 
946
        if (!context->isSharing())
 
947
            glDeleteTextures(1, &id);
 
948
     }
 
949
 
 
950
    const QGLContext *context;
 
951
    GLuint id;
 
952
};
 
953
 
 
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;
 
957
 
 
958
// DDS format structure
 
959
struct DDSFormat {
 
960
    quint32 dwSize;
 
961
    quint32 dwFlags;
 
962
    quint32 dwHeight;
 
963
    quint32 dwWidth;
 
964
    quint32 dwLinearSize;
 
965
    quint32 dummy1;
 
966
    quint32 dwMipMapCount;
 
967
    quint32 dummy2[11];
 
968
    struct {
 
969
        quint32 dummy3[2];
 
970
        quint32 dwFourCC;
 
971
        quint32 dummy4[5];
 
972
    } ddsPixelFormat;
 
973
};
 
974
 
 
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
 
981
 
 
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
 
987
#endif
 
988
 
 
989
#ifndef GL_GENERATE_MIPMAP_SGIS
 
990
#define GL_GENERATE_MIPMAP_SGIS       0x8191
 
991
#define GL_GENERATE_MIPMAP_HINT_SGIS  0x8192
 
992
#endif
 
993
 
 
994
/*!
 
995
    \class QGLContext
 
996
    \brief The QGLContext class encapsulates an OpenGL rendering context.
 
997
 
 
998
    \ingroup multimedia
 
999
 
 
1000
    An OpenGL
 
1001
    \footnote
 
1002
        OpenGL is a trademark of Silicon Graphics, Inc. in the
 
1003
        United States and other countries.
 
1004
    \endfootnote
 
1005
    rendering context is a complete set of OpenGL state variables.
 
1006
 
 
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.
 
1017
 
 
1018
    You can examine properties of the context with, e.g. isValid(),
 
1019
    isSharing(), initialized(), windowCreated() and
 
1020
    overlayTransparentColor().
 
1021
 
 
1022
    If you're using double buffering you can swap the screen contents
 
1023
    with the off-screen buffer using swapBuffers().
 
1024
 
 
1025
    Please note that QGLContext is not thread safe.
 
1026
*/
 
1027
 
 
1028
 
 
1029
/*!
 
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.
 
1033
 
 
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.
 
1038
 
 
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
 
1043
    all.
 
1044
 
 
1045
    \sa format(), isValid()
 
1046
*/
 
1047
 
 
1048
QGLContext::QGLContext(const QGLFormat &format, QPaintDevice *device)
 
1049
{
 
1050
    d_ptr = new QGLContextPrivate(this);
 
1051
    Q_D(QGLContext);
 
1052
    d->init(device, format);
 
1053
}
 
1054
 
 
1055
/*!
 
1056
    \overload
 
1057
    \internal
 
1058
*/
 
1059
QGLContext::QGLContext(const QGLFormat &format)
 
1060
{
 
1061
    d_ptr = new QGLContextPrivate(this);
 
1062
    Q_D(QGLContext);
 
1063
    d->init(0, format);
 
1064
}
 
1065
 
 
1066
/*!
 
1067
    Destroys the OpenGL context and frees its resources.
 
1068
*/
 
1069
 
 
1070
QGLContext::~QGLContext()
 
1071
{
 
1072
    Q_D(QGLContext);
 
1073
    // remove any textures cached in this context
 
1074
    if (qt_tex_cache) {
 
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);
 
1080
        }
 
1081
        // ### thread safety
 
1082
        if (qt_tex_cache->size() == 0) {
 
1083
            delete qt_tex_cache;
 
1084
            qt_tex_cache = 0;
 
1085
        }
 
1086
    }
 
1087
 
 
1088
    reset();
 
1089
    delete d;
 
1090
}
 
1091
 
 
1092
/*! \overload
 
1093
 
 
1094
    Reads the DirectDrawSurface (DDS) compressed file \a fileName and
 
1095
    generates a 2D GL texture from it.
 
1096
 
 
1097
    Only the DXT1, DXT3 and DXT5 DDS formats are supported.
 
1098
 
 
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
 
1101
    extensions.
 
1102
 
 
1103
    \sa deleteTexture()
 
1104
*/
 
1105
GLuint QGLContext::bindTexture(const QString &fileName)
 
1106
{
 
1107
    if (!qt_glCompressedTexImage2DARB) {
 
1108
        qWarning("QGLContext::bindTexture(): The GL implementation does not support texture"
 
1109
                 "compression extensions.");
 
1110
        return 0;
 
1111
    }
 
1112
 
 
1113
    if (!qt_tex_cache)
 
1114
        qt_tex_cache = new QGLTextureCache(qt_tex_cache_limit);
 
1115
 
 
1116
    QString key(fileName);
 
1117
    QGLTexture *texture = qt_tex_cache->object(key);
 
1118
 
 
1119
    if (texture && texture->context == this) {
 
1120
        glBindTexture(GL_TEXTURE_2D, texture->id);
 
1121
        return texture->id;
 
1122
    }
 
1123
 
 
1124
    QFile f(fileName);
 
1125
    f.open(QIODevice::ReadOnly);
 
1126
 
 
1127
    char tag[4];
 
1128
    f.read(&tag[0], 4);
 
1129
    if (strncmp(tag,"DDS ", 4) != 0) {
 
1130
        qWarning("QGLContext::bindTexture(): not a DDS image file.");
 
1131
        return 0;
 
1132
    }
 
1133
 
 
1134
    DDSFormat ddsHeader;
 
1135
    f.read((char *) &ddsHeader, sizeof(DDSFormat));
 
1136
 
 
1137
    if (!ddsHeader.dwLinearSize) {
 
1138
        qWarning("QGLContext::bindTexture() DDS image size is not valid.");
 
1139
        return 0;
 
1140
    }
 
1141
 
 
1142
    int factor = 4;
 
1143
    int bufferSize = 0;
 
1144
    int blockSize = 16;
 
1145
    GLenum format;
 
1146
 
 
1147
    switch(ddsHeader.ddsPixelFormat.dwFourCC) {
 
1148
    case FOURCC_DXT1:
 
1149
        format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
 
1150
        factor = 2;
 
1151
        blockSize = 8;
 
1152
        break;
 
1153
    case FOURCC_DXT3:
 
1154
        format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
 
1155
        break;
 
1156
    case FOURCC_DXT5:
 
1157
        format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
 
1158
        break;
 
1159
    default:
 
1160
        qWarning("QGLContext::bindTexture() DDS image format not supported.");
 
1161
        return 0;
 
1162
    }
 
1163
 
 
1164
    if (ddsHeader.dwMipMapCount > 1)
 
1165
        bufferSize = ddsHeader.dwLinearSize * factor;
 
1166
    else
 
1167
        bufferSize = ddsHeader.dwLinearSize;
 
1168
 
 
1169
    GLubyte *pixels = (GLubyte *) malloc(bufferSize*sizeof(GLubyte));
 
1170
    f.seek(ddsHeader.dwSize + 4);
 
1171
    f.read((char *) pixels, bufferSize);
 
1172
    f.close();
 
1173
 
 
1174
    GLuint tx_id;
 
1175
    glGenTextures(1, &tx_id);
 
1176
    glBindTexture(GL_TEXTURE_2D, tx_id);
 
1177
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
1178
 
 
1179
    int size;
 
1180
    int offset = 0;
 
1181
    int w = ddsHeader.dwWidth;
 
1182
    int h = ddsHeader.dwHeight;
 
1183
 
 
1184
    // load mip-maps
 
1185
    for(int i = 0; i < (int) ddsHeader.dwMipMapCount; ++i) {
 
1186
        if (w == 0) w = 1;
 
1187
        if (h == 0) h = 1;
 
1188
 
 
1189
        size = ((w+3)/4) * ((h+3)/4) * blockSize;
 
1190
        qt_glCompressedTexImage2DARB(GL_TEXTURE_2D, i, format, w, h, 0,
 
1191
                                     size, pixels + offset);
 
1192
        offset += size;
 
1193
 
 
1194
        // half size for each mip-map level
 
1195
        w = w/2;
 
1196
        h = h/2;
 
1197
    }
 
1198
 
 
1199
    free(pixels);
 
1200
 
 
1201
    int cost = bufferSize/1024;
 
1202
    qt_tex_cache->insert(key, new QGLTexture(this, tx_id), cost);
 
1203
    return tx_id;
 
1204
}
 
1205
 
 
1206
GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format, const QString &key)
 
1207
{
 
1208
    Q_Q(QGLContext);
 
1209
 
 
1210
    if (!qt_tex_cache)
 
1211
        qt_tex_cache = new QGLTextureCache(qt_tex_cache_limit);
 
1212
 
 
1213
    // Scale the pixmap if needed. GL textures needs to have the
 
1214
    // dimensions 2^n+2(border) x 2^m+2(border).
 
1215
    QImage tx;
 
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));
 
1220
    else
 
1221
        tx = QGLWidget::convertToGLFormat(image);
 
1222
 
 
1223
    GLuint tx_id;
 
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)
 
1229
    {
 
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);
 
1233
    } else {
 
1234
        glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
1235
    }
 
1236
 
 
1237
    glTexImage2D(target, 0, format, tx.width(), tx.height(), 0, GL_RGBA,
 
1238
                 GL_UNSIGNED_BYTE, tx.bits());
 
1239
 
 
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);
 
1243
    return tx_id;
 
1244
}
 
1245
 
 
1246
/*!
 
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.
 
1250
 
 
1251
    The \a target parameter specifies the texture target. The default
 
1252
    target is \c GL_TEXTURE_2D.
 
1253
 
 
1254
    The \a format parameter sets the internal format for the
 
1255
    texture. The default format is \c GL_RGBA8.
 
1256
 
 
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.
 
1261
 
 
1262
    The texture that is generated is cached, so multiple calls to
 
1263
    bindTexture() with the same QImage will return the same texture
 
1264
    id.
 
1265
 
 
1266
    \sa deleteTexture()
 
1267
*/
 
1268
GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format)
 
1269
{
 
1270
    Q_D(QGLContext);
 
1271
    const QString key = QString("%1_%2_%3").arg(image.serialNumber()).arg(target).arg(format);
 
1272
    if (qt_tex_cache) {
 
1273
        QGLTexture *texture = qt_tex_cache->object(key);
 
1274
        if (texture && texture->context == this) {
 
1275
            glBindTexture(target, texture->id);
 
1276
            return texture->id;
 
1277
        }
 
1278
    }
 
1279
    return d->bindTexture(image, target, format, key);
 
1280
}
 
1281
 
 
1282
/*! \overload
 
1283
 
 
1284
    Generates and binds a 2D GL texture based on \a pixmap.
 
1285
*/
 
1286
GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint format)
 
1287
{
 
1288
    Q_D(QGLContext);
 
1289
    const QString key = QString("%1_%2_%3").arg(pixmap.serialNumber()).arg(target).arg(format);
 
1290
 
 
1291
    if (qt_tex_cache) {
 
1292
        QGLTexture *texture = qt_tex_cache->object(key);
 
1293
        if (texture && texture->context == this) {
 
1294
            glBindTexture(target, texture->id);
 
1295
            return texture->id;
 
1296
        }
 
1297
    }
 
1298
    return d->bindTexture(pixmap.toImage(), target, format, key);
 
1299
}
 
1300
 
 
1301
/*!
 
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
 
1305
    context.
 
1306
 
 
1307
    \sa bindTexture()
 
1308
*/
 
1309
void QGLContext::deleteTexture(GLuint id)
 
1310
{
 
1311
    if (!qt_tex_cache)
 
1312
        return;
 
1313
 
 
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));
 
1319
            break;
 
1320
        }
 
1321
    }
 
1322
}
 
1323
 
 
1324
/*!
 
1325
    This function sets the limit for the texture cache to \a size,
 
1326
    expressed in kilobytes.
 
1327
 
 
1328
    By default, the cache limit is approximately 64 MB.
 
1329
 
 
1330
    \sa textureCacheLimit()
 
1331
*/
 
1332
void QGLContext::setTextureCacheLimit(int size)
 
1333
{
 
1334
    qt_tex_cache_limit = size;
 
1335
    if (qt_tex_cache)
 
1336
        qt_tex_cache->setMaxCost(qt_tex_cache_limit);
 
1337
}
 
1338
 
 
1339
/*!
 
1340
    Returns the current texture cache limit in kilobytes.
 
1341
 
 
1342
    \sa setTextureCacheLimit()
 
1343
*/
 
1344
int QGLContext::textureCacheLimit()
 
1345
{
 
1346
    return qt_tex_cache_limit;
 
1347
}
 
1348
 
 
1349
/*!
 
1350
    \fn QGLFormat QGLContext::format() const
 
1351
 
 
1352
    Returns the frame buffer format that was obtained (this may be a
 
1353
    subset of what was requested).
 
1354
 
 
1355
    \sa requestedFormat()
 
1356
*/
 
1357
 
 
1358
/*!
 
1359
    \fn QGLFormat QGLContext::requestedFormat() const
 
1360
 
 
1361
    Returns the frame buffer format that was originally requested in
 
1362
    the constructor or setFormat().
 
1363
 
 
1364
    \sa format()
 
1365
*/
 
1366
 
 
1367
/*!
 
1368
    Sets a \a format for this context. The context is \link reset()
 
1369
    reset\endlink.
 
1370
 
 
1371
    Call create() to create a new GL context that tries to match the
 
1372
    new format.
 
1373
 
 
1374
    \code
 
1375
    QGLContext *cx;
 
1376
    //  ...
 
1377
    QGLFormat f;
 
1378
    f.setStereo(true);
 
1379
    cx->setFormat(f);
 
1380
    if (!cx->create())
 
1381
        exit(); // no OpenGL support, or cannot render on the specified paintdevice
 
1382
    if (!cx->format().stereo())
 
1383
        exit(); // could not create stereo context
 
1384
    \endcode
 
1385
 
 
1386
    \sa format(), reset(), create()
 
1387
*/
 
1388
 
 
1389
void QGLContext::setFormat(const QGLFormat &format)
 
1390
{
 
1391
    Q_D(QGLContext);
 
1392
    reset();
 
1393
    d->glFormat = d->reqFormat = format;
 
1394
}
 
1395
 
 
1396
/*!
 
1397
    \internal
 
1398
*/
 
1399
void QGLContext::setDevice(QPaintDevice *pDev)
 
1400
{
 
1401
    Q_D(QGLContext);
 
1402
    if (isValid())
 
1403
        reset();
 
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");
 
1408
    }
 
1409
}
 
1410
 
 
1411
/*!
 
1412
    \fn bool QGLContext::isValid() const
 
1413
 
 
1414
    Returns true if a GL rendering context has been successfully
 
1415
    created; otherwise returns false.
 
1416
*/
 
1417
 
 
1418
/*!
 
1419
    \fn void QGLContext::setValid(bool valid)
 
1420
    \internal
 
1421
 
 
1422
    Forces the GL rendering context to be valid.
 
1423
*/
 
1424
 
 
1425
/*!
 
1426
    \fn bool QGLContext::isSharing() const
 
1427
 
 
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
 
1431
    formats.
 
1432
*/
 
1433
 
 
1434
/*!
 
1435
    \fn bool QGLContext::deviceIsPixmap() const
 
1436
 
 
1437
    Returns true if the paint device of this context is a pixmap;
 
1438
    otherwise returns false.
 
1439
*/
 
1440
 
 
1441
/*!
 
1442
    \fn bool QGLContext::windowCreated() const
 
1443
 
 
1444
    Returns true if a window has been created for this context;
 
1445
    otherwise returns false.
 
1446
 
 
1447
    \sa setWindowCreated()
 
1448
*/
 
1449
 
 
1450
/*!
 
1451
    \fn void QGLContext::setWindowCreated(bool on)
 
1452
 
 
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.
 
1455
 
 
1456
    \sa windowCreated()
 
1457
*/
 
1458
 
 
1459
/*!
 
1460
    \fn uint QGLContext::colorIndex(const QColor& c) const
 
1461
 
 
1462
    \internal
 
1463
 
 
1464
    Returns a colormap index for the color c, in ColorIndex mode. Used
 
1465
    by qglColor() and qglClearColor().
 
1466
*/
 
1467
 
 
1468
 
 
1469
/*!
 
1470
    \fn bool QGLContext::initialized() const
 
1471
 
 
1472
    Returns true if this context has been initialized, i.e. if
 
1473
    QGLWidget::initializeGL() has been performed on it; otherwise
 
1474
    returns false.
 
1475
 
 
1476
    \sa setInitialized()
 
1477
*/
 
1478
 
 
1479
/*!
 
1480
    \fn void QGLContext::setInitialized(bool on)
 
1481
 
 
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.
 
1485
 
 
1486
    \sa initialized()
 
1487
*/
 
1488
 
 
1489
/*!
 
1490
    \fn const QGLContext* QGLContext::currentContext()
 
1491
 
 
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
 
1494
    current.
 
1495
 
 
1496
    \sa makeCurrent()
 
1497
*/
 
1498
 
 
1499
/*!
 
1500
    \fn QColor QGLContext::overlayTransparentColor() const
 
1501
 
 
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.
 
1505
 
 
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.)
 
1509
 
 
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.
 
1515
*/
 
1516
 
 
1517
 
 
1518
/*!
 
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).
 
1523
 
 
1524
    After successful creation, format() returns the set of features of
 
1525
    the created GL rendering context.
 
1526
 
 
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
 
1531
    succeeded.
 
1532
 
 
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.
 
1542
 
 
1543
    \sa chooseContext(), format(), isValid()
 
1544
*/
 
1545
 
 
1546
bool QGLContext::create(const QGLContext* shareContext)
 
1547
{
 
1548
    Q_D(QGLContext);
 
1549
    reset();
 
1550
    d->valid = chooseContext(shareContext);
 
1551
    return d->valid;
 
1552
}
 
1553
 
 
1554
bool QGLContext::isValid() const
 
1555
{
 
1556
    Q_D(const QGLContext);
 
1557
    return d->valid;
 
1558
}
 
1559
 
 
1560
void QGLContext::setValid(bool valid)
 
1561
{
 
1562
    Q_D(QGLContext);
 
1563
    d->valid = valid;
 
1564
}
 
1565
 
 
1566
bool QGLContext::isSharing() const
 
1567
{
 
1568
    Q_D(const QGLContext);
 
1569
    return d->sharing;
 
1570
}
 
1571
 
 
1572
QGLFormat QGLContext::format() const
 
1573
{
 
1574
    Q_D(const QGLContext);
 
1575
    return d->glFormat;
 
1576
}
 
1577
 
 
1578
QGLFormat QGLContext::requestedFormat() const
 
1579
{
 
1580
    Q_D(const QGLContext);
 
1581
    return d->reqFormat;
 
1582
}
 
1583
 
 
1584
 QPaintDevice* QGLContext::device() const
 
1585
{
 
1586
    Q_D(const QGLContext);
 
1587
    return d->paintDevice;
 
1588
}
 
1589
 
 
1590
bool QGLContext::deviceIsPixmap() const
 
1591
{
 
1592
    Q_D(const QGLContext);
 
1593
    return d->paintDevice->devType() == QInternal::Pixmap;
 
1594
}
 
1595
 
 
1596
 
 
1597
bool QGLContext::windowCreated() const
 
1598
{
 
1599
    Q_D(const QGLContext);
 
1600
    return d->crWin;
 
1601
}
 
1602
 
 
1603
 
 
1604
void QGLContext::setWindowCreated(bool on)
 
1605
{
 
1606
    Q_D(QGLContext);
 
1607
    d->crWin = on;
 
1608
}
 
1609
 
 
1610
bool QGLContext::initialized() const
 
1611
{
 
1612
    Q_D(const QGLContext);
 
1613
    return d->initDone;
 
1614
}
 
1615
 
 
1616
void QGLContext::setInitialized(bool on)
 
1617
{
 
1618
    Q_D(QGLContext);
 
1619
    d->initDone = on;
 
1620
}
 
1621
 
 
1622
const QGLContext* QGLContext::currentContext()
 
1623
{
 
1624
    return currentCtx;
 
1625
}
 
1626
 
 
1627
/*!
 
1628
    \fn bool QGLContext::chooseContext(const QGLContext* shareContext = 0)
 
1629
 
 
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.
 
1633
 
 
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.
 
1638
*/
 
1639
 
 
1640
 
 
1641
/*!
 
1642
    \fn void QGLContext::reset()
 
1643
 
 
1644
    Resets the context and makes it invalid.
 
1645
 
 
1646
    \sa create(), isValid()
 
1647
*/
 
1648
 
 
1649
 
 
1650
/*!
 
1651
    \fn void QGLContext::makeCurrent()
 
1652
 
 
1653
    Makes this context the current OpenGL rendering context. All GL
 
1654
    functions you call operate on this context until another context
 
1655
    is made current.
 
1656
 
 
1657
    In some very rare cases the underlying call may fail. If this
 
1658
    occurs an error message is output to stderr.
 
1659
*/
 
1660
 
 
1661
 
 
1662
/*!
 
1663
    \fn void QGLContext::swapBuffers() const
 
1664
 
 
1665
    Swaps the screen contents with an off-screen buffer. Only works if
 
1666
    the context is in double buffer mode.
 
1667
 
 
1668
    \sa QGLFormat::setDoubleBuffer()
 
1669
*/
 
1670
 
 
1671
 
 
1672
/*!
 
1673
    \fn void QGLContext::doneCurrent()
 
1674
 
 
1675
    Makes no GL context the current context. Normally, you do not need
 
1676
    to call this function; QGLContext calls it as necessary.
 
1677
*/
 
1678
 
 
1679
 
 
1680
/*!
 
1681
    \fn QPaintDevice* QGLContext::device() const
 
1682
 
 
1683
    Returns the paint device set for this context.
 
1684
 
 
1685
    \sa QGLContext::QGLContext()
 
1686
*/
 
1687
 
 
1688
/*!
 
1689
    \fn void QGLContext::generateFontDisplayLists(const QFont& font, int listBase)
 
1690
 
 
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.
 
1693
 
 
1694
    \sa QGLWidget::renderText()
 
1695
*/
 
1696
 
 
1697
 
 
1698
/*****************************************************************************
 
1699
  QGLWidget implementation
 
1700
 *****************************************************************************/
 
1701
 
 
1702
 
 
1703
/*!
 
1704
    \class QGLWidget
 
1705
    \brief The QGLWidget class is a widget for rendering OpenGL graphics.
 
1706
 
 
1707
    \ingroup multimedia
 
1708
    \mainclass
 
1709
 
 
1710
    QGLWidget provides functionality for displaying OpenGL
 
1711
    \footnote
 
1712
        OpenGL is a trademark of Silicon Graphics, Inc. in the
 
1713
        United States and other countries.
 
1714
    \endfootnote
 
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
 
1719
    commands.
 
1720
 
 
1721
    QGLWidget provides three convenient virtual functions that you can
 
1722
    reimplement in your subclass to perform the typical OpenGL tasks:
 
1723
 
 
1724
    \list
 
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.
 
1734
    \endlist
 
1735
 
 
1736
    Here is a rough outline of how a QGLWidget subclass might look:
 
1737
 
 
1738
    \code
 
1739
    class MyGLDrawer : public QGLWidget
 
1740
    {
 
1741
        Q_OBJECT        // must include this if you use Qt signals/slots
 
1742
 
 
1743
    public:
 
1744
        MyGLDrawer(QWidget *parent)
 
1745
            : QGLWidget(parent) {}
 
1746
 
 
1747
    protected:
 
1748
 
 
1749
        void initializeGL()
 
1750
        {
 
1751
            // Set up the rendering context, define display lists etc.:
 
1752
            ...
 
1753
            glClearColor(0.0, 0.0, 0.0, 0.0);
 
1754
            glEnable(GL_DEPTH_TEST);
 
1755
            ...
 
1756
        }
 
1757
 
 
1758
        void resizeGL(int w, int h)
 
1759
        {
 
1760
            // setup viewport, projection etc.:
 
1761
            glViewport(0, 0, (GLint)w, (GLint)h);
 
1762
            ...
 
1763
            glFrustum(...);
 
1764
            ...
 
1765
        }
 
1766
 
 
1767
        void paintGL()
 
1768
        {
 
1769
            // draw the scene:
 
1770
            ...
 
1771
            glRotatef(...);
 
1772
            glMaterialfv(...);
 
1773
            glBegin(GL_QUADS);
 
1774
            glVertex3f(...);
 
1775
            glVertex3f(...);
 
1776
            ...
 
1777
            glEnd();
 
1778
            ...
 
1779
        }
 
1780
 
 
1781
    };
 
1782
    \endcode
 
1783
 
 
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.
 
1787
 
 
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.
 
1793
 
 
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.
 
1797
 
 
1798
    You can also share OpenGL display lists between QGLWidgets (see
 
1799
    the documentation of the QGLWidget constructors for details).
 
1800
 
 
1801
    \section1 Overlays
 
1802
 
 
1803
    The QGLWidget creates a GL overlay context in addition to the
 
1804
    normal context if overlays are supported by the underlying system.
 
1805
 
 
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:
 
1810
 
 
1811
    \list
 
1812
    \i paintOverlayGL()
 
1813
    \i resizeOverlayGL()
 
1814
    \i initializeOverlayGL()
 
1815
    \endlist
 
1816
 
 
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().
 
1823
 
 
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.
 
1826
*/
 
1827
 
 
1828
/*!
 
1829
    Constructs an OpenGL widget with a \a parent widget.
 
1830
 
 
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.
 
1834
 
 
1835
    The \a parent and widget flag, \a f, arguments are passed
 
1836
    to the QWidget constructor.
 
1837
 
 
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().
 
1843
 
 
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.
 
1847
 
 
1848
    \sa QGLFormat::defaultFormat()
 
1849
*/
 
1850
 
 
1851
QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WFlags f)
 
1852
    : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
 
1853
{
 
1854
    Q_D(QGLWidget);
 
1855
    setAttribute(Qt::WA_PaintOnScreen);
 
1856
    setAttribute(Qt::WA_NoSystemBackground);
 
1857
    d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget);
 
1858
}
 
1859
 
 
1860
 
 
1861
/*!
 
1862
    Constructs an OpenGL widget with parent \a parent.
 
1863
 
 
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.
 
1869
 
 
1870
    The widget will be \link isValid() invalid\endlink if the system
 
1871
    has no \link QGLFormat::hasOpenGL() OpenGL support\endlink.
 
1872
 
 
1873
    The \a parent and widget flag, \a f, arguments are passed
 
1874
    to the QWidget constructor.
 
1875
 
 
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().
 
1881
 
 
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.
 
1885
 
 
1886
    \sa QGLFormat::defaultFormat(), isValid()
 
1887
*/
 
1888
 
 
1889
QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget* shareWidget,
 
1890
                     Qt::WFlags f)
 
1891
    : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
 
1892
{
 
1893
    Q_D(QGLWidget);
 
1894
    setAttribute(Qt::WA_PaintOnScreen);
 
1895
    setAttribute(Qt::WA_NoSystemBackground);
 
1896
    d->init(new QGLContext(format, this), shareWidget);
 
1897
}
 
1898
 
 
1899
/*!
 
1900
    Constructs an OpenGL widget with parent \a parent.
 
1901
 
 
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.
 
1905
 
 
1906
    The widget will be \link isValid() invalid\endlink if the system
 
1907
    has no \link QGLFormat::hasOpenGL() OpenGL support\endlink.
 
1908
 
 
1909
    The \a parent and widget flag, \a f, arguments are passed
 
1910
    to the QWidget constructor.
 
1911
 
 
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().
 
1917
 
 
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.
 
1921
 
 
1922
    \sa QGLFormat::defaultFormat(), isValid()
 
1923
*/
 
1924
QGLWidget::QGLWidget(QGLContext *context, QWidget *parent, const QGLWidget *shareWidget,
 
1925
                     Qt::WFlags f)
 
1926
    : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
 
1927
{
 
1928
    Q_D(QGLWidget);
 
1929
    setAttribute(Qt::WA_PaintOnScreen);
 
1930
    setAttribute(Qt::WA_NoSystemBackground);
 
1931
    d->init(context, shareWidget);
 
1932
}
 
1933
 
 
1934
/*!
 
1935
    Destroys the widget.
 
1936
*/
 
1937
 
 
1938
QGLWidget::~QGLWidget()
 
1939
{
 
1940
    Q_D(QGLWidget);
 
1941
#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
 
1942
    bool doRelease = (glcx && glcx->windowCreated());
 
1943
#endif
 
1944
    delete d->glcx;
 
1945
#if defined(Q_WGL)
 
1946
    delete d->olcx;
 
1947
#endif
 
1948
#ifdef Q_WS_MAC
 
1949
    delete d->watcher;
 
1950
    d->watcher = 0;
 
1951
#endif
 
1952
#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
 
1953
    if (doRelease)
 
1954
        glXReleaseBuffersMESA(x11Display(), winId());
 
1955
#endif
 
1956
    d->cleanupColormaps();
 
1957
}
 
1958
 
 
1959
/*!
 
1960
    \fn QGLFormat QGLWidget::format() const
 
1961
 
 
1962
    Returns the format of the contained GL rendering context.
 
1963
*/
 
1964
 
 
1965
/*!
 
1966
    \fn bool QGLWidget::doubleBuffer() const
 
1967
 
 
1968
    Returns true if the contained GL rendering context has double
 
1969
    buffering; otherwise returns false.
 
1970
 
 
1971
    \sa QGLFormat::doubleBuffer()
 
1972
*/
 
1973
 
 
1974
/*!
 
1975
    \fn void QGLWidget::setAutoBufferSwap(bool on)
 
1976
 
 
1977
    If \a on is true automatic GL buffer swapping is switched on;
 
1978
    otherwise it is switched off.
 
1979
 
 
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.
 
1983
 
 
1984
    The buffer auto-swapping is on by default.
 
1985
 
 
1986
    \sa autoBufferSwap(), doubleBuffer(), swapBuffers()
 
1987
*/
 
1988
 
 
1989
/*!
 
1990
    \fn bool QGLWidget::autoBufferSwap() const
 
1991
 
 
1992
    Returns true if the widget is doing automatic GL buffer swapping;
 
1993
    otherwise returns false.
 
1994
 
 
1995
    \sa setAutoBufferSwap()
 
1996
*/
 
1997
 
 
1998
/*!
 
1999
    \fn bool QGLWidget::isValid() const
 
2000
 
 
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.
 
2004
*/
 
2005
 
 
2006
bool QGLWidget::isValid() const
 
2007
{
 
2008
    Q_D(const QGLWidget);
 
2009
    return d->glcx->isValid();
 
2010
}
 
2011
 
 
2012
/*!
 
2013
    \fn bool QGLWidget::isSharing() const
 
2014
 
 
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
 
2018
    formats.
 
2019
 
 
2020
    \sa format()
 
2021
*/
 
2022
 
 
2023
bool QGLWidget::isSharing() const
 
2024
{
 
2025
    Q_D(const QGLWidget);
 
2026
    return d->glcx->isSharing();
 
2027
}
 
2028
 
 
2029
/*!
 
2030
    \fn void QGLWidget::makeCurrent()
 
2031
 
 
2032
    Makes this widget the current widget for OpenGL operations, i.e.
 
2033
    makes the widget's rendering context the current OpenGL rendering
 
2034
    context.
 
2035
*/
 
2036
 
 
2037
void QGLWidget::makeCurrent()
 
2038
{
 
2039
    Q_D(QGLWidget);
 
2040
    d->glcx->makeCurrent();
 
2041
}
 
2042
 
 
2043
/*!
 
2044
    \fn void QGLWidget::doneCurrent()
 
2045
 
 
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.
 
2049
*/
 
2050
 
 
2051
void QGLWidget::doneCurrent()
 
2052
{
 
2053
    Q_D(QGLWidget);
 
2054
    d->glcx->doneCurrent();
 
2055
}
 
2056
 
 
2057
/*!
 
2058
    \fn void QGLWidget::swapBuffers()
 
2059
 
 
2060
    Swaps the screen contents with an off-screen buffer. This only
 
2061
    works if the widget's format specifies double buffer mode.
 
2062
 
 
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.
 
2066
 
 
2067
    \sa doubleBuffer(), setAutoBufferSwap(), QGLFormat::setDoubleBuffer()
 
2068
*/
 
2069
 
 
2070
void QGLWidget::swapBuffers()
 
2071
{
 
2072
    Q_D(QGLWidget);
 
2073
    d->glcx->swapBuffers();
 
2074
}
 
2075
 
 
2076
 
 
2077
/*!
 
2078
    \fn const QGLContext* QGLWidget::overlayContext() const
 
2079
 
 
2080
    Returns the overlay context of this widget, or 0 if this widget
 
2081
    has no overlay.
 
2082
 
 
2083
    \sa context()
 
2084
*/
 
2085
 
 
2086
 
 
2087
 
 
2088
/*!
 
2089
    \fn void QGLWidget::makeOverlayCurrent()
 
2090
 
 
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().
 
2094
 
 
2095
    Does nothing if this widget has no overlay.
 
2096
 
 
2097
    \sa makeCurrent()
 
2098
*/
 
2099
 
 
2100
 
 
2101
/*!
 
2102
  \obsolete
 
2103
 
 
2104
  Sets a new format for this widget.
 
2105
 
 
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.
 
2110
 
 
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().
 
2114
 
 
2115
  This method will try to keep any existing display list sharing with
 
2116
  other QGLWidgets, but it may fail. Use isSharing() to test.
 
2117
 
 
2118
  \sa format(), isSharing(), isValid()
 
2119
*/
 
2120
 
 
2121
void QGLWidget::setFormat(const QGLFormat &format)
 
2122
{
 
2123
    setContext(new QGLContext(format,this));
 
2124
}
 
2125
 
 
2126
 
 
2127
 
 
2128
 
 
2129
/*!
 
2130
    \fn const QGLContext *QGLWidget::context() const
 
2131
 
 
2132
    Returns the context of this widget.
 
2133
 
 
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.
 
2137
*/
 
2138
 
 
2139
/*
 
2140
  \obsolete
 
2141
 
 
2142
  \fn void QGLWidget::setContext(QGLContext *context,
 
2143
                                  const QGLContext* shareContext,
 
2144
                                  bool deleteOldContext)
 
2145
 
 
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.
 
2149
 
 
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().
 
2153
 
 
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
 
2158
  test.
 
2159
 
 
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
 
2163
  that context later.
 
2164
 
 
2165
  \sa context(), isSharing()
 
2166
*/
 
2167
 
 
2168
 
 
2169
 
 
2170
/*!
 
2171
    \fn void QGLWidget::updateGL()
 
2172
 
 
2173
    Updates the widget by calling glDraw().
 
2174
*/
 
2175
 
 
2176
void QGLWidget::updateGL()
 
2177
{
 
2178
    glDraw();
 
2179
}
 
2180
 
 
2181
 
 
2182
/*!
 
2183
    \fn void QGLWidget::updateOverlayGL()
 
2184
 
 
2185
    Updates the widget's overlay (if any). Will cause the virtual
 
2186
    function paintOverlayGL() to be executed.
 
2187
 
 
2188
    The widget's rendering context will become the current context and
 
2189
    initializeGL() will be called if it hasn't already been called.
 
2190
*/
 
2191
 
 
2192
 
 
2193
/*!
 
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.
 
2197
 
 
2198
    This function should set up any required OpenGL context rendering
 
2199
    flags, defining display lists, etc.
 
2200
 
 
2201
    There is no need to call makeCurrent() because this has already
 
2202
    been done when this function is called.
 
2203
*/
 
2204
 
 
2205
void QGLWidget::initializeGL()
 
2206
{
 
2207
}
 
2208
 
 
2209
 
 
2210
/*!
 
2211
    This virtual function is called whenever the widget needs to be
 
2212
    painted. Reimplement it in a subclass.
 
2213
 
 
2214
    There is no need to call makeCurrent() because this has already
 
2215
    been done when this function is called.
 
2216
*/
 
2217
 
 
2218
void QGLWidget::paintGL()
 
2219
{
 
2220
}
 
2221
 
 
2222
 
 
2223
/*!
 
2224
    \fn void QGLWidget::resizeGL(int width , int height)
 
2225
 
 
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.
 
2229
 
 
2230
    There is no need to call makeCurrent() because this has already
 
2231
    been done when this function is called.
 
2232
*/
 
2233
 
 
2234
void QGLWidget::resizeGL(int, int)
 
2235
{
 
2236
}
 
2237
 
 
2238
 
 
2239
 
 
2240
/*!
 
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.
 
2246
 
 
2247
    This function should set up any required OpenGL context rendering
 
2248
    flags, defining display lists, etc. for the overlay context.
 
2249
 
 
2250
    There is no need to call makeOverlayCurrent() because this has
 
2251
    already been done when this function is called.
 
2252
*/
 
2253
 
 
2254
void QGLWidget::initializeOverlayGL()
 
2255
{
 
2256
}
 
2257
 
 
2258
 
 
2259
/*!
 
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.
 
2265
 
 
2266
    There is no need to call makeOverlayCurrent() because this has
 
2267
    already been done when this function is called.
 
2268
*/
 
2269
 
 
2270
void QGLWidget::paintOverlayGL()
 
2271
{
 
2272
}
 
2273
 
 
2274
 
 
2275
/*!
 
2276
    \fn void QGLWidget::resizeOverlayGL(int width , int height)
 
2277
 
 
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.
 
2283
 
 
2284
    There is no need to call makeOverlayCurrent() because this has
 
2285
    already been done when this function is called.
 
2286
*/
 
2287
 
 
2288
void QGLWidget::resizeOverlayGL(int, int)
 
2289
{
 
2290
}
 
2291
 
 
2292
 
 
2293
 
 
2294
 
 
2295
/*!
 
2296
    \fn void QGLWidget::paintEvent(QPaintEvent *event)
 
2297
 
 
2298
    Handles paint events passed in the \a event parameter. Will cause
 
2299
    the virtual paintGL() function to be called.
 
2300
 
 
2301
    The widget's rendering context will become the current context and
 
2302
    initializeGL() will be called if it hasn't already been called.
 
2303
*/
 
2304
 
 
2305
void QGLWidget::paintEvent(QPaintEvent *)
 
2306
{
 
2307
    glDraw();
 
2308
    updateOverlayGL();
 
2309
}
 
2310
 
 
2311
 
 
2312
/*!
 
2313
    \fn void QGLWidget::resizeEvent(QResizeEvent *event)
 
2314
 
 
2315
    Handles resize events that are passed in the \a event parameter.
 
2316
    Calls the virtual function resizeGL().
 
2317
*/
 
2318
 
 
2319
 
 
2320
/*!
 
2321
    \fn void QGLWidget::setMouseTracking(bool enable)
 
2322
 
 
2323
    If \a enable is true then mouse tracking is enabled; otherwise it
 
2324
    is disabled.
 
2325
*/
 
2326
 
 
2327
 
 
2328
/*!
 
2329
    Renders the current scene on a pixmap and returns the pixmap.
 
2330
 
 
2331
    You can use this method on both visible and invisible QGLWidgets.
 
2332
 
 
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.
 
2337
 
 
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.
 
2341
 
 
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.
 
2345
 
 
2346
    Overlays are not rendered onto the pixmap.
 
2347
 
 
2348
    If the GL rendering context and the desktop have different bit
 
2349
    depths, the result will most likely look surprising.
 
2350
 
 
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.
 
2355
*/
 
2356
 
 
2357
QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
 
2358
{
 
2359
    Q_D(QGLWidget);
 
2360
    QSize sz = size();
 
2361
    if ((w > 0) && (h > 0))
 
2362
        sz = QSize(w, h);
 
2363
 
 
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.
 
2368
 
 
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();
 
2372
    QPixmap pm(sz);
 
2373
    qt_x11_preferred_pixmap_depth = old_depth;
 
2374
    Visual *gl_visual = (Visual *) d->glcx->d_func()->vi;
 
2375
    Visual *gl_pixmap_visual = 0;
 
2376
 
 
2377
    if (gl_visual != QX11Info::appVisual()) {
 
2378
        int nvis = 0;
 
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,
 
2385
                                         &visInfo, &nvis);
 
2386
        gl_pixmap_visual = vi->visual;
 
2387
        if (vi) {
 
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);
 
2392
            XFree(vi);
 
2393
        }
 
2394
    }
 
2395
 
 
2396
#else
 
2397
    QPixmap pm(sz);
 
2398
#endif
 
2399
 
 
2400
    d->glcx->doneCurrent();
 
2401
 
 
2402
    bool success = true;
 
2403
 
 
2404
    if (useContext && isValid() && d->renderCxPm(&pm))
 
2405
        return pm;
 
2406
 
 
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
 
2410
 
 
2411
    QGLContext* ocx = d->glcx;
 
2412
    bool wasCurrent = (QGLContext::currentContext() == ocx);
 
2413
    ocx->doneCurrent();
 
2414
    d->glcx = new QGLContext(fmt, &pm);
 
2415
    d->glcx->create();
 
2416
 
 
2417
    if (d->glcx->isValid())
 
2418
        updateGL();
 
2419
    else
 
2420
        success = false;
 
2421
 
 
2422
#if defined(Q_WS_WIN)
 
2423
    pm = QPixmap::fromWinHBITMAP(d->glcx->d_func()->hbitmap);
 
2424
#endif
 
2425
 
 
2426
    delete d->glcx;
 
2427
    d->glcx = ocx;
 
2428
 
 
2429
    if (wasCurrent)
 
2430
        ocx->makeCurrent();
 
2431
 
 
2432
    if (success) {
 
2433
#if defined(Q_WS_X11)
 
2434
        if (gl_pixmap_visual) {
 
2435
            QImage image = pm.toImage();
 
2436
            QPixmap p = QPixmap::fromImage(image);
 
2437
            return p;
 
2438
        }
 
2439
#endif
 
2440
        return pm;
 
2441
    } else
 
2442
        return QPixmap();
 
2443
}
 
2444
 
 
2445
 
 
2446
 
 
2447
/*!
 
2448
    Returns an image of the frame buffer. If \a withAlpha is true the
 
2449
    alpha channel is included.
 
2450
 
 
2451
    Depending on your hardware, you can explicitly select which color
 
2452
    buffer to grab with a glReadBuffer() call before calling this
 
2453
    function.
 
2454
*/
 
2455
QImage QGLWidget::grabFrameBuffer(bool withAlpha)
 
2456
{
 
2457
    makeCurrent();
 
2458
    QImage res;
 
2459
    int w = width();
 
2460
    int h = height();
 
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()) {
 
2469
                while (p < end) {
 
2470
                    uint a = *p << 24;
 
2471
                    *p = (*p >> 8) | a;
 
2472
                    p++;
 
2473
                }
 
2474
            } else {
 
2475
                while (p < end) {
 
2476
                    *p = 0xFF000000 | (*p>>8);
 
2477
                    ++p;
 
2478
                }
 
2479
            }
 
2480
        } else {
 
2481
            // OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB
 
2482
            res = res.rgbSwapped();
 
2483
        }
 
2484
    } else {
 
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();
 
2489
        if (pal.size()) {
 
2490
            res.setNumColors(pal.size());
 
2491
            for (int i = 0; i < pal.size(); i++)
 
2492
                res.setColor(i, pal.at(i).rgb());
 
2493
        }
 
2494
#endif
 
2495
    }
 
2496
 
 
2497
    return res.mirrored();
 
2498
}
 
2499
 
 
2500
 
 
2501
 
 
2502
/*!
 
2503
    Initializes OpenGL for this widget's context. Calls the virtual
 
2504
    function initializeGL().
 
2505
*/
 
2506
 
 
2507
void QGLWidget::glInit()
 
2508
{
 
2509
    Q_D(QGLWidget);
 
2510
    if (!isValid())
 
2511
        return;
 
2512
    makeCurrent();
 
2513
    initializeGL();
 
2514
    d->glcx->setInitialized(true);
 
2515
}
 
2516
 
 
2517
 
 
2518
/*!
 
2519
    Executes the virtual function paintGL().
 
2520
 
 
2521
    The widget's rendering context will become the current context and
 
2522
    initializeGL() will be called if it hasn't already been called.
 
2523
*/
 
2524
 
 
2525
void QGLWidget::glDraw()
 
2526
{
 
2527
    Q_D(QGLWidget);
 
2528
    if (!isValid())
 
2529
        return;
 
2530
    makeCurrent();
 
2531
    if (d->glcx->deviceIsPixmap())
 
2532
        glDrawBuffer(GL_FRONT);
 
2533
    if (!d->glcx->initialized()) {
 
2534
        glInit();
 
2535
        resizeGL(d->glcx->device()->width(), d->glcx->device()->height()); // New context needs this "resize"
 
2536
    }
 
2537
    paintGL();
 
2538
    if (doubleBuffer()) {
 
2539
        if (d->autoSwap)
 
2540
            swapBuffers();
 
2541
    } else {
 
2542
        glFlush();
 
2543
    }
 
2544
}
 
2545
 
 
2546
 
 
2547
/*!
 
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.
 
2551
 
 
2552
    \sa qglClearColor(), QGLContext::currentContext(), QColor
 
2553
*/
 
2554
 
 
2555
void QGLWidget::qglColor(const QColor& c) const
 
2556
{
 
2557
    Q_D(const QGLWidget);
 
2558
    const QGLContext* ctx = QGLContext::currentContext();
 
2559
    if (ctx) {
 
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());
 
2564
            if (i < 0)
 
2565
                i = d->cmap.findNearest(c.rgb());
 
2566
            glIndexi(i);
 
2567
        } else
 
2568
            glIndexi(ctx->colorIndex(c));
 
2569
    }
 
2570
}
 
2571
 
 
2572
/*!
 
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.
 
2576
 
 
2577
    \sa qglColor(), QGLContext::currentContext(), QColor
 
2578
*/
 
2579
 
 
2580
void QGLWidget::qglClearColor(const QColor& c) const
 
2581
{
 
2582
    Q_D(const QGLWidget);
 
2583
    const QGLContext* ctx = QGLContext::currentContext();
 
2584
    if (ctx) {
 
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());
 
2590
            if (i < 0)
 
2591
                i = d->cmap.findNearest(c.rgb());
 
2592
            glClearIndex(i);
 
2593
        } else
 
2594
            glClearIndex(ctx->colorIndex(c));
 
2595
    }
 
2596
}
 
2597
 
 
2598
 
 
2599
/*!
 
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.
 
2604
 
 
2605
    \omit ###
 
2606
 
 
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:
 
2610
 
 
2611
    \quotefromfile opengl/texture/gltexobj.cpp
 
2612
    \skipto tex1
 
2613
    \printline tex1
 
2614
    \printline gllogo.bmp
 
2615
 
 
2616
    We create \e tex1 (and another variable) for OpenGL, and load a real
 
2617
    image into \e buf.
 
2618
 
 
2619
    \skipto convertToGLFormat
 
2620
    \printline convertToGLFormat
 
2621
 
 
2622
    A few lines later, we convert \e buf into OpenGL format and store it
 
2623
    in \e tex1.
 
2624
 
 
2625
    \skipto glTexImage2D
 
2626
    \printline glTexImage2D
 
2627
    \printline tex1.bits
 
2628
 
 
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.
 
2633
 
 
2634
    Another function in the same example uses \e tex1 with OpenGL.
 
2635
 
 
2636
    \endomit
 
2637
*/
 
2638
 
 
2639
QImage QGLWidget::convertToGLFormat(const QImage& img)
 
2640
{
 
2641
    QImage res = img.convertToFormat(QImage::Format_ARGB32);
 
2642
    res = res.mirrored();
 
2643
 
 
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();
 
2649
            while (p < end) {
 
2650
                *p = (*p << 8) | ((*p >> 24) & 0xFF);
 
2651
                p++;
 
2652
            }
 
2653
        }
 
2654
    }
 
2655
    else {
 
2656
        // Qt has ARGB; OpenGL wants ABGR (i.e. RGBA backwards)
 
2657
        res = res.rgbSwapped();
 
2658
    }
 
2659
    return res;
 
2660
}
 
2661
 
 
2662
 
 
2663
/*!
 
2664
    \fn QGLColormap & QGLWidget::colormap() const
 
2665
 
 
2666
    Returns the colormap for this widget.
 
2667
 
 
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.
 
2671
 
 
2672
    If no colormap has been set for this widget, the QColormap
 
2673
    returned will be empty.
 
2674
 
 
2675
    \sa setColormap()
 
2676
*/
 
2677
 
 
2678
/*!
 
2679
    \fn void QGLWidget::setColormap(const QGLColormap & cmap)
 
2680
 
 
2681
    Set the colormap for this widget to \a cmap. Usually it is only
 
2682
    top-level widgets that can have colormaps installed.
 
2683
 
 
2684
    \sa colormap()
 
2685
*/
 
2686
 
 
2687
 
 
2688
/*!
 
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.
 
2693
*/
 
2694
int QGLWidget::fontDisplayListBase(const QFont & fnt, int listBase)
 
2695
{
 
2696
    Q_D(QGLWidget);
 
2697
    int base;
 
2698
 
 
2699
    if (!d->glcx) { // this can't happen unless we run out of mem
 
2700
        return 0;
 
2701
    }
 
2702
 
 
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
 
2710
    QString color_key;
 
2711
    if (fnt.styleStrategy() != QFont::NoAntialias) {
 
2712
        GLfloat color[4];
 
2713
        glGetFloatv(GL_CURRENT_COLOR, color);
 
2714
        color_key.sprintf("%f_%f_%f",color[0], color[1], color[2]);
 
2715
    }
 
2716
    QString key = fnt.key() + color_key + QString::number((int) regenerate);
 
2717
#else
 
2718
    QString key = fnt.key() + QString::number((int) regenerate);
 
2719
#endif
 
2720
    if (!regenerate && (d->displayListCache.find(key) != d->displayListCache.end())) {
 
2721
        base = d->displayListCache[key];
 
2722
    } else {
 
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();
 
2728
            }
 
2729
        }
 
2730
        maxBase += 256;
 
2731
        d->glcx->generateFontDisplayLists(fnt, maxBase);
 
2732
        d->displayListCache[key] = maxBase;
 
2733
        base = maxBase;
 
2734
    }
 
2735
    return base;
 
2736
}
 
2737
 
 
2738
/*!
 
2739
   Renders the string \a str into the GL context of this widget.
 
2740
 
 
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
 
2749
   renderText().
 
2750
 
 
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.
 
2759
*/
 
2760
 
 
2761
void QGLWidget::renderText(int x, int y, const QString & str, const QFont & fnt, int listBase)
 
2762
{
 
2763
    makeCurrent();
 
2764
    glPushAttrib(GL_TRANSFORM_BIT | GL_VIEWPORT_BIT | GL_LIST_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT);
 
2765
    glMatrixMode(GL_PROJECTION);
 
2766
    glPushMatrix();
 
2767
    glLoadIdentity();
 
2768
    glOrtho(0, width(), height(), 0, -1, 1);
 
2769
    glMatrixMode(GL_MODELVIEW);
 
2770
    glPushMatrix();
 
2771
    glLoadIdentity();
 
2772
 
 
2773
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
2774
    glEnable(GL_BLEND);
 
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());
 
2779
 
 
2780
    glPopMatrix();
 
2781
    glMatrixMode(GL_PROJECTION);
 
2782
    glPopMatrix();
 
2783
    glPopAttrib();
 
2784
}
 
2785
 
 
2786
/*! \overload
 
2787
 
 
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.
 
2792
*/
 
2793
void QGLWidget::renderText(double x, double y, double z, const QString & str, const QFont & fnt,
 
2794
                            int listBase)
 
2795
{
 
2796
    makeCurrent();
 
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);
 
2800
    glEnable(GL_BLEND);
 
2801
    glListBase(fontDisplayListBase(fnt, listBase));
 
2802
    glCallLists(str.length(), GL_UNSIGNED_BYTE, str.toLocal8Bit());
 
2803
    glPopAttrib();
 
2804
}
 
2805
 
 
2806
QGLFormat QGLWidget::format() const
 
2807
{
 
2808
    Q_D(const QGLWidget);
 
2809
    return d->glcx->format();
 
2810
}
 
2811
 
 
2812
const QGLContext *QGLWidget::context() const
 
2813
{
 
2814
    Q_D(const QGLWidget);
 
2815
    return d->glcx;
 
2816
}
 
2817
 
 
2818
bool QGLWidget::doubleBuffer() const
 
2819
{
 
2820
    Q_D(const QGLWidget);
 
2821
    return d->glcx->format().doubleBuffer();
 
2822
}
 
2823
 
 
2824
void QGLWidget::setAutoBufferSwap(bool on)
 
2825
{
 
2826
    Q_D(QGLWidget);
 
2827
    d->autoSwap = on;
 
2828
}
 
2829
 
 
2830
bool QGLWidget::autoBufferSwap() const
 
2831
{
 
2832
    Q_D(const QGLWidget);
 
2833
    return d->autoSwap;
 
2834
}
 
2835
 
 
2836
/*!
 
2837
    Calls QGLContext:::bindTexture(\a image, \a target, \a format) on the currently
 
2838
    set context.
 
2839
 
 
2840
    \sa deleteTexture()
 
2841
*/
 
2842
GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format)
 
2843
{
 
2844
    Q_D(QGLWidget);
 
2845
    return d->glcx->bindTexture(image, target, format);
 
2846
}
 
2847
 
 
2848
/*!
 
2849
    Calls QGLContext:::bindTexture(\a pixmap, \a target, \a format) on the currently
 
2850
    set context.
 
2851
 
 
2852
    \sa deleteTexture()
 
2853
*/
 
2854
GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format)
 
2855
{
 
2856
    Q_D(QGLWidget);
 
2857
    return d->glcx->bindTexture(pixmap, target, format);
 
2858
}
 
2859
 
 
2860
/*! \overload
 
2861
 
 
2862
    Calls QGLContext::bindTexture(\a fileName) on the currently set context.
 
2863
 
 
2864
    \sa deleteTexture()
 
2865
*/
 
2866
GLuint QGLWidget::bindTexture(const QString &fileName)
 
2867
{
 
2868
    Q_D(QGLWidget);
 
2869
    return d->glcx->bindTexture(fileName);
 
2870
}
 
2871
 
 
2872
/*!
 
2873
    Calls QGLContext::deleteTexture(\a id) on the currently set
 
2874
    context.
 
2875
 
 
2876
    \sa bindTexture()
 
2877
*/
 
2878
void QGLWidget::deleteTexture(GLuint id)
 
2879
{
 
2880
    Q_D(QGLWidget);
 
2881
    d->glcx->deleteTexture(id);
 
2882
}
 
2883
 
 
2884
Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_widget_paintengine)
 
2885
/*!
 
2886
    \internal
 
2887
 
 
2888
    Returns the GL widget's paint engine. This is normally a
 
2889
    QOpenGLPaintEngine.
 
2890
*/
 
2891
QPaintEngine *QGLWidget::paintEngine() const
 
2892
{
 
2893
    return qt_widget_paintengine();
 
2894
}
 
2895
 
 
2896
#ifdef QT3_SUPPORT
 
2897
/*!
 
2898
    \overload
 
2899
    \obsolete
 
2900
 */
 
2901
QGLWidget::QGLWidget(QWidget *parent, const char *name,
 
2902
                      const QGLWidget* shareWidget, Qt::WFlags f)
 
2903
    : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
 
2904
{
 
2905
    Q_D(QGLWidget);
 
2906
    if (name)
 
2907
        setObjectName(name);
 
2908
    setAttribute(Qt::WA_PaintOnScreen);
 
2909
    setAttribute(Qt::WA_NoSystemBackground);
 
2910
    d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget);
 
2911
}
 
2912
 
 
2913
/*!
 
2914
    \overload
 
2915
    \obsolete
 
2916
 */
 
2917
QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent,
 
2918
                      const char *name, const QGLWidget* shareWidget,
 
2919
                      Qt::WFlags f)
 
2920
    : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC)
 
2921
{
 
2922
    Q_D(QGLWidget);
 
2923
    if (name)
 
2924
        setObjectName(name);
 
2925
    setAttribute(Qt::WA_PaintOnScreen);
 
2926
    setAttribute(Qt::WA_NoSystemBackground);
 
2927
    d->init(new QGLContext(format, this), shareWidget);
 
2928
}
 
2929
 
 
2930
/*!
 
2931
    \overload
 
2932
    \obsolete
 
2933
 */
 
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)
 
2937
{
 
2938
    Q_D(QGLWidget);
 
2939
    if (name)
 
2940
        setObjectName(name);
 
2941
    setAttribute(Qt::WA_PaintOnScreen);
 
2942
    setAttribute(Qt::WA_NoSystemBackground);
 
2943
    d->init(context, shareWidget);
 
2944
}
 
2945
 
 
2946
#endif // QT3_SUPPORT
 
2947
 
 
2948
void QGLExtensions::init_extensions()
 
2949
{
 
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;
 
2959
 
 
2960
    QGLContext cx(QGLFormat::defaultFormat());
 
2961
    if (glExtensions & TextureCompression) {
 
2962
        qt_glCompressedTexImage2DARB = (pfn_glCompressedTexImage2DARB) cx.getProcAddress("glCompressedTexImage2DARB");
 
2963
    }
 
2964
}