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

Last change on this file since 846 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 12.2 KB
Line 
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 examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "glwidget.h"
42#include <QPainter>
43#include <math.h>
44
45#include "bubble.h"
46
47
48const int bubbleNum = 8;
49
50inline void CrossProduct(qreal &xOut, qreal &yOut, qreal &zOut, qreal x1, qreal y1, qreal z1, qreal x2, qreal y2, qreal z2)
51{
52 xOut = y1 * z2 - z1 * y2;
53 yOut = z1 * x2 - x1 * z2;
54 zOut = x1 * y2 - y1 * x2;
55}
56
57inline void Normalize(qreal &x, qreal &y, qreal &z)
58{
59 qreal l = sqrt(x*x + y*y + z*z);
60 x = x / l;
61 y = y / l;
62 z = z / l;
63}
64
65GLWidget::GLWidget(QWidget *parent)
66 : QGLWidget(parent)
67{
68 qtLogo = true;
69 createdVertices = 0;
70 createdNormals = 0;
71 m_vertexNumber = 0;
72 frames = 0;
73 setAttribute(Qt::WA_PaintOnScreen);
74 setAttribute(Qt::WA_NoSystemBackground);
75 setAutoBufferSwap(false);
76 m_showBubbles = true;
77}
78
79GLWidget::~GLWidget()
80{
81 if (createdVertices)
82 delete[] createdVertices;
83 if (createdNormals)
84 delete[] createdNormals;
85}
86
87void GLWidget::setScaling(int scale) {
88
89 if (scale > 50)
90 m_fScale = 1 + qreal(scale -50) / 50 * 0.5;
91 else if (scale < 50)
92 m_fScale = 1- (qreal(50 - scale) / 50 * 1/2);
93 else
94 m_fScale = 1;
95}
96
97void GLWidget::setLogo() {
98 qtLogo = true;
99}
100
101void GLWidget::setTexture() {
102 qtLogo = false;
103}
104
105void GLWidget::showBubbles(bool bubbles)
106{
107 m_showBubbles = bubbles;
108}
109
110//! [2]
111void GLWidget::paintQtLogo()
112{
113 glDisable(GL_TEXTURE_2D);
114 glEnableClientState(GL_VERTEX_ARRAY);
115 glVertexPointer(3,GL_FLOAT,0, createdVertices);
116 glEnableClientState(GL_NORMAL_ARRAY);
117 glNormalPointer(GL_FLOAT,0,createdNormals);
118 glDrawArrays(GL_TRIANGLES, 0, m_vertexNumber / 3);
119}
120//! [2]
121
122void GLWidget::paintTexturedCube()
123{
124 glEnable(GL_TEXTURE_2D);
125 glBindTexture(GL_TEXTURE_2D, m_uiTexture);
126 GLfloat afVertices[] = {
127 -0.5, 0.5, 0.5, 0.5,-0.5,0.5,-0.5,-0.5,0.5,
128 0.5, -0.5, 0.5, -0.5,0.5,0.5,0.5,0.5,0.5,
129 -0.5, -0.5, -0.5, 0.5,-0.5,-0.5,-0.5,0.5,-0.5,
130 0.5, 0.5, -0.5, -0.5,0.5,-0.5,0.5,-0.5,-0.5,
131
132 0.5, -0.5, -0.5, 0.5,-0.5,0.5,0.5,0.5,-0.5,
133 0.5, 0.5, 0.5, 0.5,0.5,-0.5,0.5,-0.5,0.5,
134 -0.5, 0.5, -0.5, -0.5,-0.5,0.5,-0.5,-0.5,-0.5,
135 -0.5, -0.5, 0.5, -0.5,0.5,-0.5,-0.5,0.5,0.5,
136
137 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5,
138 -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5,
139 -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5,
140 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5
141 };
142 glEnableClientState(GL_VERTEX_ARRAY);
143 glVertexPointer(3,GL_FLOAT,0,afVertices);
144
145 GLfloat afTexCoord[] = {
146 0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
147 1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
148 1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
149 0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
150
151 1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
152 0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
153 0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
154 1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
155
156 0.0f,1.0f, 1.0f,0.0f, 1.0f,1.0f,
157 1.0f,0.0f, 0.0f,1.0f, 0.0f,0.0f,
158 1.0f,0.0f, 1.0f,1.0f, 0.0f,0.0f,
159 0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f
160 };
161 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
162 glTexCoordPointer(2,GL_FLOAT,0,afTexCoord);
163
164 GLfloat afNormals[] = {
165
166 0,0,-1, 0,0,-1, 0,0,-1,
167 0,0,-1, 0,0,-1, 0,0,-1,
168 0,0,1, 0,0,1, 0,0,1,
169 0,0,1, 0,0,1, 0,0,1,
170
171 -1,0,0, -1,0,0, -1,0,0,
172 -1,0,0, -1,0,0, -1,0,0,
173 1,0,0, 1,0,0, 1,0,0,
174 1,0,0, 1,0,0, 1,0,0,
175
176 0,-1,0, 0,-1,0, 0,-1,0,
177 0,-1,0, 0,-1,0, 0,-1,0,
178 0,1,0, 0,1,0, 0,1,0,
179 0,1,0, 0,1,0, 0,1,0
180 };
181 glEnableClientState(GL_NORMAL_ARRAY);
182 glNormalPointer(GL_FLOAT,0,afNormals);
183
184 glDrawArrays(GL_TRIANGLES, 0, 36);
185}
186
187void GLWidget::initializeGL ()
188{
189 glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
190
191 glEnable(GL_TEXTURE_2D);
192 glGenTextures(1, &m_uiTexture);
193 m_uiTexture = bindTexture(QImage(":/qt.png"));
194
195 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
196 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
197 glEnable(GL_LIGHTING);
198 glEnable(GL_LIGHT0);
199
200 GLfloat aLightPosition[] = {0.0f,0.3f,1.0f,0.0f};
201
202 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, aLightPosition);
203 m_fAngle = 0;
204 m_fScale = 1;
205 createGeometry();
206 createBubbles(bubbleNum - bubbles.count());
207}
208
209void GLWidget::paintGL()
210{
211 createBubbles(bubbleNum - bubbles.count());
212
213//! [3]
214 QPainter painter;
215 painter.begin(this);
216
217 glMatrixMode(GL_PROJECTION);
218 glPushMatrix();
219 glLoadIdentity();
220//! [3]
221
222//! [4]
223 glMatrixMode(GL_MODELVIEW);
224 glPushMatrix();
225 glMatrixMode(GL_TEXTURE);
226 glPushMatrix();
227
228 //Since OpenGL ES does not support glPush/PopAttrib(GL_ALL_ATTRIB_BITS)
229 //we have to take care of the states ourselves
230
231 glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
232 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
233 glEnable(GL_TEXTURE_2D);
234
235 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
236 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
237 glEnable(GL_LIGHTING);
238 glEnable(GL_LIGHT0);
239
240 glShadeModel(GL_FLAT);
241 glFrontFace(GL_CW);
242 glCullFace(GL_FRONT);
243 glEnable(GL_CULL_FACE);
244 glEnable(GL_DEPTH_TEST);
245
246 glMatrixMode(GL_MODELVIEW);
247 glLoadIdentity();
248
249 glRotatef(m_fAngle, 0.0f, 1.0f, 0.0f);
250 glRotatef(m_fAngle, 1.0f, 0.0f, 0.0f);
251 glRotatef(m_fAngle, 0.0f, 0.0f, 1.0f);
252 glScalef(m_fScale, m_fScale,m_fScale);
253 glTranslatef(0.0f,-0.2f,0.0f);
254
255 GLfloat matDiff[] = {0.40f, 1.0f, 0.0f, 1.0f};
256 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff);
257
258 if (qtLogo)
259 paintQtLogo();
260 else
261 paintTexturedCube();
262//! [4]
263
264//![5]
265 glMatrixMode(GL_MODELVIEW);
266 glPopMatrix();
267 glMatrixMode(GL_PROJECTION);
268 glPopMatrix();
269 glMatrixMode(GL_TEXTURE);
270 glPopMatrix();
271
272 glDisable(GL_LIGHTING);
273 glDisable(GL_LIGHT0);
274
275 glDisable(GL_DEPTH_TEST);
276 glDisable(GL_CULL_FACE);
277//![5]
278
279//! [6]
280 if (m_showBubbles)
281 foreach (Bubble *bubble, bubbles) {
282 bubble->drawBubble(&painter);
283 }
284//! [6]
285
286//! [7]
287 QString framesPerSecond;
288 framesPerSecond.setNum(frames /(time.elapsed() / 1000.0), 'f', 2);
289
290 painter.setPen(Qt::white);
291
292 painter.drawText(20, 40, framesPerSecond + " fps");
293
294 painter.end();
295//! [7]
296
297//! [8]
298 swapBuffers();
299//! [8]
300
301 QMutableListIterator<Bubble*> iter(bubbles);
302
303 while (iter.hasNext()) {
304 Bubble *bubble = iter.next();
305 bubble->move(rect());
306 }
307 if (!(frames % 100)) {
308 time.start();
309 frames = 0;
310 }
311 m_fAngle += 1.0f;
312 frames ++;
313}
314
315void GLWidget::createBubbles(int number)
316{
317 for (int i = 0; i < number; ++i) {
318 QPointF position(width()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))),
319 height()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))));
320 qreal radius = qMin(width(), height())*(0.0175 + 0.0875*qrand()/(RAND_MAX+1.0));
321 QPointF velocity(width()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)),
322 height()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)));
323
324 bubbles.append(new Bubble(position, radius, velocity));
325 }
326}
327
328void GLWidget::createGeometry()
329{
330 vertices.clear();
331 normals.clear();
332
333 qreal x1 = +0.06f;
334 qreal y1 = -0.14f;
335 qreal x2 = +0.14f;
336 qreal y2 = -0.06f;
337 qreal x3 = +0.08f;
338 qreal y3 = +0.00f;
339 qreal x4 = +0.30f;
340 qreal y4 = +0.22f;
341
342 quad(x1, y1, x2, y2, y2, x2, y1, x1);
343 quad(x3, y3, x4, y4, y4, x4, y3, x3);
344
345 extrude(x1, y1, x2, y2);
346 extrude(x2, y2, y2, x2);
347 extrude(y2, x2, y1, x1);
348 extrude(y1, x1, x1, y1);
349 extrude(x3, y3, x4, y4);
350 extrude(x4, y4, y4, x4);
351 extrude(y4, x4, y3, x3);
352
353 const qreal Pi = 3.14159f;
354 const int NumSectors = 100;
355
356 for (int i = 0; i < NumSectors; ++i) {
357 qreal angle1 = (i * 2 * Pi) / NumSectors;
358 qreal x5 = 0.30 * sin(angle1);
359 qreal y5 = 0.30 * cos(angle1);
360 qreal x6 = 0.20 * sin(angle1);
361 qreal y6 = 0.20 * cos(angle1);
362
363 qreal angle2 = ((i + 1) * 2 * Pi) / NumSectors;
364 qreal x7 = 0.20 * sin(angle2);
365 qreal y7 = 0.20 * cos(angle2);
366 qreal x8 = 0.30 * sin(angle2);
367 qreal y8 = 0.30 * cos(angle2);
368
369 quad(x5, y5, x6, y6, x7, y7, x8, y8);
370
371 extrude(x6, y6, x7, y7);
372 extrude(x8, y8, x5, y5);
373 }
374
375//! [1]
376 m_vertexNumber = vertices.size();
377 createdVertices = new GLfloat[m_vertexNumber];
378 createdNormals = new GLfloat[m_vertexNumber];
379 for (int i = 0;i < m_vertexNumber;i++) {
380 createdVertices[i] = vertices.at(i) * 2;
381 createdNormals[i] = normals.at(i);
382 }
383 vertices.clear();
384 normals.clear();
385}
386//! [1]
387
388//! [0]
389void GLWidget::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4)
390{
391 qreal nx, ny, nz;
392
393 vertices << x1 << y1 << -0.05f;
394 vertices << x2 << y2 << -0.05f;
395 vertices << x4 << y4 << -0.05f;
396
397 vertices << x3 << y3 << -0.05f;
398 vertices << x4 << y4 << -0.05f;
399 vertices << x2 << y2 << -0.05f;
400
401 CrossProduct(nx, ny, nz, x2 - x1, y2 - y1, 0, x4 - x1, y4 - y1, 0);
402 Normalize(nx, ny, nz);
403
404 normals << nx << ny << nz;
405 normals << nx << ny << nz;
406 normals << nx << ny << nz;
407
408 normals << nx << ny << nz;
409 normals << nx << ny << nz;
410 normals << nx << ny << nz;
411
412 vertices << x4 << y4 << 0.05f;
413 vertices << x2 << y2 << 0.05f;
414 vertices << x1 << y1 << 0.05f;
415
416 vertices << x2 << y2 << 0.05f;
417 vertices << x4 << y4 << 0.05f;
418 vertices << x3 << y3 << 0.05f;
419
420 CrossProduct(nx, ny, nz, x2 - x4, y2 - y4, 0, x1 - x4, y1 - y4, 0);
421 Normalize(nx, ny, nz);
422
423 normals << nx << ny << nz;
424 normals << nx << ny << nz;
425 normals << nx << ny << nz;
426
427 normals << nx << ny << nz;
428 normals << nx << ny << nz;
429 normals << nx << ny << nz;
430}
431//! [0]
432
433void GLWidget::extrude(qreal x1, qreal y1, qreal x2, qreal y2)
434{
435 qreal nx, ny, nz;
436
437 vertices << x1 << y1 << +0.05f;
438 vertices << x2 << y2 << +0.05f;
439 vertices << x1 << y1 << -0.05f;
440
441 vertices << x2 << y2 << -0.05f;
442 vertices << x1 << y1 << -0.05f;
443 vertices << x2 << y2 << +0.05f;
444
445 CrossProduct(nx, ny, nz, x2 - x1, y2 - y1, 0.0f, 0.0f, 0.0f, -0.1f);
446 Normalize(nx, ny, nz);
447
448 normals << nx << ny << nz;
449 normals << nx << ny << nz;
450 normals << nx << ny << nz;
451
452 normals << nx << ny << nz;
453 normals << nx << ny << nz;
454 normals << nx << ny << nz;
455}
Note: See TracBrowser for help on using the repository browser.