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 
68 QT_BEGIN_NAMESPACE
69 
70 namespace Qt3DRender {
71 namespace Render {
72 namespace OpenGL {
73 
GraphicsHelperGL3_3()74 GraphicsHelperGL3_3::GraphicsHelperGL3_3()
75     : m_funcs(nullptr)
76     , m_tessFuncs()
77 {
78 }
79 
~GraphicsHelperGL3_3()80 GraphicsHelperGL3_3::~GraphicsHelperGL3_3()
81 {
82 }
83 
initializeHelper(QOpenGLContext * context,QAbstractOpenGLFunctions * functions)84 void 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(new QOpenGLExtension_ARB_tessellation_shader);
94         m_tessFuncs->initializeOpenGLFunctions();
95     }
96 }
97 
drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType,GLsizei primitiveCount,GLint indexType,void * indices,GLsizei instances,GLint baseVertex,GLint baseInstance)98 void 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(primitiveType,
111                                                primitiveCount,
112                                                indexType,
113                                                indices,
114                                                instances,
115                                                baseVertex);
116 }
117 
drawArraysInstanced(GLenum primitiveType,GLint first,GLsizei count,GLsizei instances)118 void 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(primitiveType,
125                                    first,
126                                    count,
127                                    instances);
128 }
129 
drawArraysInstancedBaseInstance(GLenum primitiveType,GLint first,GLsizei count,GLsizei instances,GLsizei baseInstance)130 void 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(primitiveType,
135                                    first,
136                                    count,
137                                    instances);
138 }
139 
drawElements(GLenum primitiveType,GLsizei primitiveCount,GLint indexType,void * indices,GLint baseVertex)140 void GraphicsHelperGL3_3::drawElements(GLenum primitiveType,
141                                         GLsizei primitiveCount,
142                                         GLint indexType,
143                                         void *indices,
144                                         GLint baseVertex)
145 {
146     m_funcs->glDrawElementsBaseVertex(primitiveType,
147                                       primitiveCount,
148                                       indexType,
149                                       indices,
150                                       baseVertex);
151 }
152 
drawElementsIndirect(GLenum,GLenum,void *)153 void GraphicsHelperGL3_3::drawElementsIndirect(GLenum, GLenum, void *)
154 {
155     qWarning() << "Indirect Drawing is not supported with OpenGL 3";
156 }
157 
drawArrays(GLenum primitiveType,GLint first,GLsizei count)158 void GraphicsHelperGL3_3::drawArrays(GLenum primitiveType,
159                                       GLint first,
160                                       GLsizei count)
161 {
162     m_funcs->glDrawArrays(primitiveType,
163                           first,
164                           count);
165 }
166 
drawArraysIndirect(GLenum,void *)167 void GraphicsHelperGL3_3::drawArraysIndirect(GLenum , void *)
168 {
169     qWarning() << "Indirect Drawing is not supported with OpenGL 3";
170 }
171 
setVerticesPerPatch(GLint verticesPerPatch)172 void 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, verticesPerPatch);
181 #else
182     Q_UNUSED(verticesPerPatch);
183     qWarning() << "Tessellation not supported";
184 #endif
185 }
186 
useProgram(GLuint programId)187 void GraphicsHelperGL3_3::useProgram(GLuint programId)
188 {
189     m_funcs->glUseProgram(programId);
190 }
191 
programUniformsAndLocations(GLuint programId)192 QVector<ShaderUniform> GraphicsHelperGL3_3::programUniformsAndLocations(GLuint programId)
193 {
194     QVector<ShaderUniform> uniforms;
195 
196     GLint nbrActiveUniforms = 0;
197     m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORMS, &nbrActiveUniforms);
198     uniforms.reserve(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(programId, i, sizeof(uniformName) - 1, &uniformNameLength,
206                                     &uniform.m_size, &uniform.m_type, uniformName);
207         uniformName[sizeof(uniformName) - 1] = '\0';
208         uniform.m_location = m_funcs->glGetUniformLocation(programId, uniformName);
209         uniform.m_name = QString::fromUtf8(uniformName, 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(QLatin1String("[0]")))
212             uniform.m_name.append(QLatin1String("[0]"));
213         m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, &uniform.m_blockIndex);
214         m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_OFFSET, &uniform.m_offset);
215         m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_ARRAY_STRIDE, &uniform.m_arrayStride);
216         m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_MATRIX_STRIDE, &uniform.m_matrixStride);
217         uniform.m_rawByteSize = uniformByteSize(uniform);
218         uniforms.append(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 
programAttributesAndLocations(GLuint programId)227 QVector<ShaderAttribute> GraphicsHelperGL3_3::programAttributesAndLocations(GLuint programId)
228 {
229     QVector<ShaderAttribute> attributes;
230     GLint nbrActiveAttributes = 0;
231     m_funcs->glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &nbrActiveAttributes);
232     attributes.reserve(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(programId, i, sizeof(attributeName) - 1, &attributeNameLength,
240                                    &attribute.m_size, &attribute.m_type, attributeName);
241         attributeName[sizeof(attributeName) - 1] = '\0';
242         attribute.m_location = m_funcs->glGetAttribLocation(programId, attributeName);
243         attribute.m_name = QString::fromUtf8(attributeName, attributeNameLength);
244         attributes.append(attribute);
245     }
246     return attributes;
247 }
248 
programUniformBlocks(GLuint programId)249 QVector<ShaderUniformBlock> GraphicsHelperGL3_3::programUniformBlocks(GLuint programId)
250 {
251     QVector<ShaderUniformBlock> blocks;
252     GLint nbrActiveUniformsBlocks = 0;
253     m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORM_BLOCKS, &nbrActiveUniformsBlocks);
254     blocks.reserve(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(programId, i, 256, &length, uniformBlockName.data());
260         uniformBlock.m_name = QString::fromUtf8(uniformBlockName.left(length));
261         uniformBlock.m_index = i;
262         m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &uniformBlock.m_activeUniformsCount);
263         m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_BINDING, &uniformBlock.m_binding);
264         m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlock.m_size);
265         blocks.append(uniformBlock);
266     }
267     return blocks;
268 }
269 
programShaderStorageBlocks(GLuint programId)270 QVector<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 
vertexAttribDivisor(GLuint index,GLuint divisor)278 void GraphicsHelperGL3_3::vertexAttribDivisor(GLuint index, GLuint divisor)
279 {
280     m_funcs->glVertexAttribDivisor(index, divisor);
281 }
282 
vertexAttributePointer(GLenum shaderDataType,GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * pointer)283 void 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 
readBuffer(GLenum mode)324 void GraphicsHelperGL3_3::readBuffer(GLenum mode)
325 {
326     m_funcs->glReadBuffer(mode);
327 }
328 
drawBuffer(GLenum mode)329 void GraphicsHelperGL3_3::drawBuffer(GLenum mode)
330 {
331     m_funcs->glDrawBuffer(mode);
332 }
333 
fenceSync()334 void *GraphicsHelperGL3_3::fenceSync()
335 {
336     return m_funcs->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
337 }
338 
clientWaitSync(void * sync,GLuint64 nanoSecTimeout)339 void GraphicsHelperGL3_3::clientWaitSync(void *sync, GLuint64 nanoSecTimeout)
340 {
341     m_funcs->glClientWaitSync(static_cast<GLsync>(sync), GL_SYNC_FLUSH_COMMANDS_BIT, nanoSecTimeout);
342 }
343 
waitSync(void * sync)344 void GraphicsHelperGL3_3::waitSync(void *sync)
345 {
346     m_funcs->glWaitSync(static_cast<GLsync>(sync), 0, GL_TIMEOUT_IGNORED);
347 }
348 
wasSyncSignaled(void * sync)349 bool GraphicsHelperGL3_3::wasSyncSignaled(void *sync)
350 {
351     GLint v;
352     m_funcs->glGetSynciv(static_cast<GLsync>(sync),
353                          GL_SYNC_STATUS,
354                          sizeof(v),
355                          nullptr,
356                          &v);
357     return v == GL_SIGNALED;
358 }
359 
deleteSync(void * sync)360 void GraphicsHelperGL3_3::deleteSync(void *sync)
361 {
362     m_funcs->glDeleteSync(static_cast<GLsync>(sync));
363 }
364 
rasterMode(GLenum faceMode,GLenum rasterMode)365 void GraphicsHelperGL3_3::rasterMode(GLenum faceMode, GLenum rasterMode)
366 {
367     m_funcs->glPolygonMode(faceMode, rasterMode);
368 }
369 
blendEquation(GLenum mode)370 void GraphicsHelperGL3_3::blendEquation(GLenum mode)
371 {
372     m_funcs->glBlendEquation(mode);
373 }
374 
blendFunci(GLuint buf,GLenum sfactor,GLenum dfactor)375 void 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 
blendFuncSeparatei(GLuint buf,GLenum sRGB,GLenum dRGB,GLenum sAlpha,GLenum dAlpha)384 void 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 
alphaTest(GLenum,GLenum)395 void GraphicsHelperGL3_3::alphaTest(GLenum, GLenum)
396 {
397     qCWarning(Rendering) << "AlphaTest not available with OpenGL 3.2 core";
398 }
399 
depthTest(GLenum mode)400 void GraphicsHelperGL3_3::depthTest(GLenum mode)
401 {
402     m_funcs->glEnable(GL_DEPTH_TEST);
403     m_funcs->glDepthFunc(mode);
404 }
405 
depthMask(GLenum mode)406 void GraphicsHelperGL3_3::depthMask(GLenum mode)
407 {
408     m_funcs->glDepthMask(mode);
409 }
410 
depthRange(GLdouble nearValue,GLdouble farValue)411 void GraphicsHelperGL3_3::depthRange(GLdouble nearValue, GLdouble farValue)
412 {
413     m_funcs->glDepthRange(nearValue, farValue);
414 }
415 
frontFace(GLenum mode)416 void GraphicsHelperGL3_3::frontFace(GLenum mode)
417 {
418     m_funcs->glFrontFace(mode);
419 
420 }
421 
setMSAAEnabled(bool enabled)422 void GraphicsHelperGL3_3::setMSAAEnabled(bool enabled)
423 {
424     enabled ? m_funcs->glEnable(GL_MULTISAMPLE)
425             : m_funcs->glDisable(GL_MULTISAMPLE);
426 }
427 
setAlphaCoverageEnabled(bool enabled)428 void 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 
createFrameBufferObject()434 GLuint GraphicsHelperGL3_3::createFrameBufferObject()
435 {
436     GLuint id;
437     m_funcs->glGenFramebuffers(1, &id);
438     return id;
439 }
440 
releaseFrameBufferObject(GLuint frameBufferId)441 void GraphicsHelperGL3_3::releaseFrameBufferObject(GLuint frameBufferId)
442 {
443     m_funcs->glDeleteFramebuffers(1, &frameBufferId);
444 }
445 
bindFrameBufferObject(GLuint frameBufferId,FBOBindMode mode)446 void GraphicsHelperGL3_3::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode)
447 {
448     switch (mode) {
449     case FBODraw:
450         m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId);
451         return;
452     case FBORead:
453         m_funcs->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBufferId);
454         return;
455     case FBOReadAndDraw:
456     default:
457         m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
458         return;
459     }
460 }
461 
boundFrameBufferObject()462 GLuint GraphicsHelperGL3_3::boundFrameBufferObject()
463 {
464     GLint id = 0;
465     m_funcs->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &id);
466     return id;
467 }
468 
checkFrameBufferComplete()469 bool GraphicsHelperGL3_3::checkFrameBufferComplete()
470 {
471     return (m_funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
472 }
473 
frameBufferNeedsRenderBuffer(const Attachment & attachment)474 bool GraphicsHelperGL3_3::frameBufferNeedsRenderBuffer(const Attachment &attachment)
475 {
476     Q_UNUSED(attachment);
477     return false;
478 }
479 
bindFrameBufferAttachment(QOpenGLTexture * texture,const Attachment & attachment)480 void 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, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer);
496     else if (target == QOpenGLTexture::TargetCubeMapArray && attachment.m_face != QAbstractTexture::AllFaces)
497         m_funcs->glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, 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, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel);
500     else
501         m_funcs->glFramebufferTexture(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel);
502     texture->release();
503 }
504 
bindFrameBufferAttachment(RenderBuffer * renderBuffer,const Attachment & attachment)505 void GraphicsHelperGL3_3::bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment)
506 {
507     Q_UNUSED(renderBuffer);
508     Q_UNUSED(attachment);
509     Q_UNREACHABLE();
510 }
511 
supportsFeature(GraphicsHelperInterface::Feature feature) const512 bool 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 
drawBuffers(GLsizei n,const int * bufs)531 void 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, drawBufs.constData());
539 }
540 
bindFragDataLocation(GLuint shader,const QHash<QString,int> & outputs)541 void 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(shader, it.value(), it.key().toStdString().c_str());
545 }
546 
bindUniformBlock(GLuint programId,GLuint uniformBlockIndex,GLuint uniformBlockBinding)547 void GraphicsHelperGL3_3::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
548 {
549     m_funcs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding);
550 }
551 
bindShaderStorageBlock(GLuint programId,GLuint shaderStorageBlockIndex,GLuint shaderStorageBlockBinding)552 void 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 
bindImageTexture(GLuint imageUnit,GLuint texture,GLint mipLevel,GLboolean layered,GLint layer,GLenum access,GLenum format)560 void 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 
bindBufferBase(GLenum target,GLuint index,GLuint buffer)574 void GraphicsHelperGL3_3::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
575 {
576     m_funcs->glBindBufferBase(target, index, buffer);
577 }
578 
buildUniformBuffer(const QVariant & v,const ShaderUniform & description,QByteArray & buffer)579 void 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, description.m_size, 1);
587         QGraphicsUtils::fillDataArray(bufferData, data, description, 1);
588         break;
589     }
590 
591     case GL_FLOAT_VEC2: {
592         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2);
593         QGraphicsUtils::fillDataArray(bufferData, data, description, 2);
594         break;
595     }
596 
597     case GL_FLOAT_VEC3: {
598         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3);
599         QGraphicsUtils::fillDataArray(bufferData, data, description, 3);
600         break;
601     }
602 
603     case GL_FLOAT_VEC4: {
604         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4);
605         QGraphicsUtils::fillDataArray(bufferData, data, description, 4);
606         break;
607     }
608 
609     case GL_FLOAT_MAT2: {
610         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4);
611         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 2);
612         break;
613     }
614 
615     case GL_FLOAT_MAT2x3: {
616         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6);
617         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 3);
618         break;
619     }
620 
621     case GL_FLOAT_MAT2x4: {
622         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8);
623         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 4);
624         break;
625     }
626 
627     case GL_FLOAT_MAT3: {
628         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9);
629         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 3);
630         break;
631     }
632 
633     case GL_FLOAT_MAT3x2: {
634         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6);
635         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 2);
636         break;
637     }
638 
639     case GL_FLOAT_MAT3x4: {
640         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12);
641         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 4);
642         break;
643     }
644 
645     case GL_FLOAT_MAT4: {
646         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16);
647         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 4);
648         break;
649     }
650 
651     case GL_FLOAT_MAT4x2: {
652         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8);
653         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 2);
654         break;
655     }
656 
657     case GL_FLOAT_MAT4x3: {
658         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12);
659         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 3);
660         break;
661     }
662 
663     case GL_INT: {
664         const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1);
665         QGraphicsUtils::fillDataArray(bufferData, data, description, 1);
666         break;
667     }
668 
669     case GL_INT_VEC2: {
670         const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2);
671         QGraphicsUtils::fillDataArray(bufferData, data, description, 2);
672         break;
673     }
674 
675     case GL_INT_VEC3: {
676         const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3);
677         QGraphicsUtils::fillDataArray(bufferData, data, description, 3);
678         break;
679     }
680 
681     case GL_INT_VEC4: {
682         const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4);
683         QGraphicsUtils::fillDataArray(bufferData, data, description, 4);
684         break;
685     }
686 
687     case GL_UNSIGNED_INT: {
688         const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 1);
689         QGraphicsUtils::fillDataArray(bufferData, data, description, 1);
690         break;
691     }
692 
693     case GL_UNSIGNED_INT_VEC2: {
694         const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 2);
695         QGraphicsUtils::fillDataArray(bufferData, data, description, 2);
696         break;
697     }
698 
699     case GL_UNSIGNED_INT_VEC3: {
700         const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 3);
701         QGraphicsUtils::fillDataArray(bufferData, data, description, 3);
702         break;
703     }
704 
705     case GL_UNSIGNED_INT_VEC4: {
706         const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 4);
707         QGraphicsUtils::fillDataArray(bufferData, data, description, 4);
708         break;
709     }
710 
711     case GL_BOOL: {
712         const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 1);
713         QGraphicsUtils::fillDataArray(bufferData, data, description, 1);
714         break;
715     }
716 
717     case GL_BOOL_VEC2: {
718         const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 2);
719         QGraphicsUtils::fillDataArray(bufferData, data, description, 2);
720         break;
721     }
722 
723     case GL_BOOL_VEC3: {
724         const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 3);
725         QGraphicsUtils::fillDataArray(bufferData, data, description, 3);
726         break;
727     }
728 
729     case GL_BOOL_VEC4: {
730         const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 4);
731         QGraphicsUtils::fillDataArray(bufferData, data, description, 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>(bufferData, &value, description, 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 
uniformByteSize(const ShaderUniform & description)783 uint GraphicsHelperGL3_3::uniformByteSize(const ShaderUniform &description)
784 {
785     uint rawByteSize = 0;
786     int arrayStride = qMax(description.m_arrayStride, 0);
787     int matrixStride = qMax(description.m_matrixStride, 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 
enableClipPlane(int clipPlane)907 void GraphicsHelperGL3_3::enableClipPlane(int clipPlane)
908 {
909     m_funcs->glEnable(GL_CLIP_DISTANCE0 + clipPlane);
910 }
911 
disableClipPlane(int clipPlane)912 void GraphicsHelperGL3_3::disableClipPlane(int clipPlane)
913 {
914     m_funcs->glDisable(GL_CLIP_DISTANCE0 + clipPlane);
915 }
916 
setClipPlane(int clipPlane,const QVector3D & normal,float distance)917 void 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 
maxClipPlaneCount()925 GLint GraphicsHelperGL3_3::maxClipPlaneCount()
926 {
927     GLint max = 0;
928     m_funcs->glGetIntegerv(GL_MAX_CLIP_DISTANCES, &max);
929     return max;
930 }
931 
memoryBarrier(QMemoryBarrier::Operations barriers)932 void 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 
enablePrimitiveRestart(int primitiveRestartIndex)938 void GraphicsHelperGL3_3::enablePrimitiveRestart(int primitiveRestartIndex)
939 {
940     m_funcs->glPrimitiveRestartIndex(primitiveRestartIndex);
941     m_funcs->glEnable(GL_PRIMITIVE_RESTART);
942 }
943 
enableVertexAttributeArray(int location)944 void GraphicsHelperGL3_3::enableVertexAttributeArray(int location)
945 {
946     m_funcs->glEnableVertexAttribArray(location);
947 }
948 
disablePrimitiveRestart()949 void GraphicsHelperGL3_3::disablePrimitiveRestart()
950 {
951     m_funcs->glDisable(GL_PRIMITIVE_RESTART);
952 }
953 
clearBufferf(GLint drawbuffer,const QVector4D & values)954 void 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, vec);
958 }
959 
pointSize(bool programmable,GLfloat value)960 void 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(value);
967     }
968 }
969 
enablei(GLenum cap,GLuint index)970 void GraphicsHelperGL3_3::enablei(GLenum cap, GLuint index)
971 {
972     m_funcs->glEnablei(cap, index);
973 }
974 
disablei(GLenum cap,GLuint index)975 void GraphicsHelperGL3_3::disablei(GLenum cap, GLuint index)
976 {
977     m_funcs->glDisablei(cap, index);
978 }
979 
setSeamlessCubemap(bool enable)980 void 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 
getRenderBufferDimensions(GLuint renderBufferId)988 QSize GraphicsHelperGL3_3::getRenderBufferDimensions(GLuint renderBufferId)
989 {
990     GLint width = 0;
991     GLint height = 0;
992 
993     m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, renderBufferId);
994     m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
995     m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);
996     m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, 0);
997 
998     return QSize(width, height);
999 }
1000 
getTextureDimensions(GLuint textureId,GLenum target,uint level)1001 QSize GraphicsHelperGL3_3::getTextureDimensions(GLuint textureId, GLenum target, uint level)
1002 {
1003     GLint width = 0;
1004     GLint height = 0;
1005 
1006     m_funcs->glBindTexture(target, textureId);
1007     m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
1008     m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
1009     m_funcs->glBindTexture(target, 0);
1010 
1011     return QSize(width, height);
1012 }
1013 
dispatchCompute(GLuint wx,GLuint wy,GLuint wz)1014 void 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 
mapBuffer(GLenum target,GLsizeiptr size)1022 char *GraphicsHelperGL3_3::mapBuffer(GLenum target, GLsizeiptr size)
1023 {
1024     return static_cast<char*>(m_funcs->glMapBufferRange(target, 0, size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
1025 }
1026 
unmapBuffer(GLenum target)1027 GLboolean GraphicsHelperGL3_3::unmapBuffer(GLenum target)
1028 {
1029     return m_funcs->glUnmapBuffer(target);
1030 }
1031 
glUniform1fv(GLint location,GLsizei count,const GLfloat * values)1032 void GraphicsHelperGL3_3::glUniform1fv(GLint location, GLsizei count, const GLfloat *values)
1033 {
1034     m_funcs->glUniform1fv(location, count, values);
1035 }
1036 
glUniform2fv(GLint location,GLsizei count,const GLfloat * values)1037 void GraphicsHelperGL3_3::glUniform2fv(GLint location, GLsizei count, const GLfloat *values)
1038 {
1039     m_funcs->glUniform2fv(location, count, values);
1040 }
1041 
glUniform3fv(GLint location,GLsizei count,const GLfloat * values)1042 void GraphicsHelperGL3_3::glUniform3fv(GLint location, GLsizei count, const GLfloat *values)
1043 {
1044     m_funcs->glUniform3fv(location, count, values);
1045 }
1046 
glUniform4fv(GLint location,GLsizei count,const GLfloat * values)1047 void GraphicsHelperGL3_3::glUniform4fv(GLint location, GLsizei count, const GLfloat *values)
1048 {
1049     m_funcs->glUniform4fv(location, count, values);
1050 }
1051 
glUniform1iv(GLint location,GLsizei count,const GLint * values)1052 void GraphicsHelperGL3_3::glUniform1iv(GLint location, GLsizei count, const GLint *values)
1053 {
1054     m_funcs->glUniform1iv(location, count, values);
1055 }
1056 
glUniform2iv(GLint location,GLsizei count,const GLint * values)1057 void GraphicsHelperGL3_3::glUniform2iv(GLint location, GLsizei count, const GLint *values)
1058 {
1059     m_funcs->glUniform2iv(location, count, values);
1060 }
1061 
glUniform3iv(GLint location,GLsizei count,const GLint * values)1062 void GraphicsHelperGL3_3::glUniform3iv(GLint location, GLsizei count, const GLint *values)
1063 {
1064     m_funcs->glUniform3iv(location, count, values);
1065 }
1066 
glUniform4iv(GLint location,GLsizei count,const GLint * values)1067 void GraphicsHelperGL3_3::glUniform4iv(GLint location, GLsizei count, const GLint *values)
1068 {
1069     m_funcs->glUniform4iv(location, count, values);
1070 }
1071 
glUniform1uiv(GLint location,GLsizei count,const GLuint * values)1072 void GraphicsHelperGL3_3::glUniform1uiv(GLint location, GLsizei count, const GLuint *values)
1073 {
1074     m_funcs->glUniform1uiv(location, count, values);
1075 }
1076 
glUniform2uiv(GLint location,GLsizei count,const GLuint * values)1077 void GraphicsHelperGL3_3::glUniform2uiv(GLint location, GLsizei count, const GLuint *values)
1078 {
1079     m_funcs->glUniform2uiv(location, count, values);
1080 }
1081 
glUniform3uiv(GLint location,GLsizei count,const GLuint * values)1082 void GraphicsHelperGL3_3::glUniform3uiv(GLint location, GLsizei count, const GLuint *values)
1083 {
1084     m_funcs->glUniform3uiv(location, count, values);
1085 }
1086 
glUniform4uiv(GLint location,GLsizei count,const GLuint * values)1087 void GraphicsHelperGL3_3::glUniform4uiv(GLint location, GLsizei count, const GLuint *values)
1088 {
1089     m_funcs->glUniform4uiv(location, count, values);
1090 }
1091 
glUniformMatrix2fv(GLint location,GLsizei count,const GLfloat * values)1092 void GraphicsHelperGL3_3::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values)
1093 {
1094     m_funcs->glUniformMatrix2fv(location, count, false, values);
1095 }
1096 
glUniformMatrix3fv(GLint location,GLsizei count,const GLfloat * values)1097 void GraphicsHelperGL3_3::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values)
1098 {
1099     m_funcs->glUniformMatrix3fv(location, count, false, values);
1100 }
1101 
glUniformMatrix4fv(GLint location,GLsizei count,const GLfloat * values)1102 void GraphicsHelperGL3_3::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values)
1103 {
1104     m_funcs->glUniformMatrix4fv(location, count, false, values);
1105 }
1106 
glUniformMatrix2x3fv(GLint location,GLsizei count,const GLfloat * values)1107 void GraphicsHelperGL3_3::glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *values)
1108 {
1109     m_funcs->glUniformMatrix2x3fv(location, count, false, values);
1110 }
1111 
glUniformMatrix3x2fv(GLint location,GLsizei count,const GLfloat * values)1112 void GraphicsHelperGL3_3::glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *values)
1113 {
1114     m_funcs->glUniformMatrix3x2fv(location, count, false, values);
1115 }
1116 
glUniformMatrix2x4fv(GLint location,GLsizei count,const GLfloat * values)1117 void GraphicsHelperGL3_3::glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *values)
1118 {
1119     m_funcs->glUniformMatrix2x4fv(location, count, false, values);
1120 }
1121 
glUniformMatrix4x2fv(GLint location,GLsizei count,const GLfloat * values)1122 void GraphicsHelperGL3_3::glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *values)
1123 {
1124     m_funcs->glUniformMatrix4x2fv(location, count, false, values);
1125 }
1126 
glUniformMatrix3x4fv(GLint location,GLsizei count,const GLfloat * values)1127 void GraphicsHelperGL3_3::glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *values)
1128 {
1129     m_funcs->glUniformMatrix3x4fv(location, count, false, values);
1130 }
1131 
glUniformMatrix4x3fv(GLint location,GLsizei count,const GLfloat * values)1132 void GraphicsHelperGL3_3::glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *values)
1133 {
1134     m_funcs->glUniformMatrix4x3fv(location, count, false, values);
1135 }
1136 
uniformTypeFromGLType(GLenum type)1137 UniformType 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 
blitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)1231 void 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 
1240 QT_END_NAMESPACE
1241 
1242 #endif // !QT_OPENGL_ES_2
1243