Update copyright headers
[qt:qt.git] / doc / src / examples / 2dpainting.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the documentation of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Free Documentation License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Free
19 ** Documentation License version 1.3 as published by the Free Software
20 ** Foundation and appearing in the file included in the packaging of
21 ** this file.  Please review the following information to ensure
22 ** the GNU Free Documentation License version 1.3 requirements
23 ** will be met: http://www.gnu.org/copyleft/fdl.html.
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29     \example opengl/2dpainting
30     \title 2D Painting Example
31
32     \brief The 2D Painting example shows how QPainter and QGLWidget can be used
33     together to display accelerated 2D graphics on supported hardware.
34
35     \image 2dpainting-example.png
36
37     The QPainter class is used to draw 2D graphics primitives onto
38     paint devices provided by QPaintDevice subclasses, such as QWidget
39     and QImage.
40
41     Since QGLWidget is a subclass of QWidget, it is possible
42     to reimplement its \l{QWidget::paintEvent()}{paintEvent()} and use
43     QPainter to draw on the device, just as you would with a QWidget.
44     The only difference is that the painting operations will be accelerated
45     in hardware if it is supported by your system's OpenGL drivers.
46
47     In this example, we perform the same painting operations on a
48     QWidget and a QGLWidget. The QWidget is shown with anti-aliasing
49     enabled, and the QGLWidget will also use anti-aliasing if the
50     required extensions are supported by your system's OpenGL driver.
51
52     \section1 Overview
53
54     To be able to compare the results of painting onto a QGLWidget subclass
55     with native drawing in a QWidget subclass, we want to show both kinds
56     of widget side by side. To do this, we derive subclasses of QWidget and
57     QGLWidget, using a separate \c Helper class to perform the same painting
58     operations for each, and lay them out in a top-level widget, itself
59     provided a the \c Window class.
60
61     \section1 Helper Class Definition
62
63     In this example, the painting operations are performed by a helper class.
64     We do this because we want the same painting operations to be performed
65     for both our QWidget subclass and the QGLWidget subclass.
66
67     The \c Helper class is minimal:
68
69     \snippet examples/opengl/2dpainting/helper.h 0
70
71     Apart from the constructor, it only provides a \c paint() function to paint
72     using a painter supplied by one of our widget subclasses.
73
74     \section1 Helper Class Implementation
75
76     The constructor of the class sets up the resources it needs to paint
77     content onto a widget:
78
79     \snippet examples/opengl/2dpainting/helper.cpp 0
80
81     The actual painting is performed in the \c paint() function. This takes
82     a QPainter that has already been set up to paint onto a paint device
83     (either a QWidget or a QGLWidget), a QPaintEvent that provides information
84     about the region to be painted, and a measure of the elapsed time (in
85     milliseconds) since the paint device was last updated.
86
87     \snippet examples/opengl/2dpainting/helper.cpp 1
88
89     We begin painting by filling in the region contained in the paint event
90     before translating the origin of the coordinate system so that the rest
91     of the painting operations will be displaced towards the center of the
92     paint device.
93
94     We draw a spiral pattern of circles, using the elapsed time specified to
95     animate them so that they appear to move outward and around the coordinate
96     system's origin:
97
98     \snippet examples/opengl/2dpainting/helper.cpp 2
99
100     Since the coordinate system is rotated many times during
101     this process, we \l{QPainter::save()}{save()} the QPainter's state
102     beforehand and \l{QPainter::restore()}{restore()} it afterwards.
103
104     \snippet examples/opengl/2dpainting/helper.cpp 3
105
106     We draw some text at the origin to complete the effect.
107
108     \section1 Widget Class Definition
109
110     The \c Widget class provides a basic custom widget that we use to
111     display the simple animation painted by the \c Helper class.
112
113     \snippet examples/opengl/2dpainting/widget.h 0
114
115     Apart from the constructor, it only contains a
116     \l{QWidget::paintEvent()}{paintEvent()} function, that lets us draw
117     customized content, and a slot that is used to animate its contents.
118     One member variable keeps track of the \c Helper that the widget uses
119     to paint its contents, and the other records the elapsed time since
120     it was last updated.
121
122     \section1 Widget Class Implementation
123
124     The constructor only initializes the member variables, storing the
125     \c Helper object supplied and calling the base class's constructor,
126     and enforces a fixed size for the widget:
127
128     \snippet examples/opengl/2dpainting/widget.cpp 0
129
130     The \c animate() slot is called whenever a timer, which we define later, times
131     out:
132
133     \snippet examples/opengl/2dpainting/widget.cpp 1
134
135     Here, we determine the interval that has elapsed since the timer last
136     timed out, and we add it to any existing value before repainting the
137     widget. Since the animation used in the \c Helper class loops every second,
138     we can use the modulo operator to ensure that the \c elapsed variable is
139     always less than 1000.
140
141     Since the \c Helper class does all of the actual painting, we only have
142     to implement a paint event that sets up a QPainter for the widget and calls
143     the helper's \c paint() function:
144
145     \snippet examples/opengl/2dpainting/widget.cpp 2
146
147     \section1 GLWidget Class Definition
148
149     The \c GLWidget class definition is basically the same as the \c Widget
150     class except that it is derived from QGLWidget.
151
152     \snippet examples/opengl/2dpainting/glwidget.h 0
153
154     Again, the member variables record the \c Helper used to paint the
155     widget and the elapsed time since the previous update.
156
157     \section1 GLWidget Class Implementation
158
159     The constructor differs a little from the \c Widget class's constructor:
160
161     \snippet examples/opengl/2dpainting/glwidget.cpp 0
162
163     As well as initializing the \c elapsed member variable and storing the
164     \c Helper object used to paint the widget, the base class's constructor
165     is called with the format that specifies the \l QGL::SampleBuffers flag.
166     This enables anti-aliasing if it is supported by your system's OpenGL
167     driver.
168
169     The \c animate() slot is exactly the same as that provided by the \c Widget
170     class:
171
172     \snippet examples/opengl/2dpainting/glwidget.cpp 1
173
174     The \c paintEvent() is almost the same as that found in the \c Widget class:
175
176     \snippet examples/opengl/2dpainting/glwidget.cpp 2
177
178     Since anti-aliasing will be enabled if available, we only need to set up
179     a QPainter on the widget and call the helper's \c paint() function to display
180     the widget's contents.
181
182     \section1 Window Class Definition
183
184     The \c Window class has a basic, minimal definition:
185
186     \snippet examples/opengl/2dpainting/window.h 0
187
188     It contains a single \c Helper object that will be shared between all
189     widgets.
190
191     \section1 Window Class Implementation
192
193     The constructor does all the work, creating a widget of each type and
194     inserting them with labels into a layout:
195
196     \snippet examples/opengl/2dpainting/window.cpp 0
197
198     A timer with a 50 millisecond time out is constructed for animation purposes,
199     and connected to the \c animate() slots of the \c Widget and \c GLWidget objects.
200     Once started, the widgets should be updated at around 20 frames per second.
201
202     \section1 Running the Example
203
204     The example shows the same painting operations performed at the same time
205     in a \c Widget and a \c GLWidget. The quality and speed of rendering in the
206     \c GLWidget depends on the level of support for multisampling and hardware
207     acceleration that your system's OpenGL driver provides. If support for either
208     of these is lacking, the driver may fall back on a software renderer that
209     may trade quality for speed.
210 */