1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the documentation of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
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.
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.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
43 \example opengl/hellogl_es
44 \title Hello GL ES Example
46 The Hello GL ES example is the \l{Hello GL Example} ported to OpenGL ES.
47 It also included some effects from the OpenGL \l{Overpainting Example}.
49 \image hellogl-es-example.png
51 A complete introduction to OpenGL ES and a description of all differences
52 between OpenGL and OpenGL ES is out of the scope of this document; but
53 we will describe some of the major issues and differences.
55 Since Hello GL ES is a direct port of standard OpenGL code, it is a fairly
56 good example for porting OpenGL code to OpenGL ES.
60 \section1 Using QGLWidget
62 QGLWidget can be used for OpenGL ES similar to the way it is used with
63 standard OpenGL; but there are some differences. We use EGL 1.0 to embedd
64 the OpenGL ES window within the native window manager. In
65 QGLWidget::initializeGL() we initialize OpenGL ES.
67 \section1 Using OpenGL ES rendering commands
69 To update the scene, we reimplment QGLWidget::paintGL(). We use OpenGL ES
70 rendering commands just like we do with standard OpenGL. Since the OpenGL
71 ES common light profile only supports fixed point functions, we need to
72 abstract it somehow. Hence, we define an abstraction layer in
75 \snippet examples/opengl/hellogl_es/cl_helper.h 0
77 Instead of \c glFogxv() or \c glFogfv() we use \c q_glFogv() and to
78 convert the coordinates of a vertice we use the macro \c f2vt(). That way,
79 if QT_OPENGL_ES_CL is defined we use the fixed point functions and every
80 float is converted to fixed point.
82 If QT_OPENGL_ES_CL is not defined we use the floating point functions.
84 \snippet examples/opengl/hellogl_es/cl_helper.h 1
86 This way we support OpenGL ES Common and Common Light with the same code
87 and abstract the fact that we use either the floating point functions or
88 otherwise the fixed point functions.
90 \section1 Porting OpenGL to OpenGL ES
92 Since OpenGL ES is missing the immediate mode and does not support quads,
93 we have to create triangle arrays.
95 We create a quad by adding vertices to a QList of vertices. We create both
96 sides of the quad and hardcode a distance of 0.05f. We also compute the
97 correct normal for each face and store them in another QList.
99 \snippet examples/opengl/hellogl_es/glwidget.cpp 0
101 And then we convert the complete list of vertexes and the list of normals
102 into the native OpenGL ES format that we can use with the OpenGL ES API.
104 \snippet examples/opengl/hellogl_es/glwidget.cpp 1
106 In \c paintQtLogo() we draw the triangle array using OpenGL ES. We use
107 q_vertexTypeEnum to abstract the fact that our vertex and normal arrays
108 are either in float or in fixed point format.
110 \snippet examples/opengl/hellogl_es/glwidget.cpp 2
112 \section1 Using QGLPainter
114 Since the \c QGLPainter is slower for OpenGL ES we paint the bubbles with
115 the rasterizer and cache them in a QImage. This happends only once during
118 \snippet examples/opengl/hellogl_es/bubble.cpp 0
120 For each bubble this QImage is then drawn to the QGLWidget by using the
121 according QPainter with transparency enabled.
123 \snippet examples/opengl/hellogl_es/bubble.cpp 1
125 Another difference beetwen OpenGL and OpenGL ES is that OpenGL ES does not
126 support glPushAttrib(GL_ALL_ATTRIB_BITS). So we have to restore all the
127 OpenGL states ourselves, after we created the QPainter in
130 \snippet examples/opengl/hellogl_es/glwidget.cpp 3
132 Setting up up the model view matrix and setting the right OpenGL states is
133 done in the same way as for standard OpenGL.
135 \snippet examples/opengl/hellogl_es/glwidget.cpp 4
137 Now we have to restore the OpenGL state for the QPainter. This is not done
138 automatically for OpenGL ES.
140 \snippet examples/opengl/hellogl_es/glwidget.cpp 5
142 Now we use the QPainter to draw the transparent bubbles.
144 \snippet examples/opengl/hellogl_es/glwidget.cpp 6
146 In the end, we calculate the framerate and display it using the QPainter
149 \snippet examples/opengl/hellogl_es/glwidget.cpp 7
151 After we finished all the drawing operations we swap the screen buffer.
153 \snippet examples/opengl/hellogl_es/glwidget.cpp 8
157 Similar to the \l{Hello GL Example}, we subclass QGLWidget to render
158 a 3D scene using OpenGL ES calls. QGLWidget is a subclass of QWidget.
159 Hence, its \l{QGLWidget}'s subclasses can be placed in layouts and
160 provided with interactive features just like normal custom widgets.
162 QGLWidget allows pure OpenGL ES rendering to be mixed with QPainter calls,
163 but care must be taken to maintain the state of the OpenGL ES