Merge remote-tracking branch 'origin/5.4' into dev
Change-Id: Ia03a010d1fbfc89c04144c1c106336f0e1c45ec1bb10
|
|
@ -13,4 +13,4 @@ buildversion = "Qt $QT_VERSION Reference Documentation"
|
|||
|
||||
sourcedirs += includes
|
||||
|
||||
url = http://qt-project.org/doc/qt-$QT_VER
|
||||
url = http://qt-project.org/doc/qt-5
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
QT += opengl widgets
|
||||
QT += widgets
|
||||
|
||||
HEADERS = glwidget.h \
|
||||
helper.h \
|
||||
|
|
|
|||
|
|
@ -41,11 +41,12 @@
|
|||
#include "glwidget.h"
|
||||
#include "helper.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QTimer>
|
||||
|
||||
//! [0]
|
||||
GLWidget::GLWidget(Helper *helper, QWidget *parent)
|
||||
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent), helper(helper)
|
||||
: QOpenGLWidget(parent), helper(helper)
|
||||
{
|
||||
elapsed = 0;
|
||||
setFixedSize(200, 200);
|
||||
|
|
@ -57,7 +58,7 @@ GLWidget::GLWidget(Helper *helper, QWidget *parent)
|
|||
void GLWidget::animate()
|
||||
{
|
||||
elapsed = (elapsed + qobject_cast<QTimer*>(sender())->interval()) % 1000;
|
||||
repaint();
|
||||
update();
|
||||
}
|
||||
//! [1]
|
||||
|
||||
|
|
|
|||
|
|
@ -41,12 +41,12 @@
|
|||
#ifndef GLWIDGET_H
|
||||
#define GLWIDGET_H
|
||||
|
||||
#include <QGLWidget>
|
||||
#include <QOpenGLWidget>
|
||||
|
||||
//! [0]
|
||||
class Helper;
|
||||
|
||||
class GLWidget : public QGLWidget
|
||||
class GLWidget : public QOpenGLWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
|
|
|||
|
|
@ -41,10 +41,16 @@
|
|||
#include "window.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QSurfaceFormat>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QSurfaceFormat fmt;
|
||||
fmt.setSamples(4);
|
||||
QSurfaceFormat::setDefaultFormat(fmt);
|
||||
|
||||
Window window;
|
||||
window.show();
|
||||
return app.exec();
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ Widget::Widget(Helper *helper, QWidget *parent)
|
|||
void Widget::animate()
|
||||
{
|
||||
elapsed = (elapsed + qobject_cast<QTimer*>(sender())->interval()) % 1000;
|
||||
repaint();
|
||||
update();
|
||||
}
|
||||
//! [1]
|
||||
|
||||
|
|
|
|||
|
|
@ -5,20 +5,17 @@ TEMPLATE = app
|
|||
|
||||
SOURCES += main.cpp
|
||||
|
||||
qtHaveModule(opengl) {
|
||||
QT += opengl
|
||||
SOURCES += \
|
||||
mainwidget.cpp \
|
||||
geometryengine.cpp
|
||||
|
||||
SOURCES += mainwidget.cpp \
|
||||
geometryengine.cpp
|
||||
HEADERS += \
|
||||
mainwidget.h \
|
||||
geometryengine.h
|
||||
|
||||
HEADERS += \
|
||||
mainwidget.h \
|
||||
geometryengine.h
|
||||
|
||||
RESOURCES += \
|
||||
shaders.qrc \
|
||||
textures.qrc
|
||||
}
|
||||
RESOURCES += \
|
||||
shaders.qrc \
|
||||
textures.qrc
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/opengl/cube
|
||||
|
|
|
|||
|
|
@ -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 QtCore module of the Qt Toolkit.
|
||||
|
|
@ -49,29 +49,27 @@ struct VertexData
|
|||
QVector2D texCoord;
|
||||
};
|
||||
|
||||
//! [0]
|
||||
GeometryEngine::GeometryEngine()
|
||||
: indexBuf(QOpenGLBuffer::IndexBuffer)
|
||||
{
|
||||
}
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
GeometryEngine::~GeometryEngine()
|
||||
{
|
||||
glDeleteBuffers(2, vboIds);
|
||||
}
|
||||
|
||||
void GeometryEngine::init()
|
||||
{
|
||||
initializeGLFunctions();
|
||||
|
||||
//! [0]
|
||||
// Generate 2 VBOs
|
||||
glGenBuffers(2, vboIds);
|
||||
|
||||
//! [0]
|
||||
arrayBuf.create();
|
||||
indexBuf.create();
|
||||
|
||||
// Initializes cube geometry and transfers it to VBOs
|
||||
initCubeGeometry();
|
||||
}
|
||||
|
||||
GeometryEngine::~GeometryEngine()
|
||||
{
|
||||
arrayBuf.destroy();
|
||||
indexBuf.destroy();
|
||||
}
|
||||
//! [0]
|
||||
|
||||
void GeometryEngine::initCubeGeometry()
|
||||
{
|
||||
// For cube we would need only 8 vertices but we have to
|
||||
|
|
@ -133,21 +131,21 @@ void GeometryEngine::initCubeGeometry()
|
|||
|
||||
//! [1]
|
||||
// Transfer vertex data to VBO 0
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(VertexData), vertices, GL_STATIC_DRAW);
|
||||
arrayBuf.bind();
|
||||
arrayBuf.allocate(vertices, 24 * sizeof(VertexData));
|
||||
|
||||
// Transfer index data to VBO 1
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIds[1]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 34 * sizeof(GLushort), indices, GL_STATIC_DRAW);
|
||||
indexBuf.bind();
|
||||
indexBuf.allocate(indices, 34 * sizeof(GLushort));
|
||||
//! [1]
|
||||
}
|
||||
|
||||
//! [2]
|
||||
void GeometryEngine::drawCubeGeometry(QGLShaderProgram *program)
|
||||
void GeometryEngine::drawCubeGeometry(QOpenGLShaderProgram *program)
|
||||
{
|
||||
// Tell OpenGL which VBOs to use
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIds[1]);
|
||||
arrayBuf.bind();
|
||||
indexBuf.bind();
|
||||
|
||||
// Offset for position
|
||||
quintptr offset = 0;
|
||||
|
|
@ -155,7 +153,7 @@ void GeometryEngine::drawCubeGeometry(QGLShaderProgram *program)
|
|||
// Tell OpenGL programmable pipeline how to locate vertex position data
|
||||
int vertexLocation = program->attributeLocation("a_position");
|
||||
program->enableAttributeArray(vertexLocation);
|
||||
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const void *)offset);
|
||||
program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(VertexData));
|
||||
|
||||
// Offset for texture coordinate
|
||||
offset += sizeof(QVector3D);
|
||||
|
|
@ -163,7 +161,7 @@ void GeometryEngine::drawCubeGeometry(QGLShaderProgram *program)
|
|||
// Tell OpenGL programmable pipeline how to locate vertex texture coordinate data
|
||||
int texcoordLocation = program->attributeLocation("a_texcoord");
|
||||
program->enableAttributeArray(texcoordLocation);
|
||||
glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const void *)offset);
|
||||
program->setAttributeBuffer(texcoordLocation, GL_FLOAT, offset, 2, sizeof(VertexData));
|
||||
|
||||
// Draw cube geometry using indices from VBO 1
|
||||
glDrawElements(GL_TRIANGLE_STRIP, 34, GL_UNSIGNED_SHORT, 0);
|
||||
|
|
|
|||
|
|
@ -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 QtCore module of the Qt Toolkit.
|
||||
|
|
@ -41,22 +41,23 @@
|
|||
#ifndef GEOMETRYENGINE_H
|
||||
#define GEOMETRYENGINE_H
|
||||
|
||||
#include <QGLFunctions>
|
||||
#include <QGLShaderProgram>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLBuffer>
|
||||
|
||||
class GeometryEngine : protected QGLFunctions
|
||||
class GeometryEngine : protected QOpenGLFunctions
|
||||
{
|
||||
public:
|
||||
GeometryEngine();
|
||||
virtual ~GeometryEngine();
|
||||
|
||||
void init();
|
||||
void drawCubeGeometry(QGLShaderProgram *program);
|
||||
void drawCubeGeometry(QOpenGLShaderProgram *program);
|
||||
|
||||
private:
|
||||
void initCubeGeometry();
|
||||
|
||||
GLuint vboIds[2];
|
||||
QOpenGLBuffer arrayBuf;
|
||||
QOpenGLBuffer indexBuf;
|
||||
};
|
||||
|
||||
#endif // GEOMETRYENGINE_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 QtCore module of the Qt Toolkit.
|
||||
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include <QApplication>
|
||||
#include <QLabel>
|
||||
#include <QSurfaceFormat>
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
#include "mainwidget.h"
|
||||
|
|
@ -48,6 +49,11 @@
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QSurfaceFormat format;
|
||||
format.setDepthBufferSize(24);
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
|
||||
app.setApplicationName("cube");
|
||||
app.setApplicationVersion("0.1");
|
||||
#ifndef QT_NO_OPENGL
|
||||
|
|
|
|||
|
|
@ -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 QtCore module of the Qt Toolkit.
|
||||
|
|
@ -45,14 +45,21 @@
|
|||
#include <math.h>
|
||||
|
||||
MainWidget::MainWidget(QWidget *parent) :
|
||||
QGLWidget(parent),
|
||||
QOpenGLWidget(parent),
|
||||
geometries(0),
|
||||
texture(0),
|
||||
angularSpeed(0)
|
||||
{
|
||||
}
|
||||
|
||||
MainWidget::~MainWidget()
|
||||
{
|
||||
deleteTexture(texture);
|
||||
// Make sure the context is current when deleting the texture
|
||||
// and the buffers.
|
||||
makeCurrent();
|
||||
delete texture;
|
||||
delete geometries;
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
//! [0]
|
||||
|
|
@ -95,16 +102,18 @@ void MainWidget::timerEvent(QTimerEvent *)
|
|||
// Update rotation
|
||||
rotation = QQuaternion::fromAxisAndAngle(rotationAxis, angularSpeed) * rotation;
|
||||
|
||||
// Update scene
|
||||
updateGL();
|
||||
// Request an update
|
||||
update();
|
||||
}
|
||||
}
|
||||
//! [1]
|
||||
|
||||
void MainWidget::initializeGL()
|
||||
{
|
||||
initializeGLFunctions();
|
||||
qglClearColor(Qt::black);
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
glClearColor(0, 0, 0, 1);
|
||||
|
||||
initShaders();
|
||||
initTextures();
|
||||
|
||||
|
|
@ -116,7 +125,7 @@ void MainWidget::initializeGL()
|
|||
glEnable(GL_CULL_FACE);
|
||||
//! [2]
|
||||
|
||||
geometries.init();
|
||||
geometries = new GeometryEngine;
|
||||
|
||||
// Use QBasicTimer because its faster than QTimer
|
||||
timer.start(12, this);
|
||||
|
|
@ -126,11 +135,11 @@ void MainWidget::initializeGL()
|
|||
void MainWidget::initShaders()
|
||||
{
|
||||
// Compile vertex shader
|
||||
if (!program.addShaderFromSourceFile(QGLShader::Vertex, ":/vshader.glsl"))
|
||||
if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vshader.glsl"))
|
||||
close();
|
||||
|
||||
// Compile fragment shader
|
||||
if (!program.addShaderFromSourceFile(QGLShader::Fragment, ":/fshader.glsl"))
|
||||
if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fshader.glsl"))
|
||||
close();
|
||||
|
||||
// Link shader pipeline
|
||||
|
|
@ -147,28 +156,23 @@ void MainWidget::initShaders()
|
|||
void MainWidget::initTextures()
|
||||
{
|
||||
// Load cube.png image
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
texture = bindTexture(QImage(":/cube.png"));
|
||||
texture = new QOpenGLTexture(QImage(":/cube.png").mirrored());
|
||||
|
||||
// Set nearest filtering mode for texture minification
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
texture->setMinificationFilter(QOpenGLTexture::Nearest);
|
||||
|
||||
// Set bilinear filtering mode for texture magnification
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
texture->setMagnificationFilter(QOpenGLTexture::Linear);
|
||||
|
||||
// Wrap texture coordinates by repeating
|
||||
// f.ex. texture coordinate (1.1, 1.2) is same as (0.1, 0.2)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
texture->setWrapMode(QOpenGLTexture::Repeat);
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
void MainWidget::resizeGL(int w, int h)
|
||||
{
|
||||
// Set OpenGL viewport to cover whole widget
|
||||
glViewport(0, 0, w, h);
|
||||
|
||||
// Calculate aspect ratio
|
||||
qreal aspect = qreal(w) / qreal(h ? h : 1);
|
||||
|
||||
|
|
@ -188,6 +192,8 @@ void MainWidget::paintGL()
|
|||
// Clear color and depth buffer
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
texture->bind();
|
||||
|
||||
//! [6]
|
||||
// Calculate model view transformation
|
||||
QMatrix4x4 matrix;
|
||||
|
|
@ -202,5 +208,5 @@ void MainWidget::paintGL()
|
|||
program.setUniformValue("texture", 0);
|
||||
|
||||
// Draw cube geometry
|
||||
geometries.drawCubeGeometry(&program);
|
||||
geometries->drawCubeGeometry(&program);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 QtCore module of the Qt Toolkit.
|
||||
|
|
@ -43,18 +43,18 @@
|
|||
|
||||
#include "geometryengine.h"
|
||||
|
||||
#include <QGLWidget>
|
||||
#include <QGLFunctions>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QMatrix4x4>
|
||||
#include <QQuaternion>
|
||||
#include <QVector2D>
|
||||
#include <QBasicTimer>
|
||||
#include <QGLShaderProgram>
|
||||
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLTexture>
|
||||
|
||||
class GeometryEngine;
|
||||
|
||||
class MainWidget : public QGLWidget, protected QGLFunctions
|
||||
class MainWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
|
@ -76,10 +76,10 @@ protected:
|
|||
|
||||
private:
|
||||
QBasicTimer timer;
|
||||
QGLShaderProgram program;
|
||||
GeometryEngine geometries;
|
||||
QOpenGLShaderProgram program;
|
||||
GeometryEngine *geometries;
|
||||
|
||||
GLuint texture;
|
||||
QOpenGLTexture *texture;
|
||||
|
||||
QMatrix4x4 projection;
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
|
@ -117,7 +117,9 @@
|
|||
aren't facing towards screen.
|
||||
|
||||
Creating vertex buffer objects and transferring data to them is quite simple using
|
||||
OpenGL provided functions.
|
||||
QOpenGLBuffer. MainWidget makes sure the GeometryEngine instance is created and
|
||||
destroyed with the OpenGL context current. This way we can use OpenGL resources
|
||||
in the constructor and perform proper cleanup in the destructor.
|
||||
|
||||
\snippet cube/geometryengine.cpp 0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,38 +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 documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example framebufferobject2
|
||||
\title Framebuffer Object 2 Example
|
||||
|
||||
\ingroup examples-widgets-opengl
|
||||
\brief The Framebuffer Object 2 example demonstrates how to use the
|
||||
QGLFramebufferObject class to render into an off-screen buffer and
|
||||
use the contents as a texture in a QGLWidget.
|
||||
|
||||
\image framebufferobject2-example.png
|
||||
*/
|
||||
|
|
@ -1,36 +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 documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example grabber
|
||||
\title Grabber Example
|
||||
\ingroup examples-widgets-opengl
|
||||
|
||||
\brief The Grabber examples shows how to retrieve the contents of an OpenGL framebuffer.
|
||||
|
||||
\image grabber-example.png
|
||||
*/
|
||||
|
|
@ -1,320 +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 documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example hellogl
|
||||
\title Hello GL Example
|
||||
\ingroup examples-widgets-opengl
|
||||
|
||||
\brief The Hello GL example demonstrates the basic use of the OpenGL-related classes
|
||||
provided with Qt.
|
||||
|
||||
\image hellogl-example.png
|
||||
|
||||
Qt provides the QGLWidget class to enable OpenGL graphics to be rendered within
|
||||
a standard application user interface. By subclassing this class, and providing
|
||||
reimplementations of event handler functions, 3D scenes can be displayed on
|
||||
widgets that can be placed in layouts, connected to other objects using signals
|
||||
and slots, and manipulated like any other widget.
|
||||
|
||||
\tableofcontents
|
||||
|
||||
\section1 GLWidget Class Definition
|
||||
|
||||
The \c GLWidget class contains some standard public definitions for the
|
||||
constructor, destructor, \l{QWidget::sizeHint()}{sizeHint()}, and
|
||||
\l{QWidget::minimumSizeHint()}{minimumSizeHint()} functions:
|
||||
|
||||
\snippet hellogl/glwidget.h 0
|
||||
|
||||
We use a destructor to ensure that any OpenGL-specific data structures
|
||||
are deleted when the widget is no longer needed (although in this case nothing
|
||||
needs cleaning up).
|
||||
|
||||
\snippet hellogl/glwidget.h 1
|
||||
|
||||
The signals and slots are used to allow other objects to interact with the
|
||||
3D scene.
|
||||
|
||||
\snippet hellogl/glwidget.h 2
|
||||
|
||||
OpenGL initialization, viewport resizing, and painting are handled by
|
||||
reimplementing the QGLWidget::initializeGL(), QGLWidget::resizeGL(), and
|
||||
QGLWidget::paintGL() handler functions. To enable the user to interact
|
||||
directly with the scene using the mouse, we reimplement
|
||||
QWidget::mousePressEvent() and QWidget::mouseMoveEvent().
|
||||
|
||||
\snippet hellogl/glwidget.h 3
|
||||
|
||||
The rest of the class contains utility functions and variables that are
|
||||
used to construct and hold orientation information for the scene. The
|
||||
\c logo variable will be used to hold a pointer to the QtLogo object which
|
||||
contains all the geometry.
|
||||
|
||||
\section1 GLWidget Class Implementation
|
||||
|
||||
In this example, we split the class into groups of functions and describe
|
||||
them separately. This helps to illustrate the differences between subclasses
|
||||
of native widgets (such as QWidget and QFrame) and QGLWidget subclasses.
|
||||
|
||||
\section2 Widget Construction and Sizing
|
||||
|
||||
The constructor provides default rotation angles for the scene, sets
|
||||
the pointer to the QtLogo object to null, and sets up some colors for
|
||||
later use.
|
||||
|
||||
\snippet hellogl/glwidget.cpp 0
|
||||
|
||||
We also implement a destructor to release OpenGL-related resources when the
|
||||
widget is deleted:
|
||||
|
||||
\snippet hellogl/glwidget.cpp 1
|
||||
|
||||
In this case nothing requires cleaning up.
|
||||
|
||||
We provide size hint functions to ensure that the widget is shown at a
|
||||
reasonable size:
|
||||
|
||||
\snippet hellogl/glwidget.cpp 2
|
||||
\codeline
|
||||
\snippet hellogl/glwidget.cpp 3
|
||||
\snippet hellogl/glwidget.cpp 4
|
||||
|
||||
The widget provides three slots that enable other components in the
|
||||
example to change the orientation of the scene:
|
||||
|
||||
\snippet hellogl/glwidget.cpp 5
|
||||
|
||||
In the above slot, the \c xRot variable is updated only if the new angle is
|
||||
different to the old one, the \c xRotationChanged() signal is emitted to
|
||||
allow other components to be updated, and an update is scheduled.
|
||||
|
||||
Note that the widget's \l{QGLWidget::updateGL()}{updateGL()} function is not
|
||||
called directly from here. Triggering rendering and buffer swaps directly
|
||||
from the input event handlers is not desirable. Such events may, depending
|
||||
on the platform, occur at a high frequency, and calling a potentially
|
||||
blocking function like \l{QOpenGLContext::swapBuffers()}{swapBuffers} may
|
||||
lead to unexpected results due to the main thread not being able to process
|
||||
the input events at a proper rate.
|
||||
|
||||
Instead, update() is used. This will eventually lead to a paint event, which
|
||||
will in turn invoke paintGL(). Multiple calls to update() in a row will make
|
||||
no difference while the event is still pending. This way the UI will perform
|
||||
equally well with blocking swaps, that is, a a
|
||||
\l{QGLFormat::swapInterval()}{swap interval} of 1, and non-vsynced
|
||||
configurations.
|
||||
|
||||
The \c setYRotation() and \c setZRotation() slots perform the same task for
|
||||
rotations measured by the \c yRot and \c zRot variables.
|
||||
|
||||
\section2 OpenGL Initialization
|
||||
|
||||
The \l{QGLWidget::initializeGL()}{initializeGL()} function is used to
|
||||
perform useful initialization tasks that are needed to render the 3D scene.
|
||||
These often involve defining colors and materials, enabling and disabling
|
||||
certain rendering flags, and setting other properties used to customize the
|
||||
rendering process.
|
||||
|
||||
\snippet hellogl/glwidget.cpp 6
|
||||
|
||||
In this example, we reimplement the function to set the background color,
|
||||
create a QtLogo object instance which will contain all the geometry to
|
||||
display, and set up the rendering process to use a particular shading model
|
||||
and rendering flags.
|
||||
|
||||
\section2 Resizing the Viewport
|
||||
|
||||
The \l{QGLWidget::resizeGL()}{resizeGL()} function is used to ensure that
|
||||
the OpenGL implementation renders the scene onto a viewport that matches the
|
||||
size of the widget, using the correct transformation from 3D coordinates to
|
||||
2D viewport coordinates.
|
||||
|
||||
The function is called whenever the widget's dimensions change, and is
|
||||
supplied with the new width and height. Here, we define a square viewport
|
||||
based on the length of the smallest side of the widget to ensure that
|
||||
the scene is not distorted if the widget has sides of unequal length:
|
||||
|
||||
\snippet hellogl/glwidget.cpp 8
|
||||
|
||||
A discussion of the projection transformation used is outside the scope of
|
||||
this example. Please consult the OpenGL reference documentation for an
|
||||
explanation of projection matrices.
|
||||
|
||||
\section2 Painting the Scene
|
||||
|
||||
The \l{QGLWidget::paintGL()}{paintGL()} function is used to paint the
|
||||
contents of the scene onto the widget. For widgets that only need to be
|
||||
decorated with pure OpenGL content, we reimplement QGLWidget::paintGL()
|
||||
\e instead of reimplementing QWidget::paintEvent():
|
||||
|
||||
\snippet hellogl/glwidget.cpp 7
|
||||
|
||||
In this example, we clear the widget using the background color that
|
||||
we defined in the \l{QGLWidget::initializeGL()}{initializeGL()} function,
|
||||
set up the frame of reference for the geometry we want to display, and
|
||||
call the draw method of the QtLogo object to render the scene.
|
||||
|
||||
\section2 Mouse Handling
|
||||
|
||||
Just as in subclasses of native widgets, mouse events are handled by
|
||||
reimplementing functions such as QWidget::mousePressEvent() and
|
||||
QWidget::mouseMoveEvent().
|
||||
|
||||
The \l{QWidget::mousePressEvent()}{mousePressEvent()} function simply
|
||||
records the position of the mouse when a button is initially pressed:
|
||||
|
||||
\snippet hellogl/glwidget.cpp 9
|
||||
|
||||
The \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()} function uses the
|
||||
previous location of the mouse cursor to determine how much the object
|
||||
in the scene should be rotated, and in which direction:
|
||||
|
||||
\snippet hellogl/glwidget.cpp 10
|
||||
|
||||
Since the user is expected to hold down the mouse button and drag the
|
||||
cursor to rotate the object, the cursor's position is updated every time
|
||||
a move event is received.
|
||||
|
||||
\section1 QtLogo Class
|
||||
|
||||
This class encapsulates the OpenGL geometry data which will be rendered
|
||||
in the basic 3D scene.
|
||||
|
||||
\snippet shared/qtlogo.h 0
|
||||
|
||||
The geometry is divided into a list of parts which may be rendered in
|
||||
different ways. The data itself is contained in a Geometry structure that
|
||||
includes the vertices, their lighting normals and index values which
|
||||
point into the vertices, grouping them into faces.
|
||||
|
||||
\snippet shared/qtlogo.cpp 0
|
||||
|
||||
The data in the Geometry class is stored in QVector<QVector3D> members
|
||||
which are convenient for use with OpenGL because they expose raw
|
||||
contiguous floating point values via the constData() method. Methods
|
||||
are included for adding new vertex data, either with smooth normals, or
|
||||
facetted normals; and for enabling the geometry ready for rendering.
|
||||
|
||||
\snippet shared/qtlogo.cpp 1
|
||||
|
||||
The higher level Patch class has methods for accumulating the geometry
|
||||
one face at a time, and treating collections of faces or "patches" with
|
||||
transformations, applying different colors or smoothing. Although faces
|
||||
may be added as triangles or quads, at the OpenGL level all data is
|
||||
treated as triangles for compatibility with OpenGL/ES.
|
||||
|
||||
\snippet shared/qtlogo.cpp 2
|
||||
|
||||
Drawing a Patch is simply acheived by applying any transformation,
|
||||
and material effect, then drawing the data using the index range for
|
||||
the patch. The model-view matrix is saved and then restored so that
|
||||
any transformation does not affect other parts of the scene.
|
||||
|
||||
\snippet shared/qtlogo.cpp 3
|
||||
|
||||
The geometry is built once on construction of the QtLogo, and it is
|
||||
paramaterized on a number of divisions - which controls how "chunky" the
|
||||
curved section of the logo looks - and on a scale, so larger and smaller
|
||||
QtLogo objects can be created without having to use OpenGL scaling
|
||||
(which would force normal recalculation).
|
||||
|
||||
The building process is done by helper classes (read the source for full
|
||||
details) which only exist during the build phase, to assemble the parts
|
||||
of the scene.
|
||||
|
||||
\snippet shared/qtlogo.cpp 4
|
||||
|
||||
Finally the complete QtLogo scene is simply drawn by enabling the data arrays
|
||||
and then iterating over the parts, calling draw() on each one.
|
||||
|
||||
\section1 Window Class Definition
|
||||
|
||||
The \c Window class is used as a container for the \c GLWidget used to
|
||||
display the scene:
|
||||
|
||||
\snippet hellogl/window.h 0
|
||||
|
||||
In addition, it contains sliders that are used to change the orientation
|
||||
of the object in the scene.
|
||||
|
||||
\section1 Window Class Implementation
|
||||
|
||||
The constructor constructs an instance of the \c GLWidget class and some
|
||||
sliders to manipulate its contents.
|
||||
|
||||
\snippet hellogl/window.cpp 0
|
||||
|
||||
We connect the \l{QAbstractSlider::valueChanged()}{valueChanged()} signal
|
||||
from each of the sliders to the appropriate slots in \c{glWidget}.
|
||||
This allows the user to change the orientation of the object by dragging
|
||||
the sliders.
|
||||
|
||||
We also connect the \c xRotationChanged(), \c yRotationChanged(), and
|
||||
\c zRotationChanged() signals from \c glWidget to the
|
||||
\l{QAbstractSlider::setValue()}{setValue()} slots in the
|
||||
corresponding sliders.
|
||||
|
||||
\snippet hellogl/window.cpp 1
|
||||
|
||||
The sliders are placed horizontally in a layout alongside the \c GLWidget,
|
||||
and initialized with suitable default values.
|
||||
|
||||
The \c createSlider() utility function constructs a QSlider, and ensures
|
||||
that it is set up with a suitable range, step value, tick interval, and
|
||||
page step value before returning it to the calling function:
|
||||
|
||||
\snippet hellogl/window.cpp 2
|
||||
|
||||
\section1 Summary
|
||||
|
||||
The \c GLWidget class implementation shows how to subclass QGLWidget for
|
||||
the purposes of rendering a 3D scene using OpenGL calls. Since QGLWidget
|
||||
is a subclass of QWidget, subclasses of QGLWidget can be placed in layouts
|
||||
and provided with interactive features just like normal custom widgets.
|
||||
|
||||
We ensure that the widget is able to correctly render the scene using OpenGL
|
||||
by reimplementing the following functions:
|
||||
|
||||
\list
|
||||
\li QGLWidget::initializeGL() sets up resources needed by the OpenGL implementation
|
||||
to render the scene.
|
||||
\li QGLWidget::resizeGL() resizes the viewport so that the rendered scene fits onto
|
||||
the widget, and sets up a projection matrix to map 3D coordinates to 2D viewport
|
||||
coordinates.
|
||||
\li QGLWidget::paintGL() performs painting operations using OpenGL calls.
|
||||
\endlist
|
||||
|
||||
Since QGLWidget is a subclass of QWidget, it can also be used
|
||||
as a normal paint device, allowing 2D graphics to be drawn with QPainter.
|
||||
This use of QGLWidget is discussed in the \l{2D Painting Example}{2D Painting}
|
||||
example.
|
||||
|
||||
More advanced users may want to paint over parts of a scene rendered using
|
||||
OpenGL. QGLWidget allows pure OpenGL rendering to be mixed with QPainter
|
||||
calls, but care must be taken to maintain the state of the OpenGL implementation.
|
||||
See the \l{Overpainting Example}{Overpainting} example for more information.
|
||||
*/
|
||||
|
|
@ -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 documentation of the Qt Toolkit.
|
||||
|
|
@ -26,13 +26,18 @@
|
|||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example pbuffers
|
||||
\title Pixel Buffers Example
|
||||
|
||||
\example hellogl2
|
||||
\title Hello GL2 Example
|
||||
\ingroup examples-widgets-opengl
|
||||
\brief The Pixel Buffers example demonstrates how to use the
|
||||
QGLPixelBuffer class to render into an off-screen buffer and use
|
||||
the contents as a dynamic texture in a QGLWidget.
|
||||
|
||||
\image pbuffers-example.png
|
||||
\brief The Hello GL2 example demonstrates the basic use of the OpenGL-related classes
|
||||
provided with Qt.
|
||||
|
||||
\image hellogl2-example.png
|
||||
|
||||
Qt provides the QOpenGLWidget class to enable OpenGL graphics to be rendered
|
||||
within a standard application user interface. By subclassing this class, and
|
||||
providing reimplementations of event handler functions, 3D scenes can be
|
||||
displayed on widgets that can be placed in layouts, connected to other
|
||||
objects using signals and slots, and manipulated like any other widget.
|
||||
*/
|
||||
|
|
@ -1,244 +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 documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example overpainting
|
||||
\title Overpainting Example
|
||||
|
||||
\ingroup examples-widgets-opengl
|
||||
\brief The Overpainting example shows how QPainter can be used
|
||||
to overpaint a scene rendered using OpenGL in a QGLWidget.
|
||||
|
||||
\image overpainting-example.png
|
||||
|
||||
QGLWidget provides a widget with integrated OpenGL graphics support
|
||||
that enables 3D graphics to be displayed using normal OpenGL calls,
|
||||
yet also behaves like any other standard Qt widget with support for
|
||||
signals and slots, properties, and Qt's action system.
|
||||
|
||||
Usually, QGLWidget is subclassed to display a pure 3D scene. The
|
||||
developer reimplements \l{QGLWidget::initializeGL()}{initializeGL()}
|
||||
to initialize any required resources, \l{QGLWidget::resizeGL()}{resizeGL()}
|
||||
to set up the projection and viewport, and
|
||||
\l{QGLWidget::paintGL()}{paintGL()} to perform the OpenGL calls needed
|
||||
to render the scene. However, it is possible to subclass QGLWidget
|
||||
differently to allow 2D graphics, drawn using QPainter, to be
|
||||
painted over a scene rendered using OpenGL.
|
||||
|
||||
In this example, we demonstrate how this is done by reusing the code
|
||||
from the \l{Hello GL Example}{Hello GL} example to provide a 3D scene,
|
||||
and painting over it with some translucent 2D graphics. Instead of
|
||||
examining each class in detail, we only cover the parts of the
|
||||
\c GLWidget class that enable overpainting, and provide more detailed
|
||||
discussion in the final section of this document.
|
||||
|
||||
\section1 GLWidget Class Definition
|
||||
|
||||
The \c GLWidget class is a subclass of QGLWidget, based on the one used
|
||||
in the \l{Hello GL Example}{Hello GL} example. Rather than describe the
|
||||
class as a whole, we show the first few lines of the class and only
|
||||
discuss the changes we have made to the rest of it:
|
||||
|
||||
\snippet overpainting/glwidget.h 0
|
||||
\dots
|
||||
\snippet overpainting/glwidget.h 1
|
||||
\dots
|
||||
\snippet overpainting/glwidget.h 4
|
||||
|
||||
As usual, the widget uses \l{QGLWidget::initializeGL()}{initializeGL()}
|
||||
to set up geometry for our scene and perform OpenGL initialization tasks.
|
||||
The \l{QGLWidget::resizeGL()}{resizeGL()} function is used to ensure that
|
||||
the 3D graphics in the scene are transformed correctly to the 2D viewport
|
||||
displayed in the widget.
|
||||
|
||||
Instead of implementing \l{QGLWidget::paintGL()}{paintGL()} to handle updates
|
||||
to the widget, we implement a normal QWidget::paintEvent(). This
|
||||
allows us to mix OpenGL calls and QPainter operations in a controlled way.
|
||||
|
||||
In this example, we also implement QWidget::showEvent() to help with the
|
||||
initialization of the 2D graphics used.
|
||||
|
||||
The new private member functions and variables relate exclusively to the
|
||||
2D graphics and animation. The \c animate() slot is called periodically by the
|
||||
\c animationTimer to update the widget; the \c createBubbles() function
|
||||
initializes the \c bubbles list with instances of a helper class used to
|
||||
draw the animation; the \c drawInstructions() function is responsible for
|
||||
a semi-transparent message that is also overpainted onto the OpenGL scene.
|
||||
|
||||
\section1 GLWidget Class Implementation
|
||||
|
||||
Again, we only show the parts of the \c GLWidget implementation that are
|
||||
relevant to this example. In the constructor, we initialize a QTimer to
|
||||
control the animation:
|
||||
|
||||
\snippet overpainting/glwidget.cpp 0
|
||||
|
||||
We turn off the widget's \l{QWidget::autoFillBackground}{autoFillBackground} property to
|
||||
instruct OpenGL not to paint a background for the widget when
|
||||
\l{QPainter::begin()}{QPainter::begin()} is called.
|
||||
|
||||
As in the \l{Hello GL Example}{Hello GL} example, the destructor is responsible
|
||||
for freeing any OpenGL-related resources:
|
||||
|
||||
\snippet overpainting/glwidget.cpp 1
|
||||
|
||||
The \c initializeGL() function is fairly minimal, only setting up the QtLogo
|
||||
object used in the scene. See the \l{Hello GL Example}{Hello GL} example
|
||||
for details of the QtLogo class.
|
||||
|
||||
\snippet overpainting/glwidget.cpp 2
|
||||
|
||||
To cooperate fully with QPainter, we defer matrix stack operations and attribute
|
||||
initialization until the widget needs to be updated.
|
||||
|
||||
In this example, we implement \l{QWidget::paintEvent()}{paintEvent()} rather
|
||||
than \l{QGLWidget::paintGL()}{paintGL()} to render
|
||||
our scene. When drawing on a QGLWidget, the paint engine used by QPainter
|
||||
performs certain operations that change the states of the OpenGL
|
||||
implementation's matrix and property stacks. Therefore, it is necessary to
|
||||
make all the OpenGL calls to display the 3D graphics before we construct
|
||||
a QPainter to draw the 2D overlay.
|
||||
|
||||
We render a 3D scene by setting up model and projection transformations
|
||||
and other attributes. We use an OpenGL stack operation to preserve the
|
||||
original matrix state, allowing us to recover it later:
|
||||
|
||||
\snippet overpainting/glwidget.cpp 4
|
||||
|
||||
We define a color to use for the widget's background, and set up various
|
||||
attributes that define how the scene will be rendered.
|
||||
|
||||
\snippet overpainting/glwidget.cpp 6
|
||||
|
||||
We call the \c setupViewport() private function to set up the
|
||||
projection used for the scene. This is unnecessary in OpenGL
|
||||
examples that implement the \l{QGLWidget::paintGL()}{paintGL()}
|
||||
function because the matrix stacks are usually unmodified between
|
||||
calls to \l{QGLWidget::resizeGL()}{resizeGL()} and
|
||||
\l{QGLWidget::paintGL()}{paintGL()}.
|
||||
|
||||
Since the widget's background is not drawn by the system or by Qt, we use
|
||||
an OpenGL call to paint it before positioning the object defined earlier
|
||||
in the scene:
|
||||
|
||||
\snippet overpainting/glwidget.cpp 7
|
||||
|
||||
Once the QtLogo object's draw method has been executed, the GL
|
||||
states we changed and the matrix stack needs to be restored to its
|
||||
original state at the start of this function before we can begin
|
||||
overpainting:
|
||||
|
||||
\snippet overpainting/glwidget.cpp 8
|
||||
|
||||
With the 3D graphics done, we construct a QPainter for use on the widget
|
||||
and simply overpaint the widget with 2D graphics; in this case, using a
|
||||
helper class to draw a number of translucent bubbles onto the widget,
|
||||
and calling \c drawInstructions() to overlay some instructions:
|
||||
|
||||
\snippet overpainting/glwidget.cpp 10
|
||||
|
||||
When QPainter::end() is called, suitable OpenGL-specific calls are made to
|
||||
write the scene, and its additional contents, onto the widget.
|
||||
|
||||
With \l{QGLWidget::paintGL()}{paintGL()} the
|
||||
\l{QGLWidget::swapBuffers()}{swapBuffers()} call is done for us. But an explicit
|
||||
call to swapBuffers() is still not required because in the
|
||||
\l{QWidget::paintEvent()}{paintEvent()} method the QPainter on the OpenGL
|
||||
widget takes care of this for us.
|
||||
|
||||
The implementation of the \l{QGLWidget::resizeGL()}{resizeGL()} function
|
||||
sets up the dimensions of the viewport and defines a projection
|
||||
transformation:
|
||||
|
||||
\snippet overpainting/glwidget.cpp 11
|
||||
|
||||
Ideally, we want to arrange the 2D graphics to suit the widget's dimensions.
|
||||
To achieve this, we implement the \l{QWidget::showEvent()}{showEvent()} handler,
|
||||
creating new graphic elements (bubbles) if necessary at appropriate positions
|
||||
in the widget.
|
||||
|
||||
\snippet overpainting/glwidget.cpp 12
|
||||
|
||||
This function only has an effect if less than 20 bubbles have already been
|
||||
created.
|
||||
|
||||
The \c animate() slot is called every time the widget's \c animationTimer emits
|
||||
the \l{QTimer::timeout()}{timeout()} signal. This keeps the bubbles moving
|
||||
around.
|
||||
|
||||
\snippet overpainting/glwidget.cpp 13
|
||||
|
||||
We simply iterate over the bubbles in the \c bubbles list, updating the
|
||||
widget before and after each of them is moved.
|
||||
|
||||
The \c setupViewport() function is called from \c paintEvent()
|
||||
and \c resizeGL().
|
||||
|
||||
\snippet overpainting/glwidget.cpp 14
|
||||
|
||||
The \c drawInstructions() function is used to prepare some basic
|
||||
instructions that will be painted with the other 2D graphics over
|
||||
the 3D scene.
|
||||
|
||||
\snippet overpainting/glwidget.cpp 15
|
||||
|
||||
\section1 Summary
|
||||
|
||||
When overpainting 2D content onto 3D content, we need to use a QPainter
|
||||
\e and make OpenGL calls to achieve the desired effect. Since QPainter
|
||||
itself uses OpenGL calls when used on a QGLWidget subclass, we need to
|
||||
preserve the state of various OpenGL stacks when we perform our own
|
||||
calls, using the following approach:
|
||||
|
||||
\list
|
||||
\li Reimplement QGLWidget::initializeGL(), but only perform minimal
|
||||
initialization. QPainter will perform its own initialization
|
||||
routines, modifying the matrix and property stacks, so it is better
|
||||
to defer certain initialization tasks until just before you render
|
||||
the 3D scene.
|
||||
\li Reimplement QGLWidget::resizeGL() as in the pure 3D case.
|
||||
\li Reimplement QWidget::paintEvent() to draw both 2D and 3D graphics.
|
||||
\endlist
|
||||
|
||||
The \l{QWidget::paintEvent()}{paintEvent()} implementation performs the
|
||||
following tasks:
|
||||
|
||||
\list
|
||||
\li Push the current OpenGL modelview matrix onto a stack.
|
||||
\li Perform initialization tasks usually done in the
|
||||
\l{QGLWidget::initializeGL()}{initializeGL()} function.
|
||||
\li Perform code that would normally be located in the widget's
|
||||
\l{QGLWidget::resizeGL()}{resizeGL()} function to set the correct
|
||||
perspective transformation and set up the viewport.
|
||||
\li Render the scene using OpenGL calls.
|
||||
\li Pop the OpenGL modelview matrix off the stack.
|
||||
\li Construct a QPainter object.
|
||||
\li Initialize it for use on the widget with the QPainter::begin() function.
|
||||
\li Draw primitives using QPainter's member functions.
|
||||
\li Call QPainter::end() to finish painting.
|
||||
\endlist
|
||||
*/
|
||||
|
|
@ -1,38 +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 documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example pbuffers2
|
||||
\title Pixel Buffers 2 Example
|
||||
|
||||
\ingroup examples-widgets-opengl
|
||||
\brief The Pixel Buffers 2 example demonstrates how to use the
|
||||
QGLPixelBuffer class to render into an off-screen buffer and use
|
||||
the contents as a dynamic texture in a QGLWidget.
|
||||
|
||||
\image pbuffers2-example.png
|
||||
*/
|
||||
|
|
@ -1,37 +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 documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example samplebuffers
|
||||
\title Sample Buffers Example
|
||||
|
||||
\ingroup examples-widgets-opengl
|
||||
\brief The Sample Buffers example demonstrates how to use and enable
|
||||
sample buffers in a QGLWidget.
|
||||
|
||||
\image samplebuffers-example.png
|
||||
*/
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 <QMouseEvent>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QCoreApplication>
|
||||
#include <math.h>
|
||||
|
||||
GLWidget::GLWidget(QWidget *parent)
|
||||
: QOpenGLWidget(parent),
|
||||
m_xRot(0),
|
||||
m_yRot(0),
|
||||
m_zRot(0),
|
||||
m_program(0)
|
||||
{
|
||||
m_core = QCoreApplication::arguments().contains(QStringLiteral("--coreprofile"));
|
||||
// --transparent causes the clear color to be transparent. Therefore, on systems that
|
||||
// support it, the widget will become transparent apart from the logo.
|
||||
m_transparent = QCoreApplication::arguments().contains(QStringLiteral("--transparent"));
|
||||
if (m_transparent)
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
}
|
||||
|
||||
GLWidget::~GLWidget()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
QSize GLWidget::minimumSizeHint() const
|
||||
{
|
||||
return QSize(50, 50);
|
||||
}
|
||||
|
||||
QSize GLWidget::sizeHint() const
|
||||
{
|
||||
return QSize(400, 400);
|
||||
}
|
||||
|
||||
static void qNormalizeAngle(int &angle)
|
||||
{
|
||||
while (angle < 0)
|
||||
angle += 360 * 16;
|
||||
while (angle > 360 * 16)
|
||||
angle -= 360 * 16;
|
||||
}
|
||||
|
||||
void GLWidget::setXRotation(int angle)
|
||||
{
|
||||
qNormalizeAngle(angle);
|
||||
if (angle != m_xRot) {
|
||||
m_xRot = angle;
|
||||
emit xRotationChanged(angle);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void GLWidget::setYRotation(int angle)
|
||||
{
|
||||
qNormalizeAngle(angle);
|
||||
if (angle != m_yRot) {
|
||||
m_yRot = angle;
|
||||
emit yRotationChanged(angle);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void GLWidget::setZRotation(int angle)
|
||||
{
|
||||
qNormalizeAngle(angle);
|
||||
if (angle != m_zRot) {
|
||||
m_zRot = angle;
|
||||
emit zRotationChanged(angle);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void GLWidget::cleanup()
|
||||
{
|
||||
makeCurrent();
|
||||
m_logoVbo.destroy();
|
||||
delete m_program;
|
||||
m_program = 0;
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
static const char *vertexShaderSourceCore =
|
||||
"#version 150\n"
|
||||
"in vec4 vertex;\n"
|
||||
"in vec3 normal;\n"
|
||||
"out vec3 vert;\n"
|
||||
"out vec3 vertNormal;\n"
|
||||
"uniform mat4 projMatrix;\n"
|
||||
"uniform mat4 mvMatrix;\n"
|
||||
"uniform mat3 normalMatrix;\n"
|
||||
"void main() {\n"
|
||||
" vert = vertex.xyz;\n"
|
||||
" vertNormal = normalMatrix * normal;\n"
|
||||
" gl_Position = projMatrix * mvMatrix * vertex;\n"
|
||||
"}\n";
|
||||
|
||||
static const char *fragmentShaderSourceCore =
|
||||
"#version 150\n"
|
||||
"in highp vec3 vert;\n"
|
||||
"in highp vec3 vertNormal;\n"
|
||||
"out highp vec4 fragColor;\n"
|
||||
"uniform highp vec3 lightPos;\n"
|
||||
"void main() {\n"
|
||||
" highp vec3 L = normalize(lightPos - vert);\n"
|
||||
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
|
||||
" highp vec3 color = vec3(0.39, 1.0, 0.0);\n"
|
||||
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
|
||||
" fragColor = vec4(col, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char *vertexShaderSource =
|
||||
"attribute vec4 vertex;\n"
|
||||
"attribute vec3 normal;\n"
|
||||
"varying vec3 vert;\n"
|
||||
"varying vec3 vertNormal;\n"
|
||||
"uniform mat4 projMatrix;\n"
|
||||
"uniform mat4 mvMatrix;\n"
|
||||
"uniform mat3 normalMatrix;\n"
|
||||
"void main() {\n"
|
||||
" vert = vertex.xyz;\n"
|
||||
" vertNormal = normalMatrix * normal;\n"
|
||||
" gl_Position = projMatrix * mvMatrix * vertex;\n"
|
||||
"}\n";
|
||||
|
||||
static const char *fragmentShaderSource =
|
||||
"varying highp vec3 vert;\n"
|
||||
"varying highp vec3 vertNormal;\n"
|
||||
"uniform highp vec3 lightPos;\n"
|
||||
"void main() {\n"
|
||||
" highp vec3 L = normalize(lightPos - vert);\n"
|
||||
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
|
||||
" highp vec3 color = vec3(0.39, 1.0, 0.0);\n"
|
||||
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
|
||||
" gl_FragColor = vec4(col, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
void GLWidget::initializeGL()
|
||||
{
|
||||
// In this example the widget's corresponding top-level window can change
|
||||
// several times during the widget's lifetime. Whenever this happens, the
|
||||
// QOpenGLWidget's associated context is destroyed and a new one is created.
|
||||
// Therefore we have to be prepared to clean up the resources on the
|
||||
// aboutToBeDestroyed() signal, instead of the destructor. The emission of
|
||||
// the signal will be followed by an invocation of initializeGL() where we
|
||||
// can recreate all resources.
|
||||
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWidget::cleanup);
|
||||
|
||||
initializeOpenGLFunctions();
|
||||
glClearColor(0, 0, 0, m_transparent ? 0 : 1);
|
||||
|
||||
m_program = new QOpenGLShaderProgram;
|
||||
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource);
|
||||
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_core ? fragmentShaderSourceCore : fragmentShaderSource);
|
||||
m_program->bindAttributeLocation("vertex", 0);
|
||||
m_program->bindAttributeLocation("normal", 1);
|
||||
m_program->link();
|
||||
|
||||
m_program->bind();
|
||||
m_projMatrixLoc = m_program->uniformLocation("projMatrix");
|
||||
m_mvMatrixLoc = m_program->uniformLocation("mvMatrix");
|
||||
m_normalMatrixLoc = m_program->uniformLocation("normalMatrix");
|
||||
m_lightPosLoc = m_program->uniformLocation("lightPos");
|
||||
|
||||
// Create a vertex array object. In OpenGL ES 2.0 and OpenGL 2.x
|
||||
// implementations this is optional and support may not be present
|
||||
// at all. Nonetheless the below code works in all cases and makes
|
||||
// sure there is a VAO when one is needed.
|
||||
m_vao.create();
|
||||
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
|
||||
|
||||
// Setup our vertex buffer object.
|
||||
m_logoVbo.create();
|
||||
m_logoVbo.bind();
|
||||
m_logoVbo.allocate(m_logo.constData(), m_logo.count() * sizeof(GLfloat));
|
||||
|
||||
// Store the vertex attribute bindings for the program.
|
||||
setupVertexAttribs();
|
||||
|
||||
// Our camera never changes in this example.
|
||||
m_camera.setToIdentity();
|
||||
m_camera.translate(0, 0, -1);
|
||||
|
||||
// Light position is fixed.
|
||||
m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));
|
||||
|
||||
m_program->release();
|
||||
}
|
||||
|
||||
void GLWidget::setupVertexAttribs()
|
||||
{
|
||||
m_logoVbo.bind();
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
f->glEnableVertexAttribArray(0);
|
||||
f->glEnableVertexAttribArray(1);
|
||||
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);
|
||||
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
|
||||
m_logoVbo.release();
|
||||
}
|
||||
|
||||
void GLWidget::paintGL()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
m_world.setToIdentity();
|
||||
m_world.rotate(180.0f - (m_xRot / 16.0f), 1, 0, 0);
|
||||
m_world.rotate(m_yRot / 16.0f, 0, 1, 0);
|
||||
m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
|
||||
|
||||
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
|
||||
m_program->bind();
|
||||
m_program->setUniformValue(m_projMatrixLoc, m_proj);
|
||||
m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
|
||||
QMatrix3x3 normalMatrix = m_world.normalMatrix();
|
||||
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, m_logo.vertexCount());
|
||||
|
||||
m_program->release();
|
||||
}
|
||||
|
||||
void GLWidget::resizeGL(int w, int h)
|
||||
{
|
||||
m_proj.setToIdentity();
|
||||
m_proj.perspective(45.0f, GLfloat(w) / h, 0.01f, 100.0f);
|
||||
}
|
||||
|
||||
void GLWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
m_lastPos = event->pos();
|
||||
}
|
||||
|
||||
void GLWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
int dx = event->x() - m_lastPos.x();
|
||||
int dy = event->y() - m_lastPos.y();
|
||||
|
||||
if (event->buttons() & Qt::LeftButton) {
|
||||
setXRotation(m_xRot + 8 * dy);
|
||||
setYRotation(m_yRot + 8 * dx);
|
||||
} else if (event->buttons() & Qt::RightButton) {
|
||||
setXRotation(m_xRot + 8 * dy);
|
||||
setZRotation(m_zRot + 8 * dx);
|
||||
}
|
||||
m_lastPos = event->pos();
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QMatrix4x4>
|
||||
#include "logo.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
|
||||
|
||||
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GLWidget(QWidget *parent = 0);
|
||||
~GLWidget();
|
||||
|
||||
QSize minimumSizeHint() const Q_DECL_OVERRIDE;
|
||||
QSize sizeHint() const Q_DECL_OVERRIDE;
|
||||
|
||||
public slots:
|
||||
void setXRotation(int angle);
|
||||
void setYRotation(int angle);
|
||||
void setZRotation(int angle);
|
||||
void cleanup();
|
||||
|
||||
signals:
|
||||
void xRotationChanged(int angle);
|
||||
void yRotationChanged(int angle);
|
||||
void zRotationChanged(int angle);
|
||||
|
||||
protected:
|
||||
void initializeGL() Q_DECL_OVERRIDE;
|
||||
void paintGL() Q_DECL_OVERRIDE;
|
||||
void resizeGL(int width, int height) Q_DECL_OVERRIDE;
|
||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
void setupVertexAttribs();
|
||||
|
||||
bool m_core;
|
||||
int m_xRot;
|
||||
int m_yRot;
|
||||
int m_zRot;
|
||||
QPoint m_lastPos;
|
||||
Logo m_logo;
|
||||
QOpenGLVertexArrayObject m_vao;
|
||||
QOpenGLBuffer m_logoVbo;
|
||||
QOpenGLShaderProgram *m_program;
|
||||
int m_projMatrixLoc;
|
||||
int m_mvMatrixLoc;
|
||||
int m_normalMatrixLoc;
|
||||
int m_lightPosLoc;
|
||||
QMatrix4x4 m_proj;
|
||||
QMatrix4x4 m_camera;
|
||||
QMatrix4x4 m_world;
|
||||
bool m_transparent;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
HEADERS = glwidget.h \
|
||||
window.h \
|
||||
mainwindow.h \
|
||||
logo.h
|
||||
SOURCES = glwidget.cpp \
|
||||
main.cpp \
|
||||
window.cpp \
|
||||
mainwindow.cpp \
|
||||
logo.cpp
|
||||
|
||||
QT += widgets
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/opengl/hellogl2
|
||||
INSTALLS += target
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 "logo.h"
|
||||
#include <qmath.h>
|
||||
|
||||
Logo::Logo()
|
||||
: m_count(0)
|
||||
{
|
||||
m_data.resize(2500 * 6);
|
||||
|
||||
const GLfloat x1 = +0.06f;
|
||||
const GLfloat y1 = -0.14f;
|
||||
const GLfloat x2 = +0.14f;
|
||||
const GLfloat y2 = -0.06f;
|
||||
const GLfloat x3 = +0.08f;
|
||||
const GLfloat y3 = +0.00f;
|
||||
const GLfloat x4 = +0.30f;
|
||||
const GLfloat 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 int NumSectors = 100;
|
||||
|
||||
for (int i = 0; i < NumSectors; ++i) {
|
||||
GLfloat angle = (i * 2 * M_PI) / NumSectors;
|
||||
GLfloat angleSin = qSin(angle);
|
||||
GLfloat angleCos = qCos(angle);
|
||||
const GLfloat x5 = 0.30f * angleSin;
|
||||
const GLfloat y5 = 0.30f * angleCos;
|
||||
const GLfloat x6 = 0.20f * angleSin;
|
||||
const GLfloat y6 = 0.20f * angleCos;
|
||||
|
||||
angle = ((i + 1) * 2 * M_PI) / NumSectors;
|
||||
angleSin = qSin(angle);
|
||||
angleCos = qCos(angle);
|
||||
const GLfloat x7 = 0.20f * angleSin;
|
||||
const GLfloat y7 = 0.20f * angleCos;
|
||||
const GLfloat x8 = 0.30f * angleSin;
|
||||
const GLfloat y8 = 0.30f * angleCos;
|
||||
|
||||
quad(x5, y5, x6, y6, x7, y7, x8, y8);
|
||||
|
||||
extrude(x6, y6, x7, y7);
|
||||
extrude(x8, y8, x5, y5);
|
||||
}
|
||||
}
|
||||
|
||||
void Logo::add(const QVector3D &v, const QVector3D &n)
|
||||
{
|
||||
GLfloat *p = m_data.data() + m_count;
|
||||
*p++ = v.x();
|
||||
*p++ = v.y();
|
||||
*p++ = v.z();
|
||||
*p++ = n.x();
|
||||
*p++ = n.y();
|
||||
*p++ = n.z();
|
||||
m_count += 6;
|
||||
}
|
||||
|
||||
void Logo::quad(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4)
|
||||
{
|
||||
QVector3D n = QVector3D::normal(QVector3D(x4 - x1, y4 - y1, 0.0f), QVector3D(x2 - x1, y2 - y1, 0.0f));
|
||||
|
||||
add(QVector3D(x1, y1, -0.05f), n);
|
||||
add(QVector3D(x4, y4, -0.05f), n);
|
||||
add(QVector3D(x2, y2, -0.05f), n);
|
||||
|
||||
add(QVector3D(x3, y3, -0.05f), n);
|
||||
add(QVector3D(x2, y2, -0.05f), n);
|
||||
add(QVector3D(x4, y4, -0.05f), n);
|
||||
|
||||
n = QVector3D::normal(QVector3D(x1 - x4, y1 - y4, 0.0f), QVector3D(x2 - x4, y2 - y4, 0.0f));
|
||||
|
||||
add(QVector3D(x4, y4, 0.05f), n);
|
||||
add(QVector3D(x1, y1, 0.05f), n);
|
||||
add(QVector3D(x2, y2, 0.05f), n);
|
||||
|
||||
add(QVector3D(x2, y2, 0.05f), n);
|
||||
add(QVector3D(x3, y3, 0.05f), n);
|
||||
add(QVector3D(x4, y4, 0.05f), n);
|
||||
}
|
||||
|
||||
void Logo::extrude(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
|
||||
{
|
||||
QVector3D n = QVector3D::normal(QVector3D(0.0f, 0.0f, -0.1f), QVector3D(x2 - x1, y2 - y1, 0.0f));
|
||||
|
||||
add(QVector3D(x1, y1, +0.05f), n);
|
||||
add(QVector3D(x1, y1, -0.05f), n);
|
||||
add(QVector3D(x2, y2, +0.05f), n);
|
||||
|
||||
add(QVector3D(x2, y2, -0.05f), n);
|
||||
add(QVector3D(x2, y2, +0.05f), n);
|
||||
add(QVector3D(x1, y1, -0.05f), n);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 LOGO_H
|
||||
#define LOGO_H
|
||||
|
||||
#include <qopengl.h>
|
||||
#include <QVector>
|
||||
#include <QVector3D>
|
||||
|
||||
class Logo
|
||||
{
|
||||
public:
|
||||
Logo();
|
||||
const GLfloat *constData() const { return m_data.constData(); }
|
||||
int count() const { return m_count; }
|
||||
int vertexCount() const { return m_count / 6; }
|
||||
|
||||
private:
|
||||
void quad(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4);
|
||||
void extrude(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
|
||||
void add(const QVector3D &v, const QVector3D &n);
|
||||
|
||||
QVector<GLfloat> m_data;
|
||||
int m_count;
|
||||
};
|
||||
|
||||
#endif // LOGO_H
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 <QDesktopWidget>
|
||||
#include <QSurfaceFormat>
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QSurfaceFormat fmt;
|
||||
fmt.setDepthBufferSize(24);
|
||||
if (QCoreApplication::arguments().contains(QStringLiteral("--multisample")))
|
||||
fmt.setSamples(4);
|
||||
if (QCoreApplication::arguments().contains(QStringLiteral("--coreprofile"))) {
|
||||
fmt.setVersion(3, 2);
|
||||
fmt.setProfile(QSurfaceFormat::CoreProfile);
|
||||
}
|
||||
QSurfaceFormat::setDefaultFormat(fmt);
|
||||
|
||||
MainWindow mainWindow;
|
||||
mainWindow.resize(mainWindow.sizeHint());
|
||||
int desktopArea = QApplication::desktop()->width() *
|
||||
QApplication::desktop()->height();
|
||||
int widgetArea = mainWindow.width() * mainWindow.height();
|
||||
if (((float)widgetArea / (float)desktopArea) < 0.75f)
|
||||
mainWindow.show();
|
||||
else
|
||||
mainWindow.showMaximized();
|
||||
return app.exec();
|
||||
}
|
||||
|
|
@ -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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "window.h"
|
||||
#include <QMenuBar>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
QMenuBar *menuBar = new QMenuBar;
|
||||
QMenu *menuWindow = menuBar->addMenu(tr("&Window"));
|
||||
QAction *addNew = new QAction(menuWindow);
|
||||
addNew->setText(tr("Add new"));
|
||||
menuWindow->addAction(addNew);
|
||||
connect(addNew, SIGNAL(triggered()), this, SLOT(onAddNew()));
|
||||
setMenuBar(menuBar);
|
||||
|
||||
onAddNew();
|
||||
}
|
||||
|
||||
void MainWindow::onAddNew()
|
||||
{
|
||||
if (!centralWidget())
|
||||
setCentralWidget(new Window(this));
|
||||
else
|
||||
QMessageBox::information(0, tr("Cannot add new window"), tr("Already occupied. Undock first."));
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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>
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow();
|
||||
|
||||
private slots:
|
||||
void onAddNew();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 "window.h"
|
||||
#include "mainwindow.h"
|
||||
#include <QSlider>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QKeyEvent>
|
||||
#include <QPushButton>
|
||||
#include <QDesktopWidget>
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
|
||||
Window::Window(MainWindow *mw)
|
||||
: mainWindow(mw)
|
||||
{
|
||||
glWidget = new GLWidget;
|
||||
|
||||
xSlider = createSlider();
|
||||
ySlider = createSlider();
|
||||
zSlider = createSlider();
|
||||
|
||||
connect(xSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setXRotation(int)));
|
||||
connect(glWidget, SIGNAL(xRotationChanged(int)), xSlider, SLOT(setValue(int)));
|
||||
connect(ySlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setYRotation(int)));
|
||||
connect(glWidget, SIGNAL(yRotationChanged(int)), ySlider, SLOT(setValue(int)));
|
||||
connect(zSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setZRotation(int)));
|
||||
connect(glWidget, SIGNAL(zRotationChanged(int)), zSlider, SLOT(setValue(int)));
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
QHBoxLayout *container = new QHBoxLayout;
|
||||
container->addWidget(glWidget);
|
||||
container->addWidget(xSlider);
|
||||
container->addWidget(ySlider);
|
||||
container->addWidget(zSlider);
|
||||
|
||||
QWidget *w = new QWidget;
|
||||
w->setLayout(container);
|
||||
mainLayout->addWidget(w);
|
||||
dockBtn = new QPushButton(tr("Undock"), this);
|
||||
connect(dockBtn, SIGNAL(clicked()), this, SLOT(dockUndock()));
|
||||
mainLayout->addWidget(dockBtn);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
xSlider->setValue(15 * 16);
|
||||
ySlider->setValue(345 * 16);
|
||||
zSlider->setValue(0 * 16);
|
||||
|
||||
setWindowTitle(tr("Hello GL"));
|
||||
}
|
||||
|
||||
QSlider *Window::createSlider()
|
||||
{
|
||||
QSlider *slider = new QSlider(Qt::Vertical);
|
||||
slider->setRange(0, 360 * 16);
|
||||
slider->setSingleStep(16);
|
||||
slider->setPageStep(15 * 16);
|
||||
slider->setTickInterval(15 * 16);
|
||||
slider->setTickPosition(QSlider::TicksRight);
|
||||
return slider;
|
||||
}
|
||||
|
||||
void Window::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
if (e->key() == Qt::Key_Escape)
|
||||
close();
|
||||
else
|
||||
QWidget::keyPressEvent(e);
|
||||
}
|
||||
|
||||
void Window::dockUndock()
|
||||
{
|
||||
if (parent()) {
|
||||
setParent(0);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
move(QApplication::desktop()->width() / 2 - width() / 2,
|
||||
QApplication::desktop()->height() / 2 - height() / 2);
|
||||
dockBtn->setText(tr("Dock"));
|
||||
show();
|
||||
} else {
|
||||
if (!mainWindow->centralWidget()) {
|
||||
if (mainWindow->isVisible()) {
|
||||
setAttribute(Qt::WA_DeleteOnClose, false);
|
||||
dockBtn->setText(tr("Undock"));
|
||||
mainWindow->setCentralWidget(this);
|
||||
} else {
|
||||
QMessageBox::information(0, tr("Cannot dock"), tr("Main window already closed"));
|
||||
}
|
||||
} else {
|
||||
QMessageBox::information(0, tr("Cannot dock"), tr("Main window already occupied"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 WINDOW_H
|
||||
#define WINDOW_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSlider;
|
||||
class QPushButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class GLWidget;
|
||||
class MainWindow;
|
||||
|
||||
class Window : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Window(MainWindow *mw);
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private slots:
|
||||
void dockUndock();
|
||||
|
||||
private:
|
||||
QSlider *createSlider();
|
||||
|
||||
GLWidget *glWidget;
|
||||
QSlider *xSlider;
|
||||
QSlider *ySlider;
|
||||
QSlider *zSlider;
|
||||
QPushButton *dockBtn;
|
||||
MainWindow *mainWindow;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -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.
|
||||
|
|
@ -145,29 +145,18 @@ void Renderer::render()
|
|||
|
||||
QOpenGLFunctions *f = m_context->functions();
|
||||
f->glViewport(0, 0, viewSize.width() * surface->devicePixelRatio(), viewSize.height() * surface->devicePixelRatio());
|
||||
|
||||
f->glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
|
||||
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
f->glFrontFace(GL_CW);
|
||||
f->glCullFace(GL_FRONT);
|
||||
f->glEnable(GL_CULL_FACE);
|
||||
f->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.translate(0.0f, -0.2f, 0.0f);
|
||||
|
||||
m_program->bind();
|
||||
m_program->setUniformValue(matrixUniform, modelview);
|
||||
m_program->setUniformValue(colorUniform, color);
|
||||
paintQtLogo();
|
||||
m_program->release();
|
||||
|
||||
f->glDisable(GL_DEPTH_TEST);
|
||||
f->glDisable(GL_CULL_FACE);
|
||||
m_context->functions()->glDrawArrays(GL_TRIANGLES, 0, vertices.size());
|
||||
|
||||
m_context->swapBuffers(surface);
|
||||
|
||||
|
|
@ -176,17 +165,6 @@ void Renderer::render()
|
|||
QTimer::singleShot(0, this, SLOT(render()));
|
||||
}
|
||||
|
||||
void Renderer::paintQtLogo()
|
||||
{
|
||||
m_program->enableAttributeArray(normalAttr);
|
||||
m_program->enableAttributeArray(vertexAttr);
|
||||
m_program->setAttributeArray(vertexAttr, vertices.constData());
|
||||
m_program->setAttributeArray(normalAttr, normals.constData());
|
||||
m_context->functions()->glDrawArrays(GL_TRIANGLES, 0, vertices.size());
|
||||
m_program->disableAttributeArray(normalAttr);
|
||||
m_program->disableAttributeArray(vertexAttr);
|
||||
}
|
||||
|
||||
void Renderer::initialize()
|
||||
{
|
||||
QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
|
||||
|
|
@ -218,6 +196,7 @@ void Renderer::initialize()
|
|||
m_program->addShader(vshader);
|
||||
m_program->addShader(fshader);
|
||||
m_program->link();
|
||||
m_program->bind();
|
||||
|
||||
vertexAttr = m_program->attributeLocation("vertex");
|
||||
normalAttr = m_program->attributeLocation("normal");
|
||||
|
|
@ -226,6 +205,25 @@ void Renderer::initialize()
|
|||
|
||||
m_fAngle = 0;
|
||||
createGeometry();
|
||||
|
||||
m_vbo.create();
|
||||
m_vbo.bind();
|
||||
const int verticesSize = vertices.count() * 3 * sizeof(GLfloat);
|
||||
m_vbo.allocate(verticesSize * 2);
|
||||
m_vbo.write(0, vertices.constData(), verticesSize);
|
||||
m_vbo.write(verticesSize, normals.constData(), verticesSize);
|
||||
|
||||
QOpenGLFunctions *f = m_context->functions();
|
||||
f->glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
|
||||
f->glFrontFace(GL_CW);
|
||||
f->glCullFace(GL_FRONT);
|
||||
f->glEnable(GL_CULL_FACE);
|
||||
f->glEnable(GL_DEPTH_TEST);
|
||||
|
||||
m_program->enableAttributeArray(vertexAttr);
|
||||
m_program->enableAttributeArray(normalAttr);
|
||||
m_program->setAttributeBuffer(vertexAttr, GL_FLOAT, 0, 3);
|
||||
m_program->setAttributeBuffer(normalAttr, GL_FLOAT, verticesSize, 3);
|
||||
}
|
||||
|
||||
void Renderer::createGeometry()
|
||||
|
|
|
|||
|
|
@ -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,6 +43,7 @@
|
|||
#include <QColor>
|
||||
#include <QMutex>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QSharedPointer>
|
||||
#include <QTimer>
|
||||
|
||||
|
|
@ -65,13 +66,13 @@ private slots:
|
|||
private:
|
||||
void initialize();
|
||||
|
||||
qreal m_fAngle;
|
||||
bool m_showBubbles;
|
||||
void paintQtLogo();
|
||||
void createGeometry();
|
||||
void createBubbles(int number);
|
||||
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);
|
||||
|
||||
qreal m_fAngle;
|
||||
|
||||
QVector<QVector3D> vertices;
|
||||
QVector<QVector3D> normals;
|
||||
int vertexAttr;
|
||||
|
|
@ -83,6 +84,7 @@ private:
|
|||
QSurfaceFormat m_format;
|
||||
QOpenGLContext *m_context;
|
||||
QOpenGLShaderProgram *m_program;
|
||||
QOpenGLBuffer m_vbo;
|
||||
|
||||
QList<HelloWindow *> m_windows;
|
||||
int m_currentWindow;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
#include "hellowindow.h"
|
||||
|
||||
#include <qpa/qplatformintegration.h>
|
||||
#include <private/qguiapplication_p.h>
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
|
|
@ -51,10 +50,7 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
QPlatformIntegration *integ = QGuiApplicationPrivate::platformIntegration();
|
||||
const bool multipleWindows = integ->hasCapability(QPlatformIntegration::ThreadedOpenGL)
|
||||
&& integ->hasCapability(QPlatformIntegration::WindowManagement)
|
||||
&& !QGuiApplication::arguments().contains(QStringLiteral("--single"));
|
||||
const bool multipleWindows = QGuiApplication::arguments().contains(QStringLiteral("--multiple"));
|
||||
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
This directory contains legacy examples that use the fixed pipeline
|
||||
and thus are not compatible with OpenGL ES 2.0+ and the core profile of
|
||||
OpenGL 3.0+. They also rely on the Qt OpenGL module (e.g. QGLWidget) which
|
||||
is not advisable in new application.
|
||||
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
|
|
@ -0,0 +1,16 @@
|
|||
requires(qtHaveModule(opengl))
|
||||
|
||||
TEMPLATE = subdirs
|
||||
|
||||
!contains(QT_CONFIG, dynamicgl): !contains(QT_CONFIG, opengles2) {
|
||||
# legacy desktop-only examples, no dynamic GL support
|
||||
SUBDIRS = \
|
||||
grabber \
|
||||
hellogl \
|
||||
overpainting \
|
||||
pbuffers \
|
||||
framebufferobject2 \
|
||||
samplebuffers
|
||||
}
|
||||
|
||||
EXAMPLE_FILES = shared
|
||||
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
|
@ -1,30 +1,16 @@
|
|||
requires(qtHaveModule(opengl))
|
||||
|
||||
TEMPLATE = subdirs
|
||||
|
||||
contains(QT_CONFIG, dynamicgl) {
|
||||
SUBDIRS = hellowindow \
|
||||
contextinfo \
|
||||
qopenglwidget \
|
||||
threadedqopenglwidget \
|
||||
qopenglwindow
|
||||
} else: !contains(QT_CONFIG, opengles2) {
|
||||
SUBDIRS = 2dpainting \
|
||||
grabber \
|
||||
hellogl \
|
||||
overpainting \
|
||||
pbuffers \
|
||||
framebufferobject2 \
|
||||
samplebuffers
|
||||
SUBDIRS = hellowindow \
|
||||
paintedwindow \
|
||||
qopenglwindow
|
||||
|
||||
qtHaveModule(widgets) {
|
||||
SUBDIRS += contextinfo \
|
||||
threadedqopenglwidget \
|
||||
2dpainting \
|
||||
hellogl2
|
||||
|
||||
!wince*: SUBDIRS += qopenglwidget \
|
||||
cube \
|
||||
textures
|
||||
}
|
||||
|
||||
!contains(QT_CONFIG, dynamicgl): SUBDIRS += hellowindow \
|
||||
paintedwindow \
|
||||
contextinfo \
|
||||
cube \
|
||||
textures \
|
||||
qopenglwidget \
|
||||
threadedqopenglwidget \
|
||||
qopenglwindow
|
||||
|
||||
EXAMPLE_FILES = shared
|
||||
|
|
|
|||
|
|
@ -56,15 +56,15 @@ void Bubble::updateCache()
|
|||
{
|
||||
if (cache)
|
||||
delete cache;
|
||||
cache = new QImage(qRound(radius * 2 + 2), qRound(radius * 2 + 2), QImage::Format_ARGB32);
|
||||
cache = new QImage(qRound(radius * 2 + 2), qRound(radius * 2 + 2), QImage::Format_ARGB32_Premultiplied);
|
||||
cache->fill(0x00000000);
|
||||
QPainter p(cache);
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
QPen pen(Qt::white);
|
||||
pen.setWidth(2);
|
||||
p.setPen(pen);
|
||||
p.setBrush(brush);
|
||||
p.drawEllipse(0, 0, int(2*radius), int(2*radius));
|
||||
p.drawEllipse(1, 1, int(2*radius), int(2*radius));
|
||||
}
|
||||
//! [0]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,46 +1,49 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
**
|
||||
** 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 <QPainter>
|
||||
#include <QPaintEngine>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QCoreApplication>
|
||||
#include <math.h>
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
|
@ -50,143 +53,175 @@ const int bubbleNum = 8;
|
|||
|
||||
GLWidget::GLWidget(MainWindow *mw, bool button, const QColor &background)
|
||||
: m_mainWindow(mw),
|
||||
m_showBubbles(true),
|
||||
m_qtLogo(true),
|
||||
m_frames(0),
|
||||
m_program1(0),
|
||||
m_program2(0),
|
||||
m_texture(0),
|
||||
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;
|
||||
m_showBubbles = true;
|
||||
setMinimumSize(300, 250);
|
||||
}
|
||||
|
||||
GLWidget::~GLWidget()
|
||||
{
|
||||
qDeleteAll(m_bubbles);
|
||||
|
||||
// And now release all OpenGL resources.
|
||||
makeCurrent();
|
||||
delete m_texture;
|
||||
delete m_program1;
|
||||
delete m_program2;
|
||||
delete m_vshader1;
|
||||
delete m_fshader1;
|
||||
delete m_vshader2;
|
||||
delete m_fshader2;
|
||||
m_vbo1.destroy();
|
||||
m_vbo2.destroy();
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
void GLWidget::setScaling(int scale) {
|
||||
|
||||
void GLWidget::setScaling(int scale)
|
||||
{
|
||||
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;
|
||||
m_fScale = 1;
|
||||
}
|
||||
|
||||
void GLWidget::setLogo() {
|
||||
qtLogo = true;
|
||||
}
|
||||
|
||||
void GLWidget::setTexture() {
|
||||
qtLogo = false;
|
||||
}
|
||||
|
||||
void GLWidget::showBubbles(bool bubbles)
|
||||
void GLWidget::setLogo()
|
||||
{
|
||||
m_showBubbles = bubbles;
|
||||
m_qtLogo = true;
|
||||
}
|
||||
|
||||
void GLWidget::setTexture()
|
||||
{
|
||||
m_qtLogo = false;
|
||||
}
|
||||
|
||||
void GLWidget::setShowBubbles(bool bubbles)
|
||||
{
|
||||
m_showBubbles = bubbles;
|
||||
}
|
||||
|
||||
void GLWidget::paintQtLogo()
|
||||
{
|
||||
program1.enableAttributeArray(normalAttr1);
|
||||
program1.enableAttributeArray(vertexAttr1);
|
||||
program1.setAttributeArray(vertexAttr1, vertices.constData());
|
||||
program1.setAttributeArray(normalAttr1, normals.constData());
|
||||
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
|
||||
program1.disableAttributeArray(normalAttr1);
|
||||
program1.disableAttributeArray(vertexAttr1);
|
||||
m_program1->enableAttributeArray(m_vertexAttr1);
|
||||
m_program1->enableAttributeArray(m_normalAttr1);
|
||||
|
||||
m_vbo1.bind();
|
||||
// The data in the buffer is placed like this:
|
||||
// vertex1.x, vertex1.y, vertex1.z, normal1.x, normal1.y, normal1.z, vertex2.x, ...
|
||||
m_program1->setAttributeBuffer(m_vertexAttr1, GL_FLOAT, 0, 3, 6 * sizeof(GLfloat));
|
||||
m_program1->setAttributeBuffer(m_normalAttr1, GL_FLOAT, 3 * sizeof(GLfloat), 3, 6 * sizeof(GLfloat));
|
||||
m_vbo1.release();
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
|
||||
|
||||
m_program1->disableAttributeArray(m_normalAttr1);
|
||||
m_program1->disableAttributeArray(m_vertexAttr1);
|
||||
}
|
||||
|
||||
void GLWidget::paintTexturedCube()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, m_uiTexture);
|
||||
GLfloat afVertices[] = {
|
||||
-0.5, 0.5, 0.5, 0.5,-0.5,0.5,-0.5,-0.5,0.5,
|
||||
0.5, -0.5, 0.5, -0.5,0.5,0.5,0.5,0.5,0.5,
|
||||
-0.5, -0.5, -0.5, 0.5,-0.5,-0.5,-0.5,0.5,-0.5,
|
||||
0.5, 0.5, -0.5, -0.5,0.5,-0.5,0.5,-0.5,-0.5,
|
||||
m_texture->bind();
|
||||
|
||||
0.5, -0.5, -0.5, 0.5,-0.5,0.5,0.5,0.5,-0.5,
|
||||
0.5, 0.5, 0.5, 0.5,0.5,-0.5,0.5,-0.5,0.5,
|
||||
-0.5, 0.5, -0.5, -0.5,-0.5,0.5,-0.5,-0.5,-0.5,
|
||||
-0.5, -0.5, 0.5, -0.5,0.5,-0.5,-0.5,0.5,0.5,
|
||||
if (!m_vbo2.isCreated()) {
|
||||
static GLfloat afVertices[] = {
|
||||
-0.5, 0.5, 0.5, 0.5,-0.5,0.5,-0.5,-0.5,0.5,
|
||||
0.5, -0.5, 0.5, -0.5,0.5,0.5,0.5,0.5,0.5,
|
||||
-0.5, -0.5, -0.5, 0.5,-0.5,-0.5,-0.5,0.5,-0.5,
|
||||
0.5, 0.5, -0.5, -0.5,0.5,-0.5,0.5,-0.5,-0.5,
|
||||
|
||||
0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5,
|
||||
-0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5,
|
||||
-0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5,
|
||||
0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5
|
||||
};
|
||||
program2.setAttributeArray(vertexAttr2, afVertices, 3);
|
||||
0.5, -0.5, -0.5, 0.5,-0.5,0.5,0.5,0.5,-0.5,
|
||||
0.5, 0.5, 0.5, 0.5,0.5,-0.5,0.5,-0.5,0.5,
|
||||
-0.5, 0.5, -0.5, -0.5,-0.5,0.5,-0.5,-0.5,-0.5,
|
||||
-0.5, -0.5, 0.5, -0.5,0.5,-0.5,-0.5,0.5,0.5,
|
||||
|
||||
GLfloat afTexCoord[] = {
|
||||
0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
|
||||
1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
|
||||
1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
|
||||
0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
|
||||
0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5,
|
||||
-0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5,
|
||||
-0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5,
|
||||
0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5
|
||||
};
|
||||
|
||||
1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
|
||||
0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
|
||||
0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
|
||||
1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
|
||||
static GLfloat afTexCoord[] = {
|
||||
0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
|
||||
1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
|
||||
1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
|
||||
0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
|
||||
|
||||
0.0f,1.0f, 1.0f,0.0f, 1.0f,1.0f,
|
||||
1.0f,0.0f, 0.0f,1.0f, 0.0f,0.0f,
|
||||
1.0f,0.0f, 1.0f,1.0f, 0.0f,0.0f,
|
||||
0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f
|
||||
};
|
||||
program2.setAttributeArray(texCoordAttr2, afTexCoord, 2);
|
||||
1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
|
||||
0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
|
||||
0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
|
||||
1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
|
||||
|
||||
GLfloat afNormals[] = {
|
||||
0.0f,1.0f, 1.0f,0.0f, 1.0f,1.0f,
|
||||
1.0f,0.0f, 0.0f,1.0f, 0.0f,0.0f,
|
||||
1.0f,0.0f, 1.0f,1.0f, 0.0f,0.0f,
|
||||
0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f
|
||||
};
|
||||
|
||||
0,0,-1, 0,0,-1, 0,0,-1,
|
||||
0,0,-1, 0,0,-1, 0,0,-1,
|
||||
0,0,1, 0,0,1, 0,0,1,
|
||||
0,0,1, 0,0,1, 0,0,1,
|
||||
GLfloat afNormals[] = {
|
||||
|
||||
-1,0,0, -1,0,0, -1,0,0,
|
||||
-1,0,0, -1,0,0, -1,0,0,
|
||||
1,0,0, 1,0,0, 1,0,0,
|
||||
1,0,0, 1,0,0, 1,0,0,
|
||||
0,0,-1, 0,0,-1, 0,0,-1,
|
||||
0,0,-1, 0,0,-1, 0,0,-1,
|
||||
0,0,1, 0,0,1, 0,0,1,
|
||||
0,0,1, 0,0,1, 0,0,1,
|
||||
|
||||
0,-1,0, 0,-1,0, 0,-1,0,
|
||||
0,-1,0, 0,-1,0, 0,-1,0,
|
||||
0,1,0, 0,1,0, 0,1,0,
|
||||
0,1,0, 0,1,0, 0,1,0
|
||||
};
|
||||
program2.setAttributeArray(normalAttr2, afNormals, 3);
|
||||
-1,0,0, -1,0,0, -1,0,0,
|
||||
-1,0,0, -1,0,0, -1,0,0,
|
||||
1,0,0, 1,0,0, 1,0,0,
|
||||
1,0,0, 1,0,0, 1,0,0,
|
||||
|
||||
program2.setUniformValue(textureUniform2, 0); // use texture unit 0
|
||||
0,-1,0, 0,-1,0, 0,-1,0,
|
||||
0,-1,0, 0,-1,0, 0,-1,0,
|
||||
0,1,0, 0,1,0, 0,1,0,
|
||||
0,1,0, 0,1,0, 0,1,0
|
||||
};
|
||||
|
||||
program2.enableAttributeArray(vertexAttr2);
|
||||
program2.enableAttributeArray(normalAttr2);
|
||||
program2.enableAttributeArray(texCoordAttr2);
|
||||
m_vbo2.create();
|
||||
m_vbo2.bind();
|
||||
m_vbo2.allocate(36 * 8 * sizeof(GLfloat));
|
||||
m_vbo2.write(0, afVertices, sizeof(afVertices));
|
||||
m_vbo2.write(sizeof(afVertices), afTexCoord, sizeof(afTexCoord));
|
||||
m_vbo2.write(sizeof(afVertices) + sizeof(afTexCoord), afNormals, sizeof(afNormals));
|
||||
m_vbo2.release();
|
||||
}
|
||||
|
||||
m_program2->setUniformValue(m_textureUniform2, 0); // use texture unit 0
|
||||
|
||||
m_program2->enableAttributeArray(m_vertexAttr2);
|
||||
m_program2->enableAttributeArray(m_normalAttr2);
|
||||
m_program2->enableAttributeArray(m_texCoordAttr2);
|
||||
|
||||
m_vbo2.bind();
|
||||
// In the buffer we first have 36 vertices (3 floats for each), then 36 texture
|
||||
// coordinates (2 floats for each), then 36 normals (3 floats for each).
|
||||
m_program2->setAttributeBuffer(m_vertexAttr2, GL_FLOAT, 0, 3);
|
||||
m_program2->setAttributeBuffer(m_texCoordAttr2, GL_FLOAT, 36 * 3 * sizeof(GLfloat), 2);
|
||||
m_program2->setAttributeBuffer(m_normalAttr2, GL_FLOAT, 36 * 5 * sizeof(GLfloat), 3);
|
||||
m_vbo2.release();
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
program2.disableAttributeArray(vertexAttr2);
|
||||
program2.disableAttributeArray(normalAttr2);
|
||||
program2.disableAttributeArray(texCoordAttr2);
|
||||
m_program2->disableAttributeArray(m_vertexAttr2);
|
||||
m_program2->disableAttributeArray(m_normalAttr2);
|
||||
m_program2->disableAttributeArray(m_texCoordAttr2);
|
||||
}
|
||||
|
||||
void GLWidget::initializeGL ()
|
||||
void GLWidget::initializeGL()
|
||||
{
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
glGenTextures(1, &m_uiTexture);
|
||||
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());
|
||||
m_texture = new QOpenGLTexture(QImage(":/qt.png"));
|
||||
|
||||
QOpenGLShader *vshader1 = new QOpenGLShader(QOpenGLShader::Vertex, this);
|
||||
m_vshader1 = new QOpenGLShader(QOpenGLShader::Vertex);
|
||||
const char *vsrc1 =
|
||||
"attribute highp vec4 vertex;\n"
|
||||
"attribute mediump vec3 normal;\n"
|
||||
|
|
@ -201,26 +236,27 @@ void GLWidget::initializeGL ()
|
|||
" color = clamp(color, 0.0, 1.0);\n"
|
||||
" gl_Position = matrix * vertex;\n"
|
||||
"}\n";
|
||||
vshader1->compileSourceCode(vsrc1);
|
||||
m_vshader1->compileSourceCode(vsrc1);
|
||||
|
||||
QOpenGLShader *fshader1 = new QOpenGLShader(QOpenGLShader::Fragment, this);
|
||||
m_fshader1 = new QOpenGLShader(QOpenGLShader::Fragment);
|
||||
const char *fsrc1 =
|
||||
"varying mediump vec4 color;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" gl_FragColor = color;\n"
|
||||
"}\n";
|
||||
fshader1->compileSourceCode(fsrc1);
|
||||
m_fshader1->compileSourceCode(fsrc1);
|
||||
|
||||
program1.addShader(vshader1);
|
||||
program1.addShader(fshader1);
|
||||
program1.link();
|
||||
m_program1 = new QOpenGLShaderProgram;
|
||||
m_program1->addShader(m_vshader1);
|
||||
m_program1->addShader(m_fshader1);
|
||||
m_program1->link();
|
||||
|
||||
vertexAttr1 = program1.attributeLocation("vertex");
|
||||
normalAttr1 = program1.attributeLocation("normal");
|
||||
matrixUniform1 = program1.uniformLocation("matrix");
|
||||
m_vertexAttr1 = m_program1->attributeLocation("vertex");
|
||||
m_normalAttr1 = m_program1->attributeLocation("normal");
|
||||
m_matrixUniform1 = m_program1->uniformLocation("matrix");
|
||||
|
||||
QOpenGLShader *vshader2 = new QOpenGLShader(QOpenGLShader::Vertex);
|
||||
m_vshader2 = new QOpenGLShader(QOpenGLShader::Vertex);
|
||||
const char *vsrc2 =
|
||||
"attribute highp vec4 vertex;\n"
|
||||
"attribute highp vec4 texCoord;\n"
|
||||
|
|
@ -235,9 +271,9 @@ void GLWidget::initializeGL ()
|
|||
" gl_Position = matrix * vertex;\n"
|
||||
" texc = texCoord;\n"
|
||||
"}\n";
|
||||
vshader2->compileSourceCode(vsrc2);
|
||||
m_vshader2->compileSourceCode(vsrc2);
|
||||
|
||||
QOpenGLShader *fshader2 = new QOpenGLShader(QOpenGLShader::Fragment);
|
||||
m_fshader2 = new QOpenGLShader(QOpenGLShader::Fragment);
|
||||
const char *fsrc2 =
|
||||
"varying highp vec4 texc;\n"
|
||||
"uniform sampler2D tex;\n"
|
||||
|
|
@ -248,35 +284,59 @@ void GLWidget::initializeGL ()
|
|||
" color = color * 0.2 + color * 0.8 * angle;\n"
|
||||
" gl_FragColor = vec4(clamp(color, 0.0, 1.0), 1.0);\n"
|
||||
"}\n";
|
||||
fshader2->compileSourceCode(fsrc2);
|
||||
m_fshader2->compileSourceCode(fsrc2);
|
||||
|
||||
program2.addShader(vshader2);
|
||||
program2.addShader(fshader2);
|
||||
program2.link();
|
||||
m_program2 = new QOpenGLShaderProgram;
|
||||
m_program2->addShader(m_vshader2);
|
||||
m_program2->addShader(m_fshader2);
|
||||
m_program2->link();
|
||||
|
||||
vertexAttr2 = program2.attributeLocation("vertex");
|
||||
normalAttr2 = program2.attributeLocation("normal");
|
||||
texCoordAttr2 = program2.attributeLocation("texCoord");
|
||||
matrixUniform2 = program2.uniformLocation("matrix");
|
||||
textureUniform2 = program2.uniformLocation("tex");
|
||||
m_vertexAttr2 = m_program2->attributeLocation("vertex");
|
||||
m_normalAttr2 = m_program2->attributeLocation("normal");
|
||||
m_texCoordAttr2 = m_program2->attributeLocation("texCoord");
|
||||
m_matrixUniform2 = m_program2->uniformLocation("matrix");
|
||||
m_textureUniform2 = m_program2->uniformLocation("tex");
|
||||
|
||||
m_fAngle = 0;
|
||||
m_fScale = 1;
|
||||
|
||||
createGeometry();
|
||||
createBubbles(bubbleNum - bubbles.count());
|
||||
|
||||
// Use a vertex buffer object. Client-side pointers are old-school and should be avoided.
|
||||
m_vbo1.create();
|
||||
m_vbo1.bind();
|
||||
// For the cube all the data belonging to the texture coordinates and
|
||||
// normals is placed separately, after the vertices. Here, for the Qt logo,
|
||||
// let's do something different and potentially more efficient: create a
|
||||
// properly interleaved data set.
|
||||
const int vertexCount = m_vertices.count();
|
||||
QVector<GLfloat> buf;
|
||||
buf.resize(vertexCount * 3 * 2);
|
||||
GLfloat *p = buf.data();
|
||||
for (int i = 0; i < vertexCount; ++i) {
|
||||
*p++ = m_vertices[i].x();
|
||||
*p++ = m_vertices[i].y();
|
||||
*p++ = m_vertices[i].z();
|
||||
*p++ = m_normals[i].x();
|
||||
*p++ = m_normals[i].y();
|
||||
*p++ = m_normals[i].z();
|
||||
}
|
||||
m_vbo1.allocate(buf.constData(), buf.count() * sizeof(GLfloat));
|
||||
m_vbo1.release();
|
||||
|
||||
createBubbles(bubbleNum - m_bubbles.count());
|
||||
}
|
||||
|
||||
void GLWidget::paintGL()
|
||||
{
|
||||
createBubbles(bubbleNum - bubbles.count());
|
||||
createBubbles(bubbleNum - m_bubbles.count());
|
||||
|
||||
QPainter painter;
|
||||
painter.begin(this);
|
||||
|
||||
painter.beginNativePainting();
|
||||
|
||||
glClearColor(m_background.red() / 255.0f, m_background.green() / 255.0f,
|
||||
m_background.blue() / 255.0f, m_transparent ? 0.0f : 1.0f);
|
||||
glClearColor(m_background.redF(), m_background.greenF(), m_background.blueF(), m_transparent ? 0.0f : 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glFrontFace(GL_CW);
|
||||
|
|
@ -291,16 +351,16 @@ void GLWidget::paintGL()
|
|||
modelview.scale(m_fScale);
|
||||
modelview.translate(0.0f, -0.2f, 0.0f);
|
||||
|
||||
if (qtLogo) {
|
||||
program1.bind();
|
||||
program1.setUniformValue(matrixUniform1, modelview);
|
||||
if (m_qtLogo) {
|
||||
m_program1->bind();
|
||||
m_program1->setUniformValue(m_matrixUniform1, modelview);
|
||||
paintQtLogo();
|
||||
program1.release();
|
||||
m_program1->release();
|
||||
} else {
|
||||
program2.bind();
|
||||
program1.setUniformValue(matrixUniform2, modelview);
|
||||
m_program2->bind();
|
||||
m_program2->setUniformValue(m_matrixUniform2, modelview);
|
||||
paintTexturedCube();
|
||||
program2.release();
|
||||
m_program2->release();
|
||||
}
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
|
@ -309,50 +369,50 @@ void GLWidget::paintGL()
|
|||
painter.endNativePainting();
|
||||
|
||||
if (m_showBubbles)
|
||||
foreach (Bubble *bubble, bubbles) {
|
||||
foreach (Bubble *bubble, m_bubbles) {
|
||||
bubble->drawBubble(&painter);
|
||||
}
|
||||
}
|
||||
|
||||
if (const int elapsed = time.elapsed()) {
|
||||
if (const int elapsed = m_time.elapsed()) {
|
||||
QString framesPerSecond;
|
||||
framesPerSecond.setNum(frames /(elapsed / 1000.0), 'f', 2);
|
||||
framesPerSecond.setNum(m_frames /(elapsed / 1000.0), 'f', 2);
|
||||
painter.setPen(m_transparent ? Qt::black : Qt::white);
|
||||
painter.drawText(20, 40, framesPerSecond + " paintGL calls / s");
|
||||
}
|
||||
|
||||
painter.end();
|
||||
|
||||
QMutableListIterator<Bubble*> iter(bubbles);
|
||||
QMutableListIterator<Bubble*> iter(m_bubbles);
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Bubble *bubble = iter.next();
|
||||
bubble->move(rect());
|
||||
}
|
||||
if (!(frames % 100)) {
|
||||
time.start();
|
||||
frames = 0;
|
||||
if (!(m_frames % 100)) {
|
||||
m_time.start();
|
||||
m_frames = 0;
|
||||
}
|
||||
m_fAngle += 1.0f;
|
||||
frames ++;
|
||||
++m_frames;
|
||||
}
|
||||
|
||||
void GLWidget::createBubbles(int number)
|
||||
{
|
||||
for (int i = 0; i < number; ++i) {
|
||||
QPointF position(width()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))),
|
||||
height()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))));
|
||||
height()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))));
|
||||
qreal radius = qMin(width(), height())*(0.0175 + 0.0875*qrand()/(RAND_MAX+1.0));
|
||||
QPointF velocity(width()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)),
|
||||
height()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)));
|
||||
height()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)));
|
||||
|
||||
bubbles.append(new Bubble(position, radius, velocity));
|
||||
m_bubbles.append(new Bubble(position, radius, velocity));
|
||||
}
|
||||
}
|
||||
|
||||
void GLWidget::createGeometry()
|
||||
{
|
||||
vertices.clear();
|
||||
normals.clear();
|
||||
m_vertices.clear();
|
||||
m_normals.clear();
|
||||
|
||||
qreal x1 = +0.06f;
|
||||
qreal y1 = -0.14f;
|
||||
|
|
@ -396,71 +456,71 @@ void GLWidget::createGeometry()
|
|||
extrude(x8, y8, x5, y5);
|
||||
}
|
||||
|
||||
for (int i = 0;i < vertices.size();i++)
|
||||
vertices[i] *= 2.0f;
|
||||
for (int i = 0;i < m_vertices.size();i++)
|
||||
m_vertices[i] *= 2.0f;
|
||||
}
|
||||
|
||||
void GLWidget::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);
|
||||
m_vertices << QVector3D(x1, y1, -0.05f);
|
||||
m_vertices << QVector3D(x2, y2, -0.05f);
|
||||
m_vertices << QVector3D(x4, y4, -0.05f);
|
||||
|
||||
vertices << QVector3D(x3, y3, -0.05f);
|
||||
vertices << QVector3D(x4, y4, -0.05f);
|
||||
vertices << QVector3D(x2, y2, -0.05f);
|
||||
m_vertices << QVector3D(x3, y3, -0.05f);
|
||||
m_vertices << QVector3D(x4, y4, -0.05f);
|
||||
m_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;
|
||||
m_normals << n;
|
||||
m_normals << n;
|
||||
m_normals << n;
|
||||
|
||||
normals << n;
|
||||
normals << n;
|
||||
normals << n;
|
||||
m_normals << n;
|
||||
m_normals << n;
|
||||
m_normals << n;
|
||||
|
||||
vertices << QVector3D(x4, y4, 0.05f);
|
||||
vertices << QVector3D(x2, y2, 0.05f);
|
||||
vertices << QVector3D(x1, y1, 0.05f);
|
||||
m_vertices << QVector3D(x4, y4, 0.05f);
|
||||
m_vertices << QVector3D(x2, y2, 0.05f);
|
||||
m_vertices << QVector3D(x1, y1, 0.05f);
|
||||
|
||||
vertices << QVector3D(x2, y2, 0.05f);
|
||||
vertices << QVector3D(x4, y4, 0.05f);
|
||||
vertices << QVector3D(x3, y3, 0.05f);
|
||||
m_vertices << QVector3D(x2, y2, 0.05f);
|
||||
m_vertices << QVector3D(x4, y4, 0.05f);
|
||||
m_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;
|
||||
m_normals << n;
|
||||
m_normals << n;
|
||||
m_normals << n;
|
||||
|
||||
normals << n;
|
||||
normals << n;
|
||||
normals << n;
|
||||
m_normals << n;
|
||||
m_normals << n;
|
||||
m_normals << n;
|
||||
}
|
||||
|
||||
void GLWidget::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);
|
||||
m_vertices << QVector3D(x1, y1, +0.05f);
|
||||
m_vertices << QVector3D(x2, y2, +0.05f);
|
||||
m_vertices << QVector3D(x1, y1, -0.05f);
|
||||
|
||||
vertices << QVector3D(x2, y2, -0.05f);
|
||||
vertices << QVector3D(x1, y1, -0.05f);
|
||||
vertices << QVector3D(x2, y2, +0.05f);
|
||||
m_vertices << QVector3D(x2, y2, -0.05f);
|
||||
m_vertices << QVector3D(x1, y1, -0.05f);
|
||||
m_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;
|
||||
m_normals << n;
|
||||
m_normals << n;
|
||||
m_normals << n;
|
||||
|
||||
normals << n;
|
||||
normals << n;
|
||||
normals << n;
|
||||
m_normals << n;
|
||||
m_normals << n;
|
||||
m_normals << n;
|
||||
}
|
||||
|
||||
void GLWidget::setTransparent(bool transparent)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
#include <QOpenGLWidget>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QVector3D>
|
||||
#include <QMatrix4x4>
|
||||
#include <QTime>
|
||||
|
|
@ -53,6 +53,10 @@
|
|||
class Bubble;
|
||||
class MainWindow;
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QOpenGLTexture)
|
||||
QT_FORWARD_DECLARE_CLASS(QOpenGLShader)
|
||||
QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
|
||||
|
||||
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -64,7 +68,7 @@ public slots:
|
|||
void setScaling(int scale);
|
||||
void setLogo();
|
||||
void setTexture();
|
||||
void showBubbles(bool);
|
||||
void setShowBubbles(bool);
|
||||
void setTransparent(bool transparent);
|
||||
|
||||
private slots:
|
||||
|
|
@ -76,33 +80,40 @@ protected:
|
|||
void initializeGL() Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
MainWindow *m_mainWindow;
|
||||
GLuint m_uiTexture;
|
||||
qreal m_fAngle;
|
||||
qreal m_fScale;
|
||||
bool m_showBubbles;
|
||||
void paintTexturedCube();
|
||||
void paintQtLogo();
|
||||
void createGeometry();
|
||||
void createBubbles(int number);
|
||||
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);
|
||||
QVector<QVector3D> vertices;
|
||||
QVector<QVector3D> normals;
|
||||
bool qtLogo;
|
||||
QList<Bubble*> bubbles;
|
||||
int frames;
|
||||
QTime time;
|
||||
QOpenGLShaderProgram program1;
|
||||
QOpenGLShaderProgram program2;
|
||||
int vertexAttr1;
|
||||
int normalAttr1;
|
||||
int matrixUniform1;
|
||||
int vertexAttr2;
|
||||
int normalAttr2;
|
||||
int texCoordAttr2;
|
||||
int matrixUniform2;
|
||||
int textureUniform2;
|
||||
|
||||
MainWindow *m_mainWindow;
|
||||
qreal m_fAngle;
|
||||
qreal m_fScale;
|
||||
bool m_showBubbles;
|
||||
QVector<QVector3D> m_vertices;
|
||||
QVector<QVector3D> m_normals;
|
||||
bool m_qtLogo;
|
||||
QList<Bubble *> m_bubbles;
|
||||
int m_frames;
|
||||
QTime m_time;
|
||||
QOpenGLShader *m_vshader1;
|
||||
QOpenGLShader *m_fshader1;
|
||||
QOpenGLShader *m_vshader2;
|
||||
QOpenGLShader *m_fshader2;
|
||||
QOpenGLShaderProgram *m_program1;
|
||||
QOpenGLShaderProgram *m_program2;
|
||||
QOpenGLTexture *m_texture;
|
||||
QOpenGLBuffer m_vbo1;
|
||||
QOpenGLBuffer m_vbo2;
|
||||
int m_vertexAttr1;
|
||||
int m_normalAttr1;
|
||||
int m_matrixUniform1;
|
||||
int m_vertexAttr2;
|
||||
int m_normalAttr2;
|
||||
int m_texCoordAttr2;
|
||||
int m_matrixUniform2;
|
||||
int m_textureUniform2;
|
||||
bool m_transparent;
|
||||
QPushButton *m_btn;
|
||||
bool m_hasButton;
|
||||
|
|
|
|||
|
|
@ -40,12 +40,21 @@
|
|||
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QSurfaceFormat>
|
||||
#include "mainwindow.h"
|
||||
|
||||
int main( int argc, char ** argv )
|
||||
{
|
||||
Q_INIT_RESOURCE(texture);
|
||||
QApplication a( argc, argv );
|
||||
|
||||
QSurfaceFormat format;
|
||||
format.setDepthBufferSize(24);
|
||||
format.setStencilBufferSize(8);
|
||||
if (QCoreApplication::arguments().contains(QStringLiteral("--multisample")))
|
||||
format.setSamples(4);
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
|
||||
MainWindow mw;
|
||||
mw.showMaximized();
|
||||
return a.exec();
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ MainWindow::MainWindow()
|
|||
|
||||
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(showBubbles, SIGNAL(triggered(bool)), glwidget, SLOT(setShowBubbles(bool)));
|
||||
connect(slider, SIGNAL(valueChanged(int)), glwidget, SLOT(setScaling(int)));
|
||||
connect(transparent, &QCheckBox::toggled, glwidget, &GLWidget::setTransparent);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,5 +20,6 @@ void main()
|
|||
{
|
||||
highp float coordNoise = noise(gl_FragCoord.xy);
|
||||
highp float proximity = smoothstep(0.5, 1.0, (curv() + 1.0) * (coordNoise ));
|
||||
gl_FragColor = vec4(coordNoise, coordNoise, coordNoise, 1.0) * proximity;
|
||||
highp vec3 color = vec3(coordNoise) * proximity;
|
||||
gl_FragColor = vec4(color, 1.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ void FragmentToy::draw(const QSize &windowSize)
|
|||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glClearColor(0,0,0,0);
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (!m_vao.isCreated())
|
||||
m_vao.create();
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -38,23 +38,30 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QtOpenGL>
|
||||
|
||||
#include "glwidget.h"
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QMouseEvent>
|
||||
|
||||
GLWidget::GLWidget(QWidget *parent, QGLWidget *shareWidget)
|
||||
: QGLWidget(parent, shareWidget)
|
||||
GLWidget::GLWidget(QWidget *parent)
|
||||
: QOpenGLWidget(parent),
|
||||
clearColor(Qt::black),
|
||||
xRot(0),
|
||||
yRot(0),
|
||||
zRot(0),
|
||||
program(0)
|
||||
{
|
||||
clearColor = Qt::black;
|
||||
xRot = 0;
|
||||
yRot = 0;
|
||||
zRot = 0;
|
||||
program = 0;
|
||||
memset(textures, 0, sizeof(textures));
|
||||
}
|
||||
|
||||
GLWidget::~GLWidget()
|
||||
{
|
||||
makeCurrent();
|
||||
vbo.destroy();
|
||||
for (int i = 0; i < 6; ++i)
|
||||
delete textures[i];
|
||||
delete program;
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
QSize GLWidget::minimumSizeHint() const
|
||||
|
|
@ -72,13 +79,13 @@ void GLWidget::rotateBy(int xAngle, int yAngle, int zAngle)
|
|||
xRot += xAngle;
|
||||
yRot += yAngle;
|
||||
zRot += zAngle;
|
||||
updateGL();
|
||||
update();
|
||||
}
|
||||
|
||||
void GLWidget::setClearColor(const QColor &color)
|
||||
{
|
||||
clearColor = color;
|
||||
updateGL();
|
||||
update();
|
||||
}
|
||||
|
||||
void GLWidget::initializeGL()
|
||||
|
|
@ -89,14 +96,11 @@ void GLWidget::initializeGL()
|
|||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
#ifdef GL_TEXTURE_2D
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
#endif
|
||||
|
||||
#define PROGRAM_VERTEX_ATTRIBUTE 0
|
||||
#define PROGRAM_TEXCOORD_ATTRIBUTE 1
|
||||
|
||||
QGLShader *vshader = new QGLShader(QGLShader::Vertex, this);
|
||||
QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
|
||||
const char *vsrc =
|
||||
"attribute highp vec4 vertex;\n"
|
||||
"attribute mediump vec4 texCoord;\n"
|
||||
|
|
@ -109,7 +113,7 @@ void GLWidget::initializeGL()
|
|||
"}\n";
|
||||
vshader->compileSourceCode(vsrc);
|
||||
|
||||
QGLShader *fshader = new QGLShader(QGLShader::Fragment, this);
|
||||
QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
|
||||
const char *fsrc =
|
||||
"uniform sampler2D texture;\n"
|
||||
"varying mediump vec4 texc;\n"
|
||||
|
|
@ -119,7 +123,7 @@ void GLWidget::initializeGL()
|
|||
"}\n";
|
||||
fshader->compileSourceCode(fsrc);
|
||||
|
||||
program = new QGLShaderProgram(this);
|
||||
program = new QOpenGLShaderProgram;
|
||||
program->addShader(vshader);
|
||||
program->addShader(fshader);
|
||||
program->bindAttributeLocation("vertex", PROGRAM_VERTEX_ATTRIBUTE);
|
||||
|
|
@ -132,7 +136,7 @@ void GLWidget::initializeGL()
|
|||
|
||||
void GLWidget::paintGL()
|
||||
{
|
||||
qglClearColor(clearColor);
|
||||
glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF());
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
QMatrix4x4 m;
|
||||
|
|
@ -145,17 +149,14 @@ void GLWidget::paintGL()
|
|||
program->setUniformValue("matrix", m);
|
||||
program->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE);
|
||||
program->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE);
|
||||
program->setAttributeArray
|
||||
(PROGRAM_VERTEX_ATTRIBUTE, vertices.constData());
|
||||
program->setAttributeArray
|
||||
(PROGRAM_TEXCOORD_ATTRIBUTE, texCoords.constData());
|
||||
program->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 3, 5 * sizeof(GLfloat));
|
||||
program->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 3 * sizeof(GLfloat), 2, 5 * sizeof(GLfloat));
|
||||
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
glBindTexture(GL_TEXTURE_2D, textures[i]);
|
||||
textures[i]->bind();
|
||||
glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
void GLWidget::resizeGL(int width, int height)
|
||||
{
|
||||
int side = qMin(width, height);
|
||||
|
|
@ -196,18 +197,23 @@ void GLWidget::makeObject()
|
|||
{ { -1, -1, +1 }, { +1, -1, +1 }, { +1, +1, +1 }, { -1, +1, +1 } }
|
||||
};
|
||||
|
||||
for (int j=0; j < 6; ++j) {
|
||||
textures[j] = bindTexture
|
||||
(QPixmap(QString(":/images/side%1.png").arg(j + 1)), GL_TEXTURE_2D);
|
||||
}
|
||||
for (int j = 0; j < 6; ++j)
|
||||
textures[j] = new QOpenGLTexture(QImage(QString(":/images/side%1.png").arg(j + 1)).mirrored());
|
||||
|
||||
QVector<GLfloat> vertData;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
texCoords.append
|
||||
(QVector2D(j == 0 || j == 3, j == 0 || j == 1));
|
||||
vertices.append
|
||||
(QVector3D(0.2 * coords[i][j][0], 0.2 * coords[i][j][1],
|
||||
0.2 * coords[i][j][2]));
|
||||
// vertex position
|
||||
vertData.append(0.2 * coords[i][j][0]);
|
||||
vertData.append(0.2 * coords[i][j][1]);
|
||||
vertData.append(0.2 * coords[i][j][2]);
|
||||
// texture coordinate
|
||||
vertData.append(j == 0 || j == 3);
|
||||
vertData.append(j == 0 || j == 1);
|
||||
}
|
||||
}
|
||||
|
||||
vbo.create();
|
||||
vbo.bind();
|
||||
vbo.allocate(vertData.constData(), vertData.count() * sizeof(GLfloat));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,18 +41,19 @@
|
|||
#ifndef GLWIDGET_H
|
||||
#define GLWIDGET_H
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QGLWidget>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLBuffer>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QGLShaderProgram);
|
||||
QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram);
|
||||
QT_FORWARD_DECLARE_CLASS(QOpenGLTexture)
|
||||
|
||||
class GLWidget : public QGLWidget, protected QOpenGLFunctions
|
||||
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GLWidget(QWidget *parent = 0, QGLWidget *shareWidget = 0);
|
||||
explicit GLWidget(QWidget *parent = 0);
|
||||
~GLWidget();
|
||||
|
||||
QSize minimumSizeHint() const Q_DECL_OVERRIDE;
|
||||
|
|
@ -79,10 +80,9 @@ private:
|
|||
int xRot;
|
||||
int yRot;
|
||||
int zRot;
|
||||
GLuint textures[6];
|
||||
QVector<QVector3D> vertices;
|
||||
QVector<QVector2D> texCoords;
|
||||
QGLShaderProgram *program;
|
||||
QOpenGLTexture *textures[6];
|
||||
QOpenGLShaderProgram *program;
|
||||
QOpenGLBuffer vbo;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -39,6 +39,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QSurfaceFormat>
|
||||
|
||||
#include "window.h"
|
||||
|
||||
|
|
@ -47,6 +48,11 @@ int main(int argc, char *argv[])
|
|||
Q_INIT_RESOURCE(textures);
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QSurfaceFormat format;
|
||||
format.setDepthBufferSize(24);
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
|
||||
Window window;
|
||||
window.show();
|
||||
return app.exec();
|
||||
|
|
|
|||