1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtOpenGL module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include <QtTest/QtTest> |
30 | #include <QtOpenGL/qglfunctions.h> |
31 | |
32 | class tst_QGLFunctions : public QObject |
33 | { |
34 | Q_OBJECT |
35 | public: |
36 | tst_QGLFunctions() {} |
37 | ~tst_QGLFunctions() {} |
38 | |
39 | private slots: |
40 | void features(); |
41 | void multitexture(); |
42 | void blendColor(); |
43 | |
44 | private: |
45 | static bool hasExtension(const char *name); |
46 | }; |
47 | |
48 | bool tst_QGLFunctions::hasExtension(const char *name) |
49 | { |
50 | QString extensions = |
51 | QString::fromLatin1 |
52 | (str: reinterpret_cast<const char *>(QOpenGLContext::currentContext()->functions()->glGetString(GL_EXTENSIONS))); |
53 | return extensions.split(sep: QLatin1Char(' ')).contains |
54 | (str: QString::fromLatin1(str: name)); |
55 | } |
56 | |
57 | // Check that the reported features are consistent with the platform. |
58 | void tst_QGLFunctions::features() |
59 | { |
60 | // Before being associated with a context, there should be |
61 | // no features enabled. |
62 | QGLFunctions funcs; |
63 | QVERIFY(!funcs.openGLFeatures()); |
64 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Multitexture)); |
65 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Shaders)); |
66 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Buffers)); |
67 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Framebuffers)); |
68 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendColor)); |
69 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendEquation)); |
70 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate)); |
71 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate)); |
72 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract)); |
73 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures)); |
74 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Multisample)); |
75 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate)); |
76 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures)); |
77 | |
78 | // Make a context current. |
79 | QGLWidget glw; |
80 | if (!glw.isValid()) |
81 | QSKIP("Could not create a GL context" ); |
82 | glw.makeCurrent(); |
83 | funcs.initializeGLFunctions(); |
84 | |
85 | // Validate the features against what we expect for this platform. |
86 | if (QOpenGLContext::currentContext()->isOpenGLES()) { |
87 | #if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) |
88 | QGLFunctions::OpenGLFeatures allFeatures = |
89 | (QGLFunctions::Multitexture | |
90 | QGLFunctions::Shaders | |
91 | QGLFunctions::Buffers | |
92 | QGLFunctions::Framebuffers | |
93 | QGLFunctions::BlendColor | |
94 | QGLFunctions::BlendEquation | |
95 | QGLFunctions::BlendEquationSeparate | |
96 | QGLFunctions::BlendFuncSeparate | |
97 | QGLFunctions::BlendSubtract | |
98 | QGLFunctions::CompressedTextures | |
99 | QGLFunctions::Multisample | |
100 | QGLFunctions::StencilSeparate | |
101 | QGLFunctions::NPOTTextures); |
102 | QVERIFY((funcs.openGLFeatures() & allFeatures) == allFeatures); |
103 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture)); |
104 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Shaders)); |
105 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers)); |
106 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers)); |
107 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendColor)); |
108 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation)); |
109 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate)); |
110 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate)); |
111 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract)); |
112 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures)); |
113 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample)); |
114 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate)); |
115 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures)); |
116 | #elif defined(QT_OPENGL_ES) && !defined(QT_OPENGL_ES_2) |
117 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture)); |
118 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers)); |
119 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures)); |
120 | QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample)); |
121 | |
122 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Shaders)); |
123 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendColor)); |
124 | QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate)); |
125 | |
126 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers), |
127 | hasExtension("GL_OES_framebuffer_object" )); |
128 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate), |
129 | hasExtension("GL_OES_blend_equation_separate" )); |
130 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate), |
131 | hasExtension("GL_OES_blend_func_separate" )); |
132 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract), |
133 | hasExtension("GL_OES_blend_subtract" )); |
134 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures), |
135 | hasExtension("GL_OES_texture_npot" )); |
136 | #endif |
137 | } else { |
138 | // We check for both the extension name and the minimum OpenGL version |
139 | // for the feature. This will help us catch situations where a platform |
140 | // doesn't list an extension by name but does have the feature by virtue |
141 | // of its version number. |
142 | QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags(); |
143 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multitexture), |
144 | hasExtension("GL_ARB_multitexture" ) || |
145 | (versions & QGLFormat::OpenGL_Version_1_3) != 0); |
146 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Shaders), |
147 | hasExtension("GL_ARB_shader_objects" ) || |
148 | (versions & QGLFormat::OpenGL_Version_2_0) != 0); |
149 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Buffers), |
150 | (versions & QGLFormat::OpenGL_Version_1_5) != 0); |
151 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers), |
152 | hasExtension("GL_EXT_framebuffer_object" ) || |
153 | hasExtension("GL_ARB_framebuffer_object" )); |
154 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendColor), |
155 | hasExtension("GL_EXT_blend_color" ) || |
156 | (versions & QGLFormat::OpenGL_Version_1_2) != 0); |
157 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation), |
158 | (versions & QGLFormat::OpenGL_Version_1_2) != 0); |
159 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate), |
160 | hasExtension("GL_EXT_blend_equation_separate" ) || |
161 | (versions & QGLFormat::OpenGL_Version_2_0) != 0); |
162 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate), |
163 | hasExtension("GL_EXT_blend_func_separate" ) || |
164 | (versions & QGLFormat::OpenGL_Version_1_4) != 0); |
165 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract), |
166 | hasExtension("GL_EXT_blend_subtract" )); |
167 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures), |
168 | hasExtension("GL_ARB_texture_compression" ) || |
169 | (versions & QGLFormat::OpenGL_Version_1_3) != 0); |
170 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multisample), |
171 | hasExtension("GL_ARB_multisample" ) || |
172 | (versions & QGLFormat::OpenGL_Version_1_3) != 0); |
173 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate), |
174 | (versions & QGLFormat::OpenGL_Version_2_0) != 0); |
175 | QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures), |
176 | hasExtension("GL_ARB_texture_non_power_of_two" ) || |
177 | (versions & QGLFormat::OpenGL_Version_2_0) != 0); |
178 | } |
179 | } |
180 | |
181 | // Verify that the multitexture functions appear to resolve and work. |
182 | void tst_QGLFunctions::multitexture() |
183 | { |
184 | QOpenGLFunctions funcs; |
185 | QGLWidget glw; |
186 | if (!glw.isValid()) |
187 | QSKIP("Could not create a GL context" ); |
188 | glw.makeCurrent(); |
189 | funcs.initializeOpenGLFunctions(); |
190 | |
191 | if (!funcs.hasOpenGLFeature(feature: QOpenGLFunctions::Multitexture)) |
192 | QSKIP("Multitexture functions are not supported" ); |
193 | |
194 | funcs.glActiveTexture(GL_TEXTURE1); |
195 | |
196 | GLint active = 0; |
197 | funcs.glGetIntegerv(GL_ACTIVE_TEXTURE, params: &active); |
198 | QCOMPARE(active, GL_TEXTURE1); |
199 | |
200 | funcs.glActiveTexture(GL_TEXTURE0); |
201 | |
202 | active = 0; |
203 | funcs.glGetIntegerv(GL_ACTIVE_TEXTURE, params: &active); |
204 | QCOMPARE(active, GL_TEXTURE0); |
205 | } |
206 | |
207 | // Verify that the glBlendColor() function appears to resolve and work. |
208 | void tst_QGLFunctions::blendColor() |
209 | { |
210 | QOpenGLFunctions funcs; |
211 | QGLWidget glw; |
212 | if (!glw.isValid()) |
213 | QSKIP("Could not create a GL context" ); |
214 | glw.makeCurrent(); |
215 | funcs.initializeOpenGLFunctions(); |
216 | |
217 | if (!funcs.hasOpenGLFeature(feature: QOpenGLFunctions::BlendColor)) |
218 | QSKIP("glBlendColor() is not supported" ); |
219 | |
220 | funcs.glBlendColor(red: 0.0f, green: 1.0f, blue: 0.0f, alpha: 1.0f); |
221 | |
222 | GLfloat colors[4] = {0.5f, 0.5f, 0.5f, 0.5f}; |
223 | funcs.glGetFloatv(GL_BLEND_COLOR, params: colors); |
224 | |
225 | QCOMPARE(colors[0], 0.0f); |
226 | QCOMPARE(colors[1], 1.0f); |
227 | QCOMPARE(colors[2], 0.0f); |
228 | QCOMPARE(colors[3], 1.0f); |
229 | } |
230 | |
231 | QTEST_MAIN(tst_QGLFunctions) |
232 | |
233 | #include "tst_qglfunctions.moc" |
234 | |