1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example opengl/hellogl_es
\title Hello GL ES Example
The Hello GL ES example is the \l{Hello GL Example} ported to OpenGL ES.
It also included some effects from the OpenGL \l{Overpainting Example}.
\image hellogl-es-example.png
A complete introduction to OpenGL ES and a description of all differences
between OpenGL and OpenGL ES is out of the scope of this document; but
we will describe some of the major issues and differences.
Since Hello GL ES is a direct port of standard OpenGL code, it is a fairly
good example for porting OpenGL code to OpenGL ES.
\tableofcontents
\section1 Using QGLWidget
QGLWidget can be used for OpenGL ES similar to the way it is used with
standard OpenGL; but there are some differences. We use EGL 1.0 to embedd
the OpenGL ES window within the native window manager. In
QGLWidget::initializeGL() we initialize OpenGL ES.
\section1 Using OpenGL ES rendering commands
To update the scene, we reimplment QGLWidget::paintGL(). We use OpenGL ES
rendering commands just like we do with standard OpenGL. Since the OpenGL
ES common light profile only supports fixed point functions, we need to
abstract it somehow. Hence, we define an abstraction layer in
\c{cl_helper.h}.
\snippet examples/opengl/hellogl_es/cl_helper.h 0
Instead of \c glFogxv() or \c glFogfv() we use \c q_glFogv() and to
convert the coordinates of a vertice we use the macro \c f2vt(). That way,
if QT_OPENGL_ES_CL is defined we use the fixed point functions and every
float is converted to fixed point.
If QT_OPENGL_ES_CL is not defined we use the floating point functions.
\snippet examples/opengl/hellogl_es/cl_helper.h 1
This way we support OpenGL ES Common and Common Light with the same code
and abstract the fact that we use either the floating point functions or
otherwise the fixed point functions.
\section1 Porting OpenGL to OpenGL ES
Since OpenGL ES is missing the immediate mode and does not support quads,
we have to create triangle arrays.
We create a quad by adding vertices to a QList of vertices. We create both
sides of the quad and hardcode a distance of 0.05f. We also compute the
correct normal for each face and store them in another QList.
\snippet examples/opengl/hellogl_es/glwidget.cpp 0
And then we convert the complete list of vertexes and the list of normals
into the native OpenGL ES format that we can use with the OpenGL ES API.
\snippet examples/opengl/hellogl_es/glwidget.cpp 1
In \c paintQtLogo() we draw the triangle array using OpenGL ES. We use
q_vertexTypeEnum to abstract the fact that our vertex and normal arrays
are either in float or in fixed point format.
\snippet examples/opengl/hellogl_es/glwidget.cpp 2
\section1 Using QGLPainter
Since the \c QGLPainter is slower for OpenGL ES we paint the bubbles with
the rasterizer and cache them in a QImage. This happends only once during
the initialiazation.
\snippet examples/opengl/hellogl_es/bubble.cpp 0
For each bubble this QImage is then drawn to the QGLWidget by using the
according QPainter with transparency enabled.
\snippet examples/opengl/hellogl_es/bubble.cpp 1
Another difference beetwen OpenGL and OpenGL ES is that OpenGL ES does not
support glPushAttrib(GL_ALL_ATTRIB_BITS). So we have to restore all the
OpenGL states ourselves, after we created the QPainter in
GLWidget::paintGL().
\snippet examples/opengl/hellogl_es/glwidget.cpp 3
Setting up up the model view matrix and setting the right OpenGL states is
done in the same way as for standard OpenGL.
\snippet examples/opengl/hellogl_es/glwidget.cpp 4
Now we have to restore the OpenGL state for the QPainter. This is not done
automatically for OpenGL ES.
\snippet examples/opengl/hellogl_es/glwidget.cpp 5
Now we use the QPainter to draw the transparent bubbles.
\snippet examples/opengl/hellogl_es/glwidget.cpp 6
In the end, we calculate the framerate and display it using the QPainter
again.
\snippet examples/opengl/hellogl_es/glwidget.cpp 7
After we finished all the drawing operations we swap the screen buffer.
\snippet examples/opengl/hellogl_es/glwidget.cpp 8
\section1 Summary
Similar to the \l{Hello GL Example}, we subclass QGLWidget to render
a 3D scene using OpenGL ES calls. QGLWidget is a subclass of QWidget.
Hence, its \l{QGLWidget}'s subclasses can be placed in layouts and
provided with interactive features just like normal custom widgets.
QGLWidget allows pure OpenGL ES rendering to be mixed with QPainter calls,
but care must be taken to maintain the state of the OpenGL ES
implementation.
*/
|