diff options
Diffstat (limited to 'doc/src/examples/hellogl_es.qdoc')
-rw-r--r-- | doc/src/examples/hellogl_es.qdoc | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/doc/src/examples/hellogl_es.qdoc b/doc/src/examples/hellogl_es.qdoc new file mode 100644 index 0000000..0293584 --- /dev/null +++ b/doc/src/examples/hellogl_es.qdoc @@ -0,0 +1,124 @@ +/*! + \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. +*/ |