util/examples/opengl/hellogl_es2/glwidget.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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.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 
       
   104 void 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 
       
   175 void 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 
       
   265 void 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 
       
   339 void 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 
       
   352 void 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 
       
   403 void 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 
       
   444 void 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 }