source: trunk/examples/opengl/overpainting/glwidget.cpp@ 842

Last change on this file since 842 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 7.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 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 examples 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 <QtGui>
43#include <QtOpenGL>
44#include <stdlib.h>
45
46#include <math.h>
47
48#include "bubble.h"
49#include "qtlogo.h"
50#include "glwidget.h"
51
52#ifndef GL_MULTISAMPLE
53#define GL_MULTISAMPLE 0x809D
54#endif
55
56//! [0]
57GLWidget::GLWidget(QWidget *parent)
58 : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
59{
60 QTime midnight(0, 0, 0);
61 qsrand(midnight.secsTo(QTime::currentTime()));
62
63 logo = 0;
64 xRot = 0;
65 yRot = 0;
66 zRot = 0;
67
68 qtGreen = QColor::fromCmykF(0.40, 0.0, 1.0, 0.0);
69 qtPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0);
70
71 animationTimer.setSingleShot(false);
72 connect(&animationTimer, SIGNAL(timeout()), this, SLOT(animate()));
73 animationTimer.start(25);
74
75 setAutoFillBackground(false);
76 setMinimumSize(200, 200);
77 setWindowTitle(tr("Overpainting a Scene"));
78}
79//! [0]
80
81//! [1]
82GLWidget::~GLWidget()
83{
84}
85//! [1]
86
87static void qNormalizeAngle(int &angle)
88{
89 while (angle < 0)
90 angle += 360 * 16;
91 while (angle > 360 * 16)
92 angle -= 360 * 16;
93}
94
95void GLWidget::setXRotation(int angle)
96{
97 qNormalizeAngle(angle);
98 if (angle != xRot)
99 xRot = angle;
100}
101
102void GLWidget::setYRotation(int angle)
103{
104 qNormalizeAngle(angle);
105 if (angle != yRot)
106 yRot = angle;
107}
108
109void GLWidget::setZRotation(int angle)
110{
111 qNormalizeAngle(angle);
112 if (angle != zRot)
113 zRot = angle;
114}
115
116//! [2]
117void GLWidget::initializeGL()
118{
119 glEnable(GL_MULTISAMPLE);
120
121 logo = new QtLogo(this);
122 logo->setColor(qtGreen.dark());
123}
124//! [2]
125
126void GLWidget::mousePressEvent(QMouseEvent *event)
127{
128 lastPos = event->pos();
129}
130
131void GLWidget::mouseMoveEvent(QMouseEvent *event)
132{
133 int dx = event->x() - lastPos.x();
134 int dy = event->y() - lastPos.y();
135
136 if (event->buttons() & Qt::LeftButton) {
137 setXRotation(xRot + 8 * dy);
138 setYRotation(yRot + 8 * dx);
139 } else if (event->buttons() & Qt::RightButton) {
140 setXRotation(xRot + 8 * dy);
141 setZRotation(zRot + 8 * dx);
142 }
143 lastPos = event->pos();
144}
145
146void GLWidget::paintEvent(QPaintEvent *event)
147{
148 makeCurrent();
149//! [4]
150 glMatrixMode(GL_MODELVIEW);
151 glPushMatrix();
152//! [4]
153
154//! [6]
155 qglClearColor(qtPurple.dark());
156 glShadeModel(GL_SMOOTH);
157 glEnable(GL_DEPTH_TEST);
158 glEnable(GL_CULL_FACE);
159 glEnable(GL_LIGHTING);
160 glEnable(GL_LIGHT0);
161 glEnable(GL_MULTISAMPLE);
162 static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
163 glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
164
165 setupViewport(width(), height());
166//! [6]
167
168//! [7]
169 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
170 glLoadIdentity();
171 glTranslatef(0.0, 0.0, -10.0);
172 glRotatef(xRot / 16.0, 1.0, 0.0, 0.0);
173 glRotatef(yRot / 16.0, 0.0, 1.0, 0.0);
174 glRotatef(zRot / 16.0, 0.0, 0.0, 1.0);
175
176 logo->draw();
177//! [7]
178
179//! [8]
180 glShadeModel(GL_FLAT);
181 glDisable(GL_CULL_FACE);
182 glDisable(GL_DEPTH_TEST);
183 glDisable(GL_LIGHTING);
184
185 glMatrixMode(GL_MODELVIEW);
186 glPopMatrix();
187//! [8]
188
189//! [10]
190 QPainter painter(this);
191 painter.setRenderHint(QPainter::Antialiasing);
192 foreach (Bubble *bubble, bubbles) {
193 if (bubble->rect().intersects(event->rect()))
194 bubble->drawBubble(&painter);
195 }
196 drawInstructions(&painter);
197 painter.end();
198}
199//! [10]
200
201//! [11]
202void GLWidget::resizeGL(int width, int height)
203{
204 setupViewport(width, height);
205}
206//! [11]
207
208//! [12]
209void GLWidget::showEvent(QShowEvent *event)
210{
211 Q_UNUSED(event);
212 createBubbles(20 - bubbles.count());
213}
214//! [12]
215
216QSize GLWidget::sizeHint() const
217{
218 return QSize(400, 400);
219}
220
221void GLWidget::createBubbles(int number)
222{
223 for (int i = 0; i < number; ++i) {
224 QPointF position(width()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))),
225 height()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))));
226 qreal radius = qMin(width(), height())*(0.0125 + 0.0875*qrand()/(RAND_MAX+1.0));
227 QPointF velocity(width()*0.0125*(-0.5 + qrand()/(RAND_MAX+1.0)),
228 height()*0.0125*(-0.5 + qrand()/(RAND_MAX+1.0)));
229
230 bubbles.append(new Bubble(position, radius, velocity));
231 }
232}
233
234//! [13]
235void GLWidget::animate()
236{
237 QMutableListIterator<Bubble*> iter(bubbles);
238
239 while (iter.hasNext()) {
240 Bubble *bubble = iter.next();
241 bubble->move(rect());
242 }
243 update();
244}
245//! [13]
246
247//! [14]
248void GLWidget::setupViewport(int width, int height)
249{
250 int side = qMin(width, height);
251 glViewport((width - side) / 2, (height - side) / 2, side, side);
252
253 glMatrixMode(GL_PROJECTION);
254 glLoadIdentity();
255#ifdef QT_OPENGL_ES
256 glOrthof(-0.5, +0.5, -0.5, 0.5, 4.0, 15.0);
257#else
258 glOrtho(-0.5, +0.5, -0.5, 0.5, 4.0, 15.0);
259#endif
260 glMatrixMode(GL_MODELVIEW);
261}
262//! [14]
263
264//! [15]
265void GLWidget::drawInstructions(QPainter *painter)
266{
267 QString text = tr("Click and drag with the left mouse button "
268 "to rotate the Qt logo.");
269 QFontMetrics metrics = QFontMetrics(font());
270 int border = qMax(4, metrics.leading());
271
272 QRect rect = metrics.boundingRect(0, 0, width() - 2*border, int(height()*0.125),
273 Qt::AlignCenter | Qt::TextWordWrap, text);
274 painter->setRenderHint(QPainter::TextAntialiasing);
275 painter->fillRect(QRect(0, 0, width(), rect.height() + 2*border),
276 QColor(0, 0, 0, 127));
277 painter->setPen(Qt::white);
278 painter->fillRect(QRect(0, 0, width(), rect.height() + 2*border),
279 QColor(0, 0, 0, 127));
280 painter->drawText((width() - rect.width())/2, border,
281 rect.width(), rect.height(),
282 Qt::AlignCenter | Qt::TextWordWrap, text);
283}
284//! [15]
Note: See TracBrowser for help on using the repository browser.