source: trunk/examples/opengl/hellogl_es2/glwidget.cpp@ 642

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

trunk: Merged in qt 4.6.1 sources.

File size: 13.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 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 "glwidget.h"
43#include <QPainter>
44#include <QPaintEngine>
45#include <math.h>
46
47#include "bubble.h"
48
49
50const int bubbleNum = 8;
51
52GLWidget::GLWidget(QWidget *parent)
53 : QGLWidget(parent)
54{
55 qtLogo = true;
56 frames = 0;
57 setAttribute(Qt::WA_PaintOnScreen);
58 setAttribute(Qt::WA_NoSystemBackground);
59 setAutoBufferSwap(false);
60 m_showBubbles = true;
61#ifndef Q_WS_QWS
62 setMinimumSize(300, 250);
63#endif
64}
65
66GLWidget::~GLWidget()
67{
68}
69
70void GLWidget::setScaling(int scale) {
71
72 if (scale > 50)
73 m_fScale = 1 + qreal(scale -50) / 50 * 0.5;
74 else if (scale < 50)
75 m_fScale = 1- (qreal(50 - scale) / 50 * 1/2);
76 else
77 m_fScale = 1;
78}
79
80void GLWidget::setLogo() {
81 qtLogo = true;
82}
83
84void GLWidget::setTexture() {
85 qtLogo = false;
86}
87
88void GLWidget::showBubbles(bool bubbles)
89{
90 m_showBubbles = bubbles;
91}
92
93void GLWidget::paintQtLogo()
94{
95 program1.enableAttributeArray(normalAttr1);
96 program1.enableAttributeArray(vertexAttr1);
97 program1.setAttributeArray(vertexAttr1, vertices.constData());
98 program1.setAttributeArray(normalAttr1, normals.constData());
99 glDrawArrays(GL_TRIANGLES, 0, vertices.size());
100 program1.disableAttributeArray(normalAttr1);
101 program1.disableAttributeArray(vertexAttr1);
102}
103
104void GLWidget::paintTexturedCube()
105{
106 glBindTexture(GL_TEXTURE_2D, m_uiTexture);
107 GLfloat afVertices[] = {
108 -0.5, 0.5, 0.5, 0.5,-0.5,0.5,-0.5,-0.5,0.5,
109 0.5, -0.5, 0.5, -0.5,0.5,0.5,0.5,0.5,0.5,
110 -0.5, -0.5, -0.5, 0.5,-0.5,-0.5,-0.5,0.5,-0.5,
111 0.5, 0.5, -0.5, -0.5,0.5,-0.5,0.5,-0.5,-0.5,
112
113 0.5, -0.5, -0.5, 0.5,-0.5,0.5,0.5,0.5,-0.5,
114 0.5, 0.5, 0.5, 0.5,0.5,-0.5,0.5,-0.5,0.5,
115 -0.5, 0.5, -0.5, -0.5,-0.5,0.5,-0.5,-0.5,-0.5,
116 -0.5, -0.5, 0.5, -0.5,0.5,-0.5,-0.5,0.5,0.5,
117
118 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5,
119 -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5,
120 -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5,
121 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5
122 };
123 program2.setAttributeArray(vertexAttr2, afVertices, 3);
124
125 GLfloat afTexCoord[] = {
126 0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
127 1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
128 1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
129 0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
130
131 1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
132 0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
133 0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
134 1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
135
136 0.0f,1.0f, 1.0f,0.0f, 1.0f,1.0f,
137 1.0f,0.0f, 0.0f,1.0f, 0.0f,0.0f,
138 1.0f,0.0f, 1.0f,1.0f, 0.0f,0.0f,
139 0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f
140 };
141 program2.setAttributeArray(texCoordAttr2, afTexCoord, 2);
142
143 GLfloat afNormals[] = {
144
145 0,0,-1, 0,0,-1, 0,0,-1,
146 0,0,-1, 0,0,-1, 0,0,-1,
147 0,0,1, 0,0,1, 0,0,1,
148 0,0,1, 0,0,1, 0,0,1,
149
150 -1,0,0, -1,0,0, -1,0,0,
151 -1,0,0, -1,0,0, -1,0,0,
152 1,0,0, 1,0,0, 1,0,0,
153 1,0,0, 1,0,0, 1,0,0,
154
155 0,-1,0, 0,-1,0, 0,-1,0,
156 0,-1,0, 0,-1,0, 0,-1,0,
157 0,1,0, 0,1,0, 0,1,0,
158 0,1,0, 0,1,0, 0,1,0
159 };
160 program2.setAttributeArray(normalAttr2, afNormals, 3);
161
162 program2.setUniformValue(textureUniform2, 0); // use texture unit 0
163
164 program2.enableAttributeArray(vertexAttr2);
165 program2.enableAttributeArray(normalAttr2);
166 program2.enableAttributeArray(texCoordAttr2);
167
168 glDrawArrays(GL_TRIANGLES, 0, 36);
169
170 program2.disableAttributeArray(vertexAttr2);
171 program2.disableAttributeArray(normalAttr2);
172 program2.disableAttributeArray(texCoordAttr2);
173}
174
175void GLWidget::initializeGL ()
176{
177 glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
178
179 glGenTextures(1, &m_uiTexture);
180 m_uiTexture = bindTexture(QImage(":/qt.png"));
181
182 QGLShader *vshader1 = new QGLShader(QGLShader::Vertex, this);
183 const char *vsrc1 =
184 "attribute highp vec4 vertex;\n"
185 "attribute mediump vec3 normal;\n"
186 "uniform mediump mat4 matrix;\n"
187 "varying mediump vec4 color;\n"
188 "void main(void)\n"
189 "{\n"
190 " vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));\n"
191 " float angle = max(dot(normal, toLight), 0.0);\n"
192 " vec3 col = vec3(0.40, 1.0, 0.0);\n"
193 " color = vec4(col * 0.2 + col * 0.8 * angle, 1.0);\n"
194 " color = clamp(color, 0.0, 1.0);\n"
195 " gl_Position = matrix * vertex;\n"
196 "}\n";
197 vshader1->compileSourceCode(vsrc1);
198
199 QGLShader *fshader1 = new QGLShader(QGLShader::Fragment, this);
200 const char *fsrc1 =
201 "varying mediump vec4 color;\n"
202 "void main(void)\n"
203 "{\n"
204 " gl_FragColor = color;\n"
205 "}\n";
206 fshader1->compileSourceCode(fsrc1);
207
208 program1.addShader(vshader1);
209 program1.addShader(fshader1);
210 program1.link();
211
212 vertexAttr1 = program1.attributeLocation("vertex");
213 normalAttr1 = program1.attributeLocation("normal");
214 matrixUniform1 = program1.uniformLocation("matrix");
215
216 QGLShader *vshader2 = new QGLShader(QGLShader::Vertex);
217 const char *vsrc2 =
218 "attribute highp vec4 vertex;\n"
219 "attribute highp vec4 texCoord;\n"
220 "attribute mediump vec3 normal;\n"
221 "uniform mediump mat4 matrix;\n"
222 "varying highp vec4 texc;\n"
223 "varying mediump float angle;\n"
224 "void main(void)\n"
225 "{\n"
226 " vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));\n"
227 " angle = max(dot(normal, toLight), 0.0);\n"
228 " gl_Position = matrix * vertex;\n"
229 " texc = texCoord;\n"
230 "}\n";
231 vshader2->compileSourceCode(vsrc2);
232
233 QGLShader *fshader2 = new QGLShader(QGLShader::Fragment);
234 const char *fsrc2 =
235 "varying highp vec4 texc;\n"
236 "uniform sampler2D tex;\n"
237 "varying mediump float angle;\n"
238 "void main(void)\n"
239 "{\n"
240 " highp vec3 color = texture2D(tex, texc.st).rgb;\n"
241 " color = color * 0.2 + color * 0.8 * angle;\n"
242 " gl_FragColor = vec4(clamp(color, 0.0, 1.0), 1.0);\n"
243 "}\n";
244 fshader2->compileSourceCode(fsrc2);
245
246 program2.addShader(vshader2);
247 program2.addShader(fshader2);
248 program2.link();
249
250 vertexAttr2 = program2.attributeLocation("vertex");
251 normalAttr2 = program2.attributeLocation("normal");
252 texCoordAttr2 = program2.attributeLocation("texCoord");
253 matrixUniform2 = program2.uniformLocation("matrix");
254 textureUniform2 = program2.uniformLocation("tex");
255
256 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
257 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
258
259 m_fAngle = 0;
260 m_fScale = 1;
261 createGeometry();
262 createBubbles(bubbleNum - bubbles.count());
263}
264
265void GLWidget::paintGL()
266{
267 createBubbles(bubbleNum - bubbles.count());
268
269 QPainter painter;
270 painter.begin(this);
271
272 painter.beginNativePainting();
273
274 glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
275 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
276
277 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
278 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
279
280 glFrontFace(GL_CW);
281 glCullFace(GL_FRONT);
282 glEnable(GL_CULL_FACE);
283 glEnable(GL_DEPTH_TEST);
284
285 QMatrix4x4 modelview;
286 modelview.rotate(m_fAngle, 0.0f, 1.0f, 0.0f);
287 modelview.rotate(m_fAngle, 1.0f, 0.0f, 0.0f);
288 modelview.rotate(m_fAngle, 0.0f, 0.0f, 1.0f);
289 modelview.scale(m_fScale);
290 modelview.translate(0.0f, -0.2f, 0.0f);
291
292 if (qtLogo) {
293 program1.bind();
294 program1.setUniformValue(matrixUniform1, modelview);
295 paintQtLogo();
296 program1.release();
297 } else {
298 program2.bind();
299 program1.setUniformValue(matrixUniform2, modelview);
300 paintTexturedCube();
301 program2.release();
302 }
303
304 glDisable(GL_DEPTH_TEST);
305 glDisable(GL_CULL_FACE);
306
307 painter.endNativePainting();
308
309 if (m_showBubbles)
310 foreach (Bubble *bubble, bubbles) {
311 bubble->drawBubble(&painter);
312 }
313
314 QString framesPerSecond;
315 framesPerSecond.setNum(frames /(time.elapsed() / 1000.0), 'f', 2);
316
317 painter.setPen(Qt::white);
318
319 painter.drawText(20, 40, framesPerSecond + " fps");
320
321 painter.end();
322
323 swapBuffers();
324
325 QMutableListIterator<Bubble*> iter(bubbles);
326
327 while (iter.hasNext()) {
328 Bubble *bubble = iter.next();
329 bubble->move(rect());
330 }
331 if (!(frames % 100)) {
332 time.start();
333 frames = 0;
334 }
335 m_fAngle += 1.0f;
336 frames ++;
337}
338
339void GLWidget::createBubbles(int number)
340{
341 for (int i = 0; i < number; ++i) {
342 QPointF position(width()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))),
343 height()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))));
344 qreal radius = qMin(width(), height())*(0.0175 + 0.0875*qrand()/(RAND_MAX+1.0));
345 QPointF velocity(width()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)),
346 height()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)));
347
348 bubbles.append(new Bubble(position, radius, velocity));
349 }
350}
351
352void GLWidget::createGeometry()
353{
354 vertices.clear();
355 normals.clear();
356
357 qreal x1 = +0.06f;
358 qreal y1 = -0.14f;
359 qreal x2 = +0.14f;
360 qreal y2 = -0.06f;
361 qreal x3 = +0.08f;
362 qreal y3 = +0.00f;
363 qreal x4 = +0.30f;
364 qreal y4 = +0.22f;
365
366 quad(x1, y1, x2, y2, y2, x2, y1, x1);
367 quad(x3, y3, x4, y4, y4, x4, y3, x3);
368
369 extrude(x1, y1, x2, y2);
370 extrude(x2, y2, y2, x2);
371 extrude(y2, x2, y1, x1);
372 extrude(y1, x1, x1, y1);
373 extrude(x3, y3, x4, y4);
374 extrude(x4, y4, y4, x4);
375 extrude(y4, x4, y3, x3);
376
377 const qreal Pi = 3.14159f;
378 const int NumSectors = 100;
379
380 for (int i = 0; i < NumSectors; ++i) {
381 qreal angle1 = (i * 2 * Pi) / NumSectors;
382 qreal x5 = 0.30 * sin(angle1);
383 qreal y5 = 0.30 * cos(angle1);
384 qreal x6 = 0.20 * sin(angle1);
385 qreal y6 = 0.20 * cos(angle1);
386
387 qreal angle2 = ((i + 1) * 2 * Pi) / NumSectors;
388 qreal x7 = 0.20 * sin(angle2);
389 qreal y7 = 0.20 * cos(angle2);
390 qreal x8 = 0.30 * sin(angle2);
391 qreal y8 = 0.30 * cos(angle2);
392
393 quad(x5, y5, x6, y6, x7, y7, x8, y8);
394
395 extrude(x6, y6, x7, y7);
396 extrude(x8, y8, x5, y5);
397 }
398
399 for (int i = 0;i < vertices.size();i++)
400 vertices[i] *= 2.0f;
401}
402
403void GLWidget::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4)
404{
405 vertices << QVector3D(x1, y1, -0.05f);
406 vertices << QVector3D(x2, y2, -0.05f);
407 vertices << QVector3D(x4, y4, -0.05f);
408
409 vertices << QVector3D(x3, y3, -0.05f);
410 vertices << QVector3D(x4, y4, -0.05f);
411 vertices << QVector3D(x2, y2, -0.05f);
412
413 QVector3D n = QVector3D::normal
414 (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(x4 - x1, y4 - y1, 0.0f));
415
416 normals << n;
417 normals << n;
418 normals << n;
419
420 normals << n;
421 normals << n;
422 normals << n;
423
424 vertices << QVector3D(x4, y4, 0.05f);
425 vertices << QVector3D(x2, y2, 0.05f);
426 vertices << QVector3D(x1, y1, 0.05f);
427
428 vertices << QVector3D(x2, y2, 0.05f);
429 vertices << QVector3D(x4, y4, 0.05f);
430 vertices << QVector3D(x3, y3, 0.05f);
431
432 n = QVector3D::normal
433 (QVector3D(x2 - x4, y2 - y4, 0.0f), QVector3D(x1 - x4, y1 - y4, 0.0f));
434
435 normals << n;
436 normals << n;
437 normals << n;
438
439 normals << n;
440 normals << n;
441 normals << n;
442}
443
444void GLWidget::extrude(qreal x1, qreal y1, qreal x2, qreal y2)
445{
446 vertices << QVector3D(x1, y1, +0.05f);
447 vertices << QVector3D(x2, y2, +0.05f);
448 vertices << QVector3D(x1, y1, -0.05f);
449
450 vertices << QVector3D(x2, y2, -0.05f);
451 vertices << QVector3D(x1, y1, -0.05f);
452 vertices << QVector3D(x2, y2, +0.05f);
453
454 QVector3D n = QVector3D::normal
455 (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(0.0f, 0.0f, -0.1f));
456
457 normals << n;
458 normals << n;
459 normals << n;
460
461 normals << n;
462 normals << n;
463 normals << n;
464}
Note: See TracBrowser for help on using the repository browser.