diff options
Diffstat (limited to 'examples/opengl')
19 files changed, 941 insertions, 184 deletions
diff --git a/examples/opengl/hellogl_es2/hellogl_es2.pro b/examples/opengl/hellogl_es2/hellogl_es2.pro deleted file mode 100644 index b15e8d1909..0000000000 --- a/examples/opengl/hellogl_es2/hellogl_es2.pro +++ /dev/null @@ -1,23 +0,0 @@ -QT += opengl widgets - -SOURCES += main.cpp -SOURCES += glwidget.cpp -SOURCES += mainwindow.cpp -SOURCES += bubble.cpp - -HEADERS += glwidget.h -HEADERS += mainwindow.h -HEADERS += bubble.h - -RESOURCES += texture.qrc - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/opengl/hellogl_es2 -INSTALLS += target - -maemo5 { - # Debian package name may not contain numbers or special characters - # such as '_', lets change this in Maemo. - TARGET = helloglestwo - CONFIG += qt_example -} diff --git a/examples/opengl/hellogl_es2/mainwindow.cpp b/examples/opengl/hellogl_es2/mainwindow.cpp deleted file mode 100644 index eb4ce0ac3e..0000000000 --- a/examples/opengl/hellogl_es2/mainwindow.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mainwindow.h" - -#include <QApplication> -#include <QMenuBar> -#include <QGroupBox> -#include <QGridLayout> -#include <QSlider> -#include <QLabel> -#include <QTimer> - -#include "glwidget.h" - -MainWindow::MainWindow() -{ - GLWidget *glwidget = new GLWidget(); - QLabel *label = new QLabel(this); - QTimer *timer = new QTimer(this); - QSlider *slider = new QSlider(this); - slider->setOrientation(Qt::Horizontal); - - slider->setRange(0, 100); - slider->setSliderPosition(50); - timer->setInterval(10); - label->setText("A QGlWidget with OpenGl ES"); - label->setAlignment(Qt::AlignHCenter); - - QGroupBox * groupBox = new QGroupBox(this); - setCentralWidget(groupBox); - groupBox->setTitle("OpenGL ES Example"); - - QGridLayout *layout = new QGridLayout(groupBox); - - layout->addWidget(glwidget,1,0,8,1); - layout->addWidget(label,9,0,1,1); - layout->addWidget(slider, 11,0,1,1); - - groupBox->setLayout(layout); - - QMenu *fileMenu = new QMenu("File"); - QMenu *helpMenu = new QMenu("Help"); - QMenu *showMenu = new QMenu("Show"); - menuBar()->addMenu(fileMenu); - menuBar()->addMenu(showMenu); - menuBar()->addMenu(helpMenu); - QAction *exit = new QAction("Exit", fileMenu); - QAction *aboutQt = new QAction("AboutQt", helpMenu); - QAction *showLogo = new QAction("Show 3D Logo", showMenu); - QAction *showTexture = new QAction("Show 2D Texture", showMenu); - QAction *showBubbles = new QAction("Show bubbles", showMenu); - showBubbles->setCheckable(true); - showBubbles->setChecked(true); - fileMenu->addAction(exit); - helpMenu->addAction(aboutQt); - showMenu->addAction(showLogo); - showMenu->addAction(showTexture); - showMenu->addAction(showBubbles); - - QObject::connect(timer, SIGNAL(timeout()), glwidget, SLOT(updateGL())); - QObject::connect(exit, SIGNAL(triggered(bool)), this, SLOT(close())); - QObject::connect(aboutQt, SIGNAL(triggered(bool)), qApp, SLOT(aboutQt())); - - QObject::connect(showLogo, SIGNAL(triggered(bool)), glwidget, SLOT(setLogo())); - QObject::connect(showTexture, SIGNAL(triggered(bool)), glwidget, SLOT(setTexture())); - QObject::connect(showBubbles, SIGNAL(triggered(bool)), glwidget, SLOT(showBubbles(bool))); - QObject::connect(slider, SIGNAL(valueChanged(int)), glwidget, SLOT(setScaling(int))); - timer->start(); -} diff --git a/examples/opengl/opengl.pro b/examples/opengl/opengl.pro index aea281ce5c..fb5f02c07c 100644 --- a/examples/opengl/opengl.pro +++ b/examples/opengl/opengl.pro @@ -5,10 +5,9 @@ TEMPLATE = subdirs contains(QT_CONFIG, dynamicgl) { SUBDIRS = hellowindow \ contextinfo \ - hellogl_es2 -} else: contains(QT_CONFIG, opengles2){ - SUBDIRS = hellogl_es2 -} else { + qopenglwidget \ + threadedqopenglwidget +} else: !contains(QT_CONFIG, opengles2) { SUBDIRS = 2dpainting \ grabber \ hellogl \ @@ -22,6 +21,8 @@ contains(QT_CONFIG, dynamicgl) { paintedwindow \ contextinfo \ cube \ - textures + textures \ + qopenglwidget \ + threadedqopenglwidget EXAMPLE_FILES = shared diff --git a/examples/opengl/hellogl_es2/bubble.cpp b/examples/opengl/qopenglwidget/bubble.cpp index 3e0f053bc8..bf04c64966 100644 --- a/examples/opengl/hellogl_es2/bubble.cpp +++ b/examples/opengl/qopenglwidget/bubble.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the examples of the Qt Toolkit. diff --git a/examples/opengl/hellogl_es2/bubble.h b/examples/opengl/qopenglwidget/bubble.h index 60195b4415..ea33466ef7 100644 --- a/examples/opengl/hellogl_es2/bubble.h +++ b/examples/opengl/qopenglwidget/bubble.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the examples of the Qt Toolkit. diff --git a/examples/opengl/hellogl_es2/glwidget.cpp b/examples/opengl/qopenglwidget/glwidget.cpp index 733475d321..e95ca363fc 100644 --- a/examples/opengl/hellogl_es2/glwidget.cpp +++ b/examples/opengl/qopenglwidget/glwidget.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the examples of the Qt Toolkit. @@ -43,19 +43,25 @@ #include <QPaintEngine> #include <math.h> +#include "mainwindow.h" #include "bubble.h" - const int bubbleNum = 8; -GLWidget::GLWidget(QWidget *parent) - : QGLWidget(parent) +GLWidget::GLWidget(MainWindow *mw, bool button, const QColor &background) + : m_mainWindow(mw), + m_transparent(false), + m_btn(0), + m_hasButton(button), + m_background(background) { + QSurfaceFormat format; + format.setDepthBufferSize(24); + format.setStencilBufferSize(8); + setFormat(format); + qtLogo = true; frames = 0; - setAttribute(Qt::WA_PaintOnScreen); - setAttribute(Qt::WA_NoSystemBackground); - setAutoBufferSwap(false); m_showBubbles = true; setMinimumSize(300, 250); } @@ -66,10 +72,10 @@ GLWidget::~GLWidget() void GLWidget::setScaling(int scale) { - if (scale > 50) - m_fScale = 1 + qreal(scale -50) / 50 * 0.5; - else if (scale < 50) - m_fScale = 1- (qreal(50 - scale) / 50 * 1/2); + if (scale > 30) + m_fScale = 1 + qreal(scale - 30) / 30 * 0.25; + else if (scale < 30) + m_fScale = 1 - (qreal(30 - scale) / 30 * 0.25); else m_fScale = 1; } @@ -173,12 +179,14 @@ void GLWidget::initializeGL () { initializeOpenGLFunctions(); - glClearColor(0.1f, 0.1f, 0.2f, 1.0f); - glGenTextures(1, &m_uiTexture); - m_uiTexture = bindTexture(QImage(":/qt.png")); + QImage img = QImage(":/qt.png").convertToFormat(QImage::Format_RGBA8888); + glBindTexture(GL_TEXTURE_2D, m_uiTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.constBits()); - QGLShader *vshader1 = new QGLShader(QGLShader::Vertex, this); + QOpenGLShader *vshader1 = new QOpenGLShader(QOpenGLShader::Vertex, this); const char *vsrc1 = "attribute highp vec4 vertex;\n" "attribute mediump vec3 normal;\n" @@ -195,7 +203,7 @@ void GLWidget::initializeGL () "}\n"; vshader1->compileSourceCode(vsrc1); - QGLShader *fshader1 = new QGLShader(QGLShader::Fragment, this); + QOpenGLShader *fshader1 = new QOpenGLShader(QOpenGLShader::Fragment, this); const char *fsrc1 = "varying mediump vec4 color;\n" "void main(void)\n" @@ -212,7 +220,7 @@ void GLWidget::initializeGL () normalAttr1 = program1.attributeLocation("normal"); matrixUniform1 = program1.uniformLocation("matrix"); - QGLShader *vshader2 = new QGLShader(QGLShader::Vertex); + QOpenGLShader *vshader2 = new QOpenGLShader(QOpenGLShader::Vertex); const char *vsrc2 = "attribute highp vec4 vertex;\n" "attribute highp vec4 texCoord;\n" @@ -229,7 +237,7 @@ void GLWidget::initializeGL () "}\n"; vshader2->compileSourceCode(vsrc2); - QGLShader *fshader2 = new QGLShader(QGLShader::Fragment); + QOpenGLShader *fshader2 = new QOpenGLShader(QOpenGLShader::Fragment); const char *fsrc2 = "varying highp vec4 texc;\n" "uniform sampler2D tex;\n" @@ -252,9 +260,6 @@ void GLWidget::initializeGL () matrixUniform2 = program2.uniformLocation("matrix"); textureUniform2 = program2.uniformLocation("tex"); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - m_fAngle = 0; m_fScale = 1; createGeometry(); @@ -270,12 +275,10 @@ void GLWidget::paintGL() painter.beginNativePainting(); - glClearColor(0.1f, 0.1f, 0.2f, 1.0f); + glClearColor(m_background.red() / 255.0f, m_background.green() / 255.0f, + m_background.blue() / 255.0f, m_transparent ? 0.0f : 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glFrontFace(GL_CW); glCullFace(GL_FRONT); glEnable(GL_CULL_FACE); @@ -313,14 +316,12 @@ void GLWidget::paintGL() if (const int elapsed = time.elapsed()) { QString framesPerSecond; framesPerSecond.setNum(frames /(elapsed / 1000.0), 'f', 2); - painter.setPen(Qt::white); - painter.drawText(20, 40, framesPerSecond + " fps"); + painter.setPen(m_transparent ? Qt::black : Qt::white); + painter.drawText(20, 40, framesPerSecond + " paintGL calls / s"); } painter.end(); - swapBuffers(); - QMutableListIterator<Bubble*> iter(bubbles); while (iter.hasNext()) { @@ -461,3 +462,28 @@ void GLWidget::extrude(qreal x1, qreal y1, qreal x2, qreal y2) normals << n; normals << n; } + +void GLWidget::setTransparent(bool transparent) +{ + setAttribute(Qt::WA_AlwaysStackOnTop, transparent); + m_transparent = transparent; + // Call update() on the top-level window after toggling AlwayStackOnTop to make sure + // the entire backingstore is updated accordingly. + window()->update(); +} + +void GLWidget::resizeGL(int w, int h) +{ + if (m_hasButton) { + if (!m_btn) { + m_btn = new QPushButton("A widget on top.\nPress me!", this); + connect(m_btn, &QPushButton::clicked, this, &GLWidget::handleButtonPress); + } + m_btn->move(w / 2, h / 2); + } +} + +void GLWidget::handleButtonPress() +{ + m_mainWindow->addNew(); +} diff --git a/examples/opengl/hellogl_es2/glwidget.h b/examples/opengl/qopenglwidget/glwidget.h index 00073aa047..6c43ac1576 100644 --- a/examples/opengl/hellogl_es2/glwidget.h +++ b/examples/opengl/qopenglwidget/glwidget.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the examples of the Qt Toolkit. @@ -41,33 +41,45 @@ #ifndef GLWIDGET_H #define GLWIDGET_H -#include <QGLWidget> +#include <QOpenGLWidget> #include <QOpenGLFunctions> -#include <QGLShaderProgram> +#include <QOpenGLShaderProgram> #include <QVector3D> #include <QMatrix4x4> #include <QTime> #include <QVector> +#include <QPushButton> class Bubble; -class GLWidget : public QGLWidget, protected QOpenGLFunctions +class MainWindow; + +class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT public: - GLWidget(QWidget *parent = 0); + GLWidget(MainWindow *mw, bool button, const QColor &background); ~GLWidget(); + public slots: void setScaling(int scale); void setLogo(); void setTexture(); void showBubbles(bool); + void setTransparent(bool transparent); + +private slots: + void handleButtonPress(); + protected: - void paintGL (); - void initializeGL (); + void resizeGL(int w, int h) Q_DECL_OVERRIDE; + void paintGL() Q_DECL_OVERRIDE; + void initializeGL() Q_DECL_OVERRIDE; + private: - GLuint m_uiTexture; - qreal m_fAngle; - qreal m_fScale; + MainWindow *m_mainWindow; + GLuint m_uiTexture; + qreal m_fAngle; + qreal m_fScale; bool m_showBubbles; void paintTexturedCube(); void paintQtLogo(); @@ -81,8 +93,8 @@ private: QList<Bubble*> bubbles; int frames; QTime time; - QGLShaderProgram program1; - QGLShaderProgram program2; + QOpenGLShaderProgram program1; + QOpenGLShaderProgram program2; int vertexAttr1; int normalAttr1; int matrixUniform1; @@ -91,5 +103,10 @@ private: int texCoordAttr2; int matrixUniform2; int textureUniform2; + bool m_transparent; + QPushButton *m_btn; + bool m_hasButton; + QColor m_background; }; + #endif diff --git a/examples/opengl/hellogl_es2/main.cpp b/examples/opengl/qopenglwidget/main.cpp index 5fb3385989..2156e60155 100644 --- a/examples/opengl/hellogl_es2/main.cpp +++ b/examples/opengl/qopenglwidget/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the examples of the Qt Toolkit. diff --git a/examples/opengl/qopenglwidget/mainwindow.cpp b/examples/opengl/qopenglwidget/mainwindow.cpp new file mode 100644 index 0000000000..f09acacaf0 --- /dev/null +++ b/examples/opengl/qopenglwidget/mainwindow.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" + +#include <QApplication> +#include <QMenuBar> +#include <QGroupBox> +#include <QSlider> +#include <QLabel> +#include <QCheckBox> +#include <QSpinBox> + +#include "glwidget.h" + +MainWindow::MainWindow() + : m_nextX(1), m_nextY(1) +{ + GLWidget *glwidget = new GLWidget(this, true, qRgb(20, 20, 50)); + QLabel *label = new QLabel(this); + m_timer = new QTimer(this); + QSlider *slider = new QSlider(this); + slider->setOrientation(Qt::Horizontal); + + QLabel *updateLabel = new QLabel("Update interval"); + QSpinBox *updateInterval = new QSpinBox(this); + updateInterval->setSuffix(" ms"); + updateInterval->setValue(10); + updateInterval->setToolTip("Interval for the timer that calls update().\n" + "Note that on most systems the swap will block to wait for vsync\n" + "and therefore an interval < 16 ms will likely lead to a 60 FPS update rate."); + QGroupBox *updateGroupBox = new QGroupBox(this); + QCheckBox *transparent = new QCheckBox("Transparent background", this); + transparent->setToolTip("Toggles Qt::WA_AlwaysStackOnTop and transparent clear color for glClear().\n" + "Note how the button on top stacks incorrectly when enabling this."); + QHBoxLayout *updateLayout = new QHBoxLayout; + updateLayout->addWidget(updateLabel); + updateLayout->addWidget(updateInterval); + updateLayout->addWidget(transparent); + updateGroupBox->setLayout(updateLayout); + + slider->setRange(0, 50); + slider->setSliderPosition(30); + m_timer->setInterval(10); + label->setText("A QOpenGLWidget"); + label->setAlignment(Qt::AlignHCenter); + + QGroupBox * groupBox = new QGroupBox(this); + setCentralWidget(groupBox); + groupBox->setTitle("QOpenGLWidget Example"); + + m_layout = new QGridLayout(groupBox); + + m_layout->addWidget(glwidget,1,0,8,1); + m_layout->addWidget(label,9,0,1,1); + m_layout->addWidget(updateGroupBox, 10, 0, 1, 1); + m_layout->addWidget(slider, 11,0,1,1); + + groupBox->setLayout(m_layout); + + QMenu *fileMenu = new QMenu("&File"); + QMenu *helpMenu = new QMenu("&Help"); + QMenu *showMenu = new QMenu("&Show"); + menuBar()->addMenu(fileMenu); + menuBar()->addMenu(showMenu); + menuBar()->addMenu(helpMenu); + QAction *exit = new QAction("E&xit", fileMenu); + QAction *aboutQt = new QAction("About Qt", helpMenu); + QAction *showLogo = new QAction("Show 3D Logo", showMenu); + QAction *showTexture = new QAction("Show 2D Texture", showMenu); + QAction *showBubbles = new QAction("Show bubbles", showMenu); + showBubbles->setCheckable(true); + showBubbles->setChecked(true); + fileMenu->addAction(exit); + helpMenu->addAction(aboutQt); + showMenu->addAction(showLogo); + showMenu->addAction(showTexture); + showMenu->addAction(showBubbles); + + connect(exit, SIGNAL(triggered(bool)), this, SLOT(close())); + connect(aboutQt, SIGNAL(triggered(bool)), qApp, SLOT(aboutQt())); + + connect(m_timer, SIGNAL(timeout()), glwidget, SLOT(update())); + + connect(showLogo, SIGNAL(triggered(bool)), glwidget, SLOT(setLogo())); + connect(showTexture, SIGNAL(triggered(bool)), glwidget, SLOT(setTexture())); + connect(showBubbles, SIGNAL(triggered(bool)), glwidget, SLOT(showBubbles(bool))); + connect(slider, SIGNAL(valueChanged(int)), glwidget, SLOT(setScaling(int))); + connect(transparent, &QCheckBox::toggled, glwidget, &GLWidget::setTransparent); + + connect(updateInterval, SIGNAL(valueChanged(int)), this, SLOT(updateIntervalChanged(int))); + + m_timer->start(); +} + +void MainWindow::updateIntervalChanged(int value) +{ + m_timer->setInterval(value); + m_timer->start(); +} + +void MainWindow::addNew() +{ + if (m_nextY == 4) + return; + GLWidget *w = new GLWidget(this, false, qRgb(qrand() % 256, qrand() % 256, qrand() % 256)); + connect(m_timer, SIGNAL(timeout()), w, SLOT(update())); + m_layout->addWidget(w, m_nextY, m_nextX, 1, 1); + if (m_nextX == 3) { + m_nextX = 1; + ++m_nextY; + } else { + ++m_nextX; + } +} diff --git a/examples/opengl/qopenglwidget/mainwindow.h b/examples/opengl/qopenglwidget/mainwindow.h new file mode 100644 index 0000000000..9db3e8cbec --- /dev/null +++ b/examples/opengl/qopenglwidget/mainwindow.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> +#include <QTimer> +#include <QGridLayout> + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + void addNew(); + +private slots: + void updateIntervalChanged(int value); + +private: + QTimer *m_timer; + QGridLayout *m_layout; + int m_nextX; + int m_nextY; +}; + +#endif diff --git a/examples/opengl/qopenglwidget/qopenglwidget.pro b/examples/opengl/qopenglwidget/qopenglwidget.pro new file mode 100644 index 0000000000..0165285c02 --- /dev/null +++ b/examples/opengl/qopenglwidget/qopenglwidget.pro @@ -0,0 +1,15 @@ +QT += widgets + +SOURCES += main.cpp \ + glwidget.cpp \ + mainwindow.cpp \ + bubble.cpp + +HEADERS += glwidget.h \ + mainwindow.h \ + bubble.h + +RESOURCES += texture.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/qopenglwidget +INSTALLS += target diff --git a/examples/opengl/hellogl_es2/qt.png b/examples/opengl/qopenglwidget/qt.png Binary files differindex 79e383cf50..79e383cf50 100644 --- a/examples/opengl/hellogl_es2/qt.png +++ b/examples/opengl/qopenglwidget/qt.png diff --git a/examples/opengl/hellogl_es2/texture.qrc b/examples/opengl/qopenglwidget/texture.qrc index ff1d0e535f..ff1d0e535f 100644 --- a/examples/opengl/hellogl_es2/texture.qrc +++ b/examples/opengl/qopenglwidget/texture.qrc diff --git a/examples/opengl/threadedqopenglwidget/glwidget.cpp b/examples/opengl/threadedqopenglwidget/glwidget.cpp new file mode 100644 index 0000000000..34d97bf1bf --- /dev/null +++ b/examples/opengl/threadedqopenglwidget/glwidget.cpp @@ -0,0 +1,356 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "glwidget.h" +#include <math.h> +#include <QGuiApplication> + +const int bubbleNum = 8; + +GLWidget::GLWidget(QWidget *parent) + : QOpenGLWidget(parent) +{ + QSurfaceFormat format; + format.setDepthBufferSize(16); + setFormat(format); + + setMinimumSize(300, 250); + + connect(this, &QOpenGLWidget::aboutToCompose, this, &GLWidget::onAboutToCompose); + connect(this, &QOpenGLWidget::frameSwapped, this, &GLWidget::onFrameSwapped); + connect(this, &QOpenGLWidget::aboutToResize, this, &GLWidget::onAboutToResize); + connect(this, &QOpenGLWidget::resized, this, &GLWidget::onResized); + + m_thread = new QThread; + m_renderer = new Renderer(this); + m_renderer->moveToThread(m_thread); + connect(m_thread, &QThread::finished, m_renderer, &QObject::deleteLater); + + connect(this, &GLWidget::renderRequested, m_renderer, &Renderer::render); + connect(m_renderer, &Renderer::contextWanted, this, &GLWidget::grabContext); + + m_thread->start(); +} + +GLWidget::~GLWidget() +{ + m_renderer->prepareExit(); + m_thread->quit(); + m_thread->wait(); + delete m_thread; +} + +void GLWidget::onAboutToCompose() +{ + // We are on the gui thread here. Composition is about to + // begin. Wait until the render thread finishes. + m_renderer->lockRenderer(); +} + +void GLWidget::onFrameSwapped() +{ + m_renderer->unlockRenderer(); + // Assuming a blocking swap, our animation is driven purely by the + // vsync in this example. + emit renderRequested(); +} + +void GLWidget::onAboutToResize() +{ + m_renderer->lockRenderer(); +} + +void GLWidget::onResized() +{ + m_renderer->unlockRenderer(); +} + +void GLWidget::grabContext() +{ + m_renderer->lockRenderer(); + QMutexLocker lock(m_renderer->grabMutex()); + context()->moveToThread(m_thread); + m_renderer->grabCond()->wakeAll(); + m_renderer->unlockRenderer(); +} + +Renderer::Renderer(GLWidget *w) + : m_inited(false), + m_glwidget(w), + m_exiting(false) +{ +} + +void Renderer::paintQtLogo() +{ + program.enableAttributeArray(normalAttr); + program.enableAttributeArray(vertexAttr); + program.setAttributeArray(vertexAttr, vertices.constData()); + program.setAttributeArray(normalAttr, normals.constData()); + glDrawArrays(GL_TRIANGLES, 0, vertices.size()); + program.disableAttributeArray(normalAttr); + program.disableAttributeArray(vertexAttr); +} + +// Some OpenGL implementations have serious issues with compiling and linking +// shaders on multiple threads concurrently. Avoid this. +Q_GLOBAL_STATIC(QMutex, initMutex) + +void Renderer::render() +{ + if (m_exiting) + return; + + QOpenGLContext *ctx = m_glwidget->context(); + if (!ctx) // QOpenGLWidget not yet initialized + return; + + // Grab the context. + m_grabMutex.lock(); + emit contextWanted(); + m_grabCond.wait(&m_grabMutex); + QMutexLocker lock(&m_renderMutex); + m_grabMutex.unlock(); + + if (m_exiting) + return; + + Q_ASSERT(ctx->thread() == QThread::currentThread()); + + // Make the context (and an offscreen surface) current for this thread. The + // QOpenGLWidget's fbo is bound in the context. + m_glwidget->makeCurrent(); + + if (!m_inited) { + m_inited = true; + initializeOpenGLFunctions(); + + QMutexLocker initLock(initMutex()); + QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); + const char *vsrc = + "attribute highp vec4 vertex;\n" + "attribute mediump vec3 normal;\n" + "uniform mediump mat4 matrix;\n" + "varying mediump vec4 color;\n" + "void main(void)\n" + "{\n" + " vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));\n" + " float angle = max(dot(normal, toLight), 0.0);\n" + " vec3 col = vec3(0.40, 1.0, 0.0);\n" + " color = vec4(col * 0.2 + col * 0.8 * angle, 1.0);\n" + " color = clamp(color, 0.0, 1.0);\n" + " gl_Position = matrix * vertex;\n" + "}\n"; + vshader->compileSourceCode(vsrc); + + QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); + const char *fsrc = + "varying mediump vec4 color;\n" + "void main(void)\n" + "{\n" + " gl_FragColor = color;\n" + "}\n"; + fshader->compileSourceCode(fsrc); + + program.addShader(vshader); + program.addShader(fshader); + program.link(); + + vertexAttr = program.attributeLocation("vertex"); + normalAttr = program.attributeLocation("normal"); + matrixUniform = program.uniformLocation("matrix"); + + m_fAngle = 0; + m_fScale = 1; + createGeometry(); + + m_elapsed.start(); + } + + //qDebug("%p elapsed %lld", QThread::currentThread(), m_elapsed.restart()); + + glClearColor(0.1f, 0.2f, 0.2f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glFrontFace(GL_CW); + glCullFace(GL_FRONT); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + QMatrix4x4 modelview; + modelview.rotate(m_fAngle, 0.0f, 1.0f, 0.0f); + modelview.rotate(m_fAngle, 1.0f, 0.0f, 0.0f); + modelview.rotate(m_fAngle, 0.0f, 0.0f, 1.0f); + modelview.scale(m_fScale); + modelview.translate(0.0f, -0.2f, 0.0f); + + program.bind(); + program.setUniformValue(matrixUniform, modelview); + paintQtLogo(); + program.release(); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + m_fAngle += 1.0f; + + // Make no context current on this thread and move the QOpenGLWidget's + // context back to the gui thread. + m_glwidget->doneCurrent(); + ctx->moveToThread(qGuiApp->thread()); + + // Schedule composition. Note that this will use QueuedConnection, meaning + // that update() will be invoked on the gui thread. + QMetaObject::invokeMethod(m_glwidget, "update"); +} + +void Renderer::createGeometry() +{ + vertices.clear(); + normals.clear(); + + qreal x1 = +0.06f; + qreal y1 = -0.14f; + qreal x2 = +0.14f; + qreal y2 = -0.06f; + qreal x3 = +0.08f; + qreal y3 = +0.00f; + qreal x4 = +0.30f; + qreal y4 = +0.22f; + + quad(x1, y1, x2, y2, y2, x2, y1, x1); + quad(x3, y3, x4, y4, y4, x4, y3, x3); + + extrude(x1, y1, x2, y2); + extrude(x2, y2, y2, x2); + extrude(y2, x2, y1, x1); + extrude(y1, x1, x1, y1); + extrude(x3, y3, x4, y4); + extrude(x4, y4, y4, x4); + extrude(y4, x4, y3, x3); + + const qreal Pi = 3.14159f; + const int NumSectors = 100; + + for (int i = 0; i < NumSectors; ++i) { + qreal angle1 = (i * 2 * Pi) / NumSectors; + qreal x5 = 0.30 * sin(angle1); + qreal y5 = 0.30 * cos(angle1); + qreal x6 = 0.20 * sin(angle1); + qreal y6 = 0.20 * cos(angle1); + + qreal angle2 = ((i + 1) * 2 * Pi) / NumSectors; + qreal x7 = 0.20 * sin(angle2); + qreal y7 = 0.20 * cos(angle2); + qreal x8 = 0.30 * sin(angle2); + qreal y8 = 0.30 * cos(angle2); + + quad(x5, y5, x6, y6, x7, y7, x8, y8); + + extrude(x6, y6, x7, y7); + extrude(x8, y8, x5, y5); + } + + for (int i = 0;i < vertices.size();i++) + vertices[i] *= 2.0f; +} + +void Renderer::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4) +{ + vertices << QVector3D(x1, y1, -0.05f); + vertices << QVector3D(x2, y2, -0.05f); + vertices << QVector3D(x4, y4, -0.05f); + + vertices << QVector3D(x3, y3, -0.05f); + vertices << QVector3D(x4, y4, -0.05f); + vertices << QVector3D(x2, y2, -0.05f); + + QVector3D n = QVector3D::normal + (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(x4 - x1, y4 - y1, 0.0f)); + + normals << n; + normals << n; + normals << n; + + normals << n; + normals << n; + normals << n; + + vertices << QVector3D(x4, y4, 0.05f); + vertices << QVector3D(x2, y2, 0.05f); + vertices << QVector3D(x1, y1, 0.05f); + + vertices << QVector3D(x2, y2, 0.05f); + vertices << QVector3D(x4, y4, 0.05f); + vertices << QVector3D(x3, y3, 0.05f); + + n = QVector3D::normal + (QVector3D(x2 - x4, y2 - y4, 0.0f), QVector3D(x1 - x4, y1 - y4, 0.0f)); + + normals << n; + normals << n; + normals << n; + + normals << n; + normals << n; + normals << n; +} + +void Renderer::extrude(qreal x1, qreal y1, qreal x2, qreal y2) +{ + vertices << QVector3D(x1, y1, +0.05f); + vertices << QVector3D(x2, y2, +0.05f); + vertices << QVector3D(x1, y1, -0.05f); + + vertices << QVector3D(x2, y2, -0.05f); + vertices << QVector3D(x1, y1, -0.05f); + vertices << QVector3D(x2, y2, +0.05f); + + QVector3D n = QVector3D::normal + (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(0.0f, 0.0f, -0.1f)); + + normals << n; + normals << n; + normals << n; + + normals << n; + normals << n; + normals << n; +} diff --git a/examples/opengl/threadedqopenglwidget/glwidget.h b/examples/opengl/threadedqopenglwidget/glwidget.h new file mode 100644 index 0000000000..9d746e681b --- /dev/null +++ b/examples/opengl/threadedqopenglwidget/glwidget.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GLWIDGET_H +#define GLWIDGET_H + +#include <QOpenGLWidget> +#include <QOpenGLFunctions> +#include <QOpenGLShaderProgram> +#include <QVector3D> +#include <QMatrix4x4> +#include <QThread> +#include <QMutex> +#include <QWaitCondition> +#include <QElapsedTimer> + +class GLWidget; + +class Renderer : public QObject, protected QOpenGLFunctions +{ + Q_OBJECT + +public: + Renderer(GLWidget *w); + void lockRenderer() { m_renderMutex.lock(); } + void unlockRenderer() { m_renderMutex.unlock(); } + QMutex *grabMutex() { return &m_grabMutex; } + QWaitCondition *grabCond() { return &m_grabCond; } + void prepareExit() { m_exiting = true; m_grabCond.wakeAll(); } + +signals: + void contextWanted(); + +public slots: + void render(); + +private: + void paintQtLogo(); + void createGeometry(); + void quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4); + void extrude(qreal x1, qreal y1, qreal x2, qreal y2); + + bool m_inited; + qreal m_fAngle; + qreal m_fScale; + QVector<QVector3D> vertices; + QVector<QVector3D> normals; + QOpenGLShaderProgram program; + int vertexAttr; + int normalAttr; + int matrixUniform; + GLWidget *m_glwidget; + QMutex m_renderMutex; + QElapsedTimer m_elapsed; + QMutex m_grabMutex; + QWaitCondition m_grabCond; + bool m_exiting; +}; + +class GLWidget : public QOpenGLWidget +{ + Q_OBJECT +public: + GLWidget(QWidget *parent); + ~GLWidget(); + +protected: + void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE { } + +signals: + void renderRequested(); + +public slots: + void grabContext(); + +private slots: + void onAboutToCompose(); + void onFrameSwapped(); + void onAboutToResize(); + void onResized(); + +private: + QThread *m_thread; + Renderer *m_renderer; +}; + +#endif diff --git a/examples/opengl/threadedqopenglwidget/main.cpp b/examples/opengl/threadedqopenglwidget/main.cpp new file mode 100644 index 0000000000..046a24d576 --- /dev/null +++ b/examples/opengl/threadedqopenglwidget/main.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QApplication> +#include <QMainWindow> +#include "mainwindow.h" +#include "glwidget.h" + +int main( int argc, char ** argv ) +{ + QApplication a( argc, argv ); + + // Two top-level windows with two QOpenGLWidget children in each. + // The rendering for the four QOpenGLWidgets happens on four separate threads. + MainWindow mw1; + mw1.setMinimumSize(800, 400); + mw1.show(); + + QScopedPointer<MainWindow> mw2; + if (!QApplication::arguments().contains(QStringLiteral("--single"))) { + mw2.reset(new MainWindow); + mw2->setMinimumSize(800, 400); + mw2->show(); + + // And a top-level. + GLWidget *bonus = new GLWidget(0); + bonus->resize(200, 200); + bonus->show(); + } + + return a.exec(); +} diff --git a/examples/opengl/threadedqopenglwidget/mainwindow.cpp b/examples/opengl/threadedqopenglwidget/mainwindow.cpp new file mode 100644 index 0000000000..29c59573cf --- /dev/null +++ b/examples/opengl/threadedqopenglwidget/mainwindow.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" +#include "glwidget.h" + +MainWindow::MainWindow() +{ + GLWidget *glwidget1 = new GLWidget(this); + glwidget1->resize(400, 400); + + GLWidget *glwidget2 = new GLWidget(this); + glwidget2->resize(400, 400); + glwidget2->move(400, 0); +} diff --git a/examples/opengl/hellogl_es2/mainwindow.h b/examples/opengl/threadedqopenglwidget/mainwindow.h index 3f05fd4a78..91f7580717 100644 --- a/examples/opengl/hellogl_es2/mainwindow.h +++ b/examples/opengl/threadedqopenglwidget/mainwindow.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the examples of the Qt Toolkit. @@ -41,16 +41,14 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include <QMainWindow> +#include <QWidget> -class MainWindow : public QMainWindow +class MainWindow : public QWidget { Q_OBJECT public: MainWindow(); - -private: }; #endif diff --git a/examples/opengl/threadedqopenglwidget/threadedqopenglwidget.pro b/examples/opengl/threadedqopenglwidget/threadedqopenglwidget.pro new file mode 100644 index 0000000000..4e941b28c4 --- /dev/null +++ b/examples/opengl/threadedqopenglwidget/threadedqopenglwidget.pro @@ -0,0 +1,11 @@ +QT += widgets + +SOURCES += main.cpp \ + glwidget.cpp \ + mainwindow.cpp + +HEADERS += glwidget.h \ + mainwindow.h + +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/threadedqopenglwidget +INSTALLS += target |