source: trunk/doc/src/examples/ahigl.qdoc@ 357

Last change on this file since 357 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 28.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information (qt-info@nokia.com)
5**
6** This file is part of the documentation of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at qt-sales@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \example qws/ahigl
44 \title OpenGL for Embedded Systems Example
45
46 \section1 Introduction
47
48 This example demonstrates how you can use OpenGL for Embedded
49 Systems (ES) in your own screen driver and \l{add your graphics
50 driver to Qt for Embedded Linux}. In \l{Qt for Embedded Linux},
51 painting is done in software, normally performed in two steps:
52 First, each client renders its windows onto its window surface in
53 memory using a paint engine. Then the server uses the screen
54 driver to compose the window surface images and copy the
55 composition to the screen. (See the \l{Qt for Embedded Linux
56 Architecture} documentation for details.)
57
58 This example is not for the novice. It assumes the reader is
59 familiar with both OpenGL and the screen driver framework
60 demonstrated in the \l {Accelerated Graphics Driver Example}.
61
62 An OpenGL screen driver for Qt for Embedded Linux can use OpenGL ES
63 in three ways. First, the \l{QWSServer}{Qt for Embedded Linux server}
64 can use the driver to compose multiple window images and then show the
65 composition on the screen. Second, clients can use the driver to
66 accelerate OpenGL painting operations using the QOpenGLPaintEngine
67 class. Finally, clients can use the driver to do OpenGL operations
68 with instances of the QGLWidget class. This example implements all
69 three cases.
70
71 The example uses an implementation of OpenGL ES from
72 \l {http://ati.amd.com}{ATI} for the
73 \l {http://ati.amd.com/products/imageon238x/}{Imageon 2380}. The
74 OpenGL include files gl.h and egl.h must be installed to compile
75 the example, and the OpenGL and EGL libraries must be installed
76 for linking. If your target device is different, you must install
77 the include files and libraries for that device, and you also
78 might need to modify the example source code, if any API signatures
79 in your EGL library differ from the ones used here.
80
81 After compiling and linking the example source, install the
82 screen driver plugin with the command \c {make install}. To
83 start an application that uses the plugin, you can either set the
84 environment variable \l QWS_DISPLAY and then start the
85 application, or just start the application with the \c -display
86 switch, as follows:
87
88 \snippet doc/src/snippets/code/doc_src_examples_ahigl.qdoc 0
89
90 The example driver also implements an animated transition effect
91 for use when showing new windows or reshowing windows that have
92 been minimized. To enable this transition effect, run the
93 application with \c {-display ahigl:effects}.
94
95 \section1 The Class Definitions
96
97 The example comprises three main classes plus some helper classes.
98 The three main classes are the plugin (QAhiGLScreenPlugin), which
99 is defined in qscreenahiglplugin.cpp, the screen driver
100 (QAhiGLScreen), which is defined in qscreenahigl_qws.h, and the
101 window surface (QAhiGLWindowSurface), which is defined in
102 qwindowsurface_ahigl_p.h. The "Ahi" prefix in these class names
103 stands for \e {ATI Handheld Interface}. The example was written
104 for the ATI Imageon 2380, but it can also be used as a template
105 for other ATI handheld devices.
106
107 \section2 The Plugin Class Definition
108
109 The screen driver plugin is class QAhiGLScreenPlugin.
110
111 \snippet examples/qws/ahigl/qscreenahiglplugin.cpp 0
112
113 QAhiGLScreenPlugin is derived from class QScreenDriverPlugin,
114 which in turn is derived from QObject.
115
116 \section2 The Screen Driver Class Definitions
117
118 The screen driver classes are the public class QAhiGLScreen and
119 its private implementation class QAhiGLScreenPrivate. QAhiGLScreen
120 is derived from QGLScreen, which is derived from QScreen. If your
121 screen driver will only do window compositions and display them,
122 then you can derive your screen driver class directly from
123 QScreen. But if your screen driver will do accelerated graphics
124 rendering operations with the QOpenGLPaintEngine, or if it will
125 handle instances of class QGLWidget, then you must derive your
126 screen driver class from QGLScreen.
127
128 \snippet examples/qws/ahigl/qscreenahigl_qws.h 0
129
130 All functions in the public API of class QAhiGLScreen are virtual
131 functions declared in its base classes. hasOpenGL() is declared in
132 QGLScreen. It simply returns true indicating our example screen
133 driver does support OpenGL operations. The other functions in the
134 public API are declared in QScreen. They are called by the
135 \l{QWSServer}{Qt for Embedded Linux server} at the appropriate times.
136
137 Note that class QScreen is a documented class but class QGLScreen
138 is not. This is because the design of class QGLScreen is not yet
139 final.
140
141 The only data member in class QAhiGLScreen is a standard d_ptr,
142 which points to an instance of the driver's private implementation
143 class QAhiGLScreenPrivate. The driver's internal state is stored
144 in the private class. Using the so-called d-pointer pattern allows
145 you to make changes to the driver's internal design without
146 breaking binary compatibility.
147
148 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 0
149
150 Class QAhiGLScreenPrivate is derived from QObject so that it can
151 use the Qt signal/slot mechanism. QAhiGLScreen is not a QObject,
152 so it can't use the signal/slot mechanism. Signals meant for our
153 screen driver are received by slots in the private implementation
154 class, in this case, windowEvent() and redrawScreen().
155
156 \section2 The Window Surface Class Definitions
157
158 The window surface classes are QAhiGLWindowSurface and its private
159 implementation class QAhiGLWindowSurfacePrivate. We create class
160 QAhiGLWindowSurface so the screen driver can use the OpenGL paint
161 engine and the OpenGL widget, classes QOpenGLPaintEngine and
162 QGLWidget. QAhiGLWindowSurface is derived from the more general
163 OpenGL window surface class, QWSGLWindowSurface, which is derived
164 from QWSWindowSurface.
165
166 \snippet examples/qws/ahigl/qwindowsurface_ahigl_p.h 0
167
168 In addition to implementing the standard functionality required by
169 any new subclass of QWSWindowSurface, QAhiGLWindowSurface also
170 contains the textureId() function used by QAhiGLScreen.
171
172 The same d-pointer pattern is used in this window surface class.
173 The private implementation class is QAhiGLWindowSurfacePrivate. It
174 allows making changes to the state variables of the window surface
175 without breaking binary compatibility.
176
177 \snippet examples/qws/ahigl/qwindowsurface_ahigl.cpp 0
178
179 In this case, our private implementation class has no member
180 functions except for its constructor. It contains only public data
181 members which hold state information for the window surface.
182
183 \section2 The Helper Classes
184
185 The example screen driver maintains a static \l {QMap} {map} of
186 all the \l {QWSWindow} {windows} it is showing on the screen.
187 Each window is mapped to an instance of struct WindowInfo.
188
189 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 2
190
191 As each new window is created, an instance of struct WindowInfo is
192 allocated and inserted into the window map. WindowInfo uses a
193 GLuint to identify the OpenGL texture it creates for the window.
194 Note that the example driver, in addition to drawing windows using
195 OpenGL, also supports drawing windows in the normal way without
196 OpenGL, but it uses an OpenGL texture for the rendering operations
197 in either case. Top-level windows that are drawn without OpenGL
198 are first rendered in the normal way into a shared memory segment,
199 which is then converted to a OpenGL texture and drawn to the
200 screen.
201
202 To animate the window transition effect, WindowInfo uses an
203 instance of the helper class ShowAnimation. The animation is
204 created by the windowEvent() slot in QAhiGLScreenPrivate, whenever
205 a \l {QWSServer::WindowEvent} {Show} window event is emitted by
206 the \l {QWSServer} {window server}. The server emits this signal
207 when a window is shown the first time and again later, when the
208 window is reshown after having been minimized.
209
210 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 1
211
212 Class ShowAnimation is derived from the QTimeLine class, which is
213 used for controlling animations. QTimeLine is a QObject, so
214 ShowAnimation can use the Qt signal/slot mechanism. We will see
215 how the timeline's \l {QTimeLine::valueChanged()} {valueChanged()}
216 and \l {QTimeLine::finished()} {finished()} signals are used to
217 control the animation and then destroy the instance of
218 ShowAnimation, when the animation ends. The ShowAnimation
219 constructor needs the pointer to the screen driver's private
220 implementation class so it can set up these signal/slot
221 connections.
222
223 \section1 The Class Implementations
224
225 \section2 The Plugin Class Implementation
226
227 QAhiGLScreenPlugin is a straightforward derivation of
228 QScreenDriverPlugin. It reimplements \l{QScreenDriverPlugin::}{keys()}
229 and \l{QScreenDriverPlugin::}{create()}. They are
230 called as needed by the \l{QWSServer}{Qt for Embedded Linux server.}
231 Recall that the server detects that the ahigl screen driver has
232 been requested, either by including "ahigl" in the value for the
233 environment variable QWS_DISPLAY, or by running your application
234 with a command line like the following.
235
236 \snippet doc/src/snippets/code/doc_src_examples_ahigl.qdoc 1
237
238 The server calls \l {QScreenDriverPlugin::} {keys()}, which
239 returns a \l {QStringList} containing the singleton "ahigl"
240 matching the requested screen driver and telling the server that
241 it can use our example screen driver. The server then calls \l
242 {QScreenDriverPlugin::} {create()}, which creates the instance of
243 QAhiGLScreen.
244
245 \snippet examples/qws/ahigl/qscreenahiglplugin.cpp 1
246
247 In the code snippet above, the macro Q_EXPORT_PLUGIN2 is used to export
248 the plugin class, QAhiGLScreen, for the qahiglscreen plugin.
249 Further information regarding plugins and how to create them
250 can be found at \l{How to Create Qt Plugins}.
251
252 \section2 The Screen Driver Class Implementations
253
254 The plugin creates the singleton instance of QAhiGLScreen. The
255 constructor is passed a \c displayId, which is used in the base
256 class QGLScreen to identify the server that the screen driver is
257 connected to. The constructor also creates its instance of
258 QAhiGLScreenPrivate, which instantiates a QTimer. The timeout()
259 signal of this timer is connected to the redrawScreen() slot so
260 the timer can be used to limit the frequency of actual drawing
261 operations in the hardware.
262
263 The public API of class QAhiGLScreen consists of implementations
264 of virtual functions declared in its base classes. The function
265 hasOpenGL() is declared in base class QGLScreen. The others are
266 declared in base class QScreen.
267
268 The \l {QScreen::}{connect()} function is the first one called by
269 the server after the screen driver is constructed. It initializes
270 the QScreen data members to hardcoded values that describe the ATI
271 screen. A better implementation would query the hardware for the
272 corresponding values in its current state and use those. It asks
273 whether the screen driver was started with the \c effects option
274 and sets the \c doEffects flag accordingly.
275
276 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 7
277
278 The \l {QScreen::}{initDevice()} function is called by the server
279 after \l {QScreen::}{connect()}. It uses EGL library functions to
280 initialize the ATI hardware. Note that some data structures used
281 in this example are specific to the EGL implementation used, e.g.,
282 the DummyScreen structure.
283
284 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 8
285
286 Note the signal/slot connection at the bottom of initDevice(). We
287 connect the server's QWSServer::windowEvent() signal to the
288 windowEvent() slot in the screen driver's private implementation
289 class. The windowEvent() slot handles three window events,
290 QWSServer::Create, QWSServer::Destroy, and QWSServer::Show.
291
292 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 5
293
294 The function manages instances of the helper classes associated
295 with each window. When a QWSServer::Create event occurs, it means
296 a new top-level \l {QWSWindow} {window} has been created. In this
297 case, an instance of helper class WindowInfo is created and
298 inserted into the window map with the pointer to the new \l
299 {QWSWindow} {window} as its key. When a QWSServer::Destroy event
300 occurs, a window is being destroyed, and its mapping is removed
301 from the window map. These two events are straightforward. The
302 tricky bits happen when a QWSServer::Show event occurs. This case
303 occurs when a window is shown for the first time and when it is
304 reshown after having been minimized. If the window transition
305 effect has been enabled, a new instance of the helper class
306 ShowAnimation is created and stored in a QPointer in the window's
307 instance of WindowInfo. The constructor of ShowAnimation
308 automatically \l {QTimeLine::start()} {starts} the animation of
309 the transition effect.
310
311 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 3
312
313 To ensure that a ShowAnimation is not deleted until its animation
314 ends, the \l {QTimeLine::finished()} {finished()} signal is
315 connected to the \l {QObject::deleteLater()} {deleteLater()} slot.
316 When the animation ends, the finished() signal is emitted and the
317 deleteLater() slot deletes the ShowAnimation. The key here is that
318 the pointer to the ShowAnimation is stored in a QPointer in the
319 WindowInfo class. This QPointer will also be notified when the
320 ShowAnimation is deleted, so the QPointer in WindowInfo can null
321 itself out, if and only if it is still pointing to the instance
322 of ShowAnimation being deleted.
323
324 The \l {QTimeLine::valueForTime()} {valueForTime()} function in
325 QTimeLine is reimplemented in ShowAnimation to return time values
326 that represent a curved path for the window transition effect.
327
328 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 4
329
330 valueForTime() is called internally, when the time interval it
331 computed during the previous call has elapsed. If it computes a
332 next time value that is different from the one computed
333 previously, the \l {QTimeLine::valueChanged()} {valueChanged()}
334 signal is emitted. The ShowAnimation constructor shown above
335 connects this signal to the redrawScreen() slot in the screen
336 driver's private implementation class. This is how the animation
337 actually happens.
338
339 The screen driver's implementation of \l {QScreen::}
340 {exposeRegion()} is where the main work of the screen driver is
341 meant to be done, i.e., updating the screen. It is called by the
342 \l {QWSServer} {window system} to update a particular window's
343 region of the screen. But note that it doesn't actually update the
344 screen, i.e., it doesn't actually call redrawScreen() directly,
345 but starts the updateTimer, which causes redrawScreen() to be
346 called once for each updateTimer interval. This means that all
347 calls to exposeRegion() during an updateTimer interval are handled
348 by a single call to redrawScreen(). Thus updateTimer can be used
349 to limit the frequency of screen updates.
350
351 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 13
352
353 The call to the private function invalidateTexture() destroys
354 the window's existing texture (image). This ensures that a new
355 texture will be created for the window, when redrawScreen() is
356 eventually called.
357
358 But there is a caveat to using updateTimer to limit the frequency
359 of screen updates. When the driver's animated transition effect
360 for new windows is enabled and a new window is being shown for the
361 first time or reshown after having been minimized, an instance of
362 ShowAnimation is created to run the animation. The valueChanged()
363 signal of this ShowAnimation is also connected to the
364 redrawScreen() slot, and QTimeLine, the base class of our
365 ShowAnimation, uses its own, internal timer to limit the speed of
366 the animation. This means that in the driver as currently written,
367 if the window transition effect is enabled (i.e. if the plugin is
368 started, with \c {-display ahigl:effects}), then redrawScreen()
369 can be called both when the update timer times out and when the
370 ShowAnimation timer times out, so the screen might get updated
371 more often than the frequency established by the update timer.
372 This may or may not be a bug, depending on your own hardware, if
373 you use this example as a template for your own OpenGL driver.
374
375 The screen driver's private function redrawScreen() constructs
376 the window compositions. It is called only by the function of the
377 same name in the screen driver's private implementation class.
378
379 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 6
380
381 Recall that this redrawScreen() in the private implementation
382 class is a slot function connected to two signals, the \c
383 timeout() signal of the updateTimer in the private implementation
384 class, and the valueChanged() signal of the helper class
385 ShowAnimation. Thus, the screen is only ever updated when a
386 timeout of one of the two timers occurs. This is important for two
387 reasons. First, the screen is meant to be updated no more than
388 once per updateTimer interval. Second, however, if the animated
389 window transition effect is requested, the screen might be updated
390 more often than that, and this might be a bug if the hardware
391 can't handle more frequent updates.
392
393 The redrawScreen() in QAhiGLScreen begins by using standard
394 OpenGL to fill the screen with the background color.
395
396 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 10
397
398 Next it iterates over the list of all \l {QWSWindow} {client
399 windows} obtained from the \l {QWSServer} {server}, extracting
400 from each window its instance of QWSWIndowSurface, then using that
401 window surface to create an OpenGL texture, and finally calling
402 the helper function drawWindow() to draw the texture on the
403 screen.
404
405 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 11
406
407 Note the call to glBindTexture() immediately before the call to
408 drawWindow(). This call binds the identifer \c GL_TEXTURE_2D to
409 the texture we have just created. This makes our texture
410 accessible to functions in the OpenGL libraries. If you miss that
411 point, digging into the internals of drawWindow() won't make much
412 sense.
413
414 Finally, the cursor is added to the window composition, and in the
415 last statement, the whole thing is displayed on the screen.
416
417 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 12
418
419 The call to \c drawWindow(win,progress), in addition to passing a
420 pointer to the window to be redrawn, also passes the \c progress
421 parameter obtained by calling \l {QTimeLine::currentValue()} on
422 the window's instance of ShowAnimation. Recall that the current
423 value of the timeline is updated internally by a timer local to
424 the timeline, and the redrawScreen() slot is called whenever the
425 current value changes. The progress value will only be used if
426 the animated transition effect has been enabled. These extra calls
427 of redrawScreen() may cause the screen to be updated more often
428 than the rate determined by updateTimer. This must be taken
429 into account, if you set your updateTimer to timeout at the
430 maximum screen update frequency your hardware can handle.
431
432 The drawWindow() function is not shown here and not explained
433 further, but the call to drawWindow() is the entry point to a
434 hierarchy of private helper functions that execute sequences of
435 OpenGL and EGL library calls. The reader is assumed to be familiar
436 enough with the OpenGL and EGL APIs to understand the code in
437 these helper functions on his own. Besides drawWindow(), the list
438 of these helper functions includes drawQuad(), drawQuadWavyFlag(),
439 the two overloadings of drawQuad_helper() (used by drawQuad() and
440 drawQuadWacyFlag()), and setRectCoords().
441
442 Note the two different ways the window's texture can be created in
443 redrawScreen(). If the window surface is an OpenGL window surface
444 (QAhiGLWindowSurface described below), the texture is obtained
445 from the window surface directly by calling its textureId()
446 function. But when the window surface is not an OpenGL one, the
447 static function createTexture() is called with the window
448 surface's \l {QImage} {image} to copy that image into an OpenGL
449 texture. This is done with the EGL functions glTexImage2D() and
450 glTexSubImage2D(). createTexture() is another function that
451 should be understandable for exsperienced OpenGL users, so it is
452 not shown or explained further here.
453
454 The two implementations of \l {QScreen::}{createSurface()} are for
455 instantiating new window surfaces. The overloading with the widget
456 parameter is called in the client.
457
458 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 14
459
460 If the parameter is an \l {QGLWidget} {OpenGL widget}, or, when it
461 isn't an OpenGL widget but its size is no bigger than 256 x 256,
462 we instantiate our subclass QAhiGLWindowSurface. Otherwise, we
463 instantiate a QWSWindowSurface. The size contraint is a
464 limitation of the OpenGL ES libraries we are using for our ATI
465 device.
466
467 Note the test at the top of the function asking if our application
468 process is the \l {QApplication::GuiServer} {server}. We only
469 create instances of QAhiGLWindowSurface if our client is in the
470 server process. This is because of an implementation restriction
471 required by the OpenGL library used in the example. They only
472 support use of OpenGL in the server process. Hence a client can
473 use the QAhiGLWindowSurface if the client is in the server
474 process.
475
476 The other overloading of createSurface() is called by the
477 server to create a window surface that will hold a copy of a
478 client side window surface.
479
480 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 15
481
482 This overloading accepts a QString parameter identifying the type
483 of window surface to instantiate. QAhiGLWindowSurface is
484 instantiated if the parameter is \c ahigl. Otherwise, a normal
485 QWSWindowSurface is instantiated. The client's window surface
486 communicates its image data to the server's window surface through
487 shared memory.
488
489 The implementation of \l {QScreen::}{setMode()}, is a stub in this
490 example. It would normally reset the frame buffer's resolution.
491 Its parameters are the \e width, \e height, and the bit \e depth
492 for the frame buffer's new resolution. If you implement setMode()
493 in your screen driver, remember that it must emit a signal to warn
494 other applications to redraw their frame buffers with the new
495 resolution. There is no significance to setMode() not being
496 implemented in this example. It simply wasn't implemented.
497 However, the stub had to be included because QScreen declares
498 setMode() to be pure virtual.
499
500 Before the application exits, the server will call \l {QScreen::}
501 {shutdownDevice()} to release the hardware resources. This is also
502 done using EGL library functions.
503
504 \snippet examples/qws/ahigl/qscreenahigl_qws.cpp 9
505
506 The server will also call \l {QScreen::}{disconnect()}, but this
507 function is only a stub in this example.
508
509 \section2 The window Surface Class Implementations
510
511 QAhiGLScreen creates instances of QAhiGLWindowSurface in its two
512 createSurface() functions, and there are two constructors for
513 QAhiGLWindowSurface that correspond to these two versions of
514 createSurface(). The constructor accepting a \l {QWidget} {widget}
515 parameter is called by the client side version of createSurface(),
516 and the constructor without the \l {QWidget} {widget} parameter is
517 called by the server side version. There will be a window surface
518 constructed on the server side for each one constructed on the
519 client side.
520
521 \snippet examples/qws/ahigl/qwindowsurface_ahigl.cpp 1
522 \codeline
523 \snippet examples/qws/ahigl/qwindowsurface_ahigl.cpp 2
524
525 The constructors create an instance of QAhiGLWindowSurfacePrivate,
526 the private implementation class, which contains all the state
527 variables for QAhiGLWindowSurface. The client side constructor
528 also creates an instance of QWSGLPaintDevice, the OpenGL paint
529 device, for return by \l {QWSWindowSurface::} {paintDevice()}.
530 This ensures that all \l {QPainter}s used on this surface will use
531 an OpenGL enabled QPaintEngine. It is a bit of jiggery pokery,
532 which is required because \l {QWSWindowSurface::} {paintDevice()}
533 is declared pure virtual. Normally, the client side constructor
534 will be called with an \l {QGLWidget}{OpenGL widget}, which has
535 its own \l {QWidget::} {paintEngine()} function that returns the
536 global static OpenGL paint engine, but because the constructor
537 also accepts a normal \l {QWidget}{widget}, it must be able to
538 find the OpenGL paint engine in that case as well, so since \l
539 {QWSWindowSurface::} {paintDevice()} must be implemented anyway,
540 the constructor creates an instance of QWSGLPaintDevice, which can
541 always return the global static pointer to QOpenGLPaintEngine.
542
543 The OpenGL library implementation used for this example only
544 supports one OpenGL context. This context is therefore shared
545 among the single instance of QAhiGLScreen and all instances of
546 QAhiGLWindowSurface. It is passed to both constructors.
547
548 This example uses the OpenGL frame buffer object extension, which
549 allows for accelerating OpenGL painting operations. Using this
550 OpenGL extension, painting operations are performed in a frame
551 buffer object, which QAhiGLScreen later uses to construct window
552 compositions on the screen. Allocation of the frame buffer object
553 is performed in \l {QWindowSurface::} {setGeometry()}. A safer way
554 to use this extension would be to first test to see if the
555 extension is supported by your OpenGL library, and use a different
556 approach if it is not.
557
558 \snippet examples/qws/ahigl/qwindowsurface_ahigl.cpp 3
559
560 Since there can be several instances of the QAhiGLWindowSurface, we need
561 to make sure that the correct framebuffer object is active before painting.
562 This is done by reimplementing \l QWindowSurface::beginPaint():
563
564 \snippet examples/qws/ahigl/qwindowsurface_ahigl.cpp 4
565
566 Finally we need to make sure that whenever a widget grows beyond the size
567 supported by this driver (256 x 256), the surface is deleted and a new
568 standard surface is created instead. This is handled by reimplementing
569 \l QWSWindowSurface::isValid():
570
571 \snippet examples/qws/ahigl/qwindowsurface_ahigl.cpp 5
572*/
Note: See TracBrowser for help on using the repository browser.