examples/opengl/hellogl_es2/glwidget.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the examples of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 
       
    50 const int bubbleNum = 8;
       
    51 
       
    52 GLWidget::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 
       
    66 GLWidget::~GLWidget()
       
    67 {
       
    68 }
       
    69 
       
    70 void 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 
       
    80 void GLWidget::setLogo() {
       
    81     qtLogo = true;
       
    82 }
       
    83 
       
    84 void GLWidget::setTexture() {
       
    85     qtLogo = false;
       
    86 }
       
    87 
       
    88 void GLWidget::showBubbles(bool bubbles)
       
    89 {
       
    90    m_showBubbles = bubbles;
       
    91 }
       
    92 
       
    93 void GLWidget::paintQtLogo()
       
    94 {
       
    95     program1.setAttributeArray(vertexAttr1, vertices.constData());
       
    96     program1.setAttributeArray(normalAttr1, normals.constData());
       
    97     glDrawArrays(GL_TRIANGLES, 0, vertices.size());
       
    98     program1.disableAttributeArray(normalAttr1);
       
    99     program1.disableAttributeArray(vertexAttr1);
       
   100 }
       
   101 
       
   102 void GLWidget::paintTexturedCube()
       
   103 {
       
   104     glBindTexture(GL_TEXTURE_2D, m_uiTexture);
       
   105     GLfloat afVertices[] = {
       
   106         -0.5, 0.5, 0.5, 0.5,-0.5,0.5,-0.5,-0.5,0.5,
       
   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 
       
   111         0.5, -0.5, -0.5, 0.5,-0.5,0.5,0.5,0.5,-0.5,
       
   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 
       
   116         0.5, 0.5,  -0.5, -0.5, 0.5,  0.5,  -0.5,  0.5,  -0.5,
       
   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     };
       
   121     program2.setAttributeArray(vertexAttr2, afVertices, 3);
       
   122 
       
   123     GLfloat afTexCoord[] = {
       
   124         0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
       
   125         1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
       
   126         1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
       
   127         0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
       
   128 
       
   129         1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
       
   130         0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
       
   131         0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
       
   132         1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
       
   133 
       
   134         0.0f,1.0f, 1.0f,0.0f, 1.0f,1.0f,
       
   135         1.0f,0.0f, 0.0f,1.0f, 0.0f,0.0f,
       
   136         1.0f,0.0f, 1.0f,1.0f, 0.0f,0.0f,
       
   137         0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f
       
   138     };
       
   139     program2.setAttributeArray(texCoordAttr2, afTexCoord, 2);
       
   140 
       
   141     GLfloat afNormals[] = {
       
   142 
       
   143         0,0,-1, 0,0,-1, 0,0,-1,
       
   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 
       
   148         -1,0,0, -1,0,0, -1,0,0,
       
   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 
       
   153         0,-1,0, 0,-1,0, 0,-1,0,
       
   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     };
       
   158     program2.setAttributeArray(normalAttr2, afNormals, 3);
       
   159 
       
   160     program2.setUniformValue(textureUniform2, 0);    // use texture unit 0
       
   161 
       
   162     glDrawArrays(GL_TRIANGLES, 0, 36);
       
   163 
       
   164     program2.disableAttributeArray(vertexAttr2);
       
   165     program2.disableAttributeArray(normalAttr2);
       
   166     program2.disableAttributeArray(texCoordAttr2);
       
   167 }
       
   168 
       
   169 void GLWidget::initializeGL ()
       
   170 {
       
   171     glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
       
   172 
       
   173     glGenTextures(1, &m_uiTexture);
       
   174     m_uiTexture = bindTexture(QImage(":/qt.png"));
       
   175 
       
   176     QGLShader *vshader1 = new QGLShader(QGLShader::VertexShader, this);
       
   177     const char *vsrc1 =
       
   178         "attribute highp vec4 vertex;\n"
       
   179         "attribute mediump vec3 normal;\n"
       
   180         "uniform mediump mat4 matrix;\n"
       
   181         "varying mediump vec4 color;\n"
       
   182         "void main(void)\n"
       
   183         "{\n"
       
   184         "    vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));\n"
       
   185         "    float angle = max(dot(normal, toLight), 0.0);\n"
       
   186         "    vec3 col = vec3(0.40, 1.0, 0.0);\n"
       
   187         "    color = vec4(col * 0.2 + col * 0.8 * angle, 1.0);\n"
       
   188         "    color = clamp(color, 0.0, 1.0);\n"
       
   189         "    gl_Position = matrix * vertex;\n"
       
   190         "}\n";
       
   191     vshader1->compile(vsrc1);
       
   192 
       
   193     QGLShader *fshader1 = new QGLShader(QGLShader::FragmentShader, this);
       
   194     const char *fsrc1 =
       
   195         "varying mediump vec4 color;\n"
       
   196         "void main(void)\n"
       
   197         "{\n"
       
   198         "    gl_FragColor = color;\n"
       
   199         "}\n";
       
   200     fshader1->compile(fsrc1);
       
   201 
       
   202     program1.addShader(vshader1);
       
   203     program1.addShader(fshader1);
       
   204     program1.link();
       
   205 
       
   206     vertexAttr1 = program1.attributeLocation("vertex");
       
   207     normalAttr1 = program1.attributeLocation("normal");
       
   208     matrixUniform1 = program1.uniformLocation("matrix");
       
   209 
       
   210     QGLShader *vshader2 = new QGLShader(QGLShader::VertexShader);
       
   211     const char *vsrc2 =
       
   212         "attribute highp vec4 vertex;\n"
       
   213         "attribute highp vec4 texCoord;\n"
       
   214         "attribute mediump vec3 normal;\n"
       
   215         "uniform mediump mat4 matrix;\n"
       
   216         "varying highp vec4 texc;\n"
       
   217         "varying mediump float angle;\n"
       
   218         "void main(void)\n"
       
   219         "{\n"
       
   220         "    vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));\n"
       
   221         "    angle = max(dot(normal, toLight), 0.0);\n"
       
   222         "    gl_Position = matrix * vertex;\n"
       
   223         "    texc = texCoord;\n"
       
   224         "}\n";
       
   225     vshader2->compile(vsrc2);
       
   226 
       
   227     QGLShader *fshader2 = new QGLShader(QGLShader::FragmentShader);
       
   228     const char *fsrc2 =
       
   229         "varying highp vec4 texc;\n"
       
   230         "uniform sampler2D tex;\n"
       
   231         "varying mediump float angle;\n"
       
   232         "void main(void)\n"
       
   233         "{\n"
       
   234         "    highp vec3 color = texture2D(tex, texc.st).rgb;\n"
       
   235         "    color = color * 0.2 + color * 0.8 * angle;\n"
       
   236         "    gl_FragColor = vec4(clamp(color, 0.0, 1.0), 1.0);\n"
       
   237         "}\n";
       
   238     fshader2->compile(fsrc2);
       
   239 
       
   240     program2.addShader(vshader2);
       
   241     program2.addShader(fshader2);
       
   242     program2.link();
       
   243 
       
   244     vertexAttr2 = program2.attributeLocation("vertex");
       
   245     normalAttr2 = program2.attributeLocation("normal");
       
   246     texCoordAttr2 = program2.attributeLocation("texCoord");
       
   247     matrixUniform2 = program2.uniformLocation("matrix");
       
   248     textureUniform2 = program2.uniformLocation("tex");
       
   249 
       
   250     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
       
   251     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
       
   252 
       
   253     m_fAngle = 0;
       
   254     m_fScale = 1;
       
   255     createGeometry();
       
   256     createBubbles(bubbleNum - bubbles.count());
       
   257 }
       
   258 
       
   259 void GLWidget::paintGL()
       
   260 {
       
   261     createBubbles(bubbleNum - bubbles.count());
       
   262 
       
   263     QPainter painter;
       
   264     painter.begin(this);
       
   265 
       
   266     painter.beginNativePainting();
       
   267 
       
   268     glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
       
   269     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       
   270 
       
   271     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
       
   272     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
       
   273 
       
   274     glFrontFace(GL_CW);
       
   275     glCullFace(GL_FRONT);
       
   276     glEnable(GL_CULL_FACE);
       
   277     glEnable(GL_DEPTH_TEST);
       
   278 
       
   279     QMatrix4x4 modelview;
       
   280     modelview.rotate(m_fAngle, 0.0f, 1.0f, 0.0f);
       
   281     modelview.rotate(m_fAngle, 1.0f, 0.0f, 0.0f);
       
   282     modelview.rotate(m_fAngle, 0.0f, 0.0f, 1.0f);
       
   283     modelview.scale(m_fScale);
       
   284     modelview.translate(0.0f, -0.2f, 0.0f);
       
   285 
       
   286     if (qtLogo) {
       
   287         program1.enable();
       
   288         program1.setUniformValue(matrixUniform1, modelview);
       
   289         paintQtLogo();
       
   290         program1.disable();
       
   291     } else {
       
   292         program2.enable();
       
   293         program1.setUniformValue(matrixUniform2, modelview);
       
   294         paintTexturedCube();
       
   295         program2.disable();
       
   296     }
       
   297 
       
   298     glDisable(GL_DEPTH_TEST);
       
   299     glDisable(GL_CULL_FACE);
       
   300 
       
   301     painter.endNativePainting();
       
   302 
       
   303     if (m_showBubbles)
       
   304         foreach (Bubble *bubble, bubbles) {
       
   305             bubble->drawBubble(&painter);
       
   306     }
       
   307 
       
   308     QString framesPerSecond;
       
   309     framesPerSecond.setNum(frames /(time.elapsed() / 1000.0), 'f', 2);
       
   310 
       
   311     painter.setPen(Qt::white);
       
   312 
       
   313     painter.drawText(20, 40, framesPerSecond + " fps");
       
   314 
       
   315     painter.end();
       
   316     
       
   317     swapBuffers();
       
   318 
       
   319     QMutableListIterator<Bubble*> iter(bubbles);
       
   320 
       
   321     while (iter.hasNext()) {
       
   322         Bubble *bubble = iter.next();
       
   323         bubble->move(rect());
       
   324     }
       
   325     if (!(frames % 100)) {
       
   326         time.start();
       
   327         frames = 0;
       
   328     }
       
   329     m_fAngle += 1.0f;
       
   330     frames ++;
       
   331 }
       
   332 
       
   333 void GLWidget::createBubbles(int number)
       
   334 {
       
   335     for (int i = 0; i < number; ++i) {
       
   336         QPointF position(width()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))),
       
   337                         height()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))));
       
   338         qreal radius = qMin(width(), height())*(0.0175 + 0.0875*qrand()/(RAND_MAX+1.0));
       
   339         QPointF velocity(width()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)),
       
   340                         height()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)));
       
   341 
       
   342         bubbles.append(new Bubble(position, radius, velocity));
       
   343     }
       
   344 }
       
   345 
       
   346 void GLWidget::createGeometry()
       
   347 {
       
   348     vertices.clear();
       
   349     normals.clear();
       
   350 
       
   351     qreal x1 = +0.06f;
       
   352     qreal y1 = -0.14f;
       
   353     qreal x2 = +0.14f;
       
   354     qreal y2 = -0.06f;
       
   355     qreal x3 = +0.08f;
       
   356     qreal y3 = +0.00f;
       
   357     qreal x4 = +0.30f;
       
   358     qreal y4 = +0.22f;
       
   359 
       
   360     quad(x1, y1, x2, y2, y2, x2, y1, x1);
       
   361     quad(x3, y3, x4, y4, y4, x4, y3, x3);
       
   362 
       
   363     extrude(x1, y1, x2, y2);
       
   364     extrude(x2, y2, y2, x2);
       
   365     extrude(y2, x2, y1, x1);
       
   366     extrude(y1, x1, x1, y1);
       
   367     extrude(x3, y3, x4, y4);
       
   368     extrude(x4, y4, y4, x4);
       
   369     extrude(y4, x4, y3, x3);
       
   370 
       
   371     const qreal Pi = 3.14159f;
       
   372     const int NumSectors = 100;
       
   373 
       
   374     for (int i = 0; i < NumSectors; ++i) {
       
   375         qreal angle1 = (i * 2 * Pi) / NumSectors;
       
   376         qreal x5 = 0.30 * sin(angle1);
       
   377         qreal y5 = 0.30 * cos(angle1);
       
   378         qreal x6 = 0.20 * sin(angle1);
       
   379         qreal y6 = 0.20 * cos(angle1);
       
   380 
       
   381         qreal angle2 = ((i + 1) * 2 * Pi) / NumSectors;
       
   382         qreal x7 = 0.20 * sin(angle2);
       
   383         qreal y7 = 0.20 * cos(angle2);
       
   384         qreal x8 = 0.30 * sin(angle2);
       
   385         qreal y8 = 0.30 * cos(angle2);
       
   386 
       
   387         quad(x5, y5, x6, y6, x7, y7, x8, y8);
       
   388 
       
   389         extrude(x6, y6, x7, y7);
       
   390         extrude(x8, y8, x5, y5);
       
   391     }
       
   392 
       
   393     for (int i = 0;i < vertices.size();i++)
       
   394         vertices[i] *= 2.0f;
       
   395 }
       
   396 
       
   397 void GLWidget::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4)
       
   398 {
       
   399     vertices << QVector3D(x1, y1, -0.05f);
       
   400     vertices << QVector3D(x2, y2, -0.05f);
       
   401     vertices << QVector3D(x4, y4, -0.05f);
       
   402 
       
   403     vertices << QVector3D(x3, y3, -0.05f);
       
   404     vertices << QVector3D(x4, y4, -0.05f);
       
   405     vertices << QVector3D(x2, y2, -0.05f);
       
   406 
       
   407     QVector3D n = QVector3D::normal
       
   408         (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(x4 - x1, y4 - y1, 0.0f));
       
   409 
       
   410     normals << n;
       
   411     normals << n;
       
   412     normals << n;
       
   413 
       
   414     normals << n;
       
   415     normals << n;
       
   416     normals << n;
       
   417 
       
   418     vertices << QVector3D(x4, y4, 0.05f);
       
   419     vertices << QVector3D(x2, y2, 0.05f);
       
   420     vertices << QVector3D(x1, y1, 0.05f);
       
   421 
       
   422     vertices << QVector3D(x2, y2, 0.05f);
       
   423     vertices << QVector3D(x4, y4, 0.05f);
       
   424     vertices << QVector3D(x3, y3, 0.05f);
       
   425 
       
   426     n = QVector3D::normal
       
   427         (QVector3D(x2 - x4, y2 - y4, 0.0f), QVector3D(x1 - x4, y1 - y4, 0.0f));
       
   428 
       
   429     normals << n;
       
   430     normals << n;
       
   431     normals << n;
       
   432 
       
   433     normals << n;
       
   434     normals << n;
       
   435     normals << n;
       
   436 }
       
   437 
       
   438 void GLWidget::extrude(qreal x1, qreal y1, qreal x2, qreal y2)
       
   439 {
       
   440     vertices << QVector3D(x1, y1, +0.05f);
       
   441     vertices << QVector3D(x2, y2, +0.05f);
       
   442     vertices << QVector3D(x1, y1, -0.05f);
       
   443 
       
   444     vertices << QVector3D(x2, y2, -0.05f);
       
   445     vertices << QVector3D(x1, y1, -0.05f);
       
   446     vertices << QVector3D(x2, y2, +0.05f);
       
   447 
       
   448     QVector3D n = QVector3D::normal
       
   449         (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(0.0f, 0.0f, -0.1f));
       
   450 
       
   451     normals << n;
       
   452     normals << n;
       
   453     normals << n;
       
   454 
       
   455     normals << n;
       
   456     normals << n;
       
   457     normals << n;
       
   458 }