1/****************************************************************************
2**
3** Copyright (C) 2014 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:LGPL$
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 Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "graphicshelpergl4_p.h"
41
42#ifndef QT_OPENGL_ES_2
43#include <QOpenGLFunctions_4_3_Core>
44#include <QtOpenGLExtensions/qopenglextensions.h>
45#include <private/attachmentpack_p.h>
46#include <qgraphicsutils_p.h>
47#include <logging_p.h>
48
49# ifndef QT_OPENGL_4_3
50# ifndef GL_PATCH_VERTICES
51# define GL_PATCH_VERTICES 36466
52# endif
53# define GL_ACTIVE_RESOURCES 0x92F5
54# define GL_BUFFER_BINDING 0x9302
55# define GL_BUFFER_DATA_SIZE 0x9303
56# define GL_NUM_ACTIVE_VARIABLES 0x9304
57# define GL_SHADER_STORAGE_BLOCK 0x92E6
58# define GL_UNIFORM 0x92E1
59# define GL_UNIFORM_BLOCK 0x92E2
60# define GL_UNIFORM_BLOCK_INDEX 0x8A3A
61# define GL_UNIFORM_OFFSET 0x8A3B
62# define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
63# define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
64# define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
65# define GL_UNIFORM_BLOCK_BINDING 0x8A3F
66# define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
67# define GL_ALL_BARRIER_BITS 0xFFFFFFFF
68# define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
69# define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
70# define GL_UNIFORM_BARRIER_BIT 0x00000004
71# define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
72# define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
73# define GL_COMMAND_BARRIER_BIT 0x00000040
74# define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
75# define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
76# define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
77# define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
78# define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
79# define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
80# define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
81# define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000
82# define GL_IMAGE_1D 0x904C
83# define GL_IMAGE_2D 0x904D
84# define GL_IMAGE_3D 0x904E
85# define GL_IMAGE_2D_RECT 0x904F
86# define GL_IMAGE_CUBE 0x9050
87# define GL_IMAGE_BUFFER 0x9051
88# define GL_IMAGE_1D_ARRAY 0x9052
89# define GL_IMAGE_2D_ARRAY 0x9053
90# define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
91# define GL_IMAGE_2D_MULTISAMPLE 0x9055
92# define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056
93# define GL_INT_IMAGE_1D 0x9057
94# define GL_INT_IMAGE_2D 0x9058
95# define GL_INT_IMAGE_3D 0x9059
96# define GL_INT_IMAGE_2D_RECT 0x905A
97# define GL_INT_IMAGE_CUBE 0x905B
98# define GL_INT_IMAGE_BUFFER 0x905C
99# define GL_INT_IMAGE_1D_ARRAY 0x905D
100# define GL_INT_IMAGE_2D_ARRAY 0x905E
101# define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
102# define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060
103# define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
104# define GL_UNSIGNED_INT_IMAGE_1D 0x9062
105# define GL_UNSIGNED_INT_IMAGE_2D 0x9063
106# define GL_UNSIGNED_INT_IMAGE_3D 0x9064
107# define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065
108# define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
109# define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
110# define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068
111# define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
112# define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
113# define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
114# define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
115# endif
116
117QT_BEGIN_NAMESPACE
118
119namespace Qt3DRender {
120namespace Render {
121namespace OpenGL {
122
123namespace {
124
125GLbitfield memoryBarrierGLBitfield(QMemoryBarrier::Operations barriers)
126{
127 GLbitfield bits = 0;
128
129 if (barriers.testFlag(flag: QMemoryBarrier::All)) {
130 bits |= GL_ALL_BARRIER_BITS;
131 return bits;
132 }
133
134 if (barriers.testFlag(flag: QMemoryBarrier::VertexAttributeArray))
135 bits |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT;
136 if (barriers.testFlag(flag: QMemoryBarrier::ElementArray))
137 bits |= GL_ELEMENT_ARRAY_BARRIER_BIT;
138 if (barriers.testFlag(flag: QMemoryBarrier::Uniform))
139 bits |= GL_UNIFORM_BARRIER_BIT;
140 if (barriers.testFlag(flag: QMemoryBarrier::TextureFetch))
141 bits |= GL_TEXTURE_FETCH_BARRIER_BIT;
142 if (barriers.testFlag(flag: QMemoryBarrier::ShaderImageAccess))
143 bits |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
144 if (barriers.testFlag(flag: QMemoryBarrier::Command))
145 bits |= GL_COMMAND_BARRIER_BIT;
146 if (barriers.testFlag(flag: QMemoryBarrier::PixelBuffer))
147 bits |= GL_PIXEL_BUFFER_BARRIER_BIT;
148 if (barriers.testFlag(flag: QMemoryBarrier::TextureUpdate))
149 bits |= GL_TEXTURE_UPDATE_BARRIER_BIT;
150 if (barriers.testFlag(flag: QMemoryBarrier::BufferUpdate))
151 bits |= GL_BUFFER_UPDATE_BARRIER_BIT;
152 if (barriers.testFlag(flag: QMemoryBarrier::FrameBuffer))
153 bits |= GL_FRAMEBUFFER_BARRIER_BIT;
154 if (barriers.testFlag(flag: QMemoryBarrier::TransformFeedback))
155 bits |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT;
156 if (barriers.testFlag(flag: QMemoryBarrier::AtomicCounter))
157 bits |= GL_ATOMIC_COUNTER_BARRIER_BIT;
158 if (barriers.testFlag(flag: QMemoryBarrier::ShaderStorage))
159 bits |= GL_SHADER_STORAGE_BARRIER_BIT;
160 if (barriers.testFlag(flag: QMemoryBarrier::QueryBuffer))
161 bits |= GL_QUERY_BUFFER_BARRIER_BIT;
162
163 return bits;
164}
165
166}
167
168GraphicsHelperGL4::GraphicsHelperGL4()
169 : m_funcs(nullptr)
170{
171}
172
173void GraphicsHelperGL4::initializeHelper(QOpenGLContext *context,
174 QAbstractOpenGLFunctions *functions)
175{
176 Q_UNUSED(context);
177 m_funcs = static_cast<QOpenGLFunctions_4_3_Core*>(functions);
178 const bool ok = m_funcs->initializeOpenGLFunctions();
179 Q_ASSERT(ok);
180 Q_UNUSED(ok);
181}
182
183void GraphicsHelperGL4::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType,
184 GLsizei primitiveCount,
185 GLint indexType,
186 void *indices,
187 GLsizei instances,
188 GLint baseVertex,
189 GLint baseInstance)
190{
191 if (baseInstance != 0)
192 qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2";
193
194 // glDrawElements OpenGL 3.1 or greater
195 m_funcs->glDrawElementsInstancedBaseVertex(mode: primitiveType,
196 count: primitiveCount,
197 type: indexType,
198 indices,
199 instancecount: instances,
200 basevertex: baseVertex);
201}
202
203void GraphicsHelperGL4::drawArraysInstanced(GLenum primitiveType,
204 GLint first,
205 GLsizei count,
206 GLsizei instances)
207{
208 // glDrawArraysInstanced OpenGL 3.1 or greater
209 m_funcs->glDrawArraysInstanced(mode: primitiveType,
210 first,
211 count,
212 instancecount: instances);
213}
214
215void GraphicsHelperGL4::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance)
216{
217 m_funcs->glDrawArraysInstancedBaseInstance(mode: primitiveType,
218 first,
219 count,
220 instancecount: instances,
221 baseinstance: baseInstance);
222}
223
224void GraphicsHelperGL4::drawElements(GLenum primitiveType,
225 GLsizei primitiveCount,
226 GLint indexType,
227 void *indices,
228 GLint baseVertex)
229{
230 m_funcs->glDrawElementsBaseVertex(mode: primitiveType,
231 count: primitiveCount,
232 type: indexType,
233 indices,
234 basevertex: baseVertex);
235}
236
237void GraphicsHelperGL4::drawElementsIndirect(GLenum mode,
238 GLenum type,
239 void *indirect)
240{
241 m_funcs->glDrawElementsIndirect(mode, type, indirect);
242}
243
244void GraphicsHelperGL4::drawArrays(GLenum primitiveType,
245 GLint first,
246 GLsizei count)
247{
248 m_funcs->glDrawArrays(mode: primitiveType,
249 first,
250 count);
251}
252
253void GraphicsHelperGL4::drawArraysIndirect(GLenum mode, void *indirect)
254{
255 m_funcs->glDrawArraysIndirect(mode, indirect);
256}
257
258void GraphicsHelperGL4::setVerticesPerPatch(GLint verticesPerPatch)
259{
260 m_funcs->glPatchParameteri(GL_PATCH_VERTICES, value: verticesPerPatch);
261}
262
263void GraphicsHelperGL4::useProgram(GLuint programId)
264{
265 m_funcs->glUseProgram(program: programId);
266}
267
268QVector<ShaderUniform> GraphicsHelperGL4::programUniformsAndLocations(GLuint programId)
269{
270 QVector<ShaderUniform> uniforms;
271
272 GLint nbrActiveUniforms = 0;
273 m_funcs->glGetProgramInterfaceiv(program: programId, GL_UNIFORM, GL_ACTIVE_RESOURCES, params: &nbrActiveUniforms);
274 uniforms.reserve(asize: nbrActiveUniforms);
275 char uniformName[256];
276 for (GLint i = 0; i < nbrActiveUniforms; ++i) {
277 ShaderUniform uniform;
278 GLsizei uniformNameLength = 0;
279 // Size is 1 for scalar and more for struct or arrays
280 // Type is the GL Type
281 m_funcs->glGetActiveUniform(program: programId, index: i, bufSize: sizeof(uniformName) - 1, length: &uniformNameLength,
282 size: &uniform.m_size, type: &uniform.m_type, name: uniformName);
283 uniformName[sizeof(uniformName) - 1] = '\0';
284 uniform.m_location = m_funcs->glGetUniformLocation(program: programId, name: uniformName);
285 uniform.m_name = QString::fromUtf8(str: uniformName, size: uniformNameLength);
286 // Work around for uniform array names that aren't returned with [0] by some drivers
287 if (uniform.m_size > 1 && !uniform.m_name.endsWith(s: QLatin1String("[0]")))
288 uniform.m_name.append(s: QLatin1String("[0]"));
289 m_funcs->glGetActiveUniformsiv(program: programId, uniformCount: 1, uniformIndices: (GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, params: &uniform.m_blockIndex);
290 m_funcs->glGetActiveUniformsiv(program: programId, uniformCount: 1, uniformIndices: (GLuint*)&i, GL_UNIFORM_OFFSET, params: &uniform.m_offset);
291 m_funcs->glGetActiveUniformsiv(program: programId, uniformCount: 1, uniformIndices: (GLuint*)&i, GL_UNIFORM_ARRAY_STRIDE, params: &uniform.m_arrayStride);
292 m_funcs->glGetActiveUniformsiv(program: programId, uniformCount: 1, uniformIndices: (GLuint*)&i, GL_UNIFORM_MATRIX_STRIDE, params: &uniform.m_matrixStride);
293 uniform.m_rawByteSize = uniformByteSize(description: uniform);
294 uniforms.append(t: uniform);
295 qCDebug(Rendering) << uniform.m_name << "size" << uniform.m_size
296 << " offset" << uniform.m_offset
297 << " rawSize" << uniform.m_rawByteSize;
298 }
299
300 return uniforms;
301}
302
303QVector<ShaderAttribute> GraphicsHelperGL4::programAttributesAndLocations(GLuint programId)
304{
305 QVector<ShaderAttribute> attributes;
306 GLint nbrActiveAttributes = 0;
307 m_funcs->glGetProgramiv(program: programId, GL_ACTIVE_ATTRIBUTES, params: &nbrActiveAttributes);
308 attributes.reserve(asize: nbrActiveAttributes);
309 char attributeName[256];
310 for (GLint i = 0; i < nbrActiveAttributes; ++i) {
311 ShaderAttribute attribute;
312 GLsizei attributeNameLength = 0;
313 // Size is 1 for scalar and more for struct or arrays
314 // Type is the GL Type
315 m_funcs->glGetActiveAttrib(program: programId, index: i, bufSize: sizeof(attributeName) - 1, length: &attributeNameLength,
316 size: &attribute.m_size, type: &attribute.m_type, name: attributeName);
317 attributeName[sizeof(attributeName) - 1] = '\0';
318 attribute.m_location = m_funcs->glGetAttribLocation(program: programId, name: attributeName);
319 attribute.m_name = QString::fromUtf8(str: attributeName, size: attributeNameLength);
320 attributes.append(t: attribute);
321 }
322 return attributes;
323}
324
325QVector<ShaderUniformBlock> GraphicsHelperGL4::programUniformBlocks(GLuint programId)
326{
327 QVector<ShaderUniformBlock> blocks;
328 GLint nbrActiveUniformsBlocks = 0;
329 m_funcs->glGetProgramInterfaceiv(program: programId, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, params: &nbrActiveUniformsBlocks);
330 blocks.reserve(asize: nbrActiveUniformsBlocks);
331 for (GLint i = 0; i < nbrActiveUniformsBlocks; ++i) {
332 QByteArray uniformBlockName(256, '\0');
333 GLsizei length = 0;
334 ShaderUniformBlock uniformBlock;
335 m_funcs->glGetProgramResourceName(program: programId, GL_UNIFORM_BLOCK, index: i, bufSize: 256, length: &length, name: uniformBlockName.data());
336 uniformBlock.m_name = QString::fromUtf8(str: uniformBlockName.left(len: length));
337 uniformBlock.m_index = i;
338 GLenum prop = GL_BUFFER_BINDING;
339 m_funcs->glGetProgramResourceiv(program: programId, GL_UNIFORM_BLOCK, index: i, propCount: 1, props: &prop, bufSize: 4, NULL, params: &uniformBlock.m_binding);
340 prop = GL_BUFFER_DATA_SIZE;
341 m_funcs->glGetProgramResourceiv(program: programId, GL_UNIFORM_BLOCK, index: i, propCount: 1, props: &prop, bufSize: 4, NULL, params: &uniformBlock.m_size);
342 prop = GL_NUM_ACTIVE_VARIABLES;
343 m_funcs->glGetProgramResourceiv(program: programId, GL_UNIFORM_BLOCK, index: i, propCount: 1, props: &prop, bufSize: 4, NULL, params: &uniformBlock.m_activeUniformsCount);
344 blocks.append(t: uniformBlock);
345 }
346 return blocks;
347}
348
349QVector<ShaderStorageBlock> GraphicsHelperGL4::programShaderStorageBlocks(GLuint programId)
350{
351 QVector<ShaderStorageBlock> blocks;
352 GLint nbrActiveShaderStorageBlocks = 0;
353 m_funcs->glGetProgramInterfaceiv(program: programId, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, params: &nbrActiveShaderStorageBlocks);
354 blocks.reserve(asize: nbrActiveShaderStorageBlocks);
355 for (GLint i = 0; i < nbrActiveShaderStorageBlocks; ++i) {
356 QByteArray storageBlockName(256, '\0');
357 GLsizei length = 0;
358 ShaderStorageBlock storageBlock;
359 m_funcs->glGetProgramResourceName(program: programId, GL_SHADER_STORAGE_BLOCK, index: i, bufSize: 256, length: &length, name: storageBlockName.data());
360 storageBlock.m_index = i;
361 storageBlock.m_name = QString::fromUtf8(str: storageBlockName.left(len: length));
362 GLenum prop = GL_BUFFER_BINDING;
363 m_funcs->glGetProgramResourceiv(program: programId, GL_SHADER_STORAGE_BLOCK, index: i, propCount: 1, props: &prop, bufSize: 4, NULL, params: &storageBlock.m_binding);
364 prop = GL_BUFFER_DATA_SIZE;
365 m_funcs->glGetProgramResourceiv(program: programId, GL_SHADER_STORAGE_BLOCK, index: i, propCount: 1, props: &prop, bufSize: 4, NULL, params: &storageBlock.m_size);
366 prop = GL_NUM_ACTIVE_VARIABLES;
367 m_funcs->glGetProgramResourceiv(program: programId, GL_SHADER_STORAGE_BLOCK, index: i, propCount: 1, props: &prop, bufSize: 4, NULL, params: &storageBlock.m_activeVariablesCount);
368 blocks.push_back(t: storageBlock);
369 }
370 return blocks;
371}
372
373void GraphicsHelperGL4::vertexAttribDivisor(GLuint index, GLuint divisor)
374{
375 m_funcs->glVertexAttribDivisor(index, divisor);
376}
377
378void GraphicsHelperGL4::vertexAttributePointer(GLenum shaderDataType,
379 GLuint index,
380 GLint size,
381 GLenum type,
382 GLboolean normalized,
383 GLsizei stride,
384 const GLvoid *pointer)
385{
386 switch (shaderDataType) {
387 case GL_FLOAT:
388 case GL_FLOAT_VEC2:
389 case GL_FLOAT_VEC3:
390 case GL_FLOAT_VEC4:
391 case GL_FLOAT_MAT2:
392 case GL_FLOAT_MAT2x3:
393 case GL_FLOAT_MAT2x4:
394 case GL_FLOAT_MAT3:
395 case GL_FLOAT_MAT3x2:
396 case GL_FLOAT_MAT3x4:
397 case GL_FLOAT_MAT4x2:
398 case GL_FLOAT_MAT4x3:
399 case GL_FLOAT_MAT4:
400 m_funcs->glVertexAttribPointer(index, size, type, normalized, stride, pointer);
401 break;
402
403 case GL_INT:
404 case GL_INT_VEC2:
405 case GL_INT_VEC3:
406 case GL_INT_VEC4:
407 case GL_UNSIGNED_INT:
408 case GL_UNSIGNED_INT_VEC2:
409 case GL_UNSIGNED_INT_VEC3:
410 case GL_UNSIGNED_INT_VEC4:
411 m_funcs->glVertexAttribIPointer(index, size, type, stride, pointer);
412 break;
413
414 case GL_DOUBLE:
415 case GL_DOUBLE_VEC2:
416 case GL_DOUBLE_VEC3:
417 case GL_DOUBLE_VEC4:
418 m_funcs->glVertexAttribLPointer(index, size, type, stride, pointer);
419 break;
420
421 default:
422 qCWarning(Rendering) << "vertexAttribPointer: Unhandled type";
423 Q_UNREACHABLE();
424 }
425}
426
427void GraphicsHelperGL4::readBuffer(GLenum mode)
428{
429 m_funcs->glReadBuffer(mode);
430}
431
432void GraphicsHelperGL4::drawBuffer(GLenum mode)
433{
434 m_funcs->glDrawBuffer(mode);
435}
436
437void *GraphicsHelperGL4::fenceSync()
438{
439 return m_funcs->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, flags: 0);
440}
441
442void GraphicsHelperGL4::clientWaitSync(void *sync, GLuint64 nanoSecTimeout)
443{
444 qDebug() << Q_FUNC_INFO << sync << static_cast<GLsync>(sync);
445 GLenum e = m_funcs->glClientWaitSync(sync: static_cast<GLsync>(sync), GL_SYNC_FLUSH_COMMANDS_BIT, timeout: nanoSecTimeout);
446 qDebug() << e;
447}
448
449void GraphicsHelperGL4::waitSync(void *sync)
450{
451 m_funcs->glWaitSync(sync: static_cast<GLsync>(sync), flags: 0, GL_TIMEOUT_IGNORED);
452}
453
454bool GraphicsHelperGL4::wasSyncSignaled(void *sync)
455{
456 GLint v = 0;
457 m_funcs->glGetSynciv(sync: static_cast<GLsync>(sync),
458 GL_SYNC_STATUS,
459 bufSize: sizeof(v),
460 length: nullptr,
461 values: &v);
462 return v == GL_SIGNALED;
463}
464
465void GraphicsHelperGL4::deleteSync(void *sync)
466{
467 m_funcs->glDeleteSync(sync: static_cast<GLsync>(sync));
468}
469
470void GraphicsHelperGL4::rasterMode(GLenum faceMode, GLenum rasterMode)
471{
472 m_funcs->glPolygonMode(face: faceMode, mode: rasterMode);
473}
474
475void GraphicsHelperGL4::glUniform1fv(GLint location, GLsizei count, const GLfloat *values)
476{
477 m_funcs->glUniform1fv(location, count, value: values);
478}
479
480void GraphicsHelperGL4::glUniform2fv(GLint location, GLsizei count, const GLfloat *values)
481{
482 m_funcs->glUniform2fv(location, count, value: values);
483}
484
485void GraphicsHelperGL4::glUniform3fv(GLint location, GLsizei count, const GLfloat *values)
486{
487 m_funcs->glUniform3fv(location, count, value: values);
488}
489
490void GraphicsHelperGL4::glUniform4fv(GLint location, GLsizei count, const GLfloat *values)
491{
492 m_funcs->glUniform4fv(location, count, value: values);
493}
494
495void GraphicsHelperGL4::glUniform1iv(GLint location, GLsizei count, const GLint *values)
496{
497 m_funcs->glUniform1iv(location, count, value: values);
498}
499
500void GraphicsHelperGL4::glUniform2iv(GLint location, GLsizei count, const GLint *values)
501{
502 m_funcs->glUniform2iv(location, count, value: values);
503}
504
505void GraphicsHelperGL4::glUniform3iv(GLint location, GLsizei count, const GLint *values)
506{
507 m_funcs->glUniform3iv(location, count, value: values);
508}
509
510void GraphicsHelperGL4::glUniform4iv(GLint location, GLsizei count, const GLint *values)
511{
512 m_funcs->glUniform4iv(location, count, value: values);
513}
514
515void GraphicsHelperGL4::glUniform1uiv(GLint location, GLsizei count, const GLuint *values)
516{
517 m_funcs->glUniform1uiv(location, count, value: values);
518}
519
520void GraphicsHelperGL4::glUniform2uiv(GLint location, GLsizei count, const GLuint *values)
521{
522 m_funcs->glUniform2uiv(location, count, value: values);
523}
524
525void GraphicsHelperGL4::glUniform3uiv(GLint location, GLsizei count, const GLuint *values)
526{
527 m_funcs->glUniform3uiv(location, count, value: values);
528}
529
530void GraphicsHelperGL4::glUniform4uiv(GLint location, GLsizei count, const GLuint *values)
531{
532 m_funcs->glUniform4uiv(location, count, value: values);
533}
534
535void GraphicsHelperGL4::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values)
536{
537 m_funcs->glUniformMatrix2fv(location, count, transpose: false, value: values);
538}
539
540void GraphicsHelperGL4::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values)
541{
542 m_funcs->glUniformMatrix3fv(location, count, transpose: false, value: values);
543}
544
545void GraphicsHelperGL4::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values)
546{
547 m_funcs->glUniformMatrix4fv(location, count, transpose: false, value: values);
548}
549
550void GraphicsHelperGL4::glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *values)
551{
552 m_funcs->glUniformMatrix2x3fv(location, count, transpose: false, value: values);
553}
554
555void GraphicsHelperGL4::glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *values)
556{
557 m_funcs->glUniformMatrix3x2fv(location, count, transpose: false, value: values);
558}
559
560void GraphicsHelperGL4::glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *values)
561{
562 m_funcs->glUniformMatrix2x4fv(location, count, transpose: false, value: values);
563}
564
565void GraphicsHelperGL4::glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *values)
566{
567 m_funcs->glUniformMatrix4x2fv(location, count, transpose: false, value: values);
568}
569
570void GraphicsHelperGL4::glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *values)
571{
572 m_funcs->glUniformMatrix3x4fv(location, count, transpose: false, value: values);
573}
574
575void GraphicsHelperGL4::glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *values)
576{
577 m_funcs->glUniformMatrix4x3fv(location, count, transpose: false, value: values);
578}
579
580UniformType GraphicsHelperGL4::uniformTypeFromGLType(GLenum type)
581{
582 switch (type) {
583 case GL_FLOAT:
584 return UniformType::Float;
585 case GL_FLOAT_VEC2:
586 return UniformType::Vec2;
587 case GL_FLOAT_VEC3:
588 return UniformType::Vec3;
589 case GL_FLOAT_VEC4:
590 return UniformType::Vec4;
591 case GL_FLOAT_MAT2:
592 return UniformType::Mat2;
593 case GL_FLOAT_MAT3:
594 return UniformType::Mat3;
595 case GL_FLOAT_MAT4:
596 return UniformType::Mat4;
597 case GL_FLOAT_MAT2x3:
598 return UniformType::Mat2x3;
599 case GL_FLOAT_MAT3x2:
600 return UniformType::Mat3x2;
601 case GL_FLOAT_MAT2x4:
602 return UniformType::Mat2x4;
603 case GL_FLOAT_MAT4x2:
604 return UniformType::Mat4x2;
605 case GL_FLOAT_MAT3x4:
606 return UniformType::Mat3x4;
607 case GL_FLOAT_MAT4x3:
608 return UniformType::Mat4x3;
609 case GL_INT:
610 return UniformType::Int;
611 case GL_INT_VEC2:
612 return UniformType::IVec2;
613 case GL_INT_VEC3:
614 return UniformType::IVec3;
615 case GL_INT_VEC4:
616 return UniformType::IVec4;
617 case GL_UNSIGNED_INT:
618 return UniformType::UInt;
619 case GL_UNSIGNED_INT_VEC2:
620 return UniformType::UIVec2;
621 case GL_UNSIGNED_INT_VEC3:
622 return UniformType::UIVec3;
623 case GL_UNSIGNED_INT_VEC4:
624 return UniformType::UIVec4;
625 case GL_BOOL:
626 return UniformType::Bool;
627 case GL_BOOL_VEC2:
628 return UniformType::BVec2;
629 case GL_BOOL_VEC3:
630 return UniformType::BVec3;
631 case GL_BOOL_VEC4:
632 return UniformType::BVec4;
633
634 case GL_SAMPLER_1D:
635 case GL_SAMPLER_1D_ARRAY:
636 case GL_SAMPLER_1D_SHADOW:
637 case GL_SAMPLER_1D_ARRAY_SHADOW:
638 case GL_SAMPLER_2D:
639 case GL_SAMPLER_2D_RECT:
640 case GL_SAMPLER_2D_SHADOW:
641 case GL_SAMPLER_2D_RECT_SHADOW:
642 case GL_SAMPLER_CUBE:
643 case GL_SAMPLER_CUBE_SHADOW:
644 case GL_SAMPLER_CUBE_MAP_ARRAY:
645 case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
646 case GL_SAMPLER_2D_ARRAY:
647 case GL_SAMPLER_2D_ARRAY_SHADOW:
648 case GL_SAMPLER_2D_MULTISAMPLE:
649 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
650 case GL_SAMPLER_3D:
651 case GL_SAMPLER_BUFFER:
652 case GL_INT_SAMPLER_1D:
653 case GL_INT_SAMPLER_2D:
654 case GL_INT_SAMPLER_3D:
655 case GL_INT_SAMPLER_BUFFER:
656 case GL_INT_SAMPLER_2D_RECT:
657 case GL_INT_SAMPLER_CUBE:
658 case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
659 case GL_INT_SAMPLER_1D_ARRAY:
660 case GL_INT_SAMPLER_2D_ARRAY:
661 case GL_INT_SAMPLER_2D_MULTISAMPLE:
662 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
663 case GL_UNSIGNED_INT_SAMPLER_1D:
664 case GL_UNSIGNED_INT_SAMPLER_2D:
665 case GL_UNSIGNED_INT_SAMPLER_3D:
666 case GL_UNSIGNED_INT_SAMPLER_BUFFER:
667 case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
668 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
669 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
670 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
671 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
672 case GL_UNSIGNED_INT_SAMPLER_CUBE:
673 case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
674 return UniformType::Sampler;
675
676 case GL_IMAGE_1D:
677 case GL_IMAGE_2D:
678 case GL_IMAGE_3D:
679 case GL_IMAGE_2D_RECT:
680 case GL_IMAGE_CUBE:
681 case GL_IMAGE_BUFFER:
682 case GL_IMAGE_1D_ARRAY:
683 case GL_IMAGE_2D_ARRAY:
684 case GL_IMAGE_CUBE_MAP_ARRAY:
685 case GL_IMAGE_2D_MULTISAMPLE:
686 case GL_IMAGE_2D_MULTISAMPLE_ARRAY:
687 case GL_INT_IMAGE_1D:
688 case GL_INT_IMAGE_2D:
689 case GL_INT_IMAGE_3D:
690 case GL_INT_IMAGE_2D_RECT:
691 case GL_INT_IMAGE_CUBE:
692 case GL_INT_IMAGE_BUFFER:
693 case GL_INT_IMAGE_1D_ARRAY:
694 case GL_INT_IMAGE_2D_ARRAY:
695 case GL_INT_IMAGE_CUBE_MAP_ARRAY:
696 case GL_INT_IMAGE_2D_MULTISAMPLE:
697 case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
698 case GL_UNSIGNED_INT_IMAGE_1D:
699 case GL_UNSIGNED_INT_IMAGE_2D:
700 case GL_UNSIGNED_INT_IMAGE_3D:
701 case GL_UNSIGNED_INT_IMAGE_2D_RECT:
702 case GL_UNSIGNED_INT_IMAGE_CUBE:
703 case GL_UNSIGNED_INT_IMAGE_BUFFER:
704 case GL_UNSIGNED_INT_IMAGE_1D_ARRAY:
705 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
706 case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
707 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
708 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
709 return UniformType::Image;
710
711 default:
712 // TO DO: Add support for Doubles and Images
713 Q_UNREACHABLE();
714 return UniformType::Float;
715 }
716}
717
718void GraphicsHelperGL4::blendEquation(GLenum mode)
719{
720 m_funcs->glBlendEquation(mode);
721}
722
723void GraphicsHelperGL4::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)
724{
725 m_funcs->glBlendFunci(buf, src: sfactor, dst: dfactor);
726}
727
728void GraphicsHelperGL4::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha)
729{
730 m_funcs->glBlendFuncSeparatei(buf, srcRGB: sRGB, dstRGB: dRGB, srcAlpha: sAlpha, dstAlpha: dAlpha);
731}
732
733void GraphicsHelperGL4::alphaTest(GLenum, GLenum)
734{
735 qCWarning(Rendering) << "AlphaTest not available with OpenGL 3.2 core";
736}
737
738void GraphicsHelperGL4::depthTest(GLenum mode)
739{
740 m_funcs->glEnable(GL_DEPTH_TEST);
741 m_funcs->glDepthFunc(func: mode);
742}
743
744void GraphicsHelperGL4::depthMask(GLenum mode)
745{
746 m_funcs->glDepthMask(flag: mode);
747}
748
749void GraphicsHelperGL4::depthRange(GLdouble nearValue, GLdouble farValue)
750{
751 m_funcs->glDepthRange(nearVal: nearValue, farVal: farValue);
752}
753
754void GraphicsHelperGL4::frontFace(GLenum mode)
755{
756 m_funcs->glFrontFace(mode);
757
758}
759
760void GraphicsHelperGL4::setMSAAEnabled(bool enabled)
761{
762 enabled ? m_funcs->glEnable(GL_MULTISAMPLE)
763 : m_funcs->glDisable(GL_MULTISAMPLE);
764}
765
766void GraphicsHelperGL4::setAlphaCoverageEnabled(bool enabled)
767{
768 enabled ? m_funcs->glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE)
769 : m_funcs->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
770}
771
772GLuint GraphicsHelperGL4::createFrameBufferObject()
773{
774 GLuint id;
775 m_funcs->glGenFramebuffers(n: 1, framebuffers: &id);
776 return id;
777}
778
779void GraphicsHelperGL4::releaseFrameBufferObject(GLuint frameBufferId)
780{
781 m_funcs->glDeleteFramebuffers(n: 1, framebuffers: &frameBufferId);
782}
783
784void GraphicsHelperGL4::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode)
785{
786 switch (mode) {
787 case FBODraw:
788 m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: frameBufferId);
789 return;
790 case FBORead:
791 m_funcs->glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer: frameBufferId);
792 return;
793 case FBOReadAndDraw:
794 default:
795 m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, framebuffer: frameBufferId);
796 return;
797 }
798}
799
800void GraphicsHelperGL4::bindImageTexture(GLuint imageUnit, GLuint texture,
801 GLint mipLevel, GLboolean layered,
802 GLint layer, GLenum access, GLenum format)
803{
804 m_funcs->glBindImageTexture(unit: imageUnit,
805 texture,
806 level: mipLevel,
807 layered,
808 layer,
809 access,
810 format);
811}
812
813GLuint GraphicsHelperGL4::boundFrameBufferObject()
814{
815 GLint id = 0;
816 m_funcs->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, params: &id);
817 return id;
818}
819
820bool GraphicsHelperGL4::checkFrameBufferComplete()
821{
822 return (m_funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
823}
824
825bool GraphicsHelperGL4::frameBufferNeedsRenderBuffer(const Attachment &attachment)
826{
827 Q_UNUSED(attachment);
828 return false;
829}
830
831void GraphicsHelperGL4::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment)
832{
833 GLenum attr = GL_DEPTH_STENCIL_ATTACHMENT;
834
835 if (attachment.m_point <= QRenderTargetOutput::Color15)
836 attr = GL_COLOR_ATTACHMENT0 + attachment.m_point;
837 else if (attachment.m_point == QRenderTargetOutput::Depth)
838 attr = GL_DEPTH_ATTACHMENT;
839 else if (attachment.m_point == QRenderTargetOutput::Stencil)
840 attr = GL_STENCIL_ATTACHMENT;
841
842 texture->bind();
843 QOpenGLTexture::Target target = texture->target();
844 if (target == QOpenGLTexture::Target1DArray || target == QOpenGLTexture::Target2DArray ||
845 target == QOpenGLTexture::Target2DMultisampleArray || target == QOpenGLTexture::Target3D)
846 m_funcs->glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attachment: attr, texture: texture->textureId(), level: attachment.m_mipLevel, layer: attachment.m_layer);
847 else if (target == QOpenGLTexture::TargetCubeMapArray && attachment.m_face != QAbstractTexture::AllFaces)
848 m_funcs->glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, attachment: attr, texture: texture->textureId(), level: attachment.m_mipLevel, layer: attachment.m_layer * 6 + (attachment.m_face - QAbstractTexture::CubeMapPositiveX));
849 else if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face != QAbstractTexture::AllFaces)
850 m_funcs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment: attr, textarget: attachment.m_face, texture: texture->textureId(), level: attachment.m_mipLevel);
851 else
852 m_funcs->glFramebufferTexture(GL_DRAW_FRAMEBUFFER, attachment: attr, texture: texture->textureId(), level: attachment.m_mipLevel);
853 texture->release();
854}
855
856void GraphicsHelperGL4::bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment)
857{
858 Q_UNUSED(renderBuffer);
859 Q_UNUSED(attachment);
860 Q_UNREACHABLE();
861}
862
863bool GraphicsHelperGL4::supportsFeature(GraphicsHelperInterface::Feature feature) const
864{
865 switch (feature) {
866 case MRT:
867 case Tessellation:
868 case UniformBufferObject:
869 case BindableFragmentOutputs:
870 case PrimitiveRestart:
871 case RenderBufferDimensionRetrieval:
872 case TextureDimensionRetrieval:
873 case ShaderStorageObject:
874 case Compute:
875 case DrawBuffersBlend:
876 case BlitFramebuffer:
877 case IndirectDrawing:
878 case MapBuffer:
879 case Fences:
880 case ShaderImage:
881 return true;
882 default:
883 return false;
884 }
885}
886
887void GraphicsHelperGL4::drawBuffers(GLsizei n, const int *bufs)
888{
889 // Use QVarLengthArray here
890 QVarLengthArray<GLenum, 16> drawBufs(n);
891
892 for (int i = 0; i < n; i++)
893 drawBufs[i] = GL_COLOR_ATTACHMENT0 + bufs[i];
894 m_funcs->glDrawBuffers(n, bufs: drawBufs.constData());
895}
896
897void GraphicsHelperGL4::bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs)
898{
899 for (auto it = outputs.begin(), end = outputs.end(); it != end; ++it)
900 m_funcs->glBindFragDataLocation(program: shader, color: it.value(), name: it.key().toStdString().c_str());
901}
902
903void GraphicsHelperGL4::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
904{
905 m_funcs->glUniformBlockBinding(program: programId, uniformBlockIndex, uniformBlockBinding);
906}
907
908void GraphicsHelperGL4::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding)
909{
910 m_funcs->glShaderStorageBlockBinding(program: programId, storageBlockIndex: shaderStorageBlockIndex, storageBlockBinding: shaderStorageBlockBinding);
911}
912
913void GraphicsHelperGL4::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
914{
915 m_funcs->glBindBufferBase(target, index, buffer);
916}
917
918void GraphicsHelperGL4::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer)
919{
920 char *bufferData = buffer.data();
921
922 switch (description.m_type) {
923
924 case GL_FLOAT: {
925 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 1);
926 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 1);
927 break;
928 }
929
930 case GL_FLOAT_VEC2: {
931 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 2);
932 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 2);
933 break;
934 }
935
936 case GL_FLOAT_VEC3: {
937 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 3);
938 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 3);
939 break;
940 }
941
942 case GL_FLOAT_VEC4: {
943 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 4);
944 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 4);
945 break;
946 }
947
948 case GL_FLOAT_MAT2: {
949 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 4);
950 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 2, rows: 2);
951 break;
952 }
953
954 case GL_FLOAT_MAT2x3: {
955 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 6);
956 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 2, rows: 3);
957 break;
958 }
959
960 case GL_FLOAT_MAT2x4: {
961 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 8);
962 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 2, rows: 4);
963 break;
964 }
965
966 case GL_FLOAT_MAT3: {
967 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 9);
968 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 3, rows: 3);
969 break;
970 }
971
972 case GL_FLOAT_MAT3x2: {
973 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 6);
974 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 3, rows: 2);
975 break;
976 }
977
978 case GL_FLOAT_MAT3x4: {
979 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 12);
980 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 3, rows: 4);
981 break;
982 }
983
984 case GL_FLOAT_MAT4: {
985 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 16);
986 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 4, rows: 4);
987 break;
988 }
989
990 case GL_FLOAT_MAT4x2: {
991 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 8);
992 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 4, rows: 2);
993 break;
994 }
995
996 case GL_FLOAT_MAT4x3: {
997 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 12);
998 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 4, rows: 3);
999 break;
1000 }
1001
1002 case GL_INT: {
1003 const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, count: description.m_size, tupleSize: 1);
1004 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 1);
1005 break;
1006 }
1007
1008 case GL_INT_VEC2: {
1009 const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, count: description.m_size, tupleSize: 2);
1010 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 2);
1011 break;
1012 }
1013
1014 case GL_INT_VEC3: {
1015 const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, count: description.m_size, tupleSize: 3);
1016 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 3);
1017 break;
1018 }
1019
1020 case GL_INT_VEC4: {
1021 const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, count: description.m_size, tupleSize: 4);
1022 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 4);
1023 break;
1024 }
1025
1026 case GL_UNSIGNED_INT: {
1027 const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, count: description.m_size, tupleSize: 1);
1028 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 1);
1029 break;
1030 }
1031
1032 case GL_UNSIGNED_INT_VEC2: {
1033 const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, count: description.m_size, tupleSize: 2);
1034 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 2);
1035 break;
1036 }
1037
1038 case GL_UNSIGNED_INT_VEC3: {
1039 const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, count: description.m_size, tupleSize: 3);
1040 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 3);
1041 break;
1042 }
1043
1044 case GL_UNSIGNED_INT_VEC4: {
1045 const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, count: description.m_size, tupleSize: 4);
1046 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 4);
1047 break;
1048 }
1049
1050 case GL_BOOL: {
1051 const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, count: description.m_size, tupleSize: 1);
1052 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 1);
1053 break;
1054 }
1055
1056 case GL_BOOL_VEC2: {
1057 const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, count: description.m_size, tupleSize: 2);
1058 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 2);
1059 break;
1060 }
1061
1062 case GL_BOOL_VEC3: {
1063 const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, count: description.m_size, tupleSize: 3);
1064 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 3);
1065 break;
1066 }
1067
1068 case GL_BOOL_VEC4: {
1069 const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, count: description.m_size, tupleSize: 4);
1070 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 4);
1071 break;
1072 }
1073
1074 case GL_SAMPLER_1D:
1075 case GL_SAMPLER_2D:
1076 case GL_SAMPLER_3D:
1077 case GL_SAMPLER_CUBE:
1078 case GL_SAMPLER_BUFFER:
1079 case GL_SAMPLER_2D_RECT:
1080 case GL_INT_SAMPLER_1D:
1081 case GL_INT_SAMPLER_2D:
1082 case GL_INT_SAMPLER_3D:
1083 case GL_INT_SAMPLER_CUBE:
1084 case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
1085 case GL_INT_SAMPLER_BUFFER:
1086 case GL_INT_SAMPLER_2D_RECT:
1087 case GL_UNSIGNED_INT_SAMPLER_1D:
1088 case GL_UNSIGNED_INT_SAMPLER_2D:
1089 case GL_UNSIGNED_INT_SAMPLER_3D:
1090 case GL_UNSIGNED_INT_SAMPLER_CUBE:
1091 case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
1092 case GL_UNSIGNED_INT_SAMPLER_BUFFER:
1093 case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
1094 case GL_SAMPLER_1D_SHADOW:
1095 case GL_SAMPLER_2D_SHADOW:
1096 case GL_SAMPLER_CUBE_SHADOW:
1097 case GL_SAMPLER_CUBE_MAP_ARRAY:
1098 case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
1099 case GL_SAMPLER_1D_ARRAY:
1100 case GL_SAMPLER_2D_ARRAY:
1101 case GL_INT_SAMPLER_1D_ARRAY:
1102 case GL_INT_SAMPLER_2D_ARRAY:
1103 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
1104 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
1105 case GL_SAMPLER_1D_ARRAY_SHADOW:
1106 case GL_SAMPLER_2D_ARRAY_SHADOW:
1107 case GL_SAMPLER_2D_RECT_SHADOW:
1108 case GL_SAMPLER_2D_MULTISAMPLE:
1109 case GL_INT_SAMPLER_2D_MULTISAMPLE:
1110 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
1111 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
1112 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
1113 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
1114 case GL_IMAGE_1D:
1115 case GL_IMAGE_2D:
1116 case GL_IMAGE_3D:
1117 case GL_IMAGE_2D_RECT:
1118 case GL_IMAGE_CUBE:
1119 case GL_IMAGE_BUFFER:
1120 case GL_IMAGE_1D_ARRAY:
1121 case GL_IMAGE_2D_ARRAY:
1122 case GL_IMAGE_CUBE_MAP_ARRAY:
1123 case GL_IMAGE_2D_MULTISAMPLE:
1124 case GL_IMAGE_2D_MULTISAMPLE_ARRAY:
1125 case GL_INT_IMAGE_1D:
1126 case GL_INT_IMAGE_2D:
1127 case GL_INT_IMAGE_3D:
1128 case GL_INT_IMAGE_2D_RECT:
1129 case GL_INT_IMAGE_CUBE:
1130 case GL_INT_IMAGE_BUFFER:
1131 case GL_INT_IMAGE_1D_ARRAY:
1132 case GL_INT_IMAGE_2D_ARRAY:
1133 case GL_INT_IMAGE_CUBE_MAP_ARRAY:
1134 case GL_INT_IMAGE_2D_MULTISAMPLE:
1135 case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
1136 case GL_UNSIGNED_INT_IMAGE_1D:
1137 case GL_UNSIGNED_INT_IMAGE_2D:
1138 case GL_UNSIGNED_INT_IMAGE_3D:
1139 case GL_UNSIGNED_INT_IMAGE_2D_RECT:
1140 case GL_UNSIGNED_INT_IMAGE_CUBE:
1141 case GL_UNSIGNED_INT_IMAGE_BUFFER:
1142 case GL_UNSIGNED_INT_IMAGE_1D_ARRAY:
1143 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
1144 case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
1145 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
1146 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: {
1147 Q_ASSERT(description.m_size == 1);
1148 int value = v.toInt();
1149 QGraphicsUtils::fillDataArray<GLint>(buffer: bufferData, data: &value, description, tupleSize: 1);
1150 break;
1151 }
1152
1153 default:
1154 qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name;
1155 break;
1156 }
1157}
1158
1159uint GraphicsHelperGL4::uniformByteSize(const ShaderUniform &description)
1160{
1161 uint rawByteSize = 0;
1162 int arrayStride = qMax(a: description.m_arrayStride, b: 0);
1163 int matrixStride = qMax(a: description.m_matrixStride, b: 0);
1164
1165 switch (description.m_type) {
1166
1167 case GL_FLOAT_VEC2:
1168 case GL_INT_VEC2:
1169 case GL_UNSIGNED_INT_VEC2:
1170 rawByteSize = 8;
1171 break;
1172
1173 case GL_FLOAT_VEC3:
1174 case GL_INT_VEC3:
1175 case GL_UNSIGNED_INT_VEC3:
1176 rawByteSize = 12;
1177 break;
1178
1179 case GL_FLOAT_VEC4:
1180 case GL_INT_VEC4:
1181 case GL_UNSIGNED_INT_VEC4:
1182 rawByteSize = 16;
1183 break;
1184
1185 case GL_FLOAT_MAT2:
1186 rawByteSize = matrixStride ? 2 * matrixStride : 16;
1187 break;
1188
1189 case GL_FLOAT_MAT2x4:
1190 rawByteSize = matrixStride ? 2 * matrixStride : 32;
1191 break;
1192
1193 case GL_FLOAT_MAT4x2:
1194 rawByteSize = matrixStride ? 4 * matrixStride : 32;
1195 break;
1196
1197 case GL_FLOAT_MAT3:
1198 rawByteSize = matrixStride ? 3 * matrixStride : 36;
1199 break;
1200
1201 case GL_FLOAT_MAT2x3:
1202 rawByteSize = matrixStride ? 2 * matrixStride : 24;
1203 break;
1204
1205 case GL_FLOAT_MAT3x2:
1206 rawByteSize = matrixStride ? 3 * matrixStride : 24;
1207 break;
1208
1209 case GL_FLOAT_MAT4:
1210 rawByteSize = matrixStride ? 4 * matrixStride : 64;
1211 break;
1212
1213 case GL_FLOAT_MAT4x3:
1214 rawByteSize = matrixStride ? 4 * matrixStride : 48;
1215 break;
1216
1217 case GL_FLOAT_MAT3x4:
1218 rawByteSize = matrixStride ? 3 * matrixStride : 48;
1219 break;
1220
1221 case GL_BOOL:
1222 rawByteSize = 1;
1223 break;
1224
1225 case GL_BOOL_VEC2:
1226 rawByteSize = 2;
1227 break;
1228
1229 case GL_BOOL_VEC3:
1230 rawByteSize = 3;
1231 break;
1232
1233 case GL_BOOL_VEC4:
1234 rawByteSize = 4;
1235 break;
1236
1237 case GL_INT:
1238 case GL_FLOAT:
1239 case GL_UNSIGNED_INT:
1240 case GL_SAMPLER_1D:
1241 case GL_SAMPLER_2D:
1242 case GL_SAMPLER_3D:
1243 case GL_SAMPLER_CUBE:
1244 case GL_SAMPLER_BUFFER:
1245 case GL_SAMPLER_2D_RECT:
1246 case GL_INT_SAMPLER_1D:
1247 case GL_INT_SAMPLER_2D:
1248 case GL_INT_SAMPLER_3D:
1249 case GL_INT_SAMPLER_CUBE:
1250 case GL_INT_SAMPLER_BUFFER:
1251 case GL_INT_SAMPLER_2D_RECT:
1252 case GL_UNSIGNED_INT_SAMPLER_1D:
1253 case GL_UNSIGNED_INT_SAMPLER_2D:
1254 case GL_UNSIGNED_INT_SAMPLER_3D:
1255 case GL_UNSIGNED_INT_SAMPLER_CUBE:
1256 case GL_UNSIGNED_INT_SAMPLER_BUFFER:
1257 case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
1258 case GL_SAMPLER_1D_SHADOW:
1259 case GL_SAMPLER_2D_SHADOW:
1260 case GL_SAMPLER_CUBE_SHADOW:
1261 case GL_SAMPLER_CUBE_MAP_ARRAY:
1262 case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
1263 case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
1264 case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
1265 case GL_SAMPLER_1D_ARRAY:
1266 case GL_SAMPLER_2D_ARRAY:
1267 case GL_INT_SAMPLER_1D_ARRAY:
1268 case GL_INT_SAMPLER_2D_ARRAY:
1269 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
1270 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
1271 case GL_SAMPLER_1D_ARRAY_SHADOW:
1272 case GL_SAMPLER_2D_ARRAY_SHADOW:
1273 case GL_SAMPLER_2D_RECT_SHADOW:
1274 case GL_SAMPLER_2D_MULTISAMPLE:
1275 case GL_INT_SAMPLER_2D_MULTISAMPLE:
1276 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
1277 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
1278 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
1279 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
1280 case GL_IMAGE_1D:
1281 case GL_IMAGE_2D:
1282 case GL_IMAGE_3D:
1283 case GL_IMAGE_2D_RECT:
1284 case GL_IMAGE_CUBE:
1285 case GL_IMAGE_BUFFER:
1286 case GL_IMAGE_1D_ARRAY:
1287 case GL_IMAGE_2D_ARRAY:
1288 case GL_IMAGE_CUBE_MAP_ARRAY:
1289 case GL_IMAGE_2D_MULTISAMPLE:
1290 case GL_IMAGE_2D_MULTISAMPLE_ARRAY:
1291 case GL_INT_IMAGE_1D:
1292 case GL_INT_IMAGE_2D:
1293 case GL_INT_IMAGE_3D:
1294 case GL_INT_IMAGE_2D_RECT:
1295 case GL_INT_IMAGE_CUBE:
1296 case GL_INT_IMAGE_BUFFER:
1297 case GL_INT_IMAGE_1D_ARRAY:
1298 case GL_INT_IMAGE_2D_ARRAY:
1299 case GL_INT_IMAGE_CUBE_MAP_ARRAY:
1300 case GL_INT_IMAGE_2D_MULTISAMPLE:
1301 case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
1302 case GL_UNSIGNED_INT_IMAGE_1D:
1303 case GL_UNSIGNED_INT_IMAGE_2D:
1304 case GL_UNSIGNED_INT_IMAGE_3D:
1305 case GL_UNSIGNED_INT_IMAGE_2D_RECT:
1306 case GL_UNSIGNED_INT_IMAGE_CUBE:
1307 case GL_UNSIGNED_INT_IMAGE_BUFFER:
1308 case GL_UNSIGNED_INT_IMAGE_1D_ARRAY:
1309 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
1310 case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
1311 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
1312 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
1313 rawByteSize = 4;
1314 break;
1315
1316 default: {
1317 qWarning() << Q_FUNC_INFO << "unable to deduce rawByteSize for uniform type:" << description.m_type << "for uniform" << description.m_name;
1318 break;
1319 }
1320
1321 }
1322
1323 return arrayStride ? rawByteSize * arrayStride : rawByteSize;
1324}
1325
1326void GraphicsHelperGL4::enableClipPlane(int clipPlane)
1327{
1328 m_funcs->glEnable(GL_CLIP_DISTANCE0 + clipPlane);
1329}
1330
1331void GraphicsHelperGL4::disableClipPlane(int clipPlane)
1332{
1333 m_funcs->glDisable(GL_CLIP_DISTANCE0 + clipPlane);
1334}
1335
1336void GraphicsHelperGL4::setClipPlane(int, const QVector3D &, float)
1337{
1338 // deprecated
1339}
1340
1341GLint GraphicsHelperGL4::maxClipPlaneCount()
1342{
1343 GLint max = 0;
1344 m_funcs->glGetIntegerv(GL_MAX_CLIP_DISTANCES, params: &max);
1345 return max;
1346}
1347
1348void GraphicsHelperGL4::memoryBarrier(QMemoryBarrier::Operations barriers)
1349{
1350 m_funcs->glMemoryBarrier(barriers: memoryBarrierGLBitfield(barriers));
1351}
1352
1353void GraphicsHelperGL4::enablePrimitiveRestart(int primitiveRestartIndex)
1354{
1355 m_funcs->glPrimitiveRestartIndex(index: primitiveRestartIndex);
1356 m_funcs->glEnable(GL_PRIMITIVE_RESTART);
1357}
1358
1359void GraphicsHelperGL4::enableVertexAttributeArray(int location)
1360{
1361 m_funcs->glEnableVertexAttribArray(index: location);
1362}
1363
1364void GraphicsHelperGL4::disablePrimitiveRestart()
1365{
1366 m_funcs->glDisable(GL_PRIMITIVE_RESTART);
1367}
1368
1369void GraphicsHelperGL4::clearBufferf(GLint drawbuffer, const QVector4D &values)
1370{
1371 GLfloat vec[4] = {values[0], values[1], values[2], values[3]};
1372 m_funcs->glClearBufferfv(GL_COLOR, drawbuffer, value: vec);
1373}
1374
1375void GraphicsHelperGL4::pointSize(bool programmable, GLfloat value)
1376{
1377 if (programmable) {
1378 m_funcs->glEnable(GL_PROGRAM_POINT_SIZE);
1379 } else {
1380 m_funcs->glDisable(GL_PROGRAM_POINT_SIZE);
1381 m_funcs->glPointSize(size: value);
1382 }
1383}
1384
1385void GraphicsHelperGL4::enablei(GLenum cap, GLuint index)
1386{
1387 m_funcs->glEnablei(target: cap, index);
1388}
1389
1390void GraphicsHelperGL4::disablei(GLenum cap, GLuint index)
1391{
1392 m_funcs->glDisablei(target: cap, index);
1393}
1394
1395void GraphicsHelperGL4::setSeamlessCubemap(bool enable)
1396{
1397 if (enable)
1398 m_funcs->glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
1399 else
1400 m_funcs->glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
1401}
1402
1403QSize GraphicsHelperGL4::getRenderBufferDimensions(GLuint renderBufferId)
1404{
1405 GLint width = 0;
1406 GLint height = 0;
1407
1408 m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer: renderBufferId);
1409 m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, params: &width);
1410 m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, params: &height);
1411 m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer: 0);
1412
1413 return QSize(width, height);
1414}
1415
1416QSize GraphicsHelperGL4::getTextureDimensions(GLuint textureId, GLenum target, uint level)
1417{
1418 GLint width = 0;
1419 GLint height = 0;
1420
1421 m_funcs->glBindTexture(target, texture: textureId);
1422 m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, params: &width);
1423 m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, params: &height);
1424 m_funcs->glBindTexture(target, texture: 0);
1425
1426 return QSize(width, height);
1427}
1428
1429void GraphicsHelperGL4::dispatchCompute(GLuint wx, GLuint wy, GLuint wz)
1430{
1431 m_funcs->glDispatchCompute(num_groups_x: wx, num_groups_y: wy, num_groups_z: wz);
1432}
1433
1434char *GraphicsHelperGL4::mapBuffer(GLenum target, GLsizeiptr size)
1435{
1436 return static_cast<char*>(m_funcs->glMapBufferRange(target, offset: 0, length: size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
1437}
1438
1439GLboolean GraphicsHelperGL4::unmapBuffer(GLenum target)
1440{
1441 return m_funcs->glUnmapBuffer(target);
1442}
1443
1444void GraphicsHelperGL4::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
1445{
1446 m_funcs->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
1447}
1448
1449} // namespace OpenGL
1450} // namespace Render
1451} // namespace Qt3DRender
1452
1453QT_END_NAMESPACE
1454
1455#endif // !QT_OPENGL_ES_2
1456

source code of qt3d/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp