source: trunk/examples/opengl/hellogl_es/glwidget.cpp@ 275

Last change on this file since 275 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 14.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "glwidget.h"
43#include <QPainter>
44#include <math.h>
45
46#include "bubble.h"
47#include "cl_helper.h"
48
49
50const int bubbleNum = 8;
51
52inline void CrossProduct(qreal &xOut, qreal &yOut, qreal &zOut, qreal x1, qreal y1, qreal z1, qreal x2, qreal y2, qreal z2)
53{
54 xOut = y1 * z2 - z1 * y2;
55 yOut = z1 * x2 - x1 * z2;
56 zOut = x1 * y2 - y1 * x2;
57}
58
59inline void Normalize(qreal &x, qreal &y, qreal &z)
60{
61 qreal l = sqrt(x*x + y*y + z*z);
62 x = x / l;
63 y = y / l;
64 z = z / l;
65}
66
67GLWidget::GLWidget(QWidget *parent)
68 : QGLWidget(parent)
69{
70 qtLogo = true;
71 createdVertices = 0;
72 createdNormals = 0;
73 m_vertexNumber = 0;
74 frames = 0;
75 setAttribute(Qt::WA_PaintOnScreen);
76 setAttribute(Qt::WA_NoSystemBackground);
77 setAutoBufferSwap(false);
78 m_showBubbles = true;
79}
80
81GLWidget::~GLWidget()
82{
83 if (createdVertices)
84 delete[] createdVertices;
85 if (createdNormals)
86 delete[] createdNormals;
87}
88
89void GLWidget::setScaling(int scale) {
90
91 if (scale > 50)
92 m_fScale = 1 + qreal(scale -50) / 50 * 0.5;
93 else if (scale < 50)
94 m_fScale = 1- (qreal(50 - scale) / 50 * 1/2);
95 else
96 m_fScale = 1;
97}
98
99void GLWidget::setLogo() {
100 qtLogo = true;
101}
102
103void GLWidget::setTexture() {
104 qtLogo = false;
105}
106
107void GLWidget::showBubbles(bool bubbles)
108{
109 m_showBubbles = bubbles;
110}
111
112//! [2]
113void GLWidget::paintQtLogo()
114{
115 glDisable(GL_TEXTURE_2D);
116 glEnableClientState(GL_VERTEX_ARRAY);
117 glVertexPointer(3,q_vertexTypeEnum,0, createdVertices);
118 glEnableClientState(GL_NORMAL_ARRAY);
119 glNormalPointer(q_vertexTypeEnum,0,createdNormals);
120 glDrawArrays(GL_TRIANGLES, 0, m_vertexNumber / 3);
121}
122//! [2]
123
124void GLWidget::paintTexturedCube()
125{
126 glEnable(GL_TEXTURE_2D);
127 glBindTexture(GL_TEXTURE_2D, m_uiTexture);
128 q_vertexType afVertices[] = {
129 f2vt(-0.5), f2vt(0.5), f2vt(0.5), f2vt(0.5),f2vt(-0.5),f2vt(0.5),f2vt(-0.5),f2vt(-0.5),f2vt(0.5),
130 f2vt(0.5), f2vt(-0.5), f2vt(0.5), f2vt(-0.5),f2vt(0.5),f2vt(0.5),f2vt(0.5),f2vt(0.5),f2vt(0.5),
131 f2vt(-0.5), f2vt(-0.5), f2vt(-0.5), f2vt(0.5),f2vt(-0.5),f2vt(-0.5),f2vt(-0.5),f2vt(0.5),f2vt(-0.5),
132 f2vt(0.5), f2vt(0.5), f2vt(-0.5), f2vt(-0.5),f2vt(0.5),f2vt(-0.5),f2vt(0.5),f2vt(-0.5),f2vt(-0.5),
133
134 f2vt(0.5), f2vt(-0.5), f2vt(-0.5), f2vt(0.5),f2vt(-0.5),f2vt(0.5),f2vt(0.5),f2vt(0.5),f2vt(-0.5),
135 f2vt(0.5), f2vt(0.5), f2vt(0.5), f2vt(0.5),f2vt(0.5),f2vt(-0.5),f2vt(0.5),f2vt(-0.5),f2vt(0.5),
136 f2vt(-0.5), f2vt(0.5), f2vt(-0.5), f2vt(-0.5),f2vt(-0.5),f2vt(0.5),f2vt(-0.5),f2vt(-0.5),f2vt(-0.5),
137 f2vt(-0.5), f2vt(-0.5), f2vt(0.5), f2vt(-0.5),f2vt(0.5),f2vt(-0.5),f2vt(-0.5),f2vt(0.5),f2vt(0.5),
138
139 f2vt(0.5), f2vt(0.5), f2vt(-0.5), f2vt(-0.5), f2vt(0.5), f2vt(0.5), f2vt(-0.5), f2vt(0.5), f2vt(-0.5),
140 f2vt(-0.5), f2vt(0.5), f2vt(0.5), f2vt(0.5), f2vt(0.5), f2vt(-0.5), f2vt(0.5), f2vt(0.5), f2vt(0.5),
141 f2vt(-0.5), f2vt(-0.5), f2vt(-0.5), f2vt(-0.5), f2vt(-0.5), f2vt(0.5), f2vt(0.5), f2vt(-0.5), f2vt(-0.5),
142 f2vt(0.5), f2vt(-0.5), f2vt(0.5), f2vt(0.5), f2vt(-0.5), f2vt(-0.5), f2vt(-0.5), f2vt(-0.5), f2vt(0.5)
143 };
144 glEnableClientState(GL_VERTEX_ARRAY);
145 glVertexPointer(3,q_vertexTypeEnum,0,afVertices);
146
147 q_vertexType afTexCoord[] = {
148 f2vt(0.0f),f2vt(0.0f), f2vt(1.0f),f2vt(1.0f), f2vt(1.0f),f2vt(0.0f),
149 f2vt(1.0f),f2vt(1.0f), f2vt(0.0f),f2vt(0.0f), f2vt(0.0f),f2vt(1.0f),
150 f2vt(1.0f),f2vt(1.0f), f2vt(1.0f),f2vt(0.0f), f2vt(0.0f),f2vt(1.0f),
151 f2vt(0.0f),f2vt(0.0f), f2vt(0.0f),f2vt(1.0f), f2vt(1.0f),f2vt(0.0f),
152
153 f2vt(1.0f),f2vt(1.0f), f2vt(1.0f),f2vt(0.0f), f2vt(0.0f),f2vt(1.0f),
154 f2vt(0.0f),f2vt(0.0f), f2vt(0.0f),f2vt(1.0f), f2vt(1.0f),f2vt(0.0f),
155 f2vt(0.0f),f2vt(0.0f), f2vt(1.0f),f2vt(1.0f), f2vt(1.0f),f2vt(0.0f),
156 f2vt(1.0f),f2vt(1.0f), f2vt(0.0f),f2vt(0.0f), f2vt(0.0f),f2vt(1.0f),
157
158 f2vt(0.0f),f2vt(1.0f), f2vt(1.0f),f2vt(0.0f), f2vt(1.0f),f2vt(1.0f),
159 f2vt(1.0f),f2vt(0.0f), f2vt(0.0f),f2vt(1.0f), f2vt(0.0f),f2vt(0.0f),
160 f2vt(1.0f),f2vt(0.0f), f2vt(1.0f),f2vt(1.0f), f2vt(0.0f),f2vt(0.0f),
161 f2vt(0.0f),f2vt(1.0f), f2vt(0.0f),f2vt(0.0f), f2vt(1.0f),f2vt(1.0f)
162 };
163 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
164 glTexCoordPointer(2,q_vertexTypeEnum,0,afTexCoord);
165
166 q_vertexType afNormals[] = {
167
168 f2vt(0),f2vt(0),f2vt(-1), f2vt(0),f2vt(0),f2vt(-1), f2vt(0),f2vt(0),f2vt(-1),
169 f2vt(0),f2vt(0),f2vt(-1), f2vt(0),f2vt(0),f2vt(-1), f2vt(0),f2vt(0),f2vt(-1),
170 f2vt(0),f2vt(0),f2vt(1), f2vt(0),f2vt(0),f2vt(1), f2vt(0),f2vt(0),f2vt(1),
171 f2vt(0),f2vt(0),f2vt(1), f2vt(0),f2vt(0),f2vt(1), f2vt(0),f2vt(0),f2vt(1),
172
173 f2vt(-1),f2vt(0),f2vt(0), f2vt(-1),f2vt(0),f2vt(0), f2vt(-1),f2vt(0),f2vt(0),
174 f2vt(-1),f2vt(0),f2vt(0), f2vt(-1),f2vt(0),f2vt(0), f2vt(-1),f2vt(0),f2vt(0),
175 f2vt(1),f2vt(0),f2vt(0), f2vt(1),f2vt(0),f2vt(0), f2vt(1),f2vt(0),f2vt(0),
176 f2vt(1),f2vt(0),f2vt(0), f2vt(1),f2vt(0),f2vt(0), f2vt(1),f2vt(0),f2vt(0),
177
178 f2vt(0),f2vt(-1),f2vt(0), f2vt(0),f2vt(-1),f2vt(0), f2vt(0),f2vt(-1),f2vt(0),
179 f2vt(0),f2vt(-1),f2vt(0), f2vt(0),f2vt(-1),f2vt(0), f2vt(0),f2vt(-1),f2vt(0),
180 f2vt(0),f2vt(1),f2vt(0), f2vt(0),f2vt(1),f2vt(0), f2vt(0),f2vt(1),f2vt(0),
181 f2vt(0),f2vt(1),f2vt(0), f2vt(0),f2vt(1),f2vt(0), f2vt(0),f2vt(1),f2vt(0)
182 };
183 glEnableClientState(GL_NORMAL_ARRAY);
184 glNormalPointer(q_vertexTypeEnum,0,afNormals);
185
186 glDrawArrays(GL_TRIANGLES, 0, 36);
187}
188
189void GLWidget::initializeGL ()
190{
191 q_glClearColor(f2vt(0.1f), f2vt(0.1f), f2vt(0.2f), f2vt(1.0f));
192
193 glEnable(GL_TEXTURE_2D);
194 glGenTextures(1, &m_uiTexture);
195 m_uiTexture = bindTexture(QImage(":/qt.png"));
196
197 q_glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
198 q_glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
199 glEnable(GL_LIGHTING);
200 glEnable(GL_LIGHT0);
201
202 q_vertexType aLightPosition[] = {f2vt(0.0f),f2vt(0.3f),f2vt(1.0f),f2vt(0.0f)};
203
204 q_glLightv(GL_LIGHT0, GL_SPOT_DIRECTION, aLightPosition);
205 m_fAngle = 0;
206 m_fScale = 1;
207 createGeometry();
208 createBubbles(bubbleNum - bubbles.count());
209}
210
211void GLWidget::paintGL()
212{
213 createBubbles(bubbleNum - bubbles.count());
214
215//! [3]
216 QPainter painter;
217 painter.begin(this);
218
219 glMatrixMode(GL_PROJECTION);
220 glPushMatrix();
221 glLoadIdentity();
222//! [3]
223
224//! [4]
225 glMatrixMode(GL_MODELVIEW);
226 glPushMatrix();
227 glMatrixMode(GL_TEXTURE);
228 glPushMatrix();
229
230 //Since OpenGL ES does not support glPush/PopAttrib(GL_ALL_ATTRIB_BITS)
231 //we have to take care of the states ourselves
232
233 q_glClearColor(f2vt(0.1f), f2vt(0.1f), f2vt(0.2f), f2vt(1.0f));
234 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
235 glEnable(GL_TEXTURE_2D);
236
237 q_glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
238 q_glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
239 glEnable(GL_LIGHTING);
240 glEnable(GL_LIGHT0);
241
242 glShadeModel(GL_FLAT);
243 glFrontFace(GL_CW);
244 glCullFace(GL_FRONT);
245 glEnable(GL_CULL_FACE);
246 glEnable(GL_DEPTH_TEST);
247
248 glMatrixMode(GL_MODELVIEW);
249 glLoadIdentity();
250
251 q_glRotate(f2vt(m_fAngle), f2vt(0.0), f2vt(1.0), f2vt(0.0));
252 q_glRotate(f2vt(m_fAngle), f2vt(1.0), f2vt(0.0), f2vt(0.0));
253 q_glRotate(f2vt(m_fAngle), f2vt(0.0), f2vt(0.0), f2vt(1.0));
254 q_glScale(f2vt(m_fScale), f2vt(m_fScale),f2vt(m_fScale));
255 q_glTranslate(f2vt(0),f2vt(-0.2),f2vt(0));
256
257 q_vertexType matDiff[] = {f2vt(0.40), f2vt(1.0), f2vt(0.0), f2vt(1.0)};
258 q_glMaterialv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff);
259
260 if (qtLogo)
261 paintQtLogo();
262 else
263 paintTexturedCube();
264//! [4]
265
266//![5]
267 glMatrixMode(GL_MODELVIEW);
268 glPopMatrix();
269 glMatrixMode(GL_PROJECTION);
270 glPopMatrix();
271 glMatrixMode(GL_TEXTURE);
272 glPopMatrix();
273
274 glDisable(GL_LIGHTING);
275 glDisable(GL_LIGHT0);
276
277 glDisable(GL_DEPTH_TEST);
278 glDisable(GL_CULL_FACE);
279//![5]
280
281//! [6]
282 if (m_showBubbles)
283 foreach (Bubble *bubble, bubbles) {
284 bubble->drawBubble(&painter);
285 }
286//! [6]
287
288//! [7]
289 QString framesPerSecond;
290 framesPerSecond.setNum(frames /(time.elapsed() / 1000.0), 'f', 2);
291
292 painter.setPen(Qt::white);
293
294 painter.drawText(20, 40, framesPerSecond + " fps");
295
296 painter.end();
297//! [7]
298
299//! [8]
300 swapBuffers();
301//! [8]
302
303 QMutableListIterator<Bubble*> iter(bubbles);
304
305 while (iter.hasNext()) {
306 Bubble *bubble = iter.next();
307 bubble->move(rect());
308 }
309 if (!(frames % 100)) {
310 time.start();
311 frames = 0;
312 }
313 m_fAngle += 1.0f;
314 frames ++;
315}
316
317void GLWidget::createBubbles(int number)
318{
319 for (int i = 0; i < number; ++i) {
320 QPointF position(width()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))),
321 height()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))));
322 qreal radius = qMin(width(), height())*(0.0175 + 0.0875*qrand()/(RAND_MAX+1.0));
323 QPointF velocity(width()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)),
324 height()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)));
325
326 bubbles.append(new Bubble(position, radius, velocity));
327 }
328}
329
330void GLWidget::createGeometry()
331{
332 vertices.clear();
333 normals.clear();
334
335 qreal x1 = +0.06f;
336 qreal y1 = -0.14f;
337 qreal x2 = +0.14f;
338 qreal y2 = -0.06f;
339 qreal x3 = +0.08f;
340 qreal y3 = +0.00f;
341 qreal x4 = +0.30f;
342 qreal y4 = +0.22f;
343
344 quad(x1, y1, x2, y2, y2, x2, y1, x1);
345 quad(x3, y3, x4, y4, y4, x4, y3, x3);
346
347 extrude(x1, y1, x2, y2);
348 extrude(x2, y2, y2, x2);
349 extrude(y2, x2, y1, x1);
350 extrude(y1, x1, x1, y1);
351 extrude(x3, y3, x4, y4);
352 extrude(x4, y4, y4, x4);
353 extrude(y4, x4, y3, x3);
354
355 const qreal Pi = 3.14159f;
356 const int NumSectors = 100;
357
358 for (int i = 0; i < NumSectors; ++i) {
359 qreal angle1 = (i * 2 * Pi) / NumSectors;
360 qreal x5 = 0.30 * sin(angle1);
361 qreal y5 = 0.30 * cos(angle1);
362 qreal x6 = 0.20 * sin(angle1);
363 qreal y6 = 0.20 * cos(angle1);
364
365 qreal angle2 = ((i + 1) * 2 * Pi) / NumSectors;
366 qreal x7 = 0.20 * sin(angle2);
367 qreal y7 = 0.20 * cos(angle2);
368 qreal x8 = 0.30 * sin(angle2);
369 qreal y8 = 0.30 * cos(angle2);
370
371 quad(x5, y5, x6, y6, x7, y7, x8, y8);
372
373 extrude(x6, y6, x7, y7);
374 extrude(x8, y8, x5, y5);
375 }
376
377//! [1]
378 m_vertexNumber = vertices.size();
379 createdVertices = new q_vertexType[m_vertexNumber];
380 createdNormals = new q_vertexType[m_vertexNumber];
381 for (int i = 0;i < m_vertexNumber;i++) {
382 createdVertices[i] = f2vt(vertices.at(i) * 2);
383 createdNormals[i] = f2vt(normals.at(i));
384 }
385 vertices.clear();
386 normals.clear();
387}
388//! [1]
389
390//! [0]
391void GLWidget::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4)
392{
393 qreal nx, ny, nz;
394
395 vertices << x1 << y1 << -0.05f;
396 vertices << x2 << y2 << -0.05f;
397 vertices << x4 << y4 << -0.05f;
398
399 vertices << x3 << y3 << -0.05f;
400 vertices << x4 << y4 << -0.05f;
401 vertices << x2 << y2 << -0.05f;
402
403 CrossProduct(nx, ny, nz, x2 - x1, y2 - y1, 0, x4 - x1, y4 - y1, 0);
404 Normalize(nx, ny, nz);
405
406 normals << nx << ny << nz;
407 normals << nx << ny << nz;
408 normals << nx << ny << nz;
409
410 normals << nx << ny << nz;
411 normals << nx << ny << nz;
412 normals << nx << ny << nz;
413
414 vertices << x4 << y4 << 0.05f;
415 vertices << x2 << y2 << 0.05f;
416 vertices << x1 << y1 << 0.05f;
417
418 vertices << x2 << y2 << 0.05f;
419 vertices << x4 << y4 << 0.05f;
420 vertices << x3 << y3 << 0.05f;
421
422 CrossProduct(nx, ny, nz, x2 - x4, y2 - y4, 0, x1 - x4, y1 - y4, 0);
423 Normalize(nx, ny, nz);
424
425 normals << nx << ny << nz;
426 normals << nx << ny << nz;
427 normals << nx << ny << nz;
428
429 normals << nx << ny << nz;
430 normals << nx << ny << nz;
431 normals << nx << ny << nz;
432}
433//! [0]
434
435void GLWidget::extrude(qreal x1, qreal y1, qreal x2, qreal y2)
436{
437 qreal nx, ny, nz;
438
439 vertices << x1 << y1 << +0.05f;
440 vertices << x2 << y2 << +0.05f;
441 vertices << x1 << y1 << -0.05f;
442
443 vertices << x2 << y2 << -0.05f;
444 vertices << x1 << y1 << -0.05f;
445 vertices << x2 << y2 << +0.05f;
446
447 CrossProduct(nx, ny, nz, x2 - x1, y2 - y1, 0.0f, 0.0f, 0.0f, -0.1f);
448 Normalize(nx, ny, nz);
449
450 normals << nx << ny << nz;
451 normals << nx << ny << nz;
452 normals << nx << ny << nz;
453
454 normals << nx << ny << nz;
455 normals << nx << ny << nz;
456 normals << nx << ny << nz;
457}
Note: See TracBrowser for help on using the repository browser.