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

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