1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation ([email protected])
|
---|
6 | **
|
---|
7 | ** This file is part of the demonstration applications of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
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 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at [email protected].
|
---|
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 |
|
---|