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