util/demos/composition/composition.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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 demonstration applications 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 #include "composition.h"
       
    43 #include <QBoxLayout>
       
    44 #include <QRadioButton>
       
    45 #include <QTimer>
       
    46 #include <QDateTime>
       
    47 #include <QSlider>
       
    48 #include <QMouseEvent>
       
    49 #include <qmath.h>
       
    50 
       
    51 const int animationInterval = 15; // update every 16 ms = ~60FPS
       
    52 
       
    53 CompositionWidget::CompositionWidget(QWidget *parent)
       
    54     : QWidget(parent)
       
    55 {
       
    56     CompositionRenderer *view = new CompositionRenderer(this);
       
    57 
       
    58     QGroupBox *mainGroup = new QGroupBox(parent);
       
    59     mainGroup->setTitle(tr("Composition Modes"));
       
    60 
       
    61     QGroupBox *modesGroup = new QGroupBox(mainGroup);
       
    62     modesGroup->setTitle(tr("Mode"));
       
    63 
       
    64     rbClear = new QRadioButton(tr("Clear"), modesGroup);
       
    65     connect(rbClear, SIGNAL(clicked()), view, SLOT(setClearMode()));
       
    66     rbSource = new QRadioButton(tr("Source"), modesGroup);
       
    67     connect(rbSource, SIGNAL(clicked()), view, SLOT(setSourceMode()));
       
    68     rbDest = new QRadioButton(tr("Destination"), modesGroup);
       
    69     connect(rbDest, SIGNAL(clicked()), view, SLOT(setDestMode()));
       
    70     rbSourceOver = new QRadioButton(tr("Source Over"), modesGroup);
       
    71     connect(rbSourceOver, SIGNAL(clicked()), view, SLOT(setSourceOverMode()));
       
    72     rbDestOver = new QRadioButton(tr("Destination Over"), modesGroup);
       
    73     connect(rbDestOver, SIGNAL(clicked()), view, SLOT(setDestOverMode()));
       
    74     rbSourceIn = new QRadioButton(tr("Source In"), modesGroup);
       
    75     connect(rbSourceIn, SIGNAL(clicked()), view, SLOT(setSourceInMode()));
       
    76     rbDestIn = new QRadioButton(tr("Dest In"), modesGroup);
       
    77     connect(rbDestIn, SIGNAL(clicked()), view, SLOT(setDestInMode()));
       
    78     rbSourceOut = new QRadioButton(tr("Source Out"), modesGroup);
       
    79     connect(rbSourceOut, SIGNAL(clicked()), view, SLOT(setSourceOutMode()));
       
    80     rbDestOut = new QRadioButton(tr("Dest Out"), modesGroup);
       
    81     connect(rbDestOut, SIGNAL(clicked()), view, SLOT(setDestOutMode()));
       
    82     rbSourceAtop = new QRadioButton(tr("Source Atop"), modesGroup);
       
    83     connect(rbSourceAtop, SIGNAL(clicked()), view, SLOT(setSourceAtopMode()));
       
    84     rbDestAtop = new QRadioButton(tr("Dest Atop"), modesGroup);
       
    85     connect(rbDestAtop, SIGNAL(clicked()), view, SLOT(setDestAtopMode()));
       
    86     rbXor = new QRadioButton(tr("Xor"), modesGroup);
       
    87     connect(rbXor, SIGNAL(clicked()), view, SLOT(setXorMode()));
       
    88 
       
    89     rbPlus = new QRadioButton(tr("Plus"), modesGroup);
       
    90     connect(rbPlus, SIGNAL(clicked()), view, SLOT(setPlusMode()));
       
    91     rbMultiply = new QRadioButton(tr("Multiply"), modesGroup);
       
    92     connect(rbMultiply, SIGNAL(clicked()), view, SLOT(setMultiplyMode()));
       
    93     rbScreen = new QRadioButton(tr("Screen"), modesGroup);
       
    94     connect(rbScreen, SIGNAL(clicked()), view, SLOT(setScreenMode()));
       
    95     rbOverlay = new QRadioButton(tr("Overlay"), modesGroup);
       
    96     connect(rbOverlay, SIGNAL(clicked()), view, SLOT(setOverlayMode()));
       
    97     rbDarken = new QRadioButton(tr("Darken"), modesGroup);
       
    98     connect(rbDarken, SIGNAL(clicked()), view, SLOT(setDarkenMode()));
       
    99     rbLighten = new QRadioButton(tr("Lighten"), modesGroup);
       
   100     connect(rbLighten, SIGNAL(clicked()), view, SLOT(setLightenMode()));
       
   101     rbColorDodge = new QRadioButton(tr("Color Dodge"), modesGroup);
       
   102     connect(rbColorDodge, SIGNAL(clicked()), view, SLOT(setColorDodgeMode()));
       
   103     rbColorBurn = new QRadioButton(tr("Color Burn"), modesGroup);
       
   104     connect(rbColorBurn, SIGNAL(clicked()), view, SLOT(setColorBurnMode()));
       
   105     rbHardLight = new QRadioButton(tr("Hard Light"), modesGroup);
       
   106     connect(rbHardLight, SIGNAL(clicked()), view, SLOT(setHardLightMode()));
       
   107     rbSoftLight = new QRadioButton(tr("Soft Light"), modesGroup);
       
   108     connect(rbSoftLight, SIGNAL(clicked()), view, SLOT(setSoftLightMode()));
       
   109     rbDifference = new QRadioButton(tr("Difference"), modesGroup);
       
   110     connect(rbDifference, SIGNAL(clicked()), view, SLOT(setDifferenceMode()));
       
   111     rbExclusion = new QRadioButton(tr("Exclusion"), modesGroup);
       
   112     connect(rbExclusion, SIGNAL(clicked()), view, SLOT(setExclusionMode()));
       
   113 
       
   114     QGroupBox *circleColorGroup = new QGroupBox(mainGroup);
       
   115     circleColorGroup->setTitle(tr("Circle color"));
       
   116     QSlider *circleColorSlider = new QSlider(Qt::Horizontal, circleColorGroup);
       
   117     circleColorSlider->setRange(0, 359);
       
   118     circleColorSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
       
   119     connect(circleColorSlider, SIGNAL(valueChanged(int)), view, SLOT(setCircleColor(int)));
       
   120 
       
   121     QGroupBox *circleAlphaGroup = new QGroupBox(mainGroup);
       
   122     circleAlphaGroup->setTitle(tr("Circle alpha"));
       
   123     QSlider *circleAlphaSlider = new QSlider(Qt::Horizontal, circleAlphaGroup);
       
   124     circleAlphaSlider->setRange(0, 255);
       
   125     circleAlphaSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
       
   126     connect(circleAlphaSlider, SIGNAL(valueChanged(int)), view, SLOT(setCircleAlpha(int)));
       
   127 
       
   128     QPushButton *showSourceButton = new QPushButton(mainGroup);
       
   129     showSourceButton->setText(tr("Show Source"));
       
   130 #if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
       
   131     QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
       
   132     enableOpenGLButton->setText(tr("Use OpenGL"));
       
   133     enableOpenGLButton->setCheckable(true);
       
   134     enableOpenGLButton->setChecked(view->usesOpenGL());
       
   135 
       
   136     if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers())
       
   137         enableOpenGLButton->hide();
       
   138 #endif
       
   139     QPushButton *whatsThisButton = new QPushButton(mainGroup);
       
   140     whatsThisButton->setText(tr("What's This?"));
       
   141     whatsThisButton->setCheckable(true);
       
   142 
       
   143     QPushButton *animateButton = new QPushButton(mainGroup);
       
   144     animateButton->setText(tr("Animated"));
       
   145     animateButton->setCheckable(true);
       
   146     animateButton->setChecked(true);
       
   147 
       
   148     QHBoxLayout *viewLayout = new QHBoxLayout(this);
       
   149     viewLayout->addWidget(view);
       
   150     viewLayout->addWidget(mainGroup);
       
   151 
       
   152     QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
       
   153     mainGroupLayout->addWidget(circleColorGroup);
       
   154     mainGroupLayout->addWidget(circleAlphaGroup);
       
   155     mainGroupLayout->addWidget(modesGroup);
       
   156     mainGroupLayout->addStretch();
       
   157     mainGroupLayout->addWidget(animateButton);
       
   158     mainGroupLayout->addWidget(whatsThisButton);
       
   159     mainGroupLayout->addWidget(showSourceButton);
       
   160 #if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
       
   161     mainGroupLayout->addWidget(enableOpenGLButton);
       
   162 #endif
       
   163 
       
   164     QGridLayout *modesLayout = new QGridLayout(modesGroup);
       
   165     modesLayout->addWidget(rbClear,             0,      0);
       
   166     modesLayout->addWidget(rbSource,            1,      0);
       
   167     modesLayout->addWidget(rbDest,              2,      0);
       
   168     modesLayout->addWidget(rbSourceOver,        3,      0);
       
   169     modesLayout->addWidget(rbDestOver,          4,      0);
       
   170     modesLayout->addWidget(rbSourceIn,          5,      0);
       
   171     modesLayout->addWidget(rbDestIn,            6,      0);
       
   172     modesLayout->addWidget(rbSourceOut,         7,      0);
       
   173     modesLayout->addWidget(rbDestOut,           8,      0);
       
   174     modesLayout->addWidget(rbSourceAtop,        9,      0);
       
   175     modesLayout->addWidget(rbDestAtop,         10,      0);
       
   176     modesLayout->addWidget(rbXor,              11,      0);
       
   177 
       
   178     modesLayout->addWidget(rbPlus,              0,      1);
       
   179     modesLayout->addWidget(rbMultiply,          1,      1);
       
   180     modesLayout->addWidget(rbScreen,            2,      1);
       
   181     modesLayout->addWidget(rbOverlay,           3,      1);
       
   182     modesLayout->addWidget(rbDarken,            4,      1);
       
   183     modesLayout->addWidget(rbLighten,           5,      1);
       
   184     modesLayout->addWidget(rbColorDodge,        6,      1);
       
   185     modesLayout->addWidget(rbColorBurn,         7,      1);
       
   186     modesLayout->addWidget(rbHardLight,         8,      1);
       
   187     modesLayout->addWidget(rbSoftLight,         9,      1);
       
   188     modesLayout->addWidget(rbDifference,       10,      1);
       
   189     modesLayout->addWidget(rbExclusion,        11,      1);
       
   190 
       
   191 
       
   192     QVBoxLayout *circleColorLayout = new QVBoxLayout(circleColorGroup);
       
   193     circleColorLayout->addWidget(circleColorSlider);
       
   194 
       
   195     QVBoxLayout *circleAlphaLayout = new QVBoxLayout(circleAlphaGroup);
       
   196     circleAlphaLayout->addWidget(circleAlphaSlider);
       
   197 
       
   198     view->loadDescription(":res/composition/composition.html");
       
   199     view->loadSourceFile(":res/composition/composition.cpp");
       
   200 
       
   201     connect(whatsThisButton, SIGNAL(clicked(bool)), view, SLOT(setDescriptionEnabled(bool)));
       
   202     connect(view, SIGNAL(descriptionEnabledChanged(bool)), whatsThisButton, SLOT(setChecked(bool)));
       
   203     connect(showSourceButton, SIGNAL(clicked()), view, SLOT(showSource()));
       
   204 #if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
       
   205     connect(enableOpenGLButton, SIGNAL(clicked(bool)), view, SLOT(enableOpenGL(bool)));
       
   206 #endif
       
   207     connect(animateButton, SIGNAL(toggled(bool)), view, SLOT(setAnimationEnabled(bool)));
       
   208 
       
   209     circleColorSlider->setValue(270);
       
   210     circleAlphaSlider->setValue(200);
       
   211     rbSourceOut->animateClick();
       
   212 
       
   213     setWindowTitle(tr("Composition Modes"));
       
   214 }
       
   215 
       
   216 
       
   217 void CompositionWidget::nextMode()
       
   218 {
       
   219     /*
       
   220       if (!m_animation_enabled)
       
   221       return;
       
   222       if (rbClear->isChecked()) rbSource->animateClick();
       
   223       if (rbSource->isChecked()) rbDest->animateClick();
       
   224       if (rbDest->isChecked()) rbSourceOver->animateClick();
       
   225       if (rbSourceOver->isChecked()) rbDestOver->animateClick();
       
   226       if (rbDestOver->isChecked()) rbSourceIn->animateClick();
       
   227       if (rbSourceIn->isChecked()) rbDestIn->animateClick();
       
   228       if (rbDestIn->isChecked()) rbSourceOut->animateClick();
       
   229       if (rbSourceOut->isChecked()) rbDestOut->animateClick();
       
   230       if (rbDestOut->isChecked()) rbSourceAtop->animateClick();
       
   231       if (rbSourceAtop->isChecked()) rbDestAtop->animateClick();
       
   232       if (rbDestAtop->isChecked()) rbXor->animateClick();
       
   233       if (rbXor->isChecked()) rbClear->animateClick();
       
   234     */
       
   235 }
       
   236 
       
   237 CompositionRenderer::CompositionRenderer(QWidget *parent)
       
   238     : ArthurFrame(parent)
       
   239 {
       
   240     m_animation_enabled = true;
       
   241     m_animationTimer = startTimer(animationInterval);
       
   242 #ifdef Q_WS_QWS
       
   243     m_image = QPixmap(":res/composition/flower.jpg");
       
   244     m_image.setAlphaChannel(QPixmap(":res/composition/flower_alpha.jpg"));
       
   245 #else
       
   246     m_image = QImage(":res/composition/flower.jpg");
       
   247     m_image.setAlphaChannel(QImage(":res/composition/flower_alpha.jpg"));
       
   248 #endif
       
   249     m_circle_alpha = 127;
       
   250     m_circle_hue = 255;
       
   251     m_current_object = NoObject;
       
   252     m_composition_mode = QPainter::CompositionMode_SourceOut;
       
   253 
       
   254     m_circle_pos = QPoint(200, 100);
       
   255 
       
   256     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
       
   257 #ifdef QT_OPENGL_SUPPORT
       
   258     m_pbuffer = 0;
       
   259     m_pbuffer_size = 1024;
       
   260 #endif
       
   261 }
       
   262 
       
   263 QRectF rectangle_around(const QPointF &p, const QSizeF &size = QSize(250, 200))
       
   264 {
       
   265     QRectF rect(p, size);
       
   266     rect.translate(-size.width()/2, -size.height()/2);
       
   267     return rect;
       
   268 }
       
   269 
       
   270 void CompositionRenderer::setAnimationEnabled(bool enabled)
       
   271 {
       
   272     if (m_animation_enabled == enabled)
       
   273         return;
       
   274     m_animation_enabled = enabled;
       
   275     if (enabled) {
       
   276         Q_ASSERT(!m_animationTimer);
       
   277         m_animationTimer = startTimer(animationInterval);
       
   278     } else {
       
   279         killTimer(m_animationTimer);
       
   280         m_animationTimer = 0;
       
   281     }
       
   282 }
       
   283 
       
   284 void CompositionRenderer::updateCirclePos()
       
   285 {
       
   286     if (m_current_object != NoObject)
       
   287         return;
       
   288     QDateTime dt = QDateTime::currentDateTime();
       
   289     qreal t = (dt.toTime_t() * 1000 + dt.time().msec()) / 1000.0;
       
   290 
       
   291     qreal x = width() / qreal(2) + (qCos(t*8/11) + qSin(-t)) * width() / qreal(4);
       
   292     qreal y = height() / qreal(2) + (qSin(t*6/7) + qCos(t * qreal(1.5))) * height() / qreal(4);
       
   293 
       
   294     setCirclePos(QLineF(m_circle_pos, QPointF(x, y)).pointAt(0.02));
       
   295 }
       
   296 
       
   297 void CompositionRenderer::drawBase(QPainter &p)
       
   298 {
       
   299     p.setPen(Qt::NoPen);
       
   300 
       
   301     QLinearGradient rect_gradient(0, 0, 0, height());
       
   302     rect_gradient.setColorAt(0, Qt::red);
       
   303     rect_gradient.setColorAt(.17, Qt::yellow);
       
   304     rect_gradient.setColorAt(.33, Qt::green);
       
   305     rect_gradient.setColorAt(.50, Qt::cyan);
       
   306     rect_gradient.setColorAt(.66, Qt::blue);
       
   307     rect_gradient.setColorAt(.81, Qt::magenta);
       
   308     rect_gradient.setColorAt(1, Qt::red);
       
   309     p.setBrush(rect_gradient);
       
   310     p.drawRect(width() / 2, 0, width() / 2, height());
       
   311 
       
   312     QLinearGradient alpha_gradient(0, 0, width(), 0);
       
   313     alpha_gradient.setColorAt(0, Qt::white);
       
   314     alpha_gradient.setColorAt(0.2, Qt::white);
       
   315     alpha_gradient.setColorAt(0.5, Qt::transparent);
       
   316     alpha_gradient.setColorAt(0.8, Qt::white);
       
   317     alpha_gradient.setColorAt(1, Qt::white);
       
   318 
       
   319     p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
       
   320     p.setBrush(alpha_gradient);
       
   321     p.drawRect(0, 0, width(), height());
       
   322 
       
   323     p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
       
   324 
       
   325     p.setPen(Qt::NoPen);
       
   326     p.setRenderHint(QPainter::SmoothPixmapTransform);
       
   327 #ifdef Q_WS_QWS
       
   328     p.drawPixmap(rect(), m_image);
       
   329 #else
       
   330     p.drawImage(rect(), m_image);
       
   331 #endif
       
   332 }
       
   333 
       
   334 void CompositionRenderer::drawSource(QPainter &p)
       
   335 {
       
   336     p.setPen(Qt::NoPen);
       
   337     p.setRenderHint(QPainter::Antialiasing);
       
   338     p.setCompositionMode(m_composition_mode);
       
   339 
       
   340     QRectF circle_rect = rectangle_around(m_circle_pos);
       
   341     QColor color = QColor::fromHsvF(m_circle_hue / 360.0, 1, 1, m_circle_alpha / 255.0);
       
   342     QLinearGradient circle_gradient(circle_rect.topLeft(), circle_rect.bottomRight());
       
   343     circle_gradient.setColorAt(0, color.light());
       
   344     circle_gradient.setColorAt(0.5, color);
       
   345     circle_gradient.setColorAt(1, color.dark());
       
   346     p.setBrush(circle_gradient);
       
   347 
       
   348     p.drawEllipse(circle_rect);
       
   349 }
       
   350 
       
   351 void CompositionRenderer::paint(QPainter *painter)
       
   352 {
       
   353 #if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
       
   354     if (usesOpenGL()) {
       
   355 
       
   356         int new_pbuf_size = m_pbuffer_size;
       
   357         if (size().width() > m_pbuffer_size ||
       
   358             size().height() > m_pbuffer_size)
       
   359             new_pbuf_size *= 2;
       
   360 
       
   361         if (size().width() < m_pbuffer_size/2 &&
       
   362             size().height() < m_pbuffer_size/2)
       
   363             new_pbuf_size /= 2;
       
   364 
       
   365         if (!m_pbuffer || new_pbuf_size != m_pbuffer_size) {
       
   366             if (m_pbuffer) {
       
   367                 m_pbuffer->deleteTexture(m_base_tex);
       
   368                 m_pbuffer->deleteTexture(m_compositing_tex);
       
   369                 delete m_pbuffer;
       
   370             }
       
   371 
       
   372             m_pbuffer = new QGLPixelBuffer(QSize(new_pbuf_size, new_pbuf_size), QGLFormat::defaultFormat(), glWidget());
       
   373             m_pbuffer->makeCurrent();
       
   374             m_base_tex = m_pbuffer->generateDynamicTexture();
       
   375             m_compositing_tex = m_pbuffer->generateDynamicTexture();
       
   376             m_pbuffer_size = new_pbuf_size;
       
   377         }
       
   378 
       
   379         if (size() != m_previous_size) {
       
   380             m_previous_size = size();
       
   381             QPainter p(m_pbuffer);
       
   382             p.setCompositionMode(QPainter::CompositionMode_Source);
       
   383             p.fillRect(QRect(0, 0, m_pbuffer->width(), m_pbuffer->height()), Qt::transparent);
       
   384             drawBase(p);
       
   385             p.end();
       
   386             m_pbuffer->updateDynamicTexture(m_base_tex);
       
   387         }
       
   388 
       
   389         qreal x_fraction = width()/float(m_pbuffer->width());
       
   390         qreal y_fraction = height()/float(m_pbuffer->height());
       
   391 
       
   392         {
       
   393             QPainter p(m_pbuffer);
       
   394             p.setCompositionMode(QPainter::CompositionMode_Source);
       
   395             p.fillRect(QRect(0, 0, m_pbuffer->width(), m_pbuffer->height()), Qt::transparent);
       
   396 
       
   397             p.save(); // Needed when using the GL1 engine
       
   398             p.beginNativePainting(); // Needed when using the GL2 engine
       
   399 
       
   400             glBindTexture(GL_TEXTURE_2D, m_base_tex);
       
   401             glEnable(GL_TEXTURE_2D);
       
   402             glColor4f(1.,1.,1.,1.);
       
   403 
       
   404             glBegin(GL_QUADS);
       
   405             {
       
   406                 glTexCoord2f(0, 1.0);
       
   407                 glVertex2f(0, 0);
       
   408 
       
   409                 glTexCoord2f(x_fraction, 1.0);
       
   410                 glVertex2f(width(), 0);
       
   411 
       
   412                 glTexCoord2f(x_fraction, 1.0-y_fraction);
       
   413                 glVertex2f(width(), height());
       
   414 
       
   415                 glTexCoord2f(0, 1.0-y_fraction);
       
   416                 glVertex2f(0, height());
       
   417             }
       
   418             glEnd();
       
   419 
       
   420             glDisable(GL_TEXTURE_2D);
       
   421 
       
   422             p.endNativePainting(); // Needed when using the GL2 engine
       
   423             p.restore(); // Needed when using the GL1 engine
       
   424 
       
   425             drawSource(p);
       
   426             p.end();
       
   427             m_pbuffer->updateDynamicTexture(m_compositing_tex);
       
   428         }
       
   429 
       
   430         painter->beginNativePainting(); // Needed when using the GL2 engine
       
   431         glWidget()->makeCurrent(); // Needed when using the GL1 engine
       
   432         glBindTexture(GL_TEXTURE_2D, m_compositing_tex);
       
   433         glEnable(GL_TEXTURE_2D);
       
   434         glEnable(GL_BLEND);
       
   435         glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
       
   436         glColor4f(1.,1.,1.,1.);
       
   437         glBegin(GL_QUADS);
       
   438         {
       
   439             glTexCoord2f(0, 1.0);
       
   440             glVertex2f(0, 0);
       
   441 
       
   442             glTexCoord2f(x_fraction, 1.0);
       
   443             glVertex2f(width(), 0);
       
   444 
       
   445             glTexCoord2f(x_fraction, 1.0-y_fraction);
       
   446             glVertex2f(width(), height());
       
   447 
       
   448             glTexCoord2f(0, 1.0-y_fraction);
       
   449             glVertex2f(0, height());
       
   450         }
       
   451         glEnd();
       
   452         glDisable(GL_TEXTURE_2D);
       
   453         painter->endNativePainting(); // Needed when using the GL2 engine
       
   454     } else
       
   455 #endif
       
   456     {
       
   457         // using a QImage
       
   458         if (m_buffer.size() != size()) {
       
   459 #ifdef Q_WS_QWS
       
   460             m_base_buffer = QPixmap(size());
       
   461             m_base_buffer.fill(Qt::transparent);
       
   462 #else
       
   463             m_buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied);
       
   464             m_base_buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied);
       
   465 
       
   466             m_base_buffer.fill(0);
       
   467 #endif
       
   468 
       
   469             QPainter p(&m_base_buffer);
       
   470 
       
   471             drawBase(p);
       
   472         }
       
   473 
       
   474 #ifdef Q_WS_QWS
       
   475         m_buffer = m_base_buffer;
       
   476 #else
       
   477         memcpy(m_buffer.bits(), m_base_buffer.bits(), m_buffer.byteCount());
       
   478 #endif
       
   479 
       
   480         {
       
   481             QPainter p(&m_buffer);
       
   482             drawSource(p);
       
   483         }
       
   484 
       
   485 #ifdef Q_WS_QWS
       
   486         painter->drawPixmap(0, 0, m_buffer);
       
   487 #else
       
   488         painter->drawImage(0, 0, m_buffer);
       
   489 #endif
       
   490     }
       
   491 }
       
   492 
       
   493 void CompositionRenderer::mousePressEvent(QMouseEvent *e)
       
   494 {
       
   495     setDescriptionEnabled(false);
       
   496 
       
   497     QRectF circle = rectangle_around(m_circle_pos);
       
   498 
       
   499     if (circle.contains(e->pos())) {
       
   500         m_current_object = Circle;
       
   501         m_offset = circle.center() - e->pos();
       
   502     } else {
       
   503         m_current_object = NoObject;
       
   504     }
       
   505     if (m_animation_enabled) {
       
   506         killTimer(m_animationTimer);
       
   507         m_animationTimer = 0;
       
   508     }
       
   509 }
       
   510 
       
   511 void CompositionRenderer::mouseMoveEvent(QMouseEvent *e)
       
   512 {
       
   513     if (m_current_object == Circle) setCirclePos(e->pos() + m_offset);
       
   514 }
       
   515 
       
   516 void CompositionRenderer::mouseReleaseEvent(QMouseEvent *)
       
   517 {
       
   518     m_current_object = NoObject;
       
   519 
       
   520     if (m_animation_enabled) {
       
   521         Q_ASSERT(!m_animationTimer);
       
   522         m_animationTimer = startTimer(animationInterval);
       
   523     }
       
   524 }
       
   525 
       
   526 void CompositionRenderer::timerEvent(QTimerEvent *event)
       
   527 {
       
   528     if (event->timerId() == m_animationTimer)
       
   529         updateCirclePos();
       
   530 }
       
   531 
       
   532 void CompositionRenderer::setCirclePos(const QPointF &pos)
       
   533 {
       
   534     const QRect oldRect = rectangle_around(m_circle_pos).toAlignedRect();
       
   535     m_circle_pos = pos;
       
   536     const QRect newRect = rectangle_around(m_circle_pos).toAlignedRect();
       
   537 #if defined(QT_OPENGL_SUPPORT) && !defined(QT_OPENGL_ES)
       
   538     if (usesOpenGL())
       
   539         update();
       
   540     else
       
   541 #endif
       
   542         update(oldRect | newRect);
       
   543 }
       
   544