1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt3D 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/QTest> |
30 | #include <Qt3DRender/qrendertargetoutput.h> |
31 | #include <Qt3DRender/private/uniform_p.h> |
32 | #include <Qt3DRender/private/attachmentpack_p.h> |
33 | #include <graphicshelpergl4_p.h> |
34 | #include <QOpenGLBuffer> |
35 | #include <QOpenGLFunctions_4_3_Core> |
36 | #include <QOpenGLShaderProgram> |
37 | #include <QOpenGLVertexArrayObject> |
38 | #include <QSurfaceFormat> |
39 | |
40 | #if !defined(QT_OPENGL_ES_2) && defined(QT_OPENGL_4_3) |
41 | |
42 | #define TEST_SHOULD_BE_PERFORMED 1 |
43 | |
44 | using namespace Qt3DRender; |
45 | using namespace Qt3DRender::Render; |
46 | using namespace Qt3DRender::Render::OpenGL; |
47 | |
48 | namespace { |
49 | |
50 | const QByteArray vertCode = QByteArrayLiteral( |
51 | "#version 430 core\n" \ |
52 | "layout(location = 1) in vec3 vertexPosition;\n" \ |
53 | "layout(location = 2) in vec2 vertexTexCoord;\n" \ |
54 | "out vec2 texCoord;\n" \ |
55 | "void main()\n" \ |
56 | "{\n" \ |
57 | " texCoord = vertexTexCoord;\n" \ |
58 | " gl_Position = vec4(vertexPosition, 1.0);\n" \ |
59 | "}\n" ); |
60 | |
61 | const QByteArray vertCodeUniformBuffer = QByteArrayLiteral( |
62 | "#version 430 core\n" \ |
63 | "layout(location = 1) in vec3 vertexPosition;\n" \ |
64 | "layout(location = 2) in vec2 vertexTexCoord;\n" \ |
65 | "layout(location = 3) in int vertexColorIndex;\n" \ |
66 | "layout(location = 4) in double vertexTexCoordScale;\n" \ |
67 | "out vec2 texCoord;\n" \ |
68 | "flat out int colorIndex;\n" \ |
69 | "void main()\n" \ |
70 | "{\n" \ |
71 | " texCoord = vec2(vertexTexCoordScale * vertexTexCoord);\n" \ |
72 | " colorIndex = vertexColorIndex;\n" \ |
73 | " gl_Position = vec4(vertexPosition, 1.0);\n" \ |
74 | "}\n" ); |
75 | |
76 | const QByteArray fragCodeFragOutputs = QByteArrayLiteral( |
77 | "#version 430 core\n" \ |
78 | "out vec4 color;\n" \ |
79 | "out vec2 temp;\n" \ |
80 | "void main()\n" \ |
81 | "{\n" \ |
82 | " color = vec4(1.0, 0.0, 0.0, 1.0);\n" \ |
83 | " temp = vec2(1.0, 0.3);\n" \ |
84 | "}\n" ); |
85 | |
86 | const QByteArray fragCodeUniformsFloat = QByteArrayLiteral( |
87 | "#version 430 core\n" \ |
88 | "out vec4 color;\n" \ |
89 | "layout(location = 1) uniform float multiplier;\n" \ |
90 | "layout(location = 2) uniform vec2 multiplierVec2;\n" \ |
91 | "layout(location = 3) uniform vec3 multiplierVec3;\n" \ |
92 | "layout(location = 4) uniform vec4 multiplierVec4;\n" \ |
93 | "void main()\n" \ |
94 | "{\n" \ |
95 | " vec4 randomMult = multiplierVec4 + vec4(multiplierVec3, 0.0) + vec4(multiplierVec2, 0.0, 0.0);\n" \ |
96 | " color = vec4(1.0, 0.0, 0.0, 1.0) * randomMult * multiplier;\n" \ |
97 | "}\n" ); |
98 | |
99 | const QByteArray fragCodeUniformsInt = QByteArrayLiteral( |
100 | "#version 430 core\n" \ |
101 | "out ivec4 color;\n" \ |
102 | "layout(location = 1) uniform int multiplier;\n" \ |
103 | "layout(location = 2) uniform ivec2 multiplierVec2;\n" \ |
104 | "layout(location = 3) uniform ivec3 multiplierVec3;\n" \ |
105 | "layout(location = 4) uniform ivec4 multiplierVec4;\n" \ |
106 | "void main()\n" \ |
107 | "{\n" \ |
108 | " ivec4 randomMult = multiplierVec4 + ivec4(multiplierVec3, 0) + ivec4(multiplierVec2, 0, 0);\n" \ |
109 | " color = ivec4(1, 0, 0, 1) * randomMult * multiplier;\n" \ |
110 | "}\n" ); |
111 | |
112 | const QByteArray fragCodeUniformsUInt = QByteArrayLiteral( |
113 | "#version 430 core\n" \ |
114 | "out uvec4 color;\n" \ |
115 | "layout(location = 1) uniform uint multiplier;\n" \ |
116 | "layout(location = 2) uniform uvec2 multiplierVec2;\n" \ |
117 | "layout(location = 3) uniform uvec3 multiplierVec3;\n" \ |
118 | "layout(location = 4) uniform uvec4 multiplierVec4;\n" \ |
119 | "void main()\n" \ |
120 | "{\n" \ |
121 | " uvec4 randomMult = multiplierVec4 + uvec4(multiplierVec3, 0) + uvec4(multiplierVec2, 0, 0);\n" \ |
122 | " color = uvec4(1, 0, 0, 1) * randomMult * multiplier;\n" \ |
123 | "}\n" ); |
124 | |
125 | const QByteArray fragCodeUniformsFloatMatrices = QByteArrayLiteral( |
126 | "#version 430 core\n" \ |
127 | "out vec4 color;\n" \ |
128 | "layout(location = 1) uniform mat2 m2;\n" \ |
129 | "layout(location = 2) uniform mat2x3 m23;\n" \ |
130 | "layout(location = 3) uniform mat3x2 m32;\n" \ |
131 | "layout(location = 4) uniform mat2x4 m24;\n" \ |
132 | "layout(location = 5) uniform mat4x2 m42;\n" \ |
133 | "layout(location = 6) uniform mat3 m3;\n" \ |
134 | "layout(location = 7) uniform mat3x4 m34;\n" \ |
135 | "layout(location = 8) uniform mat4x3 m43;\n" \ |
136 | "layout(location = 9) uniform mat4 m4;\n" \ |
137 | "void main()\n" \ |
138 | "{\n" \ |
139 | " float lengthSum = m2[0][0] + m23[0][0] + m32[0][0] + m24[0][0] + m42[0][0] + m3[0][0] + m34[0][0] + m43[0][0] + m4[0][0];\n" \ |
140 | " color = vec4(1, 0, 0, 1) * lengthSum;\n" \ |
141 | "}\n" ); |
142 | |
143 | const QByteArray fragCodeUniformBuffer = QByteArrayLiteral( |
144 | "#version 430 core\n" \ |
145 | "out vec4 color;\n" \ |
146 | "in vec2 texCoord;\n" \ |
147 | "flat in int colorIndex;\n" \ |
148 | "layout(binding = 2, std140) uniform ColorArray\n" \ |
149 | "{\n" \ |
150 | " vec4 colors[256];\n" \ |
151 | "};\n" \ |
152 | "void main()\n" \ |
153 | "{\n" \ |
154 | " color = colors[colorIndex] + vec4(texCoord.s, texCoord.t, 0.0, 1.0);\n" \ |
155 | "}\n" ); |
156 | |
157 | const QByteArray fragCodeSamplers = QByteArrayLiteral( |
158 | "#version 430 core\n" \ |
159 | "in vec2 texCoord;\n" \ |
160 | "out vec4 color;\n" \ |
161 | "layout(location = 1) uniform sampler1D s1;\n" \ |
162 | "layout(location = 2) uniform sampler2D s2;\n" \ |
163 | "layout(location = 3) uniform sampler2DArray s2a;\n" \ |
164 | "layout(location = 4) uniform sampler3D s3;\n" \ |
165 | "layout(location = 5) uniform samplerCube scube;\n" \ |
166 | "layout(location = 6) uniform sampler2DRect srect;\n" \ |
167 | "void main()\n" \ |
168 | "{\n" \ |
169 | " color = vec4(1, 0, 0, 1) *" \ |
170 | " texture(s1, texCoord.x) *" \ |
171 | " texture(s2, texCoord) *" \ |
172 | " texture(s2a, vec3(texCoord, 0.0)) *" \ |
173 | " texture(s3, vec3(texCoord, 0.0)) *" \ |
174 | " texture(scube, vec3(texCoord, 0)) *" \ |
175 | " texture(srect, texCoord);\n" \ |
176 | "}\n" ); |
177 | |
178 | const QByteArray fragCodeImages = QByteArrayLiteral( |
179 | "#version 430 core\n" \ |
180 | "in vec2 texCoord;\n" \ |
181 | "out vec4 color;\n" \ |
182 | "layout(location = 1, rgba32f) readonly uniform image1D s1;\n" \ |
183 | "layout(location = 2, rg16f) readonly uniform image2D s2;\n" \ |
184 | "layout(location = 3, r16f) readonly uniform image2DArray s2a;\n" \ |
185 | "layout(location = 4, rg8) readonly uniform image3D s3;\n" \ |
186 | "layout(location = 5, rgba16_snorm) readonly uniform imageCube scube;\n" \ |
187 | "layout(location = 6, rg16) readonly uniform image2DRect srect;\n" \ |
188 | "void main()\n" \ |
189 | "{\n" \ |
190 | " ivec2 coords = ivec2(texCoord);\n" \ |
191 | " color = vec4(1, 0, 0, 1) *" \ |
192 | " imageLoad(s1, coords.x) *" \ |
193 | " imageLoad(s2, coords) *" \ |
194 | " imageLoad(s2a, ivec3(coords, 0)) *" \ |
195 | " imageLoad(s3, ivec3(coords, 0)) *" \ |
196 | " imageLoad(scube, ivec3(coords, 0)) *" \ |
197 | " imageLoad(srect, coords);\n" \ |
198 | "}\n" ); |
199 | |
200 | const QByteArray computeShader = QByteArrayLiteral( |
201 | "#version 430 core\n" \ |
202 | "uniform float particleStep;\n" \ |
203 | "uniform float finalCollisionFactor;\n" \ |
204 | "layout (local_size_x = 1024) in;\n" \ |
205 | "struct ParticleData\n" \ |
206 | "{\n" \ |
207 | " vec4 position;\n" \ |
208 | " vec4 direction;\n" \ |
209 | " vec4 color;\n" \ |
210 | "};\n" \ |
211 | "layout (std140, binding = 6) coherent buffer Particles\n" \ |
212 | "{\n" \ |
213 | " ParticleData particles[];\n" \ |
214 | "} data;\n" \ |
215 | "void main(void)\n" \ |
216 | "{\n" \ |
217 | " uint globalId = gl_GlobalInvocationID.x;\n" \ |
218 | " ParticleData currentParticle = data.particles[globalId];\n" \ |
219 | " currentParticle.position = currentParticle.position + currentParticle.direction * particleStep;\n" \ |
220 | " vec4 acceleration = normalize(vec4(0.0) - currentParticle.position) * finalCollisionFactor;\n" \ |
221 | " currentParticle.direction = currentParticle.direction + acceleration * particleStep;\n" \ |
222 | " data.particles[globalId] = currentParticle;\n" \ |
223 | "}" ); |
224 | |
225 | } // anonymous |
226 | |
227 | class tst_GraphicsHelperGL4 : public QObject |
228 | { |
229 | Q_OBJECT |
230 | private Q_SLOTS: |
231 | void init() |
232 | { |
233 | m_window.reset(other: new QWindow); |
234 | m_window->setSurfaceType(QWindow::OpenGLSurface); |
235 | m_window->setGeometry(posx: 0, posy: 0, w: 10, h: 10); |
236 | |
237 | QSurfaceFormat format; |
238 | format.setVersion(major: 4, minor: 3); |
239 | format.setProfile(QSurfaceFormat::CoreProfile); |
240 | format.setDepthBufferSize(24); |
241 | format.setSamples(4); |
242 | format.setStencilBufferSize(8); |
243 | m_window->setFormat(format); |
244 | m_glContext.setFormat(format); |
245 | |
246 | m_window->create(); |
247 | |
248 | if (!m_glContext.create()) { |
249 | qWarning() << "Failed to create OpenGL context" ; |
250 | return; |
251 | } |
252 | |
253 | if (!m_glContext.makeCurrent(surface: m_window.data())) { |
254 | qWarning() << "Failed to make OpenGL context current" ; |
255 | return; |
256 | } |
257 | |
258 | if ((m_func = m_glContext.versionFunctions<QOpenGLFunctions_4_3_Core>()) != nullptr) { |
259 | m_glHelper.initializeHelper(context: &m_glContext, functions: m_func); |
260 | m_initializationSuccessful = true; |
261 | } |
262 | } |
263 | |
264 | void cleanup() |
265 | { |
266 | m_glContext.doneCurrent(); |
267 | } |
268 | |
269 | void alphaTest() |
270 | { |
271 | if (!m_initializationSuccessful) |
272 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
273 | // Deprecated |
274 | } |
275 | |
276 | void bindBufferBase() |
277 | { |
278 | if (!m_initializationSuccessful) |
279 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
280 | |
281 | // GIVEN |
282 | GLuint bufferId = 0; |
283 | // WHEN |
284 | m_func->glGenBuffers(n: 1, buffers: &bufferId); |
285 | // THEN |
286 | QVERIFY(bufferId != 0); |
287 | |
288 | |
289 | // WHEN |
290 | m_func->glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer: bufferId); |
291 | m_glHelper.bindBufferBase(GL_SHADER_STORAGE_BUFFER, index: 2, buffer: bufferId); |
292 | // THEN |
293 | const GLint error = m_func->glGetError(); |
294 | QVERIFY(error == 0); |
295 | GLint boundToPointBufferId = 0; |
296 | m_func->glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_BINDING, index: 2, data: &boundToPointBufferId); |
297 | QVERIFY(boundToPointBufferId == GLint(bufferId)); |
298 | |
299 | // Restore to sane state |
300 | m_func->glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer: 0); |
301 | m_func->glDeleteBuffers(n: 1, buffers: &bufferId); |
302 | } |
303 | |
304 | void bindFragDataLocation() |
305 | { |
306 | if (!m_initializationSuccessful) |
307 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
308 | |
309 | // GIVEN |
310 | QOpenGLShaderProgram shaderProgram; |
311 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
312 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeFragOutputs); |
313 | |
314 | // WHEN |
315 | QHash<QString, int> fragLocations; |
316 | fragLocations.insert(QStringLiteral("temp" ), avalue: 2); |
317 | fragLocations.insert(QStringLiteral("color" ), avalue: 1); |
318 | m_glHelper.bindFragDataLocation(shader: shaderProgram.programId(), outputs: fragLocations); |
319 | |
320 | // THEN |
321 | QVERIFY(shaderProgram.link()); |
322 | const GLint error = m_func->glGetError(); |
323 | QVERIFY(error == 0); |
324 | const GLint tempLocation = m_func->glGetFragDataLocation(program: shaderProgram.programId(), name: "temp" ); |
325 | const GLint colorLocation = m_func->glGetFragDataLocation(program: shaderProgram.programId(), name: "color" ); |
326 | QCOMPARE(tempLocation, 2); |
327 | QCOMPARE(colorLocation, 1); |
328 | } |
329 | |
330 | void bindFrameBufferAttachment() |
331 | { |
332 | if (!m_initializationSuccessful) |
333 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
334 | |
335 | { |
336 | // GIVEN |
337 | GLuint fboId; |
338 | m_func->glGenFramebuffers(n: 1, framebuffers: &fboId); |
339 | |
340 | Attachment attachment; |
341 | attachment.m_point = QRenderTargetOutput::Color2; |
342 | |
343 | // THEN |
344 | QVERIFY(fboId != 0); |
345 | |
346 | // WHEN |
347 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: fboId); |
348 | |
349 | QOpenGLTexture texture(QOpenGLTexture::Target2D); |
350 | texture.setSize(width: 512, height: 512); |
351 | texture.setFormat(QOpenGLTexture::RGBA32F); |
352 | texture.setMinificationFilter(QOpenGLTexture::Linear); |
353 | texture.setMagnificationFilter(QOpenGLTexture::Linear); |
354 | texture.setWrapMode(QOpenGLTexture::ClampToEdge); |
355 | if (!texture.create()) |
356 | qWarning() << "Texture creation failed" ; |
357 | texture.allocateStorage(); |
358 | QVERIFY(texture.isStorageAllocated()); |
359 | GLint error = m_func->glGetError(); |
360 | QVERIFY(error == 0); |
361 | m_glHelper.bindFrameBufferAttachment(texture: &texture, attachment); |
362 | |
363 | // THEN |
364 | GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); |
365 | QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); |
366 | |
367 | error = m_func->glGetError(); |
368 | QVERIFY(error == 0); |
369 | GLint textureAttachmentId = 0; |
370 | m_func->glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, |
371 | GL_COLOR_ATTACHMENT0 + 2, |
372 | GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, |
373 | params: &textureAttachmentId); |
374 | QCOMPARE(GLuint(textureAttachmentId), texture.textureId()); |
375 | |
376 | // Restore state |
377 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: 0); |
378 | m_func->glDeleteFramebuffers(n: 1, framebuffers: &fboId); |
379 | } |
380 | { |
381 | // GIVEN |
382 | QOpenGLTexture texture(QOpenGLTexture::TargetCubeMap); |
383 | texture.setSize(width: 512, height: 512); |
384 | texture.setFormat(QOpenGLTexture::RGBA32F); |
385 | texture.setMinificationFilter(QOpenGLTexture::Linear); |
386 | texture.setMagnificationFilter(QOpenGLTexture::Linear); |
387 | texture.setWrapMode(QOpenGLTexture::ClampToEdge); |
388 | if (!texture.create()) |
389 | qWarning() << "Texture creation failed" ; |
390 | texture.allocateStorage(); |
391 | QVERIFY(texture.isStorageAllocated()); |
392 | GLint error = m_func->glGetError(); |
393 | QVERIFY(error == 0); |
394 | |
395 | { // Check All Faces |
396 | |
397 | // GIVEN |
398 | GLuint fboId; |
399 | m_func->glGenFramebuffers(n: 1, framebuffers: &fboId); |
400 | |
401 | // THEN |
402 | QVERIFY(fboId != 0); |
403 | |
404 | // WHEN |
405 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: fboId); |
406 | |
407 | Attachment attachment; |
408 | attachment.m_point = QRenderTargetOutput::Color0; |
409 | attachment.m_face = Qt3DRender::QAbstractTexture::AllFaces; |
410 | |
411 | m_glHelper.bindFrameBufferAttachment(texture: &texture, attachment); |
412 | |
413 | // THEN |
414 | GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); |
415 | QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); |
416 | |
417 | error = m_func->glGetError(); |
418 | QVERIFY(error == 0); |
419 | GLint textureIsLayered = 0; |
420 | m_func->glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, |
421 | GL_COLOR_ATTACHMENT0, |
422 | GL_FRAMEBUFFER_ATTACHMENT_LAYERED, |
423 | params: &textureIsLayered); |
424 | QCOMPARE(textureIsLayered, GL_TRUE); |
425 | |
426 | // Restore state |
427 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: 0); |
428 | m_func->glDeleteFramebuffers(n: 1, framebuffers: &fboId); |
429 | } |
430 | { // Check Specific Faces |
431 | |
432 | // GIVEN |
433 | GLuint fboId; |
434 | m_func->glGenFramebuffers(n: 1, framebuffers: &fboId); |
435 | |
436 | // THEN |
437 | QVERIFY(fboId != 0); |
438 | |
439 | // WHEN |
440 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: fboId); |
441 | |
442 | Attachment attachment; |
443 | attachment.m_point = QRenderTargetOutput::Color0; |
444 | attachment.m_face = Qt3DRender::QAbstractTexture::CubeMapNegativeZ; |
445 | |
446 | m_glHelper.bindFrameBufferAttachment(texture: &texture, attachment); |
447 | |
448 | // THEN |
449 | GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); |
450 | QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); |
451 | |
452 | error = m_func->glGetError(); |
453 | QVERIFY(error == 0); |
454 | GLint textureFace = 0; |
455 | m_func->glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, |
456 | GL_COLOR_ATTACHMENT0, |
457 | GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, |
458 | params: &textureFace); |
459 | QCOMPARE(textureFace, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); |
460 | GLint textureIsLayered = 0; |
461 | m_func->glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, |
462 | GL_COLOR_ATTACHMENT0, |
463 | GL_FRAMEBUFFER_ATTACHMENT_LAYERED, |
464 | params: &textureIsLayered); |
465 | QCOMPARE(textureIsLayered, GL_FALSE); |
466 | |
467 | // Restore state |
468 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: 0); |
469 | m_func->glDeleteFramebuffers(n: 1, framebuffers: &fboId); |
470 | } |
471 | } |
472 | |
473 | // TargetCubeMapArray |
474 | { |
475 | // GIVEN |
476 | QOpenGLTexture texture(QOpenGLTexture::TargetCubeMapArray); |
477 | texture.setSize(width: 512, height: 512); |
478 | texture.setFormat(QOpenGLTexture::RGBA32F); |
479 | texture.setMinificationFilter(QOpenGLTexture::Linear); |
480 | texture.setMagnificationFilter(QOpenGLTexture::Linear); |
481 | texture.setWrapMode(QOpenGLTexture::ClampToEdge); |
482 | texture.setLayers(4); |
483 | if (!texture.create()) |
484 | qWarning() << "Texture creation failed" ; |
485 | texture.allocateStorage(); |
486 | QVERIFY(texture.isStorageAllocated()); |
487 | GLint error = m_func->glGetError(); |
488 | QVERIFY(error == 0); |
489 | |
490 | { // Check All Faces |
491 | |
492 | // GIVEN |
493 | GLuint fboId; |
494 | m_func->glGenFramebuffers(n: 1, framebuffers: &fboId); |
495 | |
496 | // THEN |
497 | QVERIFY(fboId != 0); |
498 | |
499 | // WHEN |
500 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: fboId); |
501 | |
502 | Attachment attachment; |
503 | attachment.m_point = QRenderTargetOutput::Color0; |
504 | attachment.m_face = Qt3DRender::QAbstractTexture::AllFaces; |
505 | |
506 | m_glHelper.bindFrameBufferAttachment(texture: &texture, attachment); |
507 | |
508 | // THEN |
509 | GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); |
510 | QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); |
511 | |
512 | error = m_func->glGetError(); |
513 | QVERIFY(error == 0); |
514 | |
515 | // Texture should be layered and attached to layer 0 since CubeMapArray textures |
516 | // are bound to entire texture, not a specific layer |
517 | GLint textureIsLayered = 0; |
518 | m_func->glGetFramebufferAttachmentParameteriv( |
519 | GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
520 | GL_FRAMEBUFFER_ATTACHMENT_LAYERED, params: &textureIsLayered); |
521 | QCOMPARE(textureIsLayered, GL_TRUE); |
522 | |
523 | GLint textureLayer = 0; |
524 | m_func->glGetFramebufferAttachmentParameteriv( |
525 | GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
526 | GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, params: &textureLayer); |
527 | QCOMPARE(textureLayer, 0); |
528 | |
529 | // Restore state |
530 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: 0); |
531 | m_func->glDeleteFramebuffers(n: 1, framebuffers: &fboId); |
532 | } |
533 | { // Check Specific Faces |
534 | |
535 | // GIVEN |
536 | GLuint fboId; |
537 | m_func->glGenFramebuffers(n: 1, framebuffers: &fboId); |
538 | |
539 | // THEN |
540 | QVERIFY(fboId != 0); |
541 | |
542 | // WHEN |
543 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: fboId); |
544 | |
545 | Attachment attachment; |
546 | attachment.m_point = QRenderTargetOutput::Color0; |
547 | attachment.m_face = Qt3DRender::QAbstractTexture::CubeMapNegativeZ; |
548 | attachment.m_layer = 1; |
549 | |
550 | m_glHelper.bindFrameBufferAttachment(texture: &texture, attachment); |
551 | |
552 | // THEN |
553 | GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); |
554 | QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); |
555 | |
556 | error = m_func->glGetError(); |
557 | QVERIFY(error == 0); |
558 | |
559 | GLint textureIsLayered = 0; |
560 | m_func->glGetFramebufferAttachmentParameteriv( |
561 | GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
562 | GL_FRAMEBUFFER_ATTACHMENT_LAYERED, params: &textureIsLayered); |
563 | QCOMPARE(textureIsLayered, GL_FALSE); |
564 | |
565 | GLint textureLayer = 0; |
566 | m_func->glGetFramebufferAttachmentParameteriv( |
567 | GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
568 | GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, params: &textureLayer); |
569 | // actual layer should be 6 * layer + face |
570 | const auto faceNo = |
571 | attachment.m_face - Qt3DRender::QAbstractTexture::CubeMapPositiveX; |
572 | QCOMPARE(textureLayer, 6 * attachment.m_layer + faceNo); |
573 | |
574 | // Restore state |
575 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: 0); |
576 | m_func->glDeleteFramebuffers(n: 1, framebuffers: &fboId); |
577 | } |
578 | } |
579 | } |
580 | |
581 | void bindFrameBufferObject() |
582 | { |
583 | if (!m_initializationSuccessful) |
584 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
585 | |
586 | // GIVEN |
587 | GLuint fboId; |
588 | m_func->glGenFramebuffers(n: 1, framebuffers: &fboId); |
589 | |
590 | // THEN |
591 | QVERIFY(fboId != 0); |
592 | |
593 | // WHEN |
594 | m_glHelper.bindFrameBufferObject(frameBufferId: fboId, mode: GraphicsHelperInterface::FBODraw); |
595 | |
596 | // THEN |
597 | GLint error = m_func->glGetError(); |
598 | QVERIFY(error == 0); |
599 | GLint boundindFBOId = 0; |
600 | m_func->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, params: &boundindFBOId); |
601 | QVERIFY(GLuint(boundindFBOId) == fboId); |
602 | |
603 | // WHEN |
604 | m_glHelper.bindFrameBufferObject(frameBufferId: fboId, mode: GraphicsHelperInterface::FBORead); |
605 | |
606 | // THEN |
607 | error = m_func->glGetError(); |
608 | QVERIFY(error == 0); |
609 | boundindFBOId = 0; |
610 | m_func->glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, params: &boundindFBOId); |
611 | QVERIFY(GLuint(boundindFBOId) == fboId); |
612 | |
613 | // WHEN |
614 | m_glHelper.bindFrameBufferObject(frameBufferId: fboId, mode: GraphicsHelperInterface::FBOReadAndDraw); |
615 | |
616 | // THEN |
617 | error = m_func->glGetError(); |
618 | QVERIFY(error == 0); |
619 | boundindFBOId = 0; |
620 | m_func->glGetIntegerv(GL_FRAMEBUFFER_BINDING, params: &boundindFBOId); |
621 | QVERIFY(GLuint(boundindFBOId) == fboId); |
622 | |
623 | // Cleanup |
624 | m_func->glDeleteFramebuffers(n: 1, framebuffers: &fboId); |
625 | } |
626 | |
627 | void bindImageTexture() |
628 | { |
629 | if (!m_initializationSuccessful) |
630 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
631 | |
632 | // GIVEN |
633 | QOpenGLTexture texture(QOpenGLTexture::Target2D); |
634 | texture.setSize(width: 512, height: 512); |
635 | texture.setFormat(QOpenGLTexture::RGBA8U); |
636 | texture.setMinificationFilter(QOpenGLTexture::Linear); |
637 | texture.setMagnificationFilter(QOpenGLTexture::Linear); |
638 | texture.create(); |
639 | texture.allocateStorage(); |
640 | |
641 | // THEN |
642 | QVERIFY(texture.textureId() != 0 && texture.isCreated() && texture.isStorageAllocated()); |
643 | |
644 | // WHEN |
645 | m_glHelper.bindImageTexture(imageUnit: 0, |
646 | texture: texture.textureId(), |
647 | mipLevel: 0, |
648 | GL_FALSE, |
649 | layer: 0, |
650 | GL_READ_WRITE, |
651 | GL_RGBA8UI); |
652 | |
653 | // THEN |
654 | GLint error = m_func->glGetError(); |
655 | QVERIFY(error == 0); |
656 | } |
657 | |
658 | void bindShaderStorageBlock() |
659 | { |
660 | if (!m_initializationSuccessful) |
661 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
662 | |
663 | // GIVEN |
664 | QOpenGLShaderProgram shaderProgram; |
665 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Compute, source: computeShader); |
666 | QVERIFY(shaderProgram.link()); |
667 | |
668 | // WHEN |
669 | GLint index = m_func->glGetProgramResourceIndex(program: shaderProgram.programId(), |
670 | GL_SHADER_STORAGE_BLOCK, |
671 | name: "Particles" ); |
672 | // THEN |
673 | GLint binding = -1; |
674 | GLenum prop = GL_BUFFER_BINDING; |
675 | m_func->glGetProgramResourceiv(program: shaderProgram.programId(), |
676 | GL_SHADER_STORAGE_BLOCK, |
677 | index, |
678 | propCount: 1, props: &prop, |
679 | bufSize: 4, NULL, params: &binding); |
680 | QCOMPARE(binding, 6); |
681 | |
682 | // WHEN |
683 | m_glHelper.bindShaderStorageBlock(programId: shaderProgram.programId(), shaderStorageBlockIndex: index, shaderStorageBlockBinding: 1); |
684 | |
685 | // THEN |
686 | const GLint error = m_func->glGetError(); |
687 | QVERIFY(error == 0); |
688 | |
689 | m_func->glGetProgramResourceiv(program: shaderProgram.programId(), |
690 | GL_SHADER_STORAGE_BLOCK, |
691 | index, |
692 | propCount: 1, props: &prop, |
693 | bufSize: 4, NULL, params: &binding); |
694 | QCOMPARE(binding, 1); |
695 | } |
696 | |
697 | void bindUniformBlock() |
698 | { |
699 | if (!m_initializationSuccessful) |
700 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
701 | |
702 | // GIVEN |
703 | QOpenGLShaderProgram shaderProgram; |
704 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCodeUniformBuffer); |
705 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformBuffer); |
706 | QVERIFY(shaderProgram.link()); |
707 | |
708 | // WHEN |
709 | GLint index = m_func->glGetUniformBlockIndex(program: shaderProgram.programId(), uniformBlockName: "ColorArray" ); |
710 | m_glHelper.bindUniformBlock(programId: shaderProgram.programId(), uniformBlockIndex: index, uniformBlockBinding: 1); |
711 | |
712 | // THEN |
713 | const GLint error = m_func->glGetError(); |
714 | QVERIFY(error == 0); |
715 | } |
716 | |
717 | void blendEquation() |
718 | { |
719 | if (!m_initializationSuccessful) |
720 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
721 | |
722 | // GIVEN |
723 | GLint equation = 0; |
724 | m_func->glGetIntegerv(GL_BLEND_EQUATION_RGB, params: &equation); |
725 | QCOMPARE(equation, GL_FUNC_ADD); |
726 | |
727 | // WHEN |
728 | m_glHelper.blendEquation(GL_FUNC_REVERSE_SUBTRACT); |
729 | |
730 | // THEN |
731 | m_func->glGetIntegerv(GL_BLEND_EQUATION_RGB, params: &equation); |
732 | QCOMPARE(equation, GL_FUNC_REVERSE_SUBTRACT); |
733 | } |
734 | |
735 | void blendFunci() |
736 | { |
737 | if (!m_initializationSuccessful) |
738 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
739 | |
740 | // GIVEN |
741 | GLint destinationRgb = 0; |
742 | GLint destinationAlpha = 0; |
743 | GLint sourceRgb = 0; |
744 | GLint sourceAlpha = 0; |
745 | m_func->glGetIntegeri_v(GL_BLEND_SRC_RGB, index: 4, data: &sourceRgb); |
746 | m_func->glGetIntegeri_v(GL_BLEND_DST_RGB, index: 4, data: &destinationRgb); |
747 | m_func->glGetIntegeri_v(GL_BLEND_SRC_ALPHA, index: 4, data: &sourceAlpha); |
748 | m_func->glGetIntegeri_v(GL_BLEND_DST_ALPHA, index: 4, data: &destinationAlpha); |
749 | |
750 | // THEN |
751 | QCOMPARE(destinationAlpha, GL_ZERO); |
752 | QCOMPARE(destinationRgb, GL_ZERO); |
753 | QCOMPARE(sourceRgb, GL_ONE); |
754 | QCOMPARE(sourceAlpha, GL_ONE); |
755 | |
756 | // WHEN |
757 | m_glHelper.blendFunci(buf: 4, GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA); |
758 | |
759 | m_func->glGetIntegeri_v(GL_BLEND_SRC_RGB, index: 4, data: &sourceRgb); |
760 | m_func->glGetIntegeri_v(GL_BLEND_DST_RGB, index: 4, data: &destinationRgb); |
761 | m_func->glGetIntegeri_v(GL_BLEND_SRC_ALPHA, index: 4, data: &sourceAlpha); |
762 | m_func->glGetIntegeri_v(GL_BLEND_DST_ALPHA, index: 4, data: &destinationAlpha); |
763 | |
764 | // THEN |
765 | QCOMPARE(destinationAlpha, GL_ONE_MINUS_SRC_ALPHA); |
766 | QCOMPARE(destinationRgb, GL_ONE_MINUS_SRC_ALPHA); |
767 | QCOMPARE(sourceRgb, GL_SRC_COLOR); |
768 | QCOMPARE(sourceAlpha, GL_SRC_COLOR); |
769 | |
770 | // Reset default |
771 | m_glHelper.blendFunci(buf: 4, GL_ONE, GL_ZERO); |
772 | } |
773 | |
774 | void blendFuncSeparatei() |
775 | { |
776 | if (!m_initializationSuccessful) |
777 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
778 | |
779 | // GIVEN |
780 | GLint destinationRgb = 0; |
781 | GLint destinationAlpha = 0; |
782 | GLint sourceRgb = 0; |
783 | GLint sourceAlpha = 0; |
784 | m_func->glGetIntegeri_v(GL_BLEND_SRC_RGB, index: 2, data: &sourceRgb); |
785 | m_func->glGetIntegeri_v(GL_BLEND_DST_RGB, index: 2, data: &destinationRgb); |
786 | m_func->glGetIntegeri_v(GL_BLEND_SRC_ALPHA, index: 2, data: &sourceAlpha); |
787 | m_func->glGetIntegeri_v(GL_BLEND_DST_ALPHA, index: 2, data: &destinationAlpha); |
788 | |
789 | // THEN |
790 | QCOMPARE(destinationAlpha, GL_ZERO); |
791 | QCOMPARE(destinationRgb, GL_ZERO); |
792 | QCOMPARE(sourceRgb, GL_ONE); |
793 | QCOMPARE(sourceAlpha, GL_ONE); |
794 | |
795 | // WHEN |
796 | m_glHelper.blendFuncSeparatei(buf: 2, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
797 | |
798 | m_func->glGetIntegeri_v(GL_BLEND_SRC_RGB, index: 2, data: &sourceRgb); |
799 | m_func->glGetIntegeri_v(GL_BLEND_DST_RGB, index: 2, data: &destinationRgb); |
800 | m_func->glGetIntegeri_v(GL_BLEND_SRC_ALPHA, index: 2, data: &sourceAlpha); |
801 | m_func->glGetIntegeri_v(GL_BLEND_DST_ALPHA, index: 2, data: &destinationAlpha); |
802 | |
803 | // THEN |
804 | QCOMPARE(destinationAlpha, GL_ONE_MINUS_SRC_ALPHA); |
805 | QCOMPARE(destinationRgb, GL_ONE_MINUS_SRC_COLOR); |
806 | QCOMPARE(sourceRgb, GL_SRC_COLOR); |
807 | QCOMPARE(sourceAlpha, GL_SRC_ALPHA); |
808 | |
809 | // Reset default |
810 | m_glHelper.blendFunci(buf: 4, GL_ONE, GL_ZERO); |
811 | } |
812 | |
813 | void boundFrameBufferObject() |
814 | { |
815 | if (!m_initializationSuccessful) |
816 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
817 | |
818 | // GIVEN |
819 | GLuint fboId; |
820 | m_func->glGenFramebuffers(n: 1, framebuffers: &fboId); |
821 | |
822 | // WHEN |
823 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: fboId); |
824 | |
825 | // THEN |
826 | GLint boundBuffer = 0; |
827 | m_func->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, params: &boundBuffer); |
828 | QCOMPARE(GLuint(boundBuffer), fboId); |
829 | |
830 | // THEN |
831 | QCOMPARE(m_glHelper.boundFrameBufferObject(), fboId); |
832 | |
833 | // Reset state |
834 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: 0); |
835 | m_func->glDeleteFramebuffers(n: 1, framebuffers: &fboId); |
836 | } |
837 | |
838 | void checkFrameBufferComplete() |
839 | { |
840 | if (!m_initializationSuccessful) |
841 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
842 | // GIVEN |
843 | GLuint fboId; |
844 | m_func->glGenFramebuffers(n: 1, framebuffers: &fboId); |
845 | |
846 | Attachment attachment; |
847 | attachment.m_point = QRenderTargetOutput::Color1; |
848 | |
849 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: fboId); |
850 | |
851 | QOpenGLTexture texture(QOpenGLTexture::Target2D); |
852 | texture.setSize(width: 512, height: 512); |
853 | texture.setFormat(QOpenGLTexture::RGBA8U); |
854 | texture.setMinificationFilter(QOpenGLTexture::Linear); |
855 | texture.setMagnificationFilter(QOpenGLTexture::Linear); |
856 | texture.create(); |
857 | texture.allocateStorage(); |
858 | m_glHelper.bindFrameBufferAttachment(texture: &texture, attachment); |
859 | |
860 | // THEN |
861 | GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); |
862 | QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); |
863 | |
864 | QVERIFY(m_glHelper.checkFrameBufferComplete()); |
865 | |
866 | // Restore |
867 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: 0); |
868 | m_func->glDeleteFramebuffers(n: 1, framebuffers: &fboId); |
869 | } |
870 | |
871 | void clearBufferf() |
872 | { |
873 | if (!m_initializationSuccessful) |
874 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
875 | |
876 | // GIVEN |
877 | // GIVEN |
878 | GLuint fboId; |
879 | m_func->glGenFramebuffers(n: 1, framebuffers: &fboId); |
880 | |
881 | // THEN |
882 | QVERIFY(fboId != 0); |
883 | |
884 | // WHEN |
885 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: fboId); |
886 | // Create 4 attachments |
887 | QOpenGLTexture *textures[4]; |
888 | for (int i = 0; i < 4; ++i) { |
889 | Attachment attachment; |
890 | attachment.m_point = static_cast<QRenderTargetOutput::AttachmentPoint>(i); |
891 | |
892 | QOpenGLTexture *texture = new QOpenGLTexture(QOpenGLTexture::Target2D); |
893 | textures[i] = texture; |
894 | texture->setSize(width: 512, height: 512); |
895 | texture->setFormat(QOpenGLTexture::RGBA32F); |
896 | texture->setMinificationFilter(QOpenGLTexture::Linear); |
897 | texture->setMagnificationFilter(QOpenGLTexture::Linear); |
898 | texture->setWrapMode(QOpenGLTexture::ClampToEdge); |
899 | if (!texture->create()) |
900 | qWarning() << "Texture creation failed" ; |
901 | texture->allocateStorage(); |
902 | QVERIFY(texture->isStorageAllocated()); |
903 | GLint error = m_func->glGetError(); |
904 | QVERIFY(error == 0); |
905 | m_glHelper.bindFrameBufferAttachment(texture, attachment); |
906 | } |
907 | |
908 | GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); |
909 | QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); |
910 | |
911 | // Set Draw buffers |
912 | GLenum clearBufferEnum = GL_COLOR_ATTACHMENT3; |
913 | m_func->glDrawBuffers(n: 1, bufs: &clearBufferEnum); |
914 | |
915 | const GLint bufferIndex = 0; // index of the element in the draw buffers |
916 | GLint error = m_func->glGetError(); |
917 | QVERIFY(error == 0); |
918 | |
919 | // WHEN |
920 | const QVector4D clearValue1 = QVector4D(0.5f, 0.2f, 0.4f, 0.8f); |
921 | m_func->glClearBufferfv(GL_COLOR, drawbuffer: bufferIndex, value: reinterpret_cast<const float *>(&clearValue1)); |
922 | error = m_func->glGetError(); |
923 | QVERIFY(error == 0); |
924 | |
925 | // THEN |
926 | QVector<QVector4D> colors(512 * 512); |
927 | textures[3]->bind(); |
928 | m_func->glGetTexImage(GL_TEXTURE_2D, level: 0, GL_RGBA, GL_FLOAT, pixels: colors.data()); |
929 | textures[3]->release(); |
930 | |
931 | for (const QVector4D c : colors) { |
932 | QVERIFY(c == clearValue1); |
933 | } |
934 | |
935 | // WHEN |
936 | const QVector4D clearValue2 = QVector4D(0.4f, 0.5f, 0.4f, 1.0f); |
937 | m_glHelper.clearBufferf(drawbuffer: bufferIndex, values: clearValue2); |
938 | |
939 | // THEN |
940 | textures[3]->bind(); |
941 | m_func->glGetTexImage(GL_TEXTURE_2D, level: 0, GL_RGBA, GL_FLOAT, pixels: colors.data()); |
942 | textures[3]->release(); |
943 | for (const QVector4D c : colors) { |
944 | QVERIFY(c == clearValue2); |
945 | } |
946 | // Restore |
947 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: 0); |
948 | m_func->glDeleteFramebuffers(n: 1, framebuffers: &fboId); |
949 | for (int i = 0; i < 4; ++i) |
950 | delete textures[i]; |
951 | } |
952 | |
953 | void createFrameBufferObject() |
954 | { |
955 | if (!m_initializationSuccessful) |
956 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
957 | |
958 | // WHEN |
959 | const GLuint fboId = m_glHelper.createFrameBufferObject(); |
960 | |
961 | // THEN |
962 | QVERIFY(fboId != 0); |
963 | |
964 | // Restore |
965 | m_func->glDeleteFramebuffers(n: 1, framebuffers: &fboId); |
966 | } |
967 | |
968 | void depthMask() |
969 | { |
970 | if (!m_initializationSuccessful) |
971 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
972 | |
973 | // GIVEN |
974 | GLboolean depthWritingEnabled = false; |
975 | m_func->glGetBooleanv(GL_DEPTH_WRITEMASK, params: &depthWritingEnabled); |
976 | |
977 | // THEN |
978 | QVERIFY(depthWritingEnabled); |
979 | |
980 | // WHEN |
981 | m_glHelper.depthMask(GL_FALSE); |
982 | |
983 | // THEN |
984 | m_func->glGetBooleanv(GL_DEPTH_WRITEMASK, params: &depthWritingEnabled); |
985 | QVERIFY(!depthWritingEnabled); |
986 | |
987 | // WHEN |
988 | m_glHelper.depthMask(GL_TRUE); |
989 | |
990 | // THEN |
991 | m_func->glGetBooleanv(GL_DEPTH_WRITEMASK, params: &depthWritingEnabled); |
992 | QVERIFY(depthWritingEnabled); |
993 | } |
994 | |
995 | void depthTest() |
996 | { |
997 | if (!m_initializationSuccessful) |
998 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
999 | |
1000 | // GIVEN |
1001 | m_func->glDisable(GL_DEPTH_TEST); |
1002 | m_func->glDepthFunc(GL_LESS); |
1003 | |
1004 | // WHEN |
1005 | m_glHelper.depthTest(GL_LEQUAL); |
1006 | |
1007 | // THEN |
1008 | QVERIFY(m_func->glIsEnabled(GL_DEPTH_TEST)); |
1009 | GLint depthMode = 0; |
1010 | m_func->glGetIntegerv(GL_DEPTH_FUNC, params: &depthMode); |
1011 | QCOMPARE(depthMode, GL_LEQUAL); |
1012 | |
1013 | // WHEN |
1014 | m_glHelper.depthTest(GL_LESS); |
1015 | QVERIFY(m_func->glIsEnabled(GL_DEPTH_TEST)); |
1016 | m_func->glGetIntegerv(GL_DEPTH_FUNC, params: &depthMode); |
1017 | QCOMPARE(depthMode, GL_LESS); |
1018 | } |
1019 | |
1020 | void disableClipPlane() |
1021 | { |
1022 | if (!m_initializationSuccessful) |
1023 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1024 | |
1025 | // GIVEN |
1026 | m_func->glEnable(GL_CLIP_DISTANCE0 + 5); |
1027 | |
1028 | // THEN |
1029 | QVERIFY(m_func->glIsEnabled(GL_CLIP_DISTANCE0 + 5)); |
1030 | |
1031 | // WHEN |
1032 | m_glHelper.disableClipPlane(clipPlane: 5); |
1033 | |
1034 | // THEN |
1035 | QVERIFY(!m_func->glIsEnabled(GL_CLIP_DISTANCE0 + 5)); |
1036 | } |
1037 | |
1038 | void disablei() |
1039 | { |
1040 | if (!m_initializationSuccessful) |
1041 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1042 | |
1043 | // GIVEN |
1044 | m_func->glEnablei(GL_BLEND, index: 2); |
1045 | |
1046 | // THEN |
1047 | QVERIFY(m_func->glIsEnabledi(GL_BLEND, 2)); |
1048 | |
1049 | // WHEN |
1050 | m_glHelper.disablei(GL_BLEND, index: 2); |
1051 | |
1052 | // THEN |
1053 | QVERIFY(!m_func->glIsEnabledi(GL_BLEND, 2)); |
1054 | } |
1055 | |
1056 | void disablePrimitiveRestart() |
1057 | { |
1058 | if (!m_initializationSuccessful) |
1059 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1060 | |
1061 | // GIVEN |
1062 | m_func->glEnable(GL_PRIMITIVE_RESTART); |
1063 | |
1064 | // THEN |
1065 | QVERIFY(m_func->glIsEnabled(GL_PRIMITIVE_RESTART)); |
1066 | |
1067 | // WHEN |
1068 | m_glHelper.disablePrimitiveRestart(); |
1069 | |
1070 | // THEN |
1071 | QVERIFY(!m_func->glIsEnabled(GL_PRIMITIVE_RESTART)); |
1072 | } |
1073 | |
1074 | void drawBuffers() |
1075 | { |
1076 | if (!m_initializationSuccessful) |
1077 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1078 | |
1079 | // GIVEN |
1080 | GLuint fboId; |
1081 | m_func->glGenFramebuffers(n: 1, framebuffers: &fboId); |
1082 | |
1083 | // THEN |
1084 | QVERIFY(fboId != 0); |
1085 | |
1086 | // WHEN |
1087 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: fboId); |
1088 | QOpenGLTexture *textures[4]; |
1089 | |
1090 | // Create 4 attachments |
1091 | for (int i = 0; i < 4; ++i) { |
1092 | Attachment attachment; |
1093 | attachment.m_point = static_cast<QRenderTargetOutput::AttachmentPoint>(i); |
1094 | |
1095 | QOpenGLTexture *texture = new QOpenGLTexture(QOpenGLTexture::Target2D); |
1096 | textures[i] = texture; |
1097 | texture->setSize(width: 512, height: 512); |
1098 | texture->setFormat(QOpenGLTexture::RGBA32F); |
1099 | texture->setMinificationFilter(QOpenGLTexture::Linear); |
1100 | texture->setMagnificationFilter(QOpenGLTexture::Linear); |
1101 | texture->setWrapMode(QOpenGLTexture::ClampToEdge); |
1102 | if (!texture->create()) |
1103 | qWarning() << "Texture creation failed" ; |
1104 | texture->allocateStorage(); |
1105 | QVERIFY(texture->isStorageAllocated()); |
1106 | GLint error = m_func->glGetError(); |
1107 | QVERIFY(error == 0); |
1108 | m_glHelper.bindFrameBufferAttachment(texture, attachment); |
1109 | } |
1110 | // THEN |
1111 | GLenum status = m_func->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); |
1112 | QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); |
1113 | |
1114 | // WHEN |
1115 | GLenum bufferEnum = GL_COLOR_ATTACHMENT4; |
1116 | m_func->glDrawBuffers(n: 1, bufs: &bufferEnum); |
1117 | |
1118 | // THEN |
1119 | GLint enumValue = -1; |
1120 | m_func->glGetIntegerv(GL_DRAW_BUFFER0, params: &enumValue); |
1121 | QCOMPARE(enumValue, GL_COLOR_ATTACHMENT4); |
1122 | |
1123 | // WHEN |
1124 | GLint newBufferEnum = 2; |
1125 | m_glHelper.drawBuffers(n: 1, bufs: &newBufferEnum); |
1126 | |
1127 | // THEN |
1128 | m_func->glGetIntegerv(GL_DRAW_BUFFER0, params: &enumValue); |
1129 | QCOMPARE(enumValue, GL_COLOR_ATTACHMENT0 + newBufferEnum); |
1130 | |
1131 | // WHEN |
1132 | newBufferEnum = 0; |
1133 | m_glHelper.drawBuffers(n: 1, bufs: &newBufferEnum); |
1134 | |
1135 | // THEN |
1136 | m_func->glGetIntegerv(GL_DRAW_BUFFER0, params: &enumValue); |
1137 | QCOMPARE(enumValue, GL_COLOR_ATTACHMENT0 + newBufferEnum); |
1138 | |
1139 | // Restore |
1140 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: 0); |
1141 | m_func->glDeleteFramebuffers(n: 1, framebuffers: &fboId); |
1142 | for (int i = 0; i < 4; ++i) |
1143 | delete textures[i]; |
1144 | } |
1145 | |
1146 | void enableClipPlane() |
1147 | { |
1148 | if (!m_initializationSuccessful) |
1149 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1150 | |
1151 | // GIVEN |
1152 | m_func->glDisable(GL_CLIP_DISTANCE0 + 4); |
1153 | |
1154 | // THEN |
1155 | QVERIFY(!m_func->glIsEnabled(GL_CLIP_DISTANCE0 + 4)); |
1156 | |
1157 | // WHEN |
1158 | m_glHelper.enableClipPlane(clipPlane: 4); |
1159 | |
1160 | // THEN |
1161 | QVERIFY(m_func->glIsEnabled(GL_CLIP_DISTANCE0 + 4)); |
1162 | } |
1163 | |
1164 | void enablei() |
1165 | { |
1166 | if (!m_initializationSuccessful) |
1167 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1168 | |
1169 | // GIVEN |
1170 | m_func->glDisablei(GL_BLEND, index: 4); |
1171 | |
1172 | // THEN |
1173 | QVERIFY(!m_func->glIsEnabledi(GL_BLEND, 4)); |
1174 | |
1175 | // WHEN |
1176 | m_glHelper.enablei(GL_BLEND, index: 4); |
1177 | |
1178 | // THEN |
1179 | QVERIFY(m_func->glIsEnabledi(GL_BLEND, 4)); |
1180 | } |
1181 | |
1182 | void enablePrimitiveRestart() |
1183 | { |
1184 | if (!m_initializationSuccessful) |
1185 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1186 | |
1187 | // GIVEN |
1188 | m_func->glDisable(GL_PRIMITIVE_RESTART); |
1189 | |
1190 | // THEN |
1191 | QVERIFY(!m_func->glIsEnabled(GL_PRIMITIVE_RESTART)); |
1192 | |
1193 | // WHEN |
1194 | m_glHelper.enablePrimitiveRestart(primitiveRestartIndex: 883); |
1195 | |
1196 | // THEN |
1197 | QVERIFY(m_func->glIsEnabled(GL_PRIMITIVE_RESTART)); |
1198 | GLint restartIndex = 0; |
1199 | m_func->glGetIntegerv(GL_PRIMITIVE_RESTART_INDEX, params: &restartIndex); |
1200 | QCOMPARE(restartIndex, 883); |
1201 | |
1202 | // Restore |
1203 | m_func->glDisable(GL_PRIMITIVE_RESTART); |
1204 | } |
1205 | |
1206 | void enableVertexAttribute() |
1207 | { |
1208 | if (!m_initializationSuccessful) |
1209 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1210 | |
1211 | // GIVEN |
1212 | QOpenGLVertexArrayObject vao; |
1213 | vao.create(); |
1214 | QOpenGLVertexArrayObject::Binder binder(&vao); |
1215 | |
1216 | QOpenGLShaderProgram shaderProgram; |
1217 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCodeUniformBuffer); |
1218 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformBuffer); |
1219 | QVERIFY(shaderProgram.link()); |
1220 | shaderProgram.bind(); |
1221 | |
1222 | // WHEN |
1223 | GLint positionLocation = m_func->glGetAttribLocation(program: shaderProgram.programId(), name: "vertexPosition" ); |
1224 | GLint texCoordLocation = m_func->glGetAttribLocation(program: shaderProgram.programId(), name: "vertexTexCoord" ); |
1225 | GLint colorIndexLocation = m_func->glGetAttribLocation(program: shaderProgram.programId(), name: "vertexColorIndex" ); |
1226 | m_glHelper.enableVertexAttributeArray(location: positionLocation); |
1227 | m_glHelper.enableVertexAttributeArray(location: texCoordLocation); |
1228 | m_glHelper.enableVertexAttributeArray(location: colorIndexLocation); |
1229 | |
1230 | // THEN |
1231 | const GLint error = m_func->glGetError(); |
1232 | QVERIFY(error == 0); |
1233 | } |
1234 | |
1235 | void frontFace() |
1236 | { |
1237 | if (!m_initializationSuccessful) |
1238 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1239 | |
1240 | // GIVEN |
1241 | m_func->glFrontFace(GL_CW); |
1242 | |
1243 | // THEN |
1244 | GLint face = 0; |
1245 | m_func->glGetIntegerv(GL_FRONT_FACE, params: &face); |
1246 | QCOMPARE(face, GL_CW); |
1247 | |
1248 | // WHEN |
1249 | m_glHelper.frontFace(GL_CCW); |
1250 | |
1251 | // THEN |
1252 | m_func->glGetIntegerv(GL_FRONT_FACE, params: &face); |
1253 | QCOMPARE(face, GL_CCW); |
1254 | } |
1255 | |
1256 | void getRenderBufferDimensions() |
1257 | { |
1258 | if (!m_initializationSuccessful) |
1259 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1260 | |
1261 | // GIVEN |
1262 | GLuint renderBufferId = 0; |
1263 | m_func->glGenRenderbuffers(n: 1, renderbuffers: &renderBufferId); |
1264 | QVERIFY(renderBufferId != 0); |
1265 | |
1266 | // WHEN |
1267 | m_func->glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer: renderBufferId); |
1268 | m_func->glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8_ALPHA8, width: 512, height: 512); |
1269 | m_func->glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer: 0); |
1270 | const QSize dimensions = m_glHelper.getRenderBufferDimensions(renderBufferId); |
1271 | |
1272 | // THEN |
1273 | QCOMPARE(dimensions, QSize(512, 512)); |
1274 | |
1275 | // Restore |
1276 | m_func->glDeleteRenderbuffers(n: 1, renderbuffers: &renderBufferId); |
1277 | } |
1278 | |
1279 | void getTextureDimensions() |
1280 | { |
1281 | if (!m_initializationSuccessful) |
1282 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1283 | |
1284 | // GIVEN |
1285 | QOpenGLTexture texture(QOpenGLTexture::Target2D); |
1286 | texture.setSize(width: 512, height: 512); |
1287 | texture.setFormat(QOpenGLTexture::RGBA8U); |
1288 | texture.setMinificationFilter(QOpenGLTexture::Linear); |
1289 | texture.setMagnificationFilter(QOpenGLTexture::Linear); |
1290 | texture.create(); |
1291 | texture.allocateStorage(); |
1292 | |
1293 | // WHEN |
1294 | const QSize dimensions = m_glHelper.getTextureDimensions(textureId: texture.textureId(), GL_TEXTURE_2D); |
1295 | |
1296 | // THEN |
1297 | QCOMPARE(dimensions, QSize(512, 512)); |
1298 | } |
1299 | |
1300 | void pointSize() |
1301 | { |
1302 | if (!m_initializationSuccessful) |
1303 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1304 | |
1305 | // GIVEN |
1306 | m_func->glEnable(GL_PROGRAM_POINT_SIZE); |
1307 | |
1308 | // THEN |
1309 | QVERIFY(m_func->glIsEnabled(GL_PROGRAM_POINT_SIZE)); |
1310 | GLfloat size = 0; |
1311 | m_func->glGetFloatv(GL_POINT_SIZE, params: &size); |
1312 | QCOMPARE(size, 1.0f); |
1313 | |
1314 | // WHEN |
1315 | m_glHelper.pointSize(programmable: false, value: 0.5f); |
1316 | |
1317 | // THEN |
1318 | QVERIFY(!m_func->glIsEnabled(GL_PROGRAM_POINT_SIZE)); |
1319 | m_func->glGetFloatv(GL_POINT_SIZE, params: &size); |
1320 | QCOMPARE(size, 0.5f); |
1321 | } |
1322 | |
1323 | void maxClipPlaneCount() |
1324 | { |
1325 | if (!m_initializationSuccessful) |
1326 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1327 | |
1328 | // GIVEN |
1329 | GLint maxCount = -1; |
1330 | m_func->glGetIntegerv(GL_MAX_CLIP_PLANES, params: &maxCount); |
1331 | |
1332 | // THEN |
1333 | QCOMPARE(maxCount, m_glHelper.maxClipPlaneCount()); |
1334 | } |
1335 | |
1336 | void programUniformBlock() |
1337 | { |
1338 | if (!m_initializationSuccessful) |
1339 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1340 | |
1341 | // GIVEN |
1342 | QOpenGLShaderProgram shaderProgram; |
1343 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCodeUniformBuffer); |
1344 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformBuffer); |
1345 | QVERIFY(shaderProgram.link()); |
1346 | |
1347 | // WHEN |
1348 | const QVector<ShaderUniformBlock> activeUniformBlocks = m_glHelper.programUniformBlocks(programId: shaderProgram.programId()); |
1349 | |
1350 | // THEN |
1351 | QCOMPARE(activeUniformBlocks.size(), 1); |
1352 | const ShaderUniformBlock uniformBlock = activeUniformBlocks.first(); |
1353 | |
1354 | QCOMPARE(uniformBlock.m_activeUniformsCount, 1); |
1355 | QCOMPARE(uniformBlock.m_name, QStringLiteral("ColorArray" )); |
1356 | QCOMPARE(uniformBlock.m_binding, 2); |
1357 | } |
1358 | |
1359 | void programAttributesAndLocations() |
1360 | { |
1361 | if (!m_initializationSuccessful) |
1362 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1363 | |
1364 | // GIVEN |
1365 | QOpenGLShaderProgram shaderProgram; |
1366 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
1367 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeSamplers); |
1368 | QVERIFY(shaderProgram.link()); |
1369 | |
1370 | // WHEN |
1371 | QVector<ShaderAttribute> activeAttributes = m_glHelper.programAttributesAndLocations(programId: shaderProgram.programId()); |
1372 | |
1373 | // THEN |
1374 | QCOMPARE(activeAttributes.size(), 2); |
1375 | std::sort(first: activeAttributes.begin(), last: activeAttributes.end(), comp: [] (const ShaderAttribute &a, const ShaderAttribute &b) { return a.m_location < b.m_location; }); |
1376 | |
1377 | const ShaderAttribute attribute1 = activeAttributes.at(i: 0); |
1378 | QCOMPARE(attribute1.m_name, QStringLiteral("vertexPosition" )); |
1379 | QCOMPARE(attribute1.m_size, 1); |
1380 | QCOMPARE(attribute1.m_location, 1); |
1381 | QCOMPARE(attribute1.m_type, GLenum(GL_FLOAT_VEC3)); |
1382 | |
1383 | const ShaderAttribute attribute2 = activeAttributes.at(i: 1); |
1384 | QCOMPARE(attribute2.m_name, QStringLiteral("vertexTexCoord" )); |
1385 | QCOMPARE(attribute2.m_size, 1); |
1386 | QCOMPARE(attribute2.m_location, 2); |
1387 | QCOMPARE(attribute2.m_type, GLenum(GL_FLOAT_VEC2)); |
1388 | } |
1389 | |
1390 | void programUniformsAndLocations() |
1391 | { |
1392 | if (!m_initializationSuccessful) |
1393 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1394 | |
1395 | // GIVEN |
1396 | QOpenGLShaderProgram shaderProgram; |
1397 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
1398 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloat); |
1399 | QVERIFY(shaderProgram.link()); |
1400 | |
1401 | // WHEN |
1402 | QVector<ShaderUniform> activeUniforms = m_glHelper.programUniformsAndLocations(programId: shaderProgram.programId()); |
1403 | |
1404 | // THEN |
1405 | QCOMPARE(activeUniforms.size(), 4); |
1406 | std::sort(first: activeUniforms.begin(), last: activeUniforms.end(), comp: [] (const ShaderUniform &a, const ShaderUniform &b) { return a.m_location < b.m_location; }); |
1407 | |
1408 | const ShaderUniform uniform1 = activeUniforms.at(i: 0); |
1409 | QCOMPARE(uniform1.m_location, 1); |
1410 | QCOMPARE(uniform1.m_offset, -1); |
1411 | QCOMPARE(uniform1.m_blockIndex, -1); |
1412 | QCOMPARE(uniform1.m_arrayStride, -1); |
1413 | QCOMPARE(uniform1.m_matrixStride, -1); |
1414 | QCOMPARE(uniform1.m_size, 1); |
1415 | QCOMPARE(uniform1.m_type, GLenum(GL_FLOAT)); |
1416 | QCOMPARE(uniform1.m_name, QStringLiteral("multiplier" )); |
1417 | |
1418 | const ShaderUniform uniform2 = activeUniforms.at(i: 1); |
1419 | QCOMPARE(uniform2.m_location, 2); |
1420 | QCOMPARE(uniform2.m_offset, -1); |
1421 | QCOMPARE(uniform2.m_blockIndex, -1); |
1422 | QCOMPARE(uniform2.m_arrayStride, -1); |
1423 | QCOMPARE(uniform2.m_matrixStride, -1); |
1424 | QCOMPARE(uniform2.m_size, 1); |
1425 | QCOMPARE(uniform2.m_type, GLenum(GL_FLOAT_VEC2)); |
1426 | QCOMPARE(uniform2.m_name, QStringLiteral("multiplierVec2" )); |
1427 | |
1428 | const ShaderUniform uniform3 = activeUniforms.at(i: 2); |
1429 | QCOMPARE(uniform3.m_location, 3); |
1430 | QCOMPARE(uniform3.m_offset, -1); |
1431 | QCOMPARE(uniform3.m_blockIndex, -1); |
1432 | QCOMPARE(uniform3.m_arrayStride, -1); |
1433 | QCOMPARE(uniform3.m_matrixStride, -1); |
1434 | QCOMPARE(uniform3.m_size, 1); |
1435 | QCOMPARE(uniform3.m_type, GLenum(GL_FLOAT_VEC3)); |
1436 | QCOMPARE(uniform3.m_name, QStringLiteral("multiplierVec3" )); |
1437 | |
1438 | const ShaderUniform uniform4 = activeUniforms.at(i: 3); |
1439 | QCOMPARE(uniform4.m_location, 4); |
1440 | QCOMPARE(uniform4.m_offset, -1); |
1441 | QCOMPARE(uniform4.m_blockIndex, -1); |
1442 | QCOMPARE(uniform4.m_arrayStride, -1); |
1443 | QCOMPARE(uniform4.m_matrixStride, -1); |
1444 | QCOMPARE(uniform4.m_size, 1); |
1445 | QCOMPARE(uniform4.m_type, GLenum(GL_FLOAT_VEC4)); |
1446 | QCOMPARE(uniform4.m_name, QStringLiteral("multiplierVec4" )); |
1447 | } |
1448 | |
1449 | void programShaderStorageBlock() |
1450 | { |
1451 | if (!m_initializationSuccessful) |
1452 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1453 | |
1454 | // GIVEN |
1455 | QOpenGLShaderProgram shaderProgram; |
1456 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Compute, source: computeShader); |
1457 | QVERIFY(shaderProgram.link()); |
1458 | |
1459 | // WHEN |
1460 | const QVector<ShaderStorageBlock> activeShaderStorageBlocks = m_glHelper.programShaderStorageBlocks(programId: shaderProgram.programId()); |
1461 | |
1462 | // THEN |
1463 | QVERIFY(activeShaderStorageBlocks.size() == 1); |
1464 | ShaderStorageBlock block = activeShaderStorageBlocks.first(); |
1465 | QCOMPARE(block.m_name, QStringLiteral("Particles" )); |
1466 | QCOMPARE(block.m_activeVariablesCount, 3); |
1467 | QCOMPARE(block.m_index, 0); |
1468 | QCOMPARE(block.m_binding, 6); |
1469 | QCOMPARE(block.m_size, (4 + 4 + 4) * 4); |
1470 | } |
1471 | |
1472 | void releaseFrameBufferObject() |
1473 | { |
1474 | if (!m_initializationSuccessful) |
1475 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1476 | |
1477 | // GIVEN |
1478 | GLuint fboId; |
1479 | m_func->glGenFramebuffers(n: 1, framebuffers: &fboId); |
1480 | |
1481 | // THEN |
1482 | QVERIFY(fboId != 0); |
1483 | |
1484 | // WHEN |
1485 | m_glHelper.releaseFrameBufferObject(frameBufferId: fboId); |
1486 | |
1487 | // THEN |
1488 | QVERIFY(!m_func->glIsFramebuffer(fboId)); |
1489 | } |
1490 | |
1491 | void setMSAAEnabled() |
1492 | { |
1493 | if (!m_initializationSuccessful) |
1494 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1495 | |
1496 | // GIVEN |
1497 | m_func->glDisable(GL_MULTISAMPLE); |
1498 | |
1499 | // THEN |
1500 | QVERIFY(!m_func->glIsEnabled(GL_MULTISAMPLE)); |
1501 | |
1502 | // WHEN |
1503 | m_glHelper.setMSAAEnabled(true); |
1504 | |
1505 | // THEN |
1506 | QVERIFY(m_func->glIsEnabled(GL_MULTISAMPLE)); |
1507 | |
1508 | // WHEN |
1509 | m_glHelper.setMSAAEnabled(false); |
1510 | |
1511 | // THEN |
1512 | QVERIFY(!m_func->glIsEnabled(GL_MULTISAMPLE)); |
1513 | } |
1514 | |
1515 | void setAlphaCoverageEnabled() |
1516 | { |
1517 | if (!m_initializationSuccessful) |
1518 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1519 | |
1520 | // GIVEN |
1521 | m_func->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); |
1522 | |
1523 | // THEN |
1524 | QVERIFY(!m_func->glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE)); |
1525 | |
1526 | // WHEN |
1527 | m_glHelper.setAlphaCoverageEnabled(true); |
1528 | |
1529 | // THEN |
1530 | QVERIFY(m_func->glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE)); |
1531 | |
1532 | // WHEN |
1533 | m_glHelper.setAlphaCoverageEnabled(false); |
1534 | |
1535 | // THEN |
1536 | QVERIFY(!m_func->glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE)); |
1537 | } |
1538 | |
1539 | void setClipPlane() |
1540 | { |
1541 | if (!m_initializationSuccessful) |
1542 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1543 | // Deprecated in GL 4 |
1544 | } |
1545 | |
1546 | void setSeamlessCubemap() |
1547 | { |
1548 | if (!m_initializationSuccessful) |
1549 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1550 | |
1551 | // GIVEN |
1552 | m_func->glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS); |
1553 | QVERIFY(!m_func->glIsEnabled(GL_TEXTURE_CUBE_MAP_SEAMLESS)); |
1554 | |
1555 | // WHEN |
1556 | m_glHelper.setSeamlessCubemap(true); |
1557 | |
1558 | // THEN |
1559 | QVERIFY(m_func->glIsEnabled(GL_TEXTURE_CUBE_MAP_SEAMLESS)); |
1560 | |
1561 | // WHEN |
1562 | m_glHelper.setSeamlessCubemap(false); |
1563 | |
1564 | // THEN |
1565 | QVERIFY(!m_func->glIsEnabled(GL_TEXTURE_CUBE_MAP_SEAMLESS)); |
1566 | } |
1567 | |
1568 | void setVerticesPerPatch() |
1569 | { |
1570 | if (!m_initializationSuccessful) |
1571 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1572 | |
1573 | // GIVEN |
1574 | m_func->glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS); |
1575 | |
1576 | // THEN |
1577 | QVERIFY(!m_func->glIsEnabled(GL_TEXTURE_CUBE_MAP_SEAMLESS)); |
1578 | |
1579 | // WHEN |
1580 | m_glHelper.setSeamlessCubemap(true); |
1581 | |
1582 | // THEN |
1583 | QVERIFY(m_func->glIsEnabled(GL_TEXTURE_CUBE_MAP_SEAMLESS)); |
1584 | |
1585 | // WHEN |
1586 | m_glHelper.setSeamlessCubemap(false); |
1587 | |
1588 | // THEN |
1589 | QVERIFY(!m_func->glIsEnabled(GL_TEXTURE_CUBE_MAP_SEAMLESS)); |
1590 | } |
1591 | |
1592 | void supportsFeature() |
1593 | { |
1594 | for (int i = 0; i <= GraphicsHelperInterface::Fences; ++i) |
1595 | QVERIFY(m_glHelper.supportsFeature(static_cast<GraphicsHelperInterface::Feature>(i))); |
1596 | } |
1597 | |
1598 | |
1599 | #define ADD_UNIFORM_ENTRY(FragShader, Type, Location, ComponentSize, ExpectedRawSize) \ |
1600 | QTest::newRow(#FragShader"_"#Type) << FragShader << Type << Location << ComponentSize << ExpectedRawSize; |
1601 | |
1602 | void uniformsByteSize_data() |
1603 | { |
1604 | QTest::addColumn<QByteArray>(name: "fragShader" ); |
1605 | QTest::addColumn<int>(name: "type" ); |
1606 | QTest::addColumn<int>(name: "location" ); |
1607 | QTest::addColumn<int>(name: "componentSize" ); |
1608 | QTest::addColumn<int>(name: "expectedByteSize" ); |
1609 | |
1610 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloat, GL_FLOAT, 1, 1, 4); |
1611 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloat, GL_FLOAT_VEC2, 2, 1, 4 * 2); |
1612 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloat, GL_FLOAT_VEC3, 3, 1, 4 * 3); |
1613 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloat, GL_FLOAT_VEC4, 4, 1, 4 * 4); |
1614 | |
1615 | ADD_UNIFORM_ENTRY(fragCodeUniformsInt, GL_INT, 1, 1, 4); |
1616 | ADD_UNIFORM_ENTRY(fragCodeUniformsInt, GL_INT_VEC2, 2, 1, 4 * 2); |
1617 | ADD_UNIFORM_ENTRY(fragCodeUniformsInt, GL_INT_VEC3, 3, 1, 4 * 3); |
1618 | ADD_UNIFORM_ENTRY(fragCodeUniformsInt, GL_INT_VEC4, 4, 1, 4 * 4); |
1619 | |
1620 | ADD_UNIFORM_ENTRY(fragCodeUniformsUInt, GL_UNSIGNED_INT, 1, 1, 4); |
1621 | ADD_UNIFORM_ENTRY(fragCodeUniformsUInt, GL_UNSIGNED_INT_VEC2, 2, 1, 4 * 2); |
1622 | ADD_UNIFORM_ENTRY(fragCodeUniformsUInt, GL_UNSIGNED_INT_VEC3, 3, 1, 4 * 3); |
1623 | ADD_UNIFORM_ENTRY(fragCodeUniformsUInt, GL_UNSIGNED_INT_VEC4, 4, 1, 4 * 4); |
1624 | |
1625 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT2, 1, 1, 4 * 2 * 2); |
1626 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT2x3, 2, 1, 4 * 2 * 3); |
1627 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT3x2, 3, 1, 4 * 3 * 2); |
1628 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT2x4, 4, 1, 4 * 2 * 4); |
1629 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT4x2, 5, 1, 4 * 4 * 2); |
1630 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT3, 6, 1, 4 * 3 * 3); |
1631 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT3x4, 7, 1, 4 * 3 * 4); |
1632 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT4x3, 8, 1, 4 * 4 * 3); |
1633 | ADD_UNIFORM_ENTRY(fragCodeUniformsFloatMatrices, GL_FLOAT_MAT4, 9, 1, 4 * 4 * 4); |
1634 | |
1635 | ADD_UNIFORM_ENTRY(fragCodeSamplers, GL_SAMPLER_1D, 1, 1, 4); |
1636 | ADD_UNIFORM_ENTRY(fragCodeSamplers, GL_SAMPLER_2D, 2, 1, 4); |
1637 | ADD_UNIFORM_ENTRY(fragCodeSamplers, GL_SAMPLER_2D_ARRAY, 3, 1, 4); |
1638 | ADD_UNIFORM_ENTRY(fragCodeSamplers, GL_SAMPLER_3D, 4, 1, 4); |
1639 | ADD_UNIFORM_ENTRY(fragCodeSamplers, GL_SAMPLER_CUBE, 5, 1, 4); |
1640 | ADD_UNIFORM_ENTRY(fragCodeSamplers, GL_SAMPLER_2D_RECT, 6, 1, 4); |
1641 | |
1642 | ADD_UNIFORM_ENTRY(fragCodeImages, GL_IMAGE_1D, 1, 1, 4); |
1643 | ADD_UNIFORM_ENTRY(fragCodeImages, GL_IMAGE_2D, 2, 1, 4); |
1644 | ADD_UNIFORM_ENTRY(fragCodeImages, GL_IMAGE_2D_ARRAY, 3, 1, 4); |
1645 | ADD_UNIFORM_ENTRY(fragCodeImages, GL_IMAGE_3D, 4, 1, 4); |
1646 | ADD_UNIFORM_ENTRY(fragCodeImages, GL_IMAGE_CUBE, 5, 1, 4); |
1647 | ADD_UNIFORM_ENTRY(fragCodeImages, GL_IMAGE_2D_RECT, 6, 1, 4); |
1648 | } |
1649 | |
1650 | void uniformsByteSize() |
1651 | { |
1652 | if (!m_initializationSuccessful) |
1653 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1654 | |
1655 | // GIVEN |
1656 | QFETCH(QByteArray, fragShader); |
1657 | QFETCH(int, type); |
1658 | QFETCH(int, location); |
1659 | QFETCH(int, componentSize); |
1660 | QFETCH(int, expectedByteSize); |
1661 | |
1662 | QOpenGLShaderProgram shaderProgram; |
1663 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
1664 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragShader); |
1665 | QVERIFY(shaderProgram.link()); |
1666 | |
1667 | // WHEN |
1668 | const QVector<ShaderUniform> activeUniforms = m_glHelper.programUniformsAndLocations(programId: shaderProgram.programId()); |
1669 | ShaderUniform matchingUniform; |
1670 | for (const ShaderUniform &u : activeUniforms) { |
1671 | if (u.m_location == location) { |
1672 | matchingUniform = u; |
1673 | break; |
1674 | } |
1675 | } |
1676 | |
1677 | // THEN |
1678 | QCOMPARE(matchingUniform.m_location, location); |
1679 | QCOMPARE(matchingUniform.m_type, GLuint(type)); |
1680 | QCOMPARE(matchingUniform.m_size, componentSize); |
1681 | |
1682 | // WHEN |
1683 | const int computedRawByteSize = m_glHelper.uniformByteSize(description: matchingUniform); |
1684 | |
1685 | // THEN |
1686 | QCOMPARE(expectedByteSize, computedRawByteSize); |
1687 | |
1688 | // Restore |
1689 | m_func->glUseProgram(program: 0); |
1690 | } |
1691 | |
1692 | void useProgram() |
1693 | { |
1694 | if (!m_initializationSuccessful) |
1695 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1696 | |
1697 | // GIVEN |
1698 | QOpenGLShaderProgram shaderProgram; |
1699 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
1700 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeFragOutputs); |
1701 | |
1702 | // THEN |
1703 | QVERIFY(shaderProgram.link()); |
1704 | |
1705 | GLint currentProg = 0; |
1706 | m_func->glGetIntegerv(GL_CURRENT_PROGRAM, params: ¤tProg); |
1707 | QVERIFY(currentProg == 0); |
1708 | |
1709 | // WHEN |
1710 | m_glHelper.useProgram(programId: shaderProgram.programId()); |
1711 | |
1712 | // THEN |
1713 | m_func->glGetIntegerv(GL_CURRENT_PROGRAM, params: ¤tProg); |
1714 | QCOMPARE(GLuint(currentProg), shaderProgram.programId()); |
1715 | |
1716 | // WHEN |
1717 | m_glHelper.useProgram(programId: 0); |
1718 | |
1719 | // THEN |
1720 | m_func->glGetIntegerv(GL_CURRENT_PROGRAM, params: ¤tProg); |
1721 | QVERIFY(currentProg == 0); |
1722 | } |
1723 | |
1724 | void vertexAttribDivisor() |
1725 | { |
1726 | if (!m_initializationSuccessful) |
1727 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1728 | } |
1729 | |
1730 | void vertexAttributePointer() |
1731 | { |
1732 | if (!m_initializationSuccessful) |
1733 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1734 | |
1735 | // GIVEN |
1736 | QOpenGLVertexArrayObject vao; |
1737 | vao.create(); |
1738 | QOpenGLVertexArrayObject::Binder binder(&vao); |
1739 | |
1740 | QOpenGLShaderProgram shaderProgram; |
1741 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCodeUniformBuffer); |
1742 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformBuffer); |
1743 | QVERIFY(shaderProgram.link()); |
1744 | |
1745 | GLint positionLocation = m_func->glGetAttribLocation(program: shaderProgram.programId(), name: "vertexPosition" ); |
1746 | GLint texCoordLocation = m_func->glGetAttribLocation(program: shaderProgram.programId(), name: "vertexTexCoord" ); |
1747 | GLint colorIndexLocation = m_func->glGetAttribLocation(program: shaderProgram.programId(), name: "vertexColorIndex" ); |
1748 | GLint texCoordScaleLocation = m_func->glGetAttribLocation(program: shaderProgram.programId(), name: "vertexTexCoordScale" ); |
1749 | |
1750 | const int vertexCount = 99; |
1751 | QOpenGLBuffer positionBuffer(QOpenGLBuffer::VertexBuffer); |
1752 | positionBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw); |
1753 | positionBuffer.create(); |
1754 | positionBuffer.bind(); |
1755 | positionBuffer.allocate(count: vertexCount * sizeof(QVector3D)); |
1756 | |
1757 | QOpenGLBuffer texCoordBuffer(QOpenGLBuffer::VertexBuffer); |
1758 | texCoordBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw); |
1759 | texCoordBuffer.create(); |
1760 | texCoordBuffer.allocate(count: vertexCount * sizeof(QVector2D)); |
1761 | |
1762 | QOpenGLBuffer colorIndexBuffer(QOpenGLBuffer::VertexBuffer); |
1763 | colorIndexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw); |
1764 | colorIndexBuffer.create(); |
1765 | colorIndexBuffer.allocate(count: vertexCount * sizeof(int)); |
1766 | |
1767 | QOpenGLBuffer scaleBuffer(QOpenGLBuffer::VertexBuffer); |
1768 | scaleBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw); |
1769 | scaleBuffer.create(); |
1770 | scaleBuffer.allocate(count: vertexCount * sizeof(double)); |
1771 | |
1772 | // WHEN |
1773 | shaderProgram.bind(); |
1774 | positionBuffer.bind(); |
1775 | m_glHelper.enableVertexAttributeArray(location: positionLocation); |
1776 | m_glHelper.vertexAttributePointer(GL_FLOAT_VEC3, index: positionLocation, size: 3, GL_FLOAT, GL_TRUE, stride: 0, pointer: 0); |
1777 | |
1778 | texCoordBuffer.bind(); |
1779 | m_glHelper.enableVertexAttributeArray(location: texCoordLocation); |
1780 | m_glHelper.vertexAttributePointer(GL_FLOAT_VEC2, index: texCoordLocation, size: 2, GL_FLOAT, GL_TRUE, stride: 0, pointer: 0); |
1781 | |
1782 | colorIndexBuffer.bind(); |
1783 | m_glHelper.enableVertexAttributeArray(location: colorIndexLocation); |
1784 | m_glHelper.vertexAttributePointer(GL_INT, index: colorIndexLocation, size: 1, GL_INT, GL_TRUE, stride: 0, pointer: 0); |
1785 | |
1786 | scaleBuffer.bind(); |
1787 | m_glHelper.enableVertexAttributeArray(location: colorIndexLocation); |
1788 | m_glHelper.vertexAttributePointer(GL_DOUBLE, index: texCoordScaleLocation, size: 1, GL_DOUBLE, GL_TRUE, stride: 0, pointer: 0); |
1789 | |
1790 | // THEN |
1791 | const GLint error = m_func->glGetError(); |
1792 | QVERIFY(error == 0); |
1793 | } |
1794 | |
1795 | void glUniform1fv() |
1796 | { |
1797 | if (!m_initializationSuccessful) |
1798 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1799 | |
1800 | // GIVEN |
1801 | QOpenGLShaderProgram shaderProgram; |
1802 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
1803 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloat); |
1804 | QVERIFY(shaderProgram.link()); |
1805 | |
1806 | // WHEN |
1807 | m_func->glUseProgram(program: shaderProgram.programId()); |
1808 | GLfloat value = 883.0f; |
1809 | m_glHelper.glUniform1fv(location: 1, count: 1, value: &value); |
1810 | |
1811 | // THEN |
1812 | GLfloat setValue = 0.0f; |
1813 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 1, params: &setValue); |
1814 | QCOMPARE(value, setValue); |
1815 | |
1816 | // Restore |
1817 | m_func->glUseProgram(program: 0); |
1818 | } |
1819 | |
1820 | void glUniform2fv() |
1821 | { |
1822 | if (!m_initializationSuccessful) |
1823 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1824 | |
1825 | // GIVEN |
1826 | QOpenGLShaderProgram shaderProgram; |
1827 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
1828 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloat); |
1829 | QVERIFY(shaderProgram.link()); |
1830 | |
1831 | // WHEN |
1832 | m_func->glUseProgram(program: shaderProgram.programId()); |
1833 | GLfloat values[2] = { 383.0f, 427.0f }; |
1834 | m_glHelper.glUniform2fv(location: 2, count: 1, value: values); |
1835 | |
1836 | // THEN |
1837 | GLfloat setValues[2] = { 0.0f, 0.0f }; |
1838 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 2, params: setValues); |
1839 | for (int i = 0; i < 2; ++i) |
1840 | QCOMPARE(setValues[i], values[i]); |
1841 | |
1842 | // Restore |
1843 | m_func->glUseProgram(program: 0); |
1844 | } |
1845 | |
1846 | void glUniform3fv() |
1847 | { |
1848 | if (!m_initializationSuccessful) |
1849 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1850 | |
1851 | // GIVEN |
1852 | QOpenGLShaderProgram shaderProgram; |
1853 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
1854 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloat); |
1855 | QVERIFY(shaderProgram.link()); |
1856 | |
1857 | // WHEN |
1858 | m_func->glUseProgram(program: shaderProgram.programId()); |
1859 | GLfloat values[3] = { 572.0f, 1340.0f, 1584.0f }; |
1860 | m_glHelper.glUniform3fv(location: 3, count: 1, value: values); |
1861 | |
1862 | // THEN |
1863 | GLfloat setValues[3] = { 0.0f, 0.0f, 0.0f }; |
1864 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 3, params: setValues); |
1865 | for (int i = 0; i < 3; ++i) |
1866 | QCOMPARE(setValues[i], values[i]); |
1867 | |
1868 | // Restore |
1869 | m_func->glUseProgram(program: 0); |
1870 | } |
1871 | |
1872 | void glUniform4fv() |
1873 | { |
1874 | if (!m_initializationSuccessful) |
1875 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1876 | |
1877 | // GIVEN |
1878 | QOpenGLShaderProgram shaderProgram; |
1879 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
1880 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloat); |
1881 | QVERIFY(shaderProgram.link()); |
1882 | |
1883 | // WHEN |
1884 | m_func->glUseProgram(program: shaderProgram.programId()); |
1885 | GLfloat values[4] = { 454.0f, 350.0f, 883.0f, 355.0f }; |
1886 | m_glHelper.glUniform4fv(location: 4, count: 1, value: values); |
1887 | |
1888 | // THEN |
1889 | GLfloat setValues[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; |
1890 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 4, params: setValues); |
1891 | for (int i = 0; i < 4; ++i) |
1892 | QCOMPARE(setValues[i], values[i]); |
1893 | |
1894 | // Restore |
1895 | m_func->glUseProgram(program: 0); |
1896 | } |
1897 | |
1898 | void glUniform1iv() |
1899 | { |
1900 | if (!m_initializationSuccessful) |
1901 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1902 | |
1903 | // GIVEN |
1904 | QOpenGLShaderProgram shaderProgram; |
1905 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
1906 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsInt); |
1907 | QVERIFY(shaderProgram.link()); |
1908 | |
1909 | // WHEN |
1910 | m_func->glUseProgram(program: shaderProgram.programId()); |
1911 | GLint value = 883; |
1912 | m_glHelper.glUniform1iv(location: 1, count: 1, value: &value); |
1913 | |
1914 | // THEN |
1915 | GLint setValue = 0; |
1916 | m_func->glGetUniformiv(program: shaderProgram.programId(), location: 1, params: &setValue); |
1917 | QCOMPARE(value, setValue); |
1918 | |
1919 | // Restore |
1920 | m_func->glUseProgram(program: 0); |
1921 | } |
1922 | |
1923 | void glUniform2iv() |
1924 | { |
1925 | if (!m_initializationSuccessful) |
1926 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1927 | |
1928 | // GIVEN |
1929 | QOpenGLShaderProgram shaderProgram; |
1930 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
1931 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsInt); |
1932 | QVERIFY(shaderProgram.link()); |
1933 | |
1934 | // WHEN |
1935 | m_func->glUseProgram(program: shaderProgram.programId()); |
1936 | GLint values[2] = { 383, 427 }; |
1937 | m_glHelper.glUniform2iv(location: 2, count: 1, value: values); |
1938 | |
1939 | // THEN |
1940 | GLint setValues[2] = { 0, 0 }; |
1941 | m_func->glGetUniformiv(program: shaderProgram.programId(), location: 2, params: setValues); |
1942 | for (int i = 0; i < 2; ++i) |
1943 | QCOMPARE(values[i], setValues[i]); |
1944 | |
1945 | // Restore |
1946 | m_func->glUseProgram(program: 0); |
1947 | } |
1948 | |
1949 | void glUniform3iv() |
1950 | { |
1951 | if (!m_initializationSuccessful) |
1952 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1953 | |
1954 | // GIVEN |
1955 | QOpenGLShaderProgram shaderProgram; |
1956 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
1957 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsInt); |
1958 | QVERIFY(shaderProgram.link()); |
1959 | |
1960 | // WHEN |
1961 | m_func->glUseProgram(program: shaderProgram.programId()); |
1962 | GLint values[3] = { 572, 1340, 1584 }; |
1963 | m_glHelper.glUniform3iv(location: 3, count: 1, value: values); |
1964 | |
1965 | // THEN |
1966 | GLint setValues[3] = { 0, 0, 0 }; |
1967 | m_func->glGetUniformiv(program: shaderProgram.programId(), location: 3, params: setValues); |
1968 | for (int i = 0; i < 3; ++i) |
1969 | QCOMPARE(values[i], setValues[i]); |
1970 | |
1971 | // Restore |
1972 | m_func->glUseProgram(program: 0); |
1973 | } |
1974 | |
1975 | void glUniform4iv() |
1976 | { |
1977 | if (!m_initializationSuccessful) |
1978 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
1979 | |
1980 | // GIVEN |
1981 | QOpenGLShaderProgram shaderProgram; |
1982 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
1983 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsInt); |
1984 | QVERIFY(shaderProgram.link()); |
1985 | |
1986 | // WHEN |
1987 | m_func->glUseProgram(program: shaderProgram.programId()); |
1988 | GLint values[4] = { 454, 350, 883, 355 }; |
1989 | m_glHelper.glUniform4iv(location: 4, count: 1, value: values); |
1990 | |
1991 | // THEN |
1992 | GLint setValues[4] = { 0, 0, 0, 0 }; |
1993 | m_func->glGetUniformiv(program: shaderProgram.programId(), location: 4, params: setValues); |
1994 | for (int i = 0; i < 4; ++i) |
1995 | QCOMPARE(values[i], setValues[i]); |
1996 | |
1997 | // Restore |
1998 | m_func->glUseProgram(program: 0); |
1999 | } |
2000 | |
2001 | void glUniform1uiv() |
2002 | { |
2003 | if (!m_initializationSuccessful) |
2004 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2005 | |
2006 | // GIVEN |
2007 | QOpenGLShaderProgram shaderProgram; |
2008 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2009 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsUInt); |
2010 | QVERIFY(shaderProgram.link()); |
2011 | |
2012 | // WHEN |
2013 | m_func->glUseProgram(program: shaderProgram.programId()); |
2014 | GLuint value = 883U; |
2015 | m_glHelper.glUniform1uiv(location: 1, count: 1, value: &value); |
2016 | |
2017 | // THEN |
2018 | GLuint setValue = 0U; |
2019 | m_func->glGetUniformuiv(program: shaderProgram.programId(), location: 1, params: &setValue); |
2020 | QCOMPARE(value, setValue); |
2021 | |
2022 | // Restore |
2023 | m_func->glUseProgram(program: 0); |
2024 | } |
2025 | |
2026 | void glUniform2uiv() |
2027 | { |
2028 | if (!m_initializationSuccessful) |
2029 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2030 | |
2031 | // GIVEN |
2032 | QOpenGLShaderProgram shaderProgram; |
2033 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2034 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsUInt); |
2035 | QVERIFY(shaderProgram.link()); |
2036 | |
2037 | // WHEN |
2038 | m_func->glUseProgram(program: shaderProgram.programId()); |
2039 | GLuint values[2] = { 383U, 427U }; |
2040 | m_glHelper.glUniform2uiv(location: 2, count: 1, value: values); |
2041 | |
2042 | // THEN |
2043 | GLuint setValues[2] = { 0U, 0U }; |
2044 | m_func->glGetUniformuiv(program: shaderProgram.programId(), location: 2, params: setValues); |
2045 | for (int i = 0; i < 2; ++i) |
2046 | QCOMPARE(values[i], setValues[i]); |
2047 | |
2048 | // Restore |
2049 | m_func->glUseProgram(program: 0); |
2050 | } |
2051 | |
2052 | void glUniform3uiv() |
2053 | { |
2054 | if (!m_initializationSuccessful) |
2055 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2056 | |
2057 | // GIVEN |
2058 | QOpenGLShaderProgram shaderProgram; |
2059 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2060 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsUInt); |
2061 | QVERIFY(shaderProgram.link()); |
2062 | |
2063 | // WHEN |
2064 | m_func->glUseProgram(program: shaderProgram.programId()); |
2065 | GLuint values[3] = { 572U, 1340U, 1584U }; |
2066 | m_glHelper.glUniform3uiv(location: 3, count: 1, value: values); |
2067 | |
2068 | // THEN |
2069 | GLuint setValues[3] = { 0U, 0U, 0U }; |
2070 | m_func->glGetUniformuiv(program: shaderProgram.programId(), location: 3, params: setValues); |
2071 | for (int i = 0; i < 3; ++i) |
2072 | QCOMPARE(values[i], setValues[i]); |
2073 | |
2074 | // Restore |
2075 | m_func->glUseProgram(program: 0); |
2076 | } |
2077 | |
2078 | void glUniform4uiv() |
2079 | { |
2080 | if (!m_initializationSuccessful) |
2081 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2082 | |
2083 | // GIVEN |
2084 | QOpenGLShaderProgram shaderProgram; |
2085 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2086 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsUInt); |
2087 | QVERIFY(shaderProgram.link()); |
2088 | |
2089 | // WHEN |
2090 | m_func->glUseProgram(program: shaderProgram.programId()); |
2091 | GLuint values[4] = { 454U, 350U, 883U, 355U }; |
2092 | m_glHelper.glUniform4uiv(location: 4, count: 1, value: values); |
2093 | |
2094 | // THEN |
2095 | GLuint setValues[4] = { 0U, 0U, 0U, 0U }; |
2096 | m_func->glGetUniformuiv(program: shaderProgram.programId(), location: 4, params: setValues); |
2097 | for (int i = 0; i < 4; ++i) |
2098 | QCOMPARE(values[i], setValues[i]); |
2099 | |
2100 | // Restore |
2101 | m_func->glUseProgram(program: 0); |
2102 | } |
2103 | |
2104 | void glUniformMatrix2fv() |
2105 | { |
2106 | if (!m_initializationSuccessful) |
2107 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2108 | |
2109 | // GIVEN |
2110 | QOpenGLShaderProgram shaderProgram; |
2111 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2112 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloatMatrices); |
2113 | QVERIFY(shaderProgram.link()); |
2114 | |
2115 | // WHEN |
2116 | m_func->glUseProgram(program: shaderProgram.programId()); |
2117 | GLfloat values[4] = { 454.0f, 350.0f, 883.0f, 355.0f }; |
2118 | m_glHelper.glUniformMatrix2fv(location: 1, count: 1, value: values); |
2119 | |
2120 | // THEN |
2121 | GLfloat setValues[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; |
2122 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 1, params: setValues); |
2123 | for (int i = 0; i < 4; ++i) |
2124 | QCOMPARE(values[i], setValues[i]); |
2125 | |
2126 | // Restore |
2127 | m_func->glUseProgram(program: 0); |
2128 | } |
2129 | |
2130 | void glUniformMatrix3fv() |
2131 | { |
2132 | if (!m_initializationSuccessful) |
2133 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2134 | |
2135 | // GIVEN |
2136 | QOpenGLShaderProgram shaderProgram; |
2137 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2138 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloatMatrices); |
2139 | QVERIFY(shaderProgram.link()); |
2140 | |
2141 | // WHEN |
2142 | m_func->glUseProgram(program: shaderProgram.programId()); |
2143 | GLfloat values[9] = { 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f, 1200.0f, 427.0f, 396.0f }; |
2144 | m_glHelper.glUniformMatrix3fv(location: 6, count: 1, value: values); |
2145 | |
2146 | // THEN |
2147 | GLfloat setValues[9] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; |
2148 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 6, params: setValues); |
2149 | for (int i = 0; i < 9; ++i) |
2150 | QCOMPARE(values[i], setValues[i]); |
2151 | |
2152 | // Restore |
2153 | m_func->glUseProgram(program: 0); |
2154 | } |
2155 | |
2156 | void glUniformMatrix4fv() |
2157 | { |
2158 | if (!m_initializationSuccessful) |
2159 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2160 | |
2161 | // GIVEN |
2162 | QOpenGLShaderProgram shaderProgram; |
2163 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2164 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloatMatrices); |
2165 | QVERIFY(shaderProgram.link()); |
2166 | |
2167 | // WHEN |
2168 | m_func->glUseProgram(program: shaderProgram.programId()); |
2169 | GLfloat values[16] = { 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f, 1200.0f, 427.0f, 396.0f, 1603.0f, 55.0f, 5.7f, 383.0f, 6.2f, 5.3f, 327.0f }; |
2170 | m_glHelper.glUniformMatrix4fv(location: 9, count: 1, value: values); |
2171 | |
2172 | // THEN |
2173 | GLfloat setValues[16] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; |
2174 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 9, params: setValues); |
2175 | for (int i = 0; i < 16; ++i) |
2176 | QCOMPARE(values[i], setValues[i]); |
2177 | |
2178 | // Restore |
2179 | m_func->glUseProgram(program: 0); |
2180 | } |
2181 | |
2182 | void glUniformMatrix2x3fv() |
2183 | { |
2184 | if (!m_initializationSuccessful) |
2185 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2186 | |
2187 | // GIVEN |
2188 | QOpenGLShaderProgram shaderProgram; |
2189 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2190 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloatMatrices); |
2191 | QVERIFY(shaderProgram.link()); |
2192 | |
2193 | // WHEN |
2194 | m_func->glUseProgram(program: shaderProgram.programId()); |
2195 | GLfloat values[6] = { 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f}; |
2196 | m_glHelper.glUniformMatrix2x3fv(location: 2, count: 1, value: values); |
2197 | |
2198 | // THEN |
2199 | GLfloat setValues[6] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; |
2200 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 2, params: setValues); |
2201 | for (int i = 0; i < 6; ++i) |
2202 | QCOMPARE(values[i], setValues[i]); |
2203 | |
2204 | // Restore |
2205 | m_func->glUseProgram(program: 0); |
2206 | } |
2207 | |
2208 | void glUniformMatrix3x2fv() |
2209 | { |
2210 | if (!m_initializationSuccessful) |
2211 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2212 | |
2213 | // GIVEN |
2214 | QOpenGLShaderProgram shaderProgram; |
2215 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2216 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloatMatrices); |
2217 | QVERIFY(shaderProgram.link()); |
2218 | |
2219 | // WHEN |
2220 | m_func->glUseProgram(program: shaderProgram.programId()); |
2221 | GLfloat values[6] = { 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f}; |
2222 | m_glHelper.glUniformMatrix3x2fv(location: 3, count: 1, value: values); |
2223 | |
2224 | // THEN |
2225 | GLfloat setValues[6] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; |
2226 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 3, params: setValues); |
2227 | for (int i = 0; i < 6; ++i) |
2228 | QCOMPARE(values[i], setValues[i]); |
2229 | |
2230 | // Restore |
2231 | m_func->glUseProgram(program: 0); |
2232 | } |
2233 | |
2234 | void glUniformMatrix2x4fv() |
2235 | { |
2236 | if (!m_initializationSuccessful) |
2237 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2238 | |
2239 | // GIVEN |
2240 | QOpenGLShaderProgram shaderProgram; |
2241 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2242 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloatMatrices); |
2243 | QVERIFY(shaderProgram.link()); |
2244 | |
2245 | // WHEN |
2246 | m_func->glUseProgram(program: shaderProgram.programId()); |
2247 | GLfloat values[8] = { 383.0f, 427.0f, 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f}; |
2248 | m_glHelper.glUniformMatrix2x4fv(location: 4, count: 1, value: values); |
2249 | |
2250 | // THEN |
2251 | GLfloat setValues[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; |
2252 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 4, params: setValues); |
2253 | for (int i = 0; i < 8; ++i) |
2254 | QCOMPARE(values[i], setValues[i]); |
2255 | |
2256 | // Restore |
2257 | m_func->glUseProgram(program: 0); |
2258 | } |
2259 | |
2260 | void glUniformMatrix4x2fv() |
2261 | { |
2262 | if (!m_initializationSuccessful) |
2263 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2264 | |
2265 | // GIVEN |
2266 | QOpenGLShaderProgram shaderProgram; |
2267 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2268 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloatMatrices); |
2269 | QVERIFY(shaderProgram.link()); |
2270 | |
2271 | // WHEN |
2272 | m_func->glUseProgram(program: shaderProgram.programId()); |
2273 | GLfloat values[8] = { 383.0f, 427.0f, 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f}; |
2274 | m_glHelper.glUniformMatrix4x2fv(location: 5, count: 1, value: values); |
2275 | |
2276 | // THEN |
2277 | GLfloat setValues[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; |
2278 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 5, params: setValues); |
2279 | for (int i = 0; i < 8; ++i) |
2280 | QCOMPARE(values[i], setValues[i]); |
2281 | |
2282 | // Restore |
2283 | m_func->glUseProgram(program: 0); |
2284 | } |
2285 | |
2286 | void glUniformMatrix3x4fv() |
2287 | { |
2288 | if (!m_initializationSuccessful) |
2289 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2290 | |
2291 | // GIVEN |
2292 | QOpenGLShaderProgram shaderProgram; |
2293 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2294 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloatMatrices); |
2295 | QVERIFY(shaderProgram.link()); |
2296 | |
2297 | // WHEN |
2298 | m_func->glUseProgram(program: shaderProgram.programId()); |
2299 | GLfloat values[12] = { 55.0f, 5.7f, 383.0f, 6.2f, 5.3f, 383.0f, 427.0f, 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f,}; |
2300 | m_glHelper.glUniformMatrix3x4fv(location: 7, count: 1, value: values); |
2301 | |
2302 | // THEN |
2303 | GLfloat setValues[12] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; |
2304 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 7, params: setValues); |
2305 | for (int i = 0; i < 12; ++i) |
2306 | QCOMPARE(values[i], setValues[i]); |
2307 | |
2308 | // Restore |
2309 | m_func->glUseProgram(program: 0); |
2310 | } |
2311 | |
2312 | void glUniformMatrix4x3fv() |
2313 | { |
2314 | if (!m_initializationSuccessful) |
2315 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2316 | |
2317 | // GIVEN |
2318 | QOpenGLShaderProgram shaderProgram; |
2319 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Vertex, source: vertCode); |
2320 | shaderProgram.addShaderFromSourceCode(type: QOpenGLShader::Fragment, source: fragCodeUniformsFloatMatrices); |
2321 | QVERIFY(shaderProgram.link()); |
2322 | |
2323 | // WHEN |
2324 | m_func->glUseProgram(program: shaderProgram.programId()); |
2325 | GLfloat values[12] = { 55.0f, 5.7f, 383.0f, 6.2f, 383.0f, 427.0f, 454.0f, 350.0f, 883.0f, 355.0f, 1340.0f, 1584.0f}; |
2326 | m_glHelper.glUniformMatrix4x3fv(location: 8, count: 1, value: values); |
2327 | |
2328 | // THEN |
2329 | GLfloat setValues[12] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; |
2330 | m_func->glGetUniformfv(program: shaderProgram.programId(), location: 8, params: setValues); |
2331 | for (int i = 0; i < 12; ++i) |
2332 | QCOMPARE(values[i], setValues[i]); |
2333 | |
2334 | // Restore |
2335 | m_func->glUseProgram(program: 0); |
2336 | } |
2337 | |
2338 | |
2339 | void blitFramebuffer() |
2340 | { |
2341 | if (!m_initializationSuccessful) |
2342 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2343 | |
2344 | // GIVEN |
2345 | GLuint fbos[2]; |
2346 | GLuint fboTextures[2]; |
2347 | |
2348 | m_func->glGenFramebuffers(n: 2, framebuffers: fbos); |
2349 | m_func->glGenTextures(n: 2, textures: fboTextures); |
2350 | |
2351 | m_func->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture: fboTextures[0]); |
2352 | m_func->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples: 4, GL_RGBA8, width: 10, height: 10, fixedsamplelocations: true); |
2353 | m_func->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture: 0); |
2354 | |
2355 | m_func->glBindTexture(GL_TEXTURE_2D, texture: fboTextures[1]); |
2356 | m_func->glTexImage2D(GL_TEXTURE_2D, level: 0, GL_RGBA8, width: 10, height: 10, border: 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels: nullptr); |
2357 | m_func->glBindTexture(GL_TEXTURE_2D, texture: 0); |
2358 | |
2359 | m_func->glBindFramebuffer(GL_FRAMEBUFFER, framebuffer: fbos[1]); |
2360 | m_func->glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture: fboTextures[1], level: 0); |
2361 | |
2362 | GLenum status = m_func->glCheckFramebufferStatus(GL_FRAMEBUFFER); |
2363 | QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); |
2364 | |
2365 | m_func->glBindFramebuffer(GL_FRAMEBUFFER, framebuffer: fbos[0]); |
2366 | m_func->glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture: fboTextures[0], level: 0); |
2367 | |
2368 | status = m_func->glCheckFramebufferStatus(GL_FRAMEBUFFER); |
2369 | QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); |
2370 | |
2371 | m_func->glEnable(GL_MULTISAMPLE); |
2372 | m_func->glClearColor(red: 0.2f, green: 0.2f, blue: 0.2f, alpha: 0.2f); |
2373 | m_func->glClear(GL_COLOR_BUFFER_BIT); |
2374 | m_func->glDisable(GL_MULTISAMPLE); |
2375 | |
2376 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: fbos[1]); |
2377 | |
2378 | // WHEN |
2379 | m_glHelper.blitFramebuffer(srcX0: 0,srcY0: 0,srcX1: 10,srcY1: 10,dstX0: 0,dstY0: 0,dstX1: 10,dstY1: 10, GL_COLOR_BUFFER_BIT, GL_NEAREST); |
2380 | |
2381 | m_func->glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer: fbos[1]); |
2382 | |
2383 | GLuint result[10*10]; |
2384 | m_func->glReadPixels(x: 0,y: 0,width: 10,height: 10,GL_RGBA, GL_UNSIGNED_BYTE, pixels: result); |
2385 | |
2386 | // THEN |
2387 | GLuint v = (0.2f) * 255; |
2388 | v = v | (v<<8) | (v<<16) | (v<<24); |
2389 | for (GLuint value : result) { |
2390 | QCOMPARE(value, v); |
2391 | } |
2392 | m_func->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: 0); |
2393 | m_func->glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer: 0); |
2394 | |
2395 | m_func->glDeleteFramebuffers(n: 2, framebuffers: fbos); |
2396 | m_func->glDeleteTextures(n: 2, textures: fboTextures); |
2397 | } |
2398 | |
2399 | #define ADD_GL_TYPE_ENTRY(Type, Expected) \ |
2400 | QTest::newRow(#Type) << Type << Expected; |
2401 | |
2402 | void uniformTypeFromGLType_data() |
2403 | { |
2404 | QTest::addColumn<int>(name: "glType" ); |
2405 | QTest::addColumn<UniformType>(name: "expected" ); |
2406 | |
2407 | ADD_GL_TYPE_ENTRY(GL_FLOAT, UniformType::Float); |
2408 | ADD_GL_TYPE_ENTRY(GL_FLOAT_VEC2, UniformType::Vec2); |
2409 | ADD_GL_TYPE_ENTRY(GL_FLOAT_VEC3, UniformType::Vec3); |
2410 | ADD_GL_TYPE_ENTRY(GL_FLOAT_VEC3, UniformType::Vec3); |
2411 | ADD_GL_TYPE_ENTRY(GL_FLOAT_VEC2, UniformType::Vec2); |
2412 | ADD_GL_TYPE_ENTRY(GL_FLOAT_VEC3, UniformType::Vec3); |
2413 | ADD_GL_TYPE_ENTRY(GL_FLOAT_VEC3, UniformType::Vec3); |
2414 | ADD_GL_TYPE_ENTRY(GL_INT, UniformType::Int); |
2415 | ADD_GL_TYPE_ENTRY(GL_INT_VEC2, UniformType::IVec2); |
2416 | ADD_GL_TYPE_ENTRY(GL_INT_VEC3, UniformType::IVec3); |
2417 | ADD_GL_TYPE_ENTRY(GL_INT_VEC4, UniformType::IVec4); |
2418 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT, UniformType::UInt); |
2419 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_VEC2, UniformType::UIVec2); |
2420 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_VEC3, UniformType::UIVec3); |
2421 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_VEC4, UniformType::UIVec4); |
2422 | ADD_GL_TYPE_ENTRY(GL_BOOL, UniformType::Bool); |
2423 | ADD_GL_TYPE_ENTRY(GL_BOOL_VEC2, UniformType::BVec2); |
2424 | ADD_GL_TYPE_ENTRY(GL_BOOL_VEC3, UniformType::BVec3); |
2425 | ADD_GL_TYPE_ENTRY(GL_BOOL_VEC4, UniformType::BVec4); |
2426 | ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT2, UniformType::Mat2); |
2427 | ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT3, UniformType::Mat3); |
2428 | ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT4, UniformType::Mat4); |
2429 | ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT2x3, UniformType::Mat2x3); |
2430 | ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT2x4, UniformType::Mat2x4); |
2431 | ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT3x2, UniformType::Mat3x2); |
2432 | ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT4x2, UniformType::Mat4x2); |
2433 | ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT4x3, UniformType::Mat4x3); |
2434 | ADD_GL_TYPE_ENTRY(GL_FLOAT_MAT3x4, UniformType::Mat3x4); |
2435 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_1D, UniformType::Sampler); |
2436 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_1D_ARRAY, UniformType::Sampler); |
2437 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_1D_SHADOW, UniformType::Sampler); |
2438 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D, UniformType::Sampler); |
2439 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D_ARRAY, UniformType::Sampler); |
2440 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D_RECT, UniformType::Sampler); |
2441 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D_MULTISAMPLE, UniformType::Sampler); |
2442 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D_MULTISAMPLE_ARRAY, UniformType::Sampler); |
2443 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D_SHADOW, UniformType::Sampler); |
2444 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_2D_ARRAY_SHADOW, UniformType::Sampler); |
2445 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_3D, UniformType::Sampler); |
2446 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_CUBE, UniformType::Sampler); |
2447 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_CUBE_SHADOW, UniformType::Sampler); |
2448 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_CUBE_MAP_ARRAY, UniformType::Sampler); |
2449 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW, UniformType::Sampler); |
2450 | ADD_GL_TYPE_ENTRY(GL_SAMPLER_BUFFER, UniformType::Sampler); |
2451 | ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_1D, UniformType::Sampler); |
2452 | ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_2D, UniformType::Sampler); |
2453 | ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_3D, UniformType::Sampler); |
2454 | ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_BUFFER, UniformType::Sampler); |
2455 | ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_2D_ARRAY, UniformType::Sampler); |
2456 | ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_2D_MULTISAMPLE, UniformType::Sampler); |
2457 | ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, UniformType::Sampler); |
2458 | ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_CUBE, UniformType::Sampler); |
2459 | ADD_GL_TYPE_ENTRY(GL_INT_SAMPLER_CUBE_MAP_ARRAY, UniformType::Sampler); |
2460 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_1D, UniformType::Sampler); |
2461 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_2D, UniformType::Sampler); |
2462 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_3D, UniformType::Sampler); |
2463 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_BUFFER, UniformType::Sampler); |
2464 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, UniformType::Sampler); |
2465 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, UniformType::Sampler); |
2466 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, UniformType::Sampler); |
2467 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_CUBE, UniformType::Sampler); |
2468 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY, UniformType::Sampler); |
2469 | ADD_GL_TYPE_ENTRY(GL_IMAGE_1D, UniformType::Image); |
2470 | ADD_GL_TYPE_ENTRY(GL_IMAGE_2D, UniformType::Image); |
2471 | ADD_GL_TYPE_ENTRY(GL_IMAGE_3D, UniformType::Image); |
2472 | ADD_GL_TYPE_ENTRY(GL_IMAGE_2D_RECT, UniformType::Image); |
2473 | ADD_GL_TYPE_ENTRY(GL_IMAGE_CUBE, UniformType::Image); |
2474 | ADD_GL_TYPE_ENTRY(GL_IMAGE_BUFFER, UniformType::Image); |
2475 | ADD_GL_TYPE_ENTRY(GL_IMAGE_1D_ARRAY, UniformType::Image); |
2476 | ADD_GL_TYPE_ENTRY(GL_IMAGE_2D_ARRAY, UniformType::Image); |
2477 | ADD_GL_TYPE_ENTRY(GL_IMAGE_CUBE_MAP_ARRAY, UniformType::Image); |
2478 | ADD_GL_TYPE_ENTRY(GL_IMAGE_2D_MULTISAMPLE, UniformType::Image); |
2479 | ADD_GL_TYPE_ENTRY(GL_IMAGE_2D_MULTISAMPLE_ARRAY, UniformType::Image); |
2480 | ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_1D, UniformType::Image); |
2481 | ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_2D, UniformType::Image); ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_3D, UniformType::Image); |
2482 | ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_2D_RECT, UniformType::Image); |
2483 | ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_CUBE, UniformType::Image); |
2484 | ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_BUFFER, UniformType::Image); |
2485 | ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_1D_ARRAY, UniformType::Image); |
2486 | ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_2D_ARRAY, UniformType::Image); |
2487 | ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_CUBE_MAP_ARRAY, UniformType::Image); |
2488 | ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_2D_MULTISAMPLE, UniformType::Image); |
2489 | ADD_GL_TYPE_ENTRY(GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY, UniformType::Image); |
2490 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_1D, UniformType::Image); |
2491 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_2D, UniformType::Image); |
2492 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_3D, UniformType::Image); |
2493 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_2D_RECT, UniformType::Image); |
2494 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_CUBE, UniformType::Image); |
2495 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_BUFFER, UniformType::Image); |
2496 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_1D_ARRAY, UniformType::Image); |
2497 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_2D_ARRAY, UniformType::Image); |
2498 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY, UniformType::Image); |
2499 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE, UniformType::Image); |
2500 | ADD_GL_TYPE_ENTRY(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY, UniformType::Image); |
2501 | } |
2502 | |
2503 | void uniformTypeFromGLType() |
2504 | { |
2505 | // GIVEN |
2506 | QFETCH(int, glType); |
2507 | QFETCH(UniformType, expected); |
2508 | |
2509 | // WHEN |
2510 | UniformType computed = m_glHelper.uniformTypeFromGLType(glType); |
2511 | |
2512 | // THEN |
2513 | QCOMPARE(computed, expected); |
2514 | } |
2515 | |
2516 | void drawBuffer() |
2517 | { |
2518 | if (!m_initializationSuccessful) |
2519 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2520 | |
2521 | m_func->glGetError(); |
2522 | |
2523 | // WHEN |
2524 | m_glHelper.drawBuffer(GL_FRONT); |
2525 | const GLint error = m_func->glGetError(); |
2526 | QVERIFY(error == 0); |
2527 | |
2528 | // THEN |
2529 | GLint p; |
2530 | m_func->glGetIntegerv(GL_DRAW_BUFFER, params: &p); |
2531 | QCOMPARE(p, GL_FRONT); |
2532 | } |
2533 | |
2534 | void readBuffer() |
2535 | { |
2536 | if (!m_initializationSuccessful) |
2537 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2538 | |
2539 | m_func->glGetError(); |
2540 | |
2541 | // WHEN |
2542 | m_glHelper.readBuffer(GL_FRONT); |
2543 | |
2544 | // THEN |
2545 | const GLint error = m_func->glGetError(); |
2546 | QVERIFY(error == 0); |
2547 | GLint p; |
2548 | m_func->glGetIntegerv(GL_READ_BUFFER, params: &p); |
2549 | QCOMPARE(p, GL_FRONT); |
2550 | } |
2551 | |
2552 | void fenceSync() |
2553 | { |
2554 | if (!m_initializationSuccessful) |
2555 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2556 | |
2557 | m_func->glGetError(); |
2558 | |
2559 | // WHEN |
2560 | GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync()); |
2561 | |
2562 | // THEN |
2563 | QVERIFY(sync != nullptr); |
2564 | QCOMPARE(m_func->glIsSync(sync), GL_TRUE); |
2565 | const GLint error = m_func->glGetError(); |
2566 | QVERIFY(error == 0); |
2567 | } |
2568 | |
2569 | void clientWaitSync() |
2570 | { |
2571 | if (!m_initializationSuccessful) |
2572 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2573 | |
2574 | m_func->glGetError(); |
2575 | |
2576 | // WHEN |
2577 | QElapsedTimer t; |
2578 | t.start(); |
2579 | |
2580 | GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync()); |
2581 | |
2582 | m_glHelper.clientWaitSync(sync, nanoSecTimeout: 1000000); |
2583 | |
2584 | // THEN |
2585 | const GLint error = m_func->glGetError(); |
2586 | QVERIFY(error == 0); |
2587 | qDebug() << t.nsecsElapsed(); |
2588 | } |
2589 | |
2590 | void waitSync() |
2591 | { |
2592 | if (!m_initializationSuccessful) |
2593 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2594 | |
2595 | m_func->glGetError(); |
2596 | |
2597 | // WHEN |
2598 | GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync()); |
2599 | m_func->glFlush(); |
2600 | m_glHelper.waitSync(sync); |
2601 | |
2602 | // THEN |
2603 | const GLint error = m_func->glGetError(); |
2604 | QVERIFY(error == 0); |
2605 | } |
2606 | |
2607 | void wasSyncSignaled() |
2608 | { |
2609 | if (!m_initializationSuccessful) |
2610 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2611 | |
2612 | m_func->glGetError(); |
2613 | |
2614 | // WHEN |
2615 | GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync()); |
2616 | m_func->glFlush(); |
2617 | m_glHelper.waitSync(sync); |
2618 | |
2619 | // THEN |
2620 | const GLint error = m_func->glGetError(); |
2621 | QVERIFY(error == 0); |
2622 | |
2623 | // Shouldn't loop forever |
2624 | while (!m_glHelper.wasSyncSignaled(sync)) |
2625 | ; |
2626 | } |
2627 | |
2628 | void deleteSync() |
2629 | { |
2630 | if (!m_initializationSuccessful) |
2631 | QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported" ); |
2632 | |
2633 | m_func->glGetError(); |
2634 | |
2635 | // WHEN |
2636 | GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync()); |
2637 | m_glHelper.clientWaitSync(sync, nanoSecTimeout: GLuint64(-1)); |
2638 | |
2639 | // THEN |
2640 | const GLint error = m_func->glGetError(); |
2641 | QVERIFY(error == 0); |
2642 | QVERIFY(m_glHelper.wasSyncSignaled(sync) == true); |
2643 | |
2644 | // WHEN |
2645 | m_glHelper.deleteSync(sync); |
2646 | |
2647 | // THEN |
2648 | QCOMPARE(m_func->glIsSync(sync), GL_FALSE); |
2649 | } |
2650 | |
2651 | void rasterMode() |
2652 | { |
2653 | if (!m_initializationSuccessful) |
2654 | QSKIP("Initialization failed, OpenGL 4.3 functions not supported" ); |
2655 | |
2656 | m_func->glGetError(); |
2657 | m_glHelper.rasterMode(GL_FRONT_AND_BACK, GL_LINE); |
2658 | |
2659 | // THEN |
2660 | const GLint error = m_func->glGetError(); |
2661 | QVERIFY(error == 0); |
2662 | GLint p; |
2663 | m_func->glGetIntegerv(GL_POLYGON_MODE, params: &p); |
2664 | QCOMPARE(p, GL_LINE); |
2665 | } |
2666 | |
2667 | private: |
2668 | QScopedPointer<QWindow> m_window; |
2669 | QOpenGLContext m_glContext; |
2670 | GraphicsHelperGL4 m_glHelper; |
2671 | QOpenGLFunctions_4_3_Core *m_func = nullptr; |
2672 | bool m_initializationSuccessful = false; |
2673 | }; |
2674 | |
2675 | #endif |
2676 | |
2677 | int main(int argc, char *argv[]) |
2678 | { |
2679 | #ifdef TEST_SHOULD_BE_PERFORMED |
2680 | QGuiApplication app(argc, argv); |
2681 | app.setAttribute(attribute: Qt::AA_Use96Dpi, on: true); |
2682 | tst_GraphicsHelperGL4 tc; |
2683 | QTEST_SET_MAIN_SOURCE_PATH |
2684 | return QTest::qExec(testObject: &tc, argc, argv); |
2685 | #endif |
2686 | return 0; |
2687 | } |
2688 | |
2689 | #ifdef TEST_SHOULD_BE_PERFORMED |
2690 | #include "tst_graphicshelpergl4.moc" |
2691 | #endif |
2692 | |