Update copyright headers
[qt:qt.git] / doc / src / examples / cube.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:LGPL$
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 Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 /*!
43     \example opengl/cube
44     \group all-examples
45     \title Cube OpenGL ES 2.0 example
46
47     \brief The Cube OpenGL ES 2.0 example shows how to write mouse rotateable
48         textured 3D cube using OpenGL ES 2.0 with Qt.
49     
50     It shows how to handle
51         polygon geometries efficiently and how to write simple vertex and
52         fragment shader for programmable graphics pipeline. In addition it
53         shows how to use quaternions for representing 3D object orientation.
54
55     This example has been written for OpenGL ES 2.0 but it works also on
56         desktop OpenGL because this example is simple enough and for the
57         most parts desktop OpenGL API is same. It compiles also without OpenGL
58         support but then it just shows a label stating that OpenGL support is
59         required.
60
61         \image cube.png Screenshot of the Cube example running on N900
62
63         The example consist of two classes:
64
65         \list
66         \o \c MainWidget extends QGLWidget and contains OpenGL ES 2.0
67                 initialization and drawing and mouse and timer event handling
68         \o \c GeometryEngine handles polygon geometries. Transfers polygon geometry
69                 to vertex buffer objects and draws geometries from vertex buffer objects.
70         \endlist
71
72         We'll start by initializing OpenGL ES 2.0 in \c MainWidget.
73
74         \tableofcontents
75
76         \section1 Initializing OpenGL ES 2.0
77
78         Since OpenGL ES 2.0 doesn't support fixed graphics pipeline anymore it has to
79         be implemented by ourselves. This makes graphics pipeline very flexible but
80         in the same time it becomes more difficult because user has to implement graphics
81         pipeline to get even the simplest example running. It also makes graphics pipeline
82         more efficient because user can decide what kind of pipeline is needed for the
83         application.
84
85         First we have to implement vertex shader. It gets vertex data and
86         model-view-projection matrix (MVP) as parameters. It transforms vertex position
87         using MVP matrix to screen space and passes texture coordinate to
88         fragment shader. Texture coordinate will be automatically interpolated on polygon
89         faces.
90
91         \snippet examples/opengl/cube/vshader.glsl 0
92
93         After that we need to implement second part of the graphics pipeline - fragment
94         shader. For this exercise we need to implement fragment shader that handles
95         texturing. It gets interpolated texture coordinate as a parameter and looks up
96         fragment color from the given texture.
97
98         \snippet examples/opengl/cube/fshader.glsl 0
99
100         Using \c QGLShaderProgram we can compile, link and bind shader code to
101         graphics pipeline. This code uses Qt Resource files to access shader source code.
102
103         \snippet examples/opengl/cube/mainwidget.cpp 3
104
105         The following code enables depth buffering and back face culling.
106
107         \snippet examples/opengl/cube/mainwidget.cpp 2
108
109         \section1 Loading textures from Qt Resource files
110
111         \c QGLWidget interface implements methods for loading textures from QImage to GL
112         texture memory. We still need to use OpenGL provided functions for specifying
113         the GL texture unit and configuring texture filtering options.
114
115         \snippet examples/opengl/cube/mainwidget.cpp 4
116
117         \section1 Cube Geometry
118
119         There are many ways to render polygons in OpenGL but the most efficient way is
120         to use only triangle strip primitives and render vertices from graphics hardware
121         memory. OpenGL has a mechanism to create buffer objects to this memory area and
122         transfer vertex data to these buffers. In OpenGL terminology these are referred
123         as Vertex Buffer Objects (VBO).
124
125         \image cube_faces.png Cube faces and vertices
126
127         This is how cube faces break down to triangles. Vertices are ordered this way
128         to get vertex ordering correct using triangle strips. OpenGL determines triangle
129         front and back face based on vertex ordering. By default OpenGL uses
130         counter-clockwise order for front faces. This information is used by back face
131         culling which improves rendering performance by not rendering back faces of the
132         triangles. This way graphics pipeline can omit rendering sides of the triangle that
133         aren't facing towards screen.
134
135         Creating vertex buffer objects and transferring data to them is quite simple using
136         OpenGL provided functions.
137
138         \snippet examples/opengl/cube/geometryengine.cpp 0
139
140         \snippet examples/opengl/cube/geometryengine.cpp 1
141
142         Drawing primitives from VBOs and telling programmable graphics pipeline how to
143         locate vertex data requires few steps. First we need to bind VBOs to be used.
144         After that we bind shader program attribute names and configure what
145         kind of data it has in the bound VBO. Finally we'll draw triangle
146         strip primitives using indices from the other VBO.
147
148         \snippet examples/opengl/cube/geometryengine.cpp 2
149
150         \section1 Perspective projection
151
152         Using \c QMatrix4x4 helper methods it's really easy to calculate perpective
153         projection matrix. This matrix is used to project vertices to screen space.
154
155         \snippet examples/opengl/cube/mainwidget.cpp 5
156
157         \section1 Orientation of the 3D object
158
159         Quaternions are handy way to represent orientation of the 3D object. Quaternions
160         involve quite complex mathematics but fortunately all the necessary mathematics
161         behind quaternions is implemented in \c QQuaternion. That allows us to store
162         cube orientation in quaternion and rotating cube around given axis is quite
163         simple.
164
165         The following code calculates rotation axis and angular speed based on mouse events.
166
167         \snippet examples/opengl/cube/mainwidget.cpp 0
168
169         \c QBasicTimer is used to animate scene and update cube orientation. Rotations
170         can be concatenated simply by multiplying quaternions.
171
172         \snippet examples/opengl/cube/mainwidget.cpp 1
173
174         Model-view matrix is calculated using the quaternion and by moving world by Z axis.
175         This matrix is multiplied with the projection matrix to get MVP matrix for shader
176         program.
177
178         \snippet examples/opengl/cube/mainwidget.cpp 6
179
180 */