source: trunk/doc/src/examples/hellogl.qdoc@ 561

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 13.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this 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 have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \example opengl/hellogl
44 \title Hello GL Example
45
46 The Hello GL example demonstrates the basic use of the OpenGL-related classes
47 provided with Qt.
48
49 \image hellogl-example.png
50
51 Qt provides the QGLWidget class to enable OpenGL graphics to be rendered within
52 a standard application user interface. By subclassing this class, and providing
53 reimplementations of event handler functions, 3D scenes can be displayed on
54 widgets that can be placed in layouts, connected to other objects using signals
55 and slots, and manipulated like any other widget.
56
57 \tableofcontents
58
59 \section1 GLWidget Class Definition
60
61 The \c GLWidget class contains some standard public definitions for the
62 constructor, destructor, \l{QWidget::sizeHint()}{sizeHint()}, and
63 \l{QWidget::minimumSizeHint()}{minimumSizeHint()} functions:
64
65 \snippet examples/opengl/hellogl/glwidget.h 0
66
67 We use a destructor to ensure that any OpenGL-specific data structures
68 are deleted when the widget is no longer needed (although in this case nothing
69 needs cleaning up).
70
71 \snippet examples/opengl/hellogl/glwidget.h 1
72
73 The signals and slots are used to allow other objects to interact with the
74 3D scene.
75
76 \snippet examples/opengl/hellogl/glwidget.h 2
77
78 OpenGL initialization, viewport resizing, and painting are handled by
79 reimplementing the QGLWidget::initializeGL(), QGLWidget::resizeGL(), and
80 QGLWidget::paintGL() handler functions. To enable the user to interact
81 directly with the scene using the mouse, we reimplement
82 QWidget::mousePressEvent() and QWidget::mouseMoveEvent().
83
84 \snippet examples/opengl/hellogl/glwidget.h 3
85
86 The rest of the class contains utility functions and variables that are
87 used to construct and hold orientation information for the scene. The
88 \c logo variable will be used to hold a pointer to the QtLogo object which
89 contains all the geometry.
90
91 \section1 GLWidget Class Implementation
92
93 In this example, we split the class into groups of functions and describe
94 them separately. This helps to illustrate the differences between subclasses
95 of native widgets (such as QWidget and QFrame) and QGLWidget subclasses.
96
97 \section2 Widget Construction and Sizing
98
99 The constructor provides default rotation angles for the scene, sets
100 the pointer to the QtLogo object to null, and sets up some colors for
101 later use.
102
103 \snippet examples/opengl/hellogl/glwidget.cpp 0
104
105 We also implement a destructor to release OpenGL-related resources when the
106 widget is deleted:
107
108 \snippet examples/opengl/hellogl/glwidget.cpp 1
109
110 In this case nothing requires cleaning up.
111
112 We provide size hint functions to ensure that the widget is shown at a
113 reasonable size:
114
115 \snippet examples/opengl/hellogl/glwidget.cpp 2
116 \codeline
117 \snippet examples/opengl/hellogl/glwidget.cpp 3
118 \snippet examples/opengl/hellogl/glwidget.cpp 4
119
120 The widget provides three slots that enable other components in the
121 example to change the orientation of the scene:
122
123 \snippet examples/opengl/hellogl/glwidget.cpp 5
124
125 In the above slot, the \c xRot variable is updated only if the new angle
126 is different to the old one, the \c xRotationChanged() signal is emitted to
127 allow other components to be updated, and the widget's
128 \l{QGLWidget::updateGL()}{updateGL()} handler function is called.
129
130 The \c setYRotation() and \c setZRotation() slots perform the same task for
131 rotations measured by the \c yRot and \c zRot variables.
132
133 \section2 OpenGL Initialization
134
135 The \l{QGLWidget::initializeGL()}{initializeGL()} function is used to
136 perform useful initialization tasks that are needed to render the 3D scene.
137 These often involve defining colors and materials, enabling and disabling
138 certain rendering flags, and setting other properties used to customize the
139 rendering process.
140
141 \snippet examples/opengl/hellogl/glwidget.cpp 6
142
143 In this example, we reimplement the function to set the background color,
144 create a QtLogo object instance which will contain all the geometry to
145 display, and set up the rendering process to use a particular shading model
146 and rendering flags.
147
148 \section2 Resizing the Viewport
149
150 The \l{QGLWidget::resizeGL()}{resizeGL()} function is used to ensure that
151 the OpenGL implementation renders the scene onto a viewport that matches the
152 size of the widget, using the correct transformation from 3D coordinates to
153 2D viewport coordinates.
154
155 The function is called whenever the widget's dimensions change, and is
156 supplied with the new width and height. Here, we define a square viewport
157 based on the length of the smallest side of the widget to ensure that
158 the scene is not distorted if the widget has sides of unequal length:
159
160 \snippet examples/opengl/hellogl/glwidget.cpp 8
161
162 A discussion of the projection transformation used is outside the scope of
163 this example. Please consult the OpenGL reference documentation for an
164 explanation of projection matrices.
165
166 \section2 Painting the Scene
167
168 The \l{QGLWidget::paintGL()}{paintGL()} function is used to paint the
169 contents of the scene onto the widget. For widgets that only need to be
170 decorated with pure OpenGL content, we reimplement QGLWidget::paintGL()
171 \e instead of reimplementing QWidget::paintEvent():
172
173 \snippet examples/opengl/hellogl/glwidget.cpp 7
174
175 In this example, we clear the widget using the background color that
176 we defined in the \l{QGLWidget::initializeGL()}{initializeGL()} function,
177 set up the frame of reference for the geometry we want to display, and
178 call the draw method of the QtLogo object to render the scene.
179
180 \section2 Mouse Handling
181
182 Just as in subclasses of native widgets, mouse events are handled by
183 reimplementing functions such as QWidget::mousePressEvent() and
184 QWidget::mouseMoveEvent().
185
186 The \l{QWidget::mousePressEvent()}{mousePressEvent()} function simply
187 records the position of the mouse when a button is initially pressed:
188
189 \snippet examples/opengl/hellogl/glwidget.cpp 9
190
191 The \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()} function uses the
192 previous location of the mouse cursor to determine how much the object
193 in the scene should be rotated, and in which direction:
194
195 \snippet examples/opengl/hellogl/glwidget.cpp 10
196
197 Since the user is expected to hold down the mouse button and drag the
198 cursor to rotate the object, the cursor's position is updated every time
199 a move event is received.
200
201 \section1 QtLogo Class
202
203 This class encapsulates the OpenGL geometry data which will be rendered
204 in the basic 3D scene.
205
206 \snippet examples/opengl/shared/qtlogo.h 0
207
208 The geometry is divided into a list of parts which may be rendered in
209 different ways. The data itself is contained in a Geometry structure that
210 includes the vertices, their lighting normals and index values which
211 point into the vertices, grouping them into faces.
212
213 \snippet examples/opengl/shared/qtlogo.cpp 0
214
215 The data in the Geometry class is stored in QVector<QVector3D> members
216 which are convenient for use with OpenGL because they expose raw
217 contiguous floating point values via the constData() method. Methods
218 are included for adding new vertex data, either with smooth normals, or
219 facetted normals; and for enabling the geometry ready for rendering.
220
221 \snippet examples/opengl/shared/qtlogo.cpp 1
222
223 The higher level Patch class has methods for accumulating the geometry
224 one face at a time, and treating collections of faces or "patches" with
225 transformations, applying different colors or smoothing. Although faces
226 may be added as triangles or quads, at the OpenGL level all data is
227 treated as triangles for compatibility with OpenGL/ES.
228
229 \snippet examples/opengl/shared/qtlogo.cpp 2
230
231 Drawing a Patch is simply acheived by applying any transformation,
232 and material effect, then drawing the data using the index range for
233 the patch. The model-view matrix is saved and then restored so that
234 any transformation does not affect other parts of the scene.
235
236 \snippet examples/opengl/shared/qtlogo.cpp 3
237
238 The geometry is built once on construction of the QtLogo, and it is
239 paramaterized on a number of divisions - which controls how "chunky" the
240 curved section of the logo looks - and on a scale, so larger and smaller
241 QtLogo objects can be created without having to use OpenGL scaling
242 (which would force normal recalculation).
243
244 The building process is done by helper classes (read the source for full
245 details) which only exist during the build phase, to assemble the parts
246 of the scene.
247
248 \snippet examples/opengl/shared/qtlogo.cpp 4
249
250 Finally the complete QtLogo scene is simply drawn by enabling the data arrays
251 and then iterating over the parts, calling draw() on each one.
252
253 \section1 Window Class Definition
254
255 The \c Window class is used as a container for the \c GLWidget used to
256 display the scene:
257
258 \snippet examples/opengl/hellogl/window.h 0
259
260 In addition, it contains sliders that are used to change the orientation
261 of the object in the scene.
262
263 \section1 Window Class Implementation
264
265 The constructor constructs an instance of the \c GLWidget class and some
266 sliders to manipulate its contents.
267
268 \snippet examples/opengl/hellogl/window.cpp 0
269
270 We connect the \l{QAbstractSlider::valueChanged()}{valueChanged()} signal
271 from each of the sliders to the appropriate slots in \c{glWidget}.
272 This allows the user to change the orientation of the object by dragging
273 the sliders.
274
275 We also connect the \c xRotationChanged(), \c yRotationChanged(), and
276 \c zRotationChanged() signals from \c glWidget to the
277 \l{QAbstractSlider::setValue()}{setValue()} slots in the
278 corresponding sliders.
279
280 \snippet examples/opengl/hellogl/window.cpp 1
281
282 The sliders are placed horizontally in a layout alongside the \c GLWidget,
283 and initialized with suitable default values.
284
285 The \c createSlider() utility function constructs a QSlider, and ensures
286 that it is set up with a suitable range, step value, tick interval, and
287 page step value before returning it to the calling function:
288
289 \snippet examples/opengl/hellogl/window.cpp 2
290
291 \section1 Summary
292
293 The \c GLWidget class implementation shows how to subclass QGLWidget for
294 the purposes of rendering a 3D scene using OpenGL calls. Since QGLWidget
295 is a subclass of QWidget, subclasses of QGLWidget can be placed in layouts
296 and provided with interactive features just like normal custom widgets.
297
298 We ensure that the widget is able to correctly render the scene using OpenGL
299 by reimplementing the following functions:
300
301 \list
302 \o QGLWidget::initializeGL() sets up resources needed by the OpenGL implementation
303 to render the scene.
304 \o QGLWidget::resizeGL() resizes the viewport so that the rendered scene fits onto
305 the widget, and sets up a projection matrix to map 3D coordinates to 2D viewport
306 coordinates.
307 \o QGLWidget::paintGL() performs painting operations using OpenGL calls.
308 \endlist
309
310 Since QGLWidget is a subclass of QWidget, it can also be used
311 as a normal paint device, allowing 2D graphics to be drawn with QPainter.
312 This use of QGLWidget is discussed in the \l{2D Painting Example}{2D Painting}
313 example.
314
315 More advanced users may want to paint over parts of a scene rendered using
316 OpenGL. QGLWidget allows pure OpenGL rendering to be mixed with QPainter
317 calls, but care must be taken to maintain the state of the OpenGL implementation.
318 See the \l{Overpainting Example}{Overpainting} example for more information.
319*/
Note: See TracBrowser for help on using the repository browser.