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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

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