source: trunk/doc/src/examples/2dpainting.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: 9.2 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 opengl/2dpainting
44 \title 2D Painting Example
45
46 The 2D Painting example shows how QPainter and QGLWidget can be used
47 together to display accelerated 2D graphics on supported hardware.
48
49 \image 2dpainting-example.png
50
51 The QPainter class is used to draw 2D graphics primitives onto
52 paint devices provided by QPaintDevice subclasses, such as QWidget
53 and QImage.
54
55 Since QGLWidget is a subclass of QWidget, it is possible
56 to reimplement its \l{QWidget::paintEvent()}{paintEvent()} and use
57 QPainter to draw on the device, just as you would with a QWidget.
58 The only difference is that the painting operations will be accelerated
59 in hardware if it is supported by your system's OpenGL drivers.
60
61 In this example, we perform the same painting operations on a
62 QWidget and a QGLWidget. The QWidget is shown with anti-aliasing
63 enabled, and the QGLWidget will also use anti-aliasing if the
64 required extensions are supported by your system's OpenGL driver.
65
66 \section1 Overview
67
68 To be able to compare the results of painting onto a QGLWidget subclass
69 with native drawing in a QWidget subclass, we want to show both kinds
70 of widget side by side. To do this, we derive subclasses of QWidget and
71 QGLWidget, using a separate \c Helper class to perform the same painting
72 operations for each, and lay them out in a top-level widget, itself
73 provided a the \c Window class.
74
75 \section1 Helper Class Definition
76
77 In this example, the painting operations are performed by a helper class.
78 We do this because we want the same painting operations to be performed
79 for both our QWidget subclass and the QGLWidget subclass.
80
81 The \c Helper class is minimal:
82
83 \snippet examples/opengl/2dpainting/helper.h 0
84
85 Apart from the constructor, it only provides a \c paint() function to paint
86 using a painter supplied by one of our widget subclasses.
87
88 \section1 Helper Class Implementation
89
90 The constructor of the class sets up the resources it needs to paint
91 content onto a widget:
92
93 \snippet examples/opengl/2dpainting/helper.cpp 0
94
95 The actual painting is performed in the \c paint() function. This takes
96 a QPainter that has already been set up to paint onto a paint device
97 (either a QWidget or a QGLWidget), a QPaintEvent that provides information
98 about the region to be painted, and a measure of the elapsed time (in
99 milliseconds) since the paint device was last updated.
100
101 \snippet examples/opengl/2dpainting/helper.cpp 1
102
103 We begin painting by filling in the region contained in the paint event
104 before translating the origin of the coordinate system so that the rest
105 of the painting operations will be displaced towards the center of the
106 paint device.
107
108 We draw a spiral pattern of circles, using the elapsed time specified to
109 animate them so that they appear to move outward and around the coordinate
110 system's origin:
111
112 \snippet examples/opengl/2dpainting/helper.cpp 2
113
114 Since the coordinate system is rotated many times during
115 this process, we \l{QPainter::save()}{save()} the QPainter's state
116 beforehand and \l{QPainter::restore()}{restore()} it afterwards.
117
118 \snippet examples/opengl/2dpainting/helper.cpp 3
119
120 We draw some text at the origin to complete the effect.
121
122 \section1 Widget Class Definition
123
124 The \c Widget class provides a basic custom widget that we use to
125 display the simple animation painted by the \c Helper class.
126
127 \snippet examples/opengl/2dpainting/widget.h 0
128
129 Apart from the constructor, it only contains a
130 \l{QWidget::paintEvent()}{paintEvent()} function, that lets us draw
131 customized content, and a slot that is used to animate its contents.
132 One member variable keeps track of the \c Helper that the widget uses
133 to paint its contents, and the other records the elapsed time since
134 it was last updated.
135
136 \section1 Widget Class Implementation
137
138 The constructor only initializes the member variables, storing the
139 \c Helper object supplied and calling the base class's constructor,
140 and enforces a fixed size for the widget:
141
142 \snippet examples/opengl/2dpainting/widget.cpp 0
143
144 The \c animate() slot is called whenever a timer, which we define later, times
145 out:
146
147 \snippet examples/opengl/2dpainting/widget.cpp 1
148
149 Here, we determine the interval that has elapsed since the timer last
150 timed out, and we add it to any existing value before repainting the
151 widget. Since the animation used in the \c Helper class loops every second,
152 we can use the modulo operator to ensure that the \c elapsed variable is
153 always less than 1000.
154
155 Since the \c Helper class does all of the actual painting, we only have
156 to implement a paint event that sets up a QPainter for the widget and calls
157 the helper's \c paint() function:
158
159 \snippet examples/opengl/2dpainting/widget.cpp 2
160
161 \section1 GLWidget Class Definition
162
163 The \c GLWidget class definition is basically the same as the \c Widget
164 class except that it is derived from QGLWidget.
165
166 \snippet examples/opengl/2dpainting/glwidget.h 0
167
168 Again, the member variables record the \c Helper used to paint the
169 widget and the elapsed time since the previous update.
170
171 \section1 GLWidget Class Implementation
172
173 The constructor differs a little from the \c Widget class's constructor:
174
175 \snippet examples/opengl/2dpainting/glwidget.cpp 0
176
177 As well as initializing the \c elapsed member variable and storing the
178 \c Helper object used to paint the widget, the base class's constructor
179 is called with the format that specifies the \l QGL::SampleBuffers flag.
180 This enables anti-aliasing if it is supported by your system's OpenGL
181 driver.
182
183 The \c animate() slot is exactly the same as that provided by the \c Widget
184 class:
185
186 \snippet examples/opengl/2dpainting/glwidget.cpp 1
187
188 The \c paintEvent() is almost the same as that found in the \c Widget class:
189
190 \snippet examples/opengl/2dpainting/glwidget.cpp 2
191
192 Since anti-aliasing will be enabled if available, we only need to set up
193 a QPainter on the widget and call the helper's \c paint() function to display
194 the widget's contents.
195
196 \section1 Window Class Definition
197
198 The \c Window class has a basic, minimal definition:
199
200 \snippet examples/opengl/2dpainting/window.h 0
201
202 It contains a single \c Helper object that will be shared between all
203 widgets.
204
205 \section1 Window Class Implementation
206
207 The constructor does all the work, creating a widget of each type and
208 inserting them with labels into a layout:
209
210 \snippet examples/opengl/2dpainting/window.cpp 0
211
212 A timer with a 50 millisecond time out is constructed for animation purposes,
213 and connected to the \c animate() slots of the \c Widget and \c GLWidget objects.
214 Once started, the widgets should be updated at around 20 frames per second.
215
216 \section1 Running the Example
217
218 The example shows the same painting operations performed at the same time
219 in a \c Widget and a \c GLWidget. The quality and speed of rendering in the
220 \c GLWidget depends on the level of support for multisampling and hardware
221 acceleration that your system's OpenGL driver provides. If support for either
222 of these is lacking, the driver may fall back on a software renderer that
223 may trade quality for speed.
224*/
Note: See TracBrowser for help on using the repository browser.