diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2012-09-18 20:32:53 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-09-21 19:59:06 +0200 |
commit | d16c565ca6a55788435c52ad45647eda67854d80 (patch) | |
tree | 17e2c192b412e4959d422c1691e74ad172601ff7 /examples/opengl | |
parent | 53373bdd9faf343611796e401805327e6de47586 (diff) |
Move opengl/wid/net example docs to proper folders.
Change-Id: I846439a9cf7ad965ed27a00f98dbc4ff97abe73b
Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
Reviewed-by: Martin Smith <martin.smith@digia.com>
Diffstat (limited to 'examples/opengl')
23 files changed, 1282 insertions, 0 deletions
diff --git a/examples/opengl/doc/images/2dpainting-example.png b/examples/opengl/doc/images/2dpainting-example.png Binary files differnew file mode 100644 index 0000000000..2a77e7d7d5 --- /dev/null +++ b/examples/opengl/doc/images/2dpainting-example.png diff --git a/examples/opengl/doc/images/cube.png b/examples/opengl/doc/images/cube.png Binary files differnew file mode 100644 index 0000000000..95dfc984dd --- /dev/null +++ b/examples/opengl/doc/images/cube.png diff --git a/examples/opengl/doc/images/cube_faces.png b/examples/opengl/doc/images/cube_faces.png Binary files differnew file mode 100644 index 0000000000..2c7102a94c --- /dev/null +++ b/examples/opengl/doc/images/cube_faces.png diff --git a/examples/opengl/doc/images/framebufferobject2-example.png b/examples/opengl/doc/images/framebufferobject2-example.png Binary files differnew file mode 100644 index 0000000000..bafb05a08b --- /dev/null +++ b/examples/opengl/doc/images/framebufferobject2-example.png diff --git a/examples/opengl/doc/images/grabber-example.png b/examples/opengl/doc/images/grabber-example.png Binary files differnew file mode 100644 index 0000000000..6a05b94bec --- /dev/null +++ b/examples/opengl/doc/images/grabber-example.png diff --git a/examples/opengl/doc/images/hellogl-es-example.png b/examples/opengl/doc/images/hellogl-es-example.png Binary files differnew file mode 100644 index 0000000000..7e55f09a7a --- /dev/null +++ b/examples/opengl/doc/images/hellogl-es-example.png diff --git a/examples/opengl/doc/images/hellogl-example.png b/examples/opengl/doc/images/hellogl-example.png Binary files differnew file mode 100644 index 0000000000..ecb3a3a7b0 --- /dev/null +++ b/examples/opengl/doc/images/hellogl-example.png diff --git a/examples/opengl/doc/images/overpainting-example.png b/examples/opengl/doc/images/overpainting-example.png Binary files differnew file mode 100644 index 0000000000..0368dcabc8 --- /dev/null +++ b/examples/opengl/doc/images/overpainting-example.png diff --git a/examples/opengl/doc/images/pbuffers-example.png b/examples/opengl/doc/images/pbuffers-example.png Binary files differnew file mode 100644 index 0000000000..c34a6fd02b --- /dev/null +++ b/examples/opengl/doc/images/pbuffers-example.png diff --git a/examples/opengl/doc/images/pbuffers2-example.png b/examples/opengl/doc/images/pbuffers2-example.png Binary files differnew file mode 100644 index 0000000000..4a9c7175a3 --- /dev/null +++ b/examples/opengl/doc/images/pbuffers2-example.png diff --git a/examples/opengl/doc/images/samplebuffers-example.png b/examples/opengl/doc/images/samplebuffers-example.png Binary files differnew file mode 100644 index 0000000000..b751c143b3 --- /dev/null +++ b/examples/opengl/doc/images/samplebuffers-example.png diff --git a/examples/opengl/doc/images/textures-example.png b/examples/opengl/doc/images/textures-example.png Binary files differnew file mode 100644 index 0000000000..b583ede063 --- /dev/null +++ b/examples/opengl/doc/images/textures-example.png diff --git a/examples/opengl/doc/src/2dpainting.qdoc b/examples/opengl/doc/src/2dpainting.qdoc new file mode 100644 index 0000000000..7239ddbf3d --- /dev/null +++ b/examples/opengl/doc/src/2dpainting.qdoc @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example 2dpainting + \title 2D Painting Example + + The 2D Painting example shows how QPainter and QGLWidget can be used + together to display accelerated 2D graphics on supported hardware. + + \image 2dpainting-example.png + + The QPainter class is used to draw 2D graphics primitives onto + paint devices provided by QPaintDevice subclasses, such as QWidget + and QImage. + + Since QGLWidget is a subclass of QWidget, it is possible + to reimplement its \l{QWidget::paintEvent()}{paintEvent()} and use + QPainter to draw on the device, just as you would with a QWidget. + The only difference is that the painting operations will be accelerated + in hardware if it is supported by your system's OpenGL drivers. + + In this example, we perform the same painting operations on a + QWidget and a QGLWidget. The QWidget is shown with anti-aliasing + enabled, and the QGLWidget will also use anti-aliasing if the + required extensions are supported by your system's OpenGL driver. + + \section1 Overview + + To be able to compare the results of painting onto a QGLWidget subclass + with native drawing in a QWidget subclass, we want to show both kinds + of widget side by side. To do this, we derive subclasses of QWidget and + QGLWidget, using a separate \c Helper class to perform the same painting + operations for each, and lay them out in a top-level widget, itself + provided a the \c Window class. + + \section1 Helper Class Definition + + In this example, the painting operations are performed by a helper class. + We do this because we want the same painting operations to be performed + for both our QWidget subclass and the QGLWidget subclass. + + The \c Helper class is minimal: + + \snippet 2dpainting/helper.h 0 + + Apart from the constructor, it only provides a \c paint() function to paint + using a painter supplied by one of our widget subclasses. + + \section1 Helper Class Implementation + + The constructor of the class sets up the resources it needs to paint + content onto a widget: + + \snippet 2dpainting/helper.cpp 0 + + The actual painting is performed in the \c paint() function. This takes + a QPainter that has already been set up to paint onto a paint device + (either a QWidget or a QGLWidget), a QPaintEvent that provides information + about the region to be painted, and a measure of the elapsed time (in + milliseconds) since the paint device was last updated. + + \snippet 2dpainting/helper.cpp 1 + + We begin painting by filling in the region contained in the paint event + before translating the origin of the coordinate system so that the rest + of the painting operations will be displaced towards the center of the + paint device. + + We draw a spiral pattern of circles, using the elapsed time specified to + animate them so that they appear to move outward and around the coordinate + system's origin: + + \snippet 2dpainting/helper.cpp 2 + + Since the coordinate system is rotated many times during + this process, we \l{QPainter::save()}{save()} the QPainter's state + beforehand and \l{QPainter::restore()}{restore()} it afterwards. + + \snippet 2dpainting/helper.cpp 3 + + We draw some text at the origin to complete the effect. + + \section1 Widget Class Definition + + The \c Widget class provides a basic custom widget that we use to + display the simple animation painted by the \c Helper class. + + \snippet 2dpainting/widget.h 0 + + Apart from the constructor, it only contains a + \l{QWidget::paintEvent()}{paintEvent()} function, that lets us draw + customized content, and a slot that is used to animate its contents. + One member variable keeps track of the \c Helper that the widget uses + to paint its contents, and the other records the elapsed time since + it was last updated. + + \section1 Widget Class Implementation + + The constructor only initializes the member variables, storing the + \c Helper object supplied and calling the base class's constructor, + and enforces a fixed size for the widget: + + \snippet 2dpainting/widget.cpp 0 + + The \c animate() slot is called whenever a timer, which we define later, times + out: + + \snippet 2dpainting/widget.cpp 1 + + Here, we determine the interval that has elapsed since the timer last + timed out, and we add it to any existing value before repainting the + widget. Since the animation used in the \c Helper class loops every second, + we can use the modulo operator to ensure that the \c elapsed variable is + always less than 1000. + + Since the \c Helper class does all of the actual painting, we only have + to implement a paint event that sets up a QPainter for the widget and calls + the helper's \c paint() function: + + \snippet 2dpainting/widget.cpp 2 + + \section1 GLWidget Class Definition + + The \c GLWidget class definition is basically the same as the \c Widget + class except that it is derived from QGLWidget. + + \snippet 2dpainting/glwidget.h 0 + + Again, the member variables record the \c Helper used to paint the + widget and the elapsed time since the previous update. + + \section1 GLWidget Class Implementation + + The constructor differs a little from the \c Widget class's constructor: + + \snippet 2dpainting/glwidget.cpp 0 + + As well as initializing the \c elapsed member variable and storing the + \c Helper object used to paint the widget, the base class's constructor + is called with the format that specifies the \l QGL::SampleBuffers flag. + This enables anti-aliasing if it is supported by your system's OpenGL + driver. + + The \c animate() slot is exactly the same as that provided by the \c Widget + class: + + \snippet 2dpainting/glwidget.cpp 1 + + The \c paintEvent() is almost the same as that found in the \c Widget class: + + \snippet 2dpainting/glwidget.cpp 2 + + Since anti-aliasing will be enabled if available, we only need to set up + a QPainter on the widget and call the helper's \c paint() function to display + the widget's contents. + + \section1 Window Class Definition + + The \c Window class has a basic, minimal definition: + + \snippet 2dpainting/window.h 0 + + It contains a single \c Helper object that will be shared between all + widgets. + + \section1 Window Class Implementation + + The constructor does all the work, creating a widget of each type and + inserting them with labels into a layout: + + \snippet 2dpainting/window.cpp 0 + + A timer with a 50 millisecond time out is constructed for animation purposes, + and connected to the \c animate() slots of the \c Widget and \c GLWidget objects. + Once started, the widgets should be updated at around 20 frames per second. + + \section1 Running the Example + + The example shows the same painting operations performed at the same time + in a \c Widget and a \c GLWidget. The quality and speed of rendering in the + \c GLWidget depends on the level of support for multisampling and hardware + acceleration that your system's OpenGL driver provides. If support for either + of these is lacking, the driver may fall back on a software renderer that + may trade quality for speed. +*/ diff --git a/examples/opengl/doc/src/cube.qdoc b/examples/opengl/doc/src/cube.qdoc new file mode 100644 index 0000000000..578c0c9ef9 --- /dev/null +++ b/examples/opengl/doc/src/cube.qdoc @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example cube + \group all-examples + \title Cube OpenGL ES 2.0 example + + The Cube OpenGL ES 2.0 example shows how to write mouse rotateable + textured 3D cube using OpenGL ES 2.0 with Qt. It shows how to handle + polygon geometries efficiently and how to write simple vertex and + fragment shader for programmable graphics pipeline. In addition it + shows how to use quaternions for representing 3D object orientation. + + This example has been written for OpenGL ES 2.0 but it works also on + desktop OpenGL because this example is simple enough and for the + most parts desktop OpenGL API is same. It compiles also without OpenGL + support but then it just shows a label stating that OpenGL support is + required. + + \image cube.png Screenshot of the Cube example running on N900 + + The example consist of two classes: + + \list + \li \c MainWidget extends QGLWidget and contains OpenGL ES 2.0 + initialization and drawing and mouse and timer event handling + \li \c GeometryEngine handles polygon geometries. Transfers polygon geometry + to vertex buffer objects and draws geometries from vertex buffer objects. + \endlist + + We'll start by initializing OpenGL ES 2.0 in \c MainWidget. + + \tableofcontents + + \section1 Initializing OpenGL ES 2.0 + + Since OpenGL ES 2.0 doesn't support fixed graphics pipeline anymore it has to + be implemented by ourselves. This makes graphics pipeline very flexible but + in the same time it becomes more difficult because user has to implement graphics + pipeline to get even the simplest example running. It also makes graphics pipeline + more efficient because user can decide what kind of pipeline is needed for the + application. + + First we have to implement vertex shader. It gets vertex data and + model-view-projection matrix (MVP) as parameters. It transforms vertex position + using MVP matrix to screen space and passes texture coordinate to + fragment shader. Texture coordinate will be automatically interpolated on polygon + faces. + + \snippet cube/vshader.glsl 0 + + After that we need to implement second part of the graphics pipeline - fragment + shader. For this exercise we need to implement fragment shader that handles + texturing. It gets interpolated texture coordinate as a parameter and looks up + fragment color from the given texture. + + \snippet cube/fshader.glsl 0 + + Using \c QGLShaderProgram we can compile, link and bind shader code to + graphics pipeline. This code uses Qt Resource files to access shader source code. + + \snippet cube/mainwidget.cpp 3 + + The following code enables depth buffering and back face culling. + + \snippet cube/mainwidget.cpp 2 + + \section1 Loading textures from Qt Resource files + + \c QGLWidget interface implements methods for loading textures from QImage to GL + texture memory. We still need to use OpenGL provided functions for specifying + the GL texture unit and configuring texture filtering options. + + \snippet cube/mainwidget.cpp 4 + + \section1 Cube Geometry + + There are many ways to render polygons in OpenGL but the most efficient way is + to use only triangle strip primitives and render vertices from graphics hardware + memory. OpenGL has a mechanism to create buffer objects to this memory area and + transfer vertex data to these buffers. In OpenGL terminology these are referred + as Vertex Buffer Objects (VBO). + + \image cube_faces.png Cube faces and vertices + + This is how cube faces break down to triangles. Vertices are ordered this way + to get vertex ordering correct using triangle strips. OpenGL determines triangle + front and back face based on vertex ordering. By default OpenGL uses + counter-clockwise order for front faces. This information is used by back face + culling which improves rendering performance by not rendering back faces of the + triangles. This way graphics pipeline can omit rendering sides of the triangle that + aren't facing towards screen. + + Creating vertex buffer objects and transferring data to them is quite simple using + OpenGL provided functions. + + \snippet cube/geometryengine.cpp 0 + + \snippet cube/geometryengine.cpp 1 + + Drawing primitives from VBOs and telling programmable graphics pipeline how to + locate vertex data requires few steps. First we need to bind VBOs to be used. + After that we bind shader program attribute names and configure what + kind of data it has in the bound VBO. Finally we'll draw triangle + strip primitives using indices from the other VBO. + + \snippet cube/geometryengine.cpp 2 + + \section1 Perspective projection + + Using \c QMatrix4x4 helper methods it's really easy to calculate perpective + projection matrix. This matrix is used to project vertices to screen space. + + \snippet cube/mainwidget.cpp 5 + + \section1 Orientation of the 3D object + + Quaternions are handy way to represent orientation of the 3D object. Quaternions + involve quite complex mathematics but fortunately all the necessary mathematics + behind quaternions is implemented in \c QQuaternion. That allows us to store + cube orientation in quaternion and rotating cube around given axis is quite + simple. + + The following code calculates rotation axis and angular speed based on mouse events. + + \snippet cube/mainwidget.cpp 0 + + \c QBasicTimer is used to animate scene and update cube orientation. Rotations + can be concatenated simply by multiplying quaternions. + + \snippet cube/mainwidget.cpp 1 + + Model-view matrix is calculated using the quaternion and by moving world by Z axis. + This matrix is multiplied with the projection matrix to get MVP matrix for shader + program. + + \snippet cube/mainwidget.cpp 6 + +*/ diff --git a/examples/opengl/doc/src/framebufferobject2.qdoc b/examples/opengl/doc/src/framebufferobject2.qdoc new file mode 100644 index 0000000000..44b6fc6018 --- /dev/null +++ b/examples/opengl/doc/src/framebufferobject2.qdoc @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example framebufferobject2 + \title Framebuffer Object 2 Example + + The Framebuffer Object 2 example demonstrates how to use the + QGLFramebufferObject class to render into an off-screen buffer and + use the contents as a texture in a QGLWidget. + + \image framebufferobject2-example.png +*/ diff --git a/examples/opengl/doc/src/grabber.qdoc b/examples/opengl/doc/src/grabber.qdoc new file mode 100644 index 0000000000..12e1483c9a --- /dev/null +++ b/examples/opengl/doc/src/grabber.qdoc @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example grabber + \title Grabber Example + + The Grabber examples shows how to retrieve the contents of an OpenGL framebuffer. + + \image grabber-example.png +*/ diff --git a/examples/opengl/doc/src/hellogl.qdoc b/examples/opengl/doc/src/hellogl.qdoc new file mode 100644 index 0000000000..2f866a3642 --- /dev/null +++ b/examples/opengl/doc/src/hellogl.qdoc @@ -0,0 +1,305 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example hellogl + \title Hello GL Example + + The Hello GL example demonstrates the basic use of the OpenGL-related classes + provided with Qt. + + \image hellogl-example.png + + Qt provides the QGLWidget class to enable OpenGL graphics to be rendered within + a standard application user interface. By subclassing this class, and providing + reimplementations of event handler functions, 3D scenes can be displayed on + widgets that can be placed in layouts, connected to other objects using signals + and slots, and manipulated like any other widget. + + \tableofcontents + + \section1 GLWidget Class Definition + + The \c GLWidget class contains some standard public definitions for the + constructor, destructor, \l{QWidget::sizeHint()}{sizeHint()}, and + \l{QWidget::minimumSizeHint()}{minimumSizeHint()} functions: + + \snippet hellogl/glwidget.h 0 + + We use a destructor to ensure that any OpenGL-specific data structures + are deleted when the widget is no longer needed (although in this case nothing + needs cleaning up). + + \snippet hellogl/glwidget.h 1 + + The signals and slots are used to allow other objects to interact with the + 3D scene. + + \snippet hellogl/glwidget.h 2 + + OpenGL initialization, viewport resizing, and painting are handled by + reimplementing the QGLWidget::initializeGL(), QGLWidget::resizeGL(), and + QGLWidget::paintGL() handler functions. To enable the user to interact + directly with the scene using the mouse, we reimplement + QWidget::mousePressEvent() and QWidget::mouseMoveEvent(). + + \snippet hellogl/glwidget.h 3 + + The rest of the class contains utility functions and variables that are + used to construct and hold orientation information for the scene. The + \c logo variable will be used to hold a pointer to the QtLogo object which + contains all the geometry. + + \section1 GLWidget Class Implementation + + In this example, we split the class into groups of functions and describe + them separately. This helps to illustrate the differences between subclasses + of native widgets (such as QWidget and QFrame) and QGLWidget subclasses. + + \section2 Widget Construction and Sizing + + The constructor provides default rotation angles for the scene, sets + the pointer to the QtLogo object to null, and sets up some colors for + later use. + + \snippet hellogl/glwidget.cpp 0 + + We also implement a destructor to release OpenGL-related resources when the + widget is deleted: + + \snippet hellogl/glwidget.cpp 1 + + In this case nothing requires cleaning up. + + We provide size hint functions to ensure that the widget is shown at a + reasonable size: + + \snippet hellogl/glwidget.cpp 2 + \codeline + \snippet hellogl/glwidget.cpp 3 + \snippet hellogl/glwidget.cpp 4 + + The widget provides three slots that enable other components in the + example to change the orientation of the scene: + + \snippet hellogl/glwidget.cpp 5 + + In the above slot, the \c xRot variable is updated only if the new angle + is different to the old one, the \c xRotationChanged() signal is emitted to + allow other components to be updated, and the widget's + \l{QGLWidget::updateGL()}{updateGL()} handler function is called. + + The \c setYRotation() and \c setZRotation() slots perform the same task for + rotations measured by the \c yRot and \c zRot variables. + + \section2 OpenGL Initialization + + The \l{QGLWidget::initializeGL()}{initializeGL()} function is used to + perform useful initialization tasks that are needed to render the 3D scene. + These often involve defining colors and materials, enabling and disabling + certain rendering flags, and setting other properties used to customize the + rendering process. + + \snippet hellogl/glwidget.cpp 6 + + In this example, we reimplement the function to set the background color, + create a QtLogo object instance which will contain all the geometry to + display, and set up the rendering process to use a particular shading model + and rendering flags. + + \section2 Resizing the Viewport + + The \l{QGLWidget::resizeGL()}{resizeGL()} function is used to ensure that + the OpenGL implementation renders the scene onto a viewport that matches the + size of the widget, using the correct transformation from 3D coordinates to + 2D viewport coordinates. + + The function is called whenever the widget's dimensions change, and is + supplied with the new width and height. Here, we define a square viewport + based on the length of the smallest side of the widget to ensure that + the scene is not distorted if the widget has sides of unequal length: + + \snippet hellogl/glwidget.cpp 8 + + A discussion of the projection transformation used is outside the scope of + this example. Please consult the OpenGL reference documentation for an + explanation of projection matrices. + + \section2 Painting the Scene + + The \l{QGLWidget::paintGL()}{paintGL()} function is used to paint the + contents of the scene onto the widget. For widgets that only need to be + decorated with pure OpenGL content, we reimplement QGLWidget::paintGL() + \e instead of reimplementing QWidget::paintEvent(): + + \snippet hellogl/glwidget.cpp 7 + + In this example, we clear the widget using the background color that + we defined in the \l{QGLWidget::initializeGL()}{initializeGL()} function, + set up the frame of reference for the geometry we want to display, and + call the draw method of the QtLogo object to render the scene. + + \section2 Mouse Handling + + Just as in subclasses of native widgets, mouse events are handled by + reimplementing functions such as QWidget::mousePressEvent() and + QWidget::mouseMoveEvent(). + + The \l{QWidget::mousePressEvent()}{mousePressEvent()} function simply + records the position of the mouse when a button is initially pressed: + + \snippet hellogl/glwidget.cpp 9 + + The \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()} function uses the + previous location of the mouse cursor to determine how much the object + in the scene should be rotated, and in which direction: + + \snippet hellogl/glwidget.cpp 10 + + Since the user is expected to hold down the mouse button and drag the + cursor to rotate the object, the cursor's position is updated every time + a move event is received. + + \section1 QtLogo Class + + This class encapsulates the OpenGL geometry data which will be rendered + in the basic 3D scene. + + \snippet shared/qtlogo.h 0 + + The geometry is divided into a list of parts which may be rendered in + different ways. The data itself is contained in a Geometry structure that + includes the vertices, their lighting normals and index values which + point into the vertices, grouping them into faces. + + \snippet shared/qtlogo.cpp 0 + + The data in the Geometry class is stored in QVector<QVector3D> members + which are convenient for use with OpenGL because they expose raw + contiguous floating point values via the constData() method. Methods + are included for adding new vertex data, either with smooth normals, or + facetted normals; and for enabling the geometry ready for rendering. + + \snippet shared/qtlogo.cpp 1 + + The higher level Patch class has methods for accumulating the geometry + one face at a time, and treating collections of faces or "patches" with + transformations, applying different colors or smoothing. Although faces + may be added as triangles or quads, at the OpenGL level all data is + treated as triangles for compatibility with OpenGL/ES. + + \snippet shared/qtlogo.cpp 2 + + Drawing a Patch is simply acheived by applying any transformation, + and material effect, then drawing the data using the index range for + the patch. The model-view matrix is saved and then restored so that + any transformation does not affect other parts of the scene. + + \snippet shared/qtlogo.cpp 3 + + The geometry is built once on construction of the QtLogo, and it is + paramaterized on a number of divisions - which controls how "chunky" the + curved section of the logo looks - and on a scale, so larger and smaller + QtLogo objects can be created without having to use OpenGL scaling + (which would force normal recalculation). + + The building process is done by helper classes (read the source for full + details) which only exist during the build phase, to assemble the parts + of the scene. + + \snippet shared/qtlogo.cpp 4 + + Finally the complete QtLogo scene is simply drawn by enabling the data arrays + and then iterating over the parts, calling draw() on each one. + + \section1 Window Class Definition + + The \c Window class is used as a container for the \c GLWidget used to + display the scene: + + \snippet hellogl/window.h 0 + + In addition, it contains sliders that are used to change the orientation + of the object in the scene. + + \section1 Window Class Implementation + + The constructor constructs an instance of the \c GLWidget class and some + sliders to manipulate its contents. + + \snippet hellogl/window.cpp 0 + + We connect the \l{QAbstractSlider::valueChanged()}{valueChanged()} signal + from each of the sliders to the appropriate slots in \c{glWidget}. + This allows the user to change the orientation of the object by dragging + the sliders. + + We also connect the \c xRotationChanged(), \c yRotationChanged(), and + \c zRotationChanged() signals from \c glWidget to the + \l{QAbstractSlider::setValue()}{setValue()} slots in the + corresponding sliders. + + \snippet hellogl/window.cpp 1 + + The sliders are placed horizontally in a layout alongside the \c GLWidget, + and initialized with suitable default values. + + The \c createSlider() utility function constructs a QSlider, and ensures + that it is set up with a suitable range, step value, tick interval, and + page step value before returning it to the calling function: + + \snippet hellogl/window.cpp 2 + + \section1 Summary + + The \c GLWidget class implementation shows how to subclass QGLWidget for + the purposes of rendering a 3D scene using OpenGL calls. Since QGLWidget + is a subclass of QWidget, subclasses of QGLWidget can be placed in layouts + and provided with interactive features just like normal custom widgets. + + We ensure that the widget is able to correctly render the scene using OpenGL + by reimplementing the following functions: + + \list + \li QGLWidget::initializeGL() sets up resources needed by the OpenGL implementation + to render the scene. + \li QGLWidget::resizeGL() resizes the viewport so that the rendered scene fits onto + the widget, and sets up a projection matrix to map 3D coordinates to 2D viewport + coordinates. + \li QGLWidget::paintGL() performs painting operations using OpenGL calls. + \endlist + + Since QGLWidget is a subclass of QWidget, it can also be used + as a normal paint device, allowing 2D graphics to be drawn with QPainter. + This use of QGLWidget is discussed in the \l{2D Painting Example}{2D Painting} + example. + + More advanced users may want to paint over parts of a scene rendered using + OpenGL. QGLWidget allows pure OpenGL rendering to be mixed with QPainter + calls, but care must be taken to maintain the state of the OpenGL implementation. + See the \l{Overpainting Example}{Overpainting} example for more information. +*/ diff --git a/examples/opengl/doc/src/hellogl_es.qdoc b/examples/opengl/doc/src/hellogl_es.qdoc new file mode 100644 index 0000000000..8764eda4d6 --- /dev/null +++ b/examples/opengl/doc/src/hellogl_es.qdoc @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example 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 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 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 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 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 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 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 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 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 hellogl_es/glwidget.cpp 5 + + Now we use the QPainter to draw the transparent bubbles. + + \snippet hellogl_es/glwidget.cpp 6 + + In the end, we calculate the framerate and display it using the QPainter + again. + + \snippet hellogl_es/glwidget.cpp 7 + + After we finished all the drawing operations we swap the screen buffer. + + \snippet 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. +*/ diff --git a/examples/opengl/doc/src/overpainting.qdoc b/examples/opengl/doc/src/overpainting.qdoc new file mode 100644 index 0000000000..e24af4c3ca --- /dev/null +++ b/examples/opengl/doc/src/overpainting.qdoc @@ -0,0 +1,243 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example overpainting + \title Overpainting Example + + The Overpainting example shows how QPainter can be used + to overpaint a scene rendered using OpenGL in a QGLWidget. + + \image overpainting-example.png + + QGLWidget provides a widget with integrated OpenGL graphics support + that enables 3D graphics to be displayed using normal OpenGL calls, + yet also behaves like any other standard Qt widget with support for + signals and slots, properties, and Qt's action system. + + Usually, QGLWidget is subclassed to display a pure 3D scene. The + developer reimplements \l{QGLWidget::initializeGL()}{initializeGL()} + to initialize any required resources, \l{QGLWidget::resizeGL()}{resizeGL()} + to set up the projection and viewport, and + \l{QGLWidget::paintGL()}{paintGL()} to perform the OpenGL calls needed + to render the scene. However, it is possible to subclass QGLWidget + differently to allow 2D graphics, drawn using QPainter, to be + painted over a scene rendered using OpenGL. + + In this example, we demonstrate how this is done by reusing the code + from the \l{Hello GL Example}{Hello GL} example to provide a 3D scene, + and painting over it with some translucent 2D graphics. Instead of + examining each class in detail, we only cover the parts of the + \c GLWidget class that enable overpainting, and provide more detailed + discussion in the final section of this document. + + \section1 GLWidget Class Definition + + The \c GLWidget class is a subclass of QGLWidget, based on the one used + in the \l{Hello GL Example}{Hello GL} example. Rather than describe the + class as a whole, we show the first few lines of the class and only + discuss the changes we have made to the rest of it: + + \snippet overpainting/glwidget.h 0 + \dots + \snippet overpainting/glwidget.h 1 + \dots + \snippet overpainting/glwidget.h 4 + + As usual, the widget uses \l{QGLWidget::initializeGL()}{initializeGL()} + to set up geometry for our scene and perform OpenGL initialization tasks. + The \l{QGLWidget::resizeGL()}{resizeGL()} function is used to ensure that + the 3D graphics in the scene are transformed correctly to the 2D viewport + displayed in the widget. + + Instead of implementing \l{QGLWidget::paintGL()}{paintGL()} to handle updates + to the widget, we implement a normal QWidget::paintEvent(). This + allows us to mix OpenGL calls and QPainter operations in a controlled way. + + In this example, we also implement QWidget::showEvent() to help with the + initialization of the 2D graphics used. + + The new private member functions and variables relate exclusively to the + 2D graphics and animation. The \c animate() slot is called periodically by the + \c animationTimer to update the widget; the \c createBubbles() function + initializes the \c bubbles list with instances of a helper class used to + draw the animation; the \c drawInstructions() function is responsible for + a semi-transparent message that is also overpainted onto the OpenGL scene. + + \section1 GLWidget Class Implementation + + Again, we only show the parts of the \c GLWidget implementation that are + relevant to this example. In the constructor, we initialize a QTimer to + control the animation: + + \snippet overpainting/glwidget.cpp 0 + + We turn off the widget's \l{QWidget::autoFillBackground}{autoFillBackground} property to + instruct OpenGL not to paint a background for the widget when + \l{QPainter::begin()}{QPainter::begin()} is called. + + As in the \l{Hello GL Example}{Hello GL} example, the destructor is responsible + for freeing any OpenGL-related resources: + + \snippet overpainting/glwidget.cpp 1 + + The \c initializeGL() function is fairly minimal, only setting up the QtLogo + object used in the scene. See the \l{Hello GL Example}{Hello GL} example + for details of the QtLogo class. + + \snippet overpainting/glwidget.cpp 2 + + To cooperate fully with QPainter, we defer matrix stack operations and attribute + initialization until the widget needs to be updated. + + In this example, we implement \l{QWidget::paintEvent()}{paintEvent()} rather + than \l{QGLWidget::paintGL()}{paintGL()} to render + our scene. When drawing on a QGLWidget, the paint engine used by QPainter + performs certain operations that change the states of the OpenGL + implementation's matrix and property stacks. Therefore, it is necessary to + make all the OpenGL calls to display the 3D graphics before we construct + a QPainter to draw the 2D overlay. + + We render a 3D scene by setting up model and projection transformations + and other attributes. We use an OpenGL stack operation to preserve the + original matrix state, allowing us to recover it later: + + \snippet overpainting/glwidget.cpp 4 + + We define a color to use for the widget's background, and set up various + attributes that define how the scene will be rendered. + + \snippet overpainting/glwidget.cpp 6 + + We call the \c setupViewport() private function to set up the + projection used for the scene. This is unnecessary in OpenGL + examples that implement the \l{QGLWidget::paintGL()}{paintGL()} + function because the matrix stacks are usually unmodified between + calls to \l{QGLWidget::resizeGL()}{resizeGL()} and + \l{QGLWidget::paintGL()}{paintGL()}. + + Since the widget's background is not drawn by the system or by Qt, we use + an OpenGL call to paint it before positioning the object defined earlier + in the scene: + + \snippet overpainting/glwidget.cpp 7 + + Once the QtLogo object's draw method has been executed, the GL + states we changed and the matrix stack needs to be restored to its + original state at the start of this function before we can begin + overpainting: + + \snippet overpainting/glwidget.cpp 8 + + With the 3D graphics done, we construct a QPainter for use on the widget + and simply overpaint the widget with 2D graphics; in this case, using a + helper class to draw a number of translucent bubbles onto the widget, + and calling \c drawInstructions() to overlay some instructions: + + \snippet overpainting/glwidget.cpp 10 + + When QPainter::end() is called, suitable OpenGL-specific calls are made to + write the scene, and its additional contents, onto the widget. + + With \l{QGLWidget::paintGL()}{paintGL()} the + \l{QGLWidget::swapBuffers()}{swapBuffers()} call is done for us. But an explicit + call to swapBuffers() is still not required because in the + \l{QWidget::paintEvent()}{paintEvent()} method the QPainter on the OpenGL + widget takes care of this for us. + + The implementation of the \l{QGLWidget::resizeGL()}{resizeGL()} function + sets up the dimensions of the viewport and defines a projection + transformation: + + \snippet overpainting/glwidget.cpp 11 + + Ideally, we want to arrange the 2D graphics to suit the widget's dimensions. + To achieve this, we implement the \l{QWidget::showEvent()}{showEvent()} handler, + creating new graphic elements (bubbles) if necessary at appropriate positions + in the widget. + + \snippet overpainting/glwidget.cpp 12 + + This function only has an effect if less than 20 bubbles have already been + created. + + The \c animate() slot is called every time the widget's \c animationTimer emits + the \l{QTimer::timeout()}{timeout()} signal. This keeps the bubbles moving + around. + + \snippet overpainting/glwidget.cpp 13 + + We simply iterate over the bubbles in the \c bubbles list, updating the + widget before and after each of them is moved. + + The \c setupViewport() function is called from \c paintEvent() + and \c resizeGL(). + + \snippet overpainting/glwidget.cpp 14 + + The \c drawInstructions() function is used to prepare some basic + instructions that will be painted with the other 2D graphics over + the 3D scene. + + \snippet overpainting/glwidget.cpp 15 + + \section1 Summary + + When overpainting 2D content onto 3D content, we need to use a QPainter + \e and make OpenGL calls to achieve the desired effect. Since QPainter + itself uses OpenGL calls when used on a QGLWidget subclass, we need to + preserve the state of various OpenGL stacks when we perform our own + calls, using the following approach: + + \list + \li Reimplement QGLWidget::initializeGL(), but only perform minimal + initialization. QPainter will perform its own initialization + routines, modifying the matrix and property stacks, so it is better + to defer certain initialization tasks until just before you render + the 3D scene. + \li Reimplement QGLWidget::resizeGL() as in the pure 3D case. + \li Reimplement QWidget::paintEvent() to draw both 2D and 3D graphics. + \endlist + + The \l{QWidget::paintEvent()}{paintEvent()} implementation performs the + following tasks: + + \list + \li Push the current OpenGL modelview matrix onto a stack. + \li Perform initialization tasks usually done in the + \l{QGLWidget::initializeGL()}{initializeGL()} function. + \li Perform code that would normally be located in the widget's + \l{QGLWidget::resizeGL()}{resizeGL()} function to set the correct + perspective transformation and set up the viewport. + \li Render the scene using OpenGL calls. + \li Pop the OpenGL modelview matrix off the stack. + \li Construct a QPainter object. + \li Initialize it for use on the widget with the QPainter::begin() function. + \li Draw primitives using QPainter's member functions. + \li Call QPainter::end() to finish painting. + \endlist +*/ diff --git a/examples/opengl/doc/src/pbuffers.qdoc b/examples/opengl/doc/src/pbuffers.qdoc new file mode 100644 index 0000000000..baa657e14e --- /dev/null +++ b/examples/opengl/doc/src/pbuffers.qdoc @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example pbuffers + \title Pixel Buffers Example + + The Pixel Buffers example demonstrates how to use the + QGLPixelBuffer class to render into an off-screen buffer and use + the contents as a dynamic texture in a QGLWidget. + + \image pbuffers-example.png +*/ diff --git a/examples/opengl/doc/src/pbuffers2.qdoc b/examples/opengl/doc/src/pbuffers2.qdoc new file mode 100644 index 0000000000..efa53b06cc --- /dev/null +++ b/examples/opengl/doc/src/pbuffers2.qdoc @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example pbuffers2 + \title Pixel Buffers 2 Example + + The Pixel Buffers 2 example demonstrates how to use the + QGLPixelBuffer class to render into an off-screen buffer and use + the contents as a dynamic texture in a QGLWidget. + + \image pbuffers2-example.png +*/ diff --git a/examples/opengl/doc/src/samplebuffers.qdoc b/examples/opengl/doc/src/samplebuffers.qdoc new file mode 100644 index 0000000000..93d8b54b4a --- /dev/null +++ b/examples/opengl/doc/src/samplebuffers.qdoc @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example samplebuffers + \title Sample Buffers Example + + The Sample Buffers example demonstrates how to use and enable + sample buffers in a QGLWidget. + + \image samplebuffers-example.png +*/ diff --git a/examples/opengl/doc/src/textures.qdoc b/examples/opengl/doc/src/textures.qdoc new file mode 100644 index 0000000000..b7e694239d --- /dev/null +++ b/examples/opengl/doc/src/textures.qdoc @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example textures + \title Textures Example + + The Textures example demonstrates the use of Qt's image classes as textures in + applications that use both OpenGL and Qt to display graphics. + + \image textures-example.png +*/ |