1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example hellogles3
\title Hello GLES3 Example
\ingroup examples-widgets-opengl
\examplecategory {Graphics}
\examplecategory {Mobile}
\brief Demonstrates OpenGL ES 3.0 functions via QOpenGLExtraFunctions.
\image hellogles3-example.png
\section1 Overview
This example demonstrates easy, cross-platform usage of OpenGL ES 3.0
functions via QOpenGLExtraFunctions in an application that
works identically on desktop platforms with OpenGL 3.3 and mobile/embedded
devices with OpenGL ES 3.0.
This example has no QWidget dependencies, it uses QOpenGLWindow, a
convenience subclass of QWindow that allows easy implementation of windows
that contain OpenGL-rendered content. In this sense it complements the
\l{OpenGL Window Example}, which shows the implementation of an OpenGL-based
QWindow without using the convenience subclass.
The Qt logo shape implementation is included from the \l{Hello GL2 Example}.
In other aspects pertaining to using OpenGL there are the following
differences.
\list
\li The OpenGL context creation has to have a sufficiently high version
number for the features that are in use.
\li The shader's version directive is different.
\endlist
\section1 Setting up in main.cpp
Here we instantiate our QGuiApplication, QSurfaceformat and set its
\l{QSurfaceFormat::depthBufferSize()}{depth buffer size}:
\quotefromfile hellogles3/main.cpp
\skipto int main(int argc, char *argv[])
\printuntil fmt.setDepthBufferSize(24);
We request an OpenGL 3.3 core or OpenGL ES 3.0 context, depending on
QOpenGLContext::openGLModuleType():
\skipto if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
\printuntil QSurfaceFormat::setDefaultFormat(fmt);
We set the default surface format and instantiate our GLWindow \c glWindow.
\section1 Implementing GLWindow
This class delivers the features of the example application.
To start, \c GLWindow is declared by implementing a subclass of
QOpenGLWindow:
\quotefromfile hellogles3/glwindow.h
\skipto class GLWindow : public QOpenGLWindow
\printto {
The following properties are declared using Q_PROPERTY:
\printto public:
The following public functions are declared:
\printto private slots:
The following private objects are declared:
\printto };
On the implementation side, those functions that are not declared inline are
implemented (or re-implemented) in \c{glwindow.cpp}. The following selections
will cover implementation particulars pertaining to the use of OpenGL ES 3.0.
\section2 Animations
The following code pertains to the animations, and won't be explored here:
\quotefromfile hellogles3/glwindow.cpp
\skipto GLWindow::GLWindow()
\printto static const char *vertexShaderSource =
For more information see the documentation for \l QPropertyAnimation,
\l QSequentialAnimationGroup.
\section2 Shaders
The shaders are defined like so:
\printto QByteArray versionedShaderCode(const char *src)
\note These are OpenGL version agnostic. We take this and append
the version like so:
\printto void GLWindow::initializeGL()
\section2 Initializing OpenGL
Initializing the shader program in handled by \c initializeGL():
\printuntil m_program = new QOpenGLShaderProgram;
\skipto m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, versionedShaderCode(vertexShaderSource));
Now the OpenGL version is prepended and the various matrices and light
position is set:
\printuntil m_lightPosLoc = m_program->uniformLocation("lightPos");
While not strictly required for ES 3, a vertex array object is created.
\skipto delete m_vao;
\printuntil f->glEnable(GL_CULL_FACE);
\section2 Resizing the window
The perspective needs to be aligned with the new window size as so:
\skipto void GLWindow::resizeGL(int w, int h)
\printto void GLWindow::paintGL()
\section2 Painting
We use QOpenGLExtraFunctions instead of QOpenGLFunctions as we want to
do more than what GL(ES) 2.0 offers:
\printuntil QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions();
We clear the screen and buffers and bind our shader program and texture:
\printuntil m_texture->bind();
Logic for handling an initial \c paintGL() call or a call after a
\c resizeGL() call is implemented like so:
\printuntil }
Last, we demonstrate a function introduced in OpenGL 3.1 or OpenGL ES 3.0:
\skipto f->glDrawArraysInstanced(GL_TRIANGLES, 0, m_logo.vertexCount(), 32 * 36);
\printuntil }
This works because we earlier requested 3.3 or 3.0 context.
*/
|