doc/src/examples/2dpainting.qdoc
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     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
       
    14 ** this package.
       
    15 **
       
    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.
       
    23 **
       
    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.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*!
       
    43     \example opengl/2dpainting
       
    44     \title 2D Painting Example
       
    45 
       
    46     The 2D Painting example shows how QPainter and QGLWidget can be used
       
    47     together to display accelerated 2D graphics on supported hardware.
       
    48 
       
    49     \image 2dpainting-example.png
       
    50 
       
    51     The QPainter class is used to draw 2D graphics primitives onto
       
    52     paint devices provided by QPaintDevice subclasses, such as QWidget
       
    53     and QImage.
       
    54 
       
    55     Since QGLWidget is a subclass of QWidget, it is possible
       
    56     to reimplement its \l{QWidget::paintEvent()}{paintEvent()} and use
       
    57     QPainter to draw on the device, just as you would with a QWidget.
       
    58     The only difference is that the painting operations will be accelerated
       
    59     in hardware if it is supported by your system's OpenGL drivers.
       
    60 
       
    61     In this example, we perform the same painting operations on a
       
    62     QWidget and a QGLWidget. The QWidget is shown with anti-aliasing
       
    63     enabled, and the QGLWidget will also use anti-aliasing if the
       
    64     required extensions are supported by your system's OpenGL driver.
       
    65 
       
    66     \section1 Overview
       
    67 
       
    68     To be able to compare the results of painting onto a QGLWidget subclass
       
    69     with native drawing in a QWidget subclass, we want to show both kinds
       
    70     of widget side by side. To do this, we derive subclasses of QWidget and
       
    71     QGLWidget, using a separate \c Helper class to perform the same painting
       
    72     operations for each, and lay them out in a top-level widget, itself
       
    73     provided a the \c Window class.
       
    74 
       
    75     \section1 Helper Class Definition
       
    76 
       
    77     In this example, the painting operations are performed by a helper class.
       
    78     We do this because we want the same painting operations to be performed
       
    79     for both our QWidget subclass and the QGLWidget subclass.
       
    80 
       
    81     The \c Helper class is minimal:
       
    82 
       
    83     \snippet examples/opengl/2dpainting/helper.h 0
       
    84 
       
    85     Apart from the constructor, it only provides a \c paint() function to paint
       
    86     using a painter supplied by one of our widget subclasses.
       
    87 
       
    88     \section1 Helper Class Implementation
       
    89 
       
    90     The constructor of the class sets up the resources it needs to paint
       
    91     content onto a widget:
       
    92 
       
    93     \snippet examples/opengl/2dpainting/helper.cpp 0
       
    94 
       
    95     The actual painting is performed in the \c paint() function. This takes
       
    96     a QPainter that has already been set up to paint onto a paint device
       
    97     (either a QWidget or a QGLWidget), a QPaintEvent that provides information
       
    98     about the region to be painted, and a measure of the elapsed time (in
       
    99     milliseconds) since the paint device was last updated.
       
   100 
       
   101     \snippet examples/opengl/2dpainting/helper.cpp 1
       
   102 
       
   103     We begin painting by filling in the region contained in the paint event
       
   104     before translating the origin of the coordinate system so that the rest
       
   105     of the painting operations will be displaced towards the center of the
       
   106     paint device.
       
   107 
       
   108     We draw a spiral pattern of circles, using the elapsed time specified to
       
   109     animate them so that they appear to move outward and around the coordinate
       
   110     system's origin:
       
   111 
       
   112     \snippet examples/opengl/2dpainting/helper.cpp 2
       
   113 
       
   114     Since the coordinate system is rotated many times during
       
   115     this process, we \l{QPainter::save()}{save()} the QPainter's state
       
   116     beforehand and \l{QPainter::restore()}{restore()} it afterwards.
       
   117 
       
   118     \snippet examples/opengl/2dpainting/helper.cpp 3
       
   119 
       
   120     We draw some text at the origin to complete the effect.
       
   121 
       
   122     \section1 Widget Class Definition
       
   123 
       
   124     The \c Widget class provides a basic custom widget that we use to
       
   125     display the simple animation painted by the \c Helper class.
       
   126 
       
   127     \snippet examples/opengl/2dpainting/widget.h 0
       
   128 
       
   129     Apart from the constructor, it only contains a
       
   130     \l{QWidget::paintEvent()}{paintEvent()} function, that lets us draw
       
   131     customized content, and a slot that is used to animate its contents.
       
   132     One member variable keeps track of the \c Helper that the widget uses
       
   133     to paint its contents, and the other records the elapsed time since
       
   134     it was last updated.
       
   135 
       
   136     \section1 Widget Class Implementation
       
   137 
       
   138     The constructor only initializes the member variables, storing the
       
   139     \c Helper object supplied and calling the base class's constructor,
       
   140     and enforces a fixed size for the widget:
       
   141 
       
   142     \snippet examples/opengl/2dpainting/widget.cpp 0
       
   143 
       
   144     The \c animate() slot is called whenever a timer, which we define later, times
       
   145     out:
       
   146 
       
   147     \snippet examples/opengl/2dpainting/widget.cpp 1
       
   148 
       
   149     Here, we determine the interval that has elapsed since the timer last
       
   150     timed out, and we add it to any existing value before repainting the
       
   151     widget. Since the animation used in the \c Helper class loops every second,
       
   152     we can use the modulo operator to ensure that the \c elapsed variable is
       
   153     always less than 1000.
       
   154 
       
   155     Since the \c Helper class does all of the actual painting, we only have
       
   156     to implement a paint event that sets up a QPainter for the widget and calls
       
   157     the helper's \c paint() function:
       
   158 
       
   159     \snippet examples/opengl/2dpainting/widget.cpp 2
       
   160 
       
   161     \section1 GLWidget Class Definition
       
   162 
       
   163     The \c GLWidget class definition is basically the same as the \c Widget
       
   164     class except that it is derived from QGLWidget.
       
   165 
       
   166     \snippet examples/opengl/2dpainting/glwidget.h 0
       
   167 
       
   168     Again, the member variables record the \c Helper used to paint the
       
   169     widget and the elapsed time since the previous update.
       
   170 
       
   171     \section1 GLWidget Class Implementation
       
   172 
       
   173     The constructor differs a little from the \c Widget class's constructor:
       
   174 
       
   175     \snippet examples/opengl/2dpainting/glwidget.cpp 0
       
   176 
       
   177     As well as initializing the \c elapsed member variable and storing the
       
   178     \c Helper object used to paint the widget, the base class's constructor
       
   179     is called with the format that specifies the \l QGL::SampleBuffers flag.
       
   180     This enables anti-aliasing if it is supported by your system's OpenGL
       
   181     driver.
       
   182 
       
   183     The \c animate() slot is exactly the same as that provided by the \c Widget
       
   184     class:
       
   185 
       
   186     \snippet examples/opengl/2dpainting/glwidget.cpp 1
       
   187 
       
   188     The \c paintEvent() is almost the same as that found in the \c Widget class:
       
   189 
       
   190     \snippet examples/opengl/2dpainting/glwidget.cpp 2
       
   191 
       
   192     Since anti-aliasing will be enabled if available, we only need to set up
       
   193     a QPainter on the widget and call the helper's \c paint() function to display
       
   194     the widget's contents.
       
   195 
       
   196     \section1 Window Class Definition
       
   197 
       
   198     The \c Window class has a basic, minimal definition:
       
   199 
       
   200     \snippet examples/opengl/2dpainting/window.h 0
       
   201 
       
   202     It contains a single \c Helper object that will be shared between all
       
   203     widgets.
       
   204 
       
   205     \section1 Window Class Implementation
       
   206 
       
   207     The constructor does all the work, creating a widget of each type and
       
   208     inserting them with labels into a layout:
       
   209 
       
   210     \snippet examples/opengl/2dpainting/window.cpp 0
       
   211 
       
   212     A timer with a 50 millisecond time out is constructed for animation purposes,
       
   213     and connected to the \c animate() slots of the \c Widget and \c GLWidget objects.
       
   214     Once started, the widgets should be updated at around 20 frames per second.
       
   215 
       
   216     \section1 Running the Example
       
   217 
       
   218     The example shows the same painting operations performed at the same time
       
   219     in a \c Widget and a \c GLWidget. The quality and speed of rendering in the
       
   220     \c GLWidget depends on the level of support for multisampling and hardware
       
   221     acceleration that your system's OpenGL driver provides. If support for either
       
   222     of these is lacking, the driver may fall back on a software renderer that
       
   223     may trade quality for speed.
       
   224 */