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

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