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

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