diff options
Diffstat (limited to 'doc/src/examples/overpainting.qdoc')
-rw-r--r-- | doc/src/examples/overpainting.qdoc | 243 |
1 files changed, 0 insertions, 243 deletions
diff --git a/doc/src/examples/overpainting.qdoc b/doc/src/examples/overpainting.qdoc deleted file mode 100644 index d20ee64698..0000000000 --- a/doc/src/examples/overpainting.qdoc +++ /dev/null @@ -1,243 +0,0 @@ -/**************************************************************************** -** -** 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 opengl/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 examples/opengl/overpainting/glwidget.h 0 - \dots - \snippet examples/opengl/overpainting/glwidget.h 1 - \dots - \snippet examples/opengl/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 examples/opengl/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 examples/opengl/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 examples/opengl/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 examples/opengl/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 examples/opengl/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 examples/opengl/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 examples/opengl/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 examples/opengl/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 examples/opengl/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 examples/opengl/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 examples/opengl/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 examples/opengl/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 examples/opengl/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 -*/ |