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 "graphicshelperes2_p.h"
41#include <Qt3DRender/private/renderlogging_p.h>
42#include <private/attachmentpack_p.h>
43#include <private/qgraphicsutils_p.h>
44#include <private/renderbuffer_p.h>
45#include <QtGui/private/qopenglextensions_p.h>
46
47QT_BEGIN_NAMESPACE
48
49// ES 3.0+
50#ifndef GL_SAMPLER_3D
51#define GL_SAMPLER_3D 0x8B5F
52#endif
53#ifndef GL_SAMPLER_2D_SHADOW
54#define GL_SAMPLER_2D_SHADOW 0x8B62
55#endif
56#ifndef GL_SAMPLER_CUBE_SHADOW
57#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
58#endif
59#ifndef GL_SAMPLER_2D_ARRAY
60#define GL_SAMPLER_2D_ARRAY 0x8DC1
61#endif
62#ifndef GL_SAMPLER_2D_ARRAY_SHADOW
63#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
64#endif
65
66namespace Qt3DRender {
67namespace Render {
68
69GraphicsHelperES2::GraphicsHelperES2()
70 : m_funcs(0)
71 , m_supportFramebufferBlit(false)
72{
73}
74
75GraphicsHelperES2::~GraphicsHelperES2()
76{
77}
78
79void GraphicsHelperES2::initializeHelper(QOpenGLContext *context,
80 QAbstractOpenGLFunctions *)
81{
82 Q_ASSERT(context);
83 m_funcs = context->functions();
84 Q_ASSERT(m_funcs);
85 m_ext.reset(new QOpenGLExtensions(context));
86 if (m_ext->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit))
87 m_supportFramebufferBlit = true;
88}
89
90void GraphicsHelperES2::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType,
91 GLsizei primitiveCount,
92 GLint indexType,
93 void *indices,
94 GLsizei instances,
95 GLint baseVertex,
96 GLint baseInstance)
97{
98 if (baseInstance != 0)
99 qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2";
100
101 if (baseVertex != 0)
102 qWarning() << "glDrawElementsInstancedBaseVertex is not supported with OpenGL ES 2";
103
104 for (GLint i = 0; i < instances; i++)
105 drawElements(primitiveType,
106 primitiveCount,
107 indexType,
108 indices);
109}
110
111void GraphicsHelperES2::drawArraysInstanced(GLenum primitiveType,
112 GLint first,
113 GLsizei count,
114 GLsizei instances)
115{
116 for (GLint i = 0; i < instances; i++)
117 drawArrays(primitiveType,
118 first,
119 count);
120}
121
122void GraphicsHelperES2::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance)
123{
124 if (baseInstance != 0)
125 qWarning() << "glDrawArraysInstancedBaseInstance is not supported with OpenGL ES 2";
126 for (GLint i = 0; i < instances; i++)
127 drawArrays(primitiveType,
128 first,
129 count);
130}
131
132void GraphicsHelperES2::drawElements(GLenum primitiveType,
133 GLsizei primitiveCount,
134 GLint indexType,
135 void *indices,
136 GLint baseVertex)
137{
138 if (baseVertex != 0)
139 qWarning() << "glDrawElementsBaseVertex is not supported with OpenGL ES 2";
140 QOpenGLExtensions *xfuncs = static_cast<QOpenGLExtensions *>(m_funcs);
141 if (indexType == GL_UNSIGNED_INT && !xfuncs->hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint)) {
142 static bool warnShown = false;
143 if (!warnShown) {
144 warnShown = true;
145 qWarning("GL_UNSIGNED_INT index type not supported on this system, skipping draw call.");
146 }
147 return;
148 }
149 m_funcs->glDrawElements(primitiveType,
150 primitiveCount,
151 indexType,
152 indices);
153}
154
155void GraphicsHelperES2::drawArrays(GLenum primitiveType,
156 GLint first,
157 GLsizei count)
158{
159 m_funcs->glDrawArrays(primitiveType,
160 first,
161 count);
162}
163
164void GraphicsHelperES2::drawElementsIndirect(GLenum, GLenum, void *)
165{
166 static bool showWarning = true;
167 if (!showWarning)
168 return;
169 showWarning = false;
170 qWarning() << "Indirect Drawing is not supported with OpenGL ES 2";
171}
172
173void GraphicsHelperES2::drawArraysIndirect(GLenum , void *)
174{
175 static bool showWarning = true;
176 if (!showWarning)
177 return;
178 showWarning = false;
179 qWarning() << "Indirect Drawing is not supported with OpenGL ES 2";
180}
181
182void GraphicsHelperES2::setVerticesPerPatch(GLint verticesPerPatch)
183{
184 Q_UNUSED(verticesPerPatch);
185 static bool showWarning = true;
186 if (!showWarning)
187 return;
188 showWarning = false;
189 qWarning() << "Tessellation not supported with OpenGL ES 2";
190}
191
192void GraphicsHelperES2::useProgram(GLuint programId)
193{
194 m_funcs->glUseProgram(programId);
195}
196
197QVector<ShaderUniform> GraphicsHelperES2::programUniformsAndLocations(GLuint programId)
198{
199 QVector<ShaderUniform> uniforms;
200
201 GLint nbrActiveUniforms = 0;
202 m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORMS, &nbrActiveUniforms);
203 uniforms.reserve(nbrActiveUniforms);
204 char uniformName[256];
205 for (GLint i = 0; i < nbrActiveUniforms; i++) {
206 ShaderUniform uniform;
207 GLsizei uniformNameLength = 0;
208 // Size is 1 for scalar and more for struct or arrays
209 // Type is the GL Type
210 m_funcs->glGetActiveUniform(programId, i, sizeof(uniformName) - 1, &uniformNameLength,
211 &uniform.m_size, &uniform.m_type, uniformName);
212 uniformName[sizeof(uniformName) - 1] = '\0';
213 uniform.m_location = m_funcs->glGetUniformLocation(programId, uniformName);
214 uniform.m_name = QString::fromUtf8(uniformName, uniformNameLength);
215 // Work around for uniform array names that aren't returned with [0] by some drivers
216 if (uniform.m_size > 1 && !uniform.m_name.endsWith(QLatin1String("[0]")))
217 uniform.m_name.append(QLatin1String("[0]"));
218 uniform.m_rawByteSize = uniformByteSize(uniform);
219 uniforms.append(uniform);
220 }
221 return uniforms;
222}
223
224QVector<ShaderAttribute> GraphicsHelperES2::programAttributesAndLocations(GLuint programId)
225{
226 QVector<ShaderAttribute> attributes;
227 GLint nbrActiveAttributes = 0;
228 m_funcs->glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &nbrActiveAttributes);
229 attributes.reserve(nbrActiveAttributes);
230 char attributeName[256];
231 for (GLint i = 0; i < nbrActiveAttributes; i++) {
232 ShaderAttribute attribute;
233 GLsizei attributeNameLength = 0;
234 // Size is 1 for scalar and more for struct or arrays
235 // Type is the GL Type
236 m_funcs->glGetActiveAttrib(programId, i, sizeof(attributeName) - 1, &attributeNameLength,
237 &attribute.m_size, &attribute.m_type, attributeName);
238 attributeName[sizeof(attributeName) - 1] = '\0';
239 attribute.m_location = m_funcs->glGetAttribLocation(programId, attributeName);
240 attribute.m_name = QString::fromUtf8(attributeName, attributeNameLength);
241 attributes.append(attribute);
242 }
243 return attributes;
244}
245
246QVector<ShaderUniformBlock> GraphicsHelperES2::programUniformBlocks(GLuint programId)
247{
248 Q_UNUSED(programId);
249 QVector<ShaderUniformBlock> blocks;
250 static bool showWarning = true;
251 if (!showWarning)
252 return blocks;
253 showWarning = false;
254 qWarning() << "UBO are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
255 return blocks;
256}
257
258QVector<ShaderStorageBlock> GraphicsHelperES2::programShaderStorageBlocks(GLuint programId)
259{
260 Q_UNUSED(programId);
261 QVector<ShaderStorageBlock> blocks;
262 static bool showWarning = true;
263 if (!showWarning)
264 return blocks;
265 showWarning = false;
266 qWarning() << "SSBO are not supported by OpenGL ES 2.0 (since OpenGL ES 3.1)";
267 return blocks;
268}
269
270void GraphicsHelperES2::vertexAttribDivisor(GLuint index, GLuint divisor)
271{
272 Q_UNUSED(index);
273 Q_UNUSED(divisor);
274}
275
276void GraphicsHelperES2::vertexAttributePointer(GLenum shaderDataType,
277 GLuint index,
278 GLint size,
279 GLenum type,
280 GLboolean normalized,
281 GLsizei stride,
282 const GLvoid *pointer)
283{
284 switch (shaderDataType) {
285 case GL_FLOAT:
286 case GL_FLOAT_VEC2:
287 case GL_FLOAT_VEC3:
288 case GL_FLOAT_VEC4:
289 case GL_FLOAT_MAT2:
290 case GL_FLOAT_MAT3:
291 case GL_FLOAT_MAT4:
292 m_funcs->glVertexAttribPointer(index, size, type, normalized, stride, pointer);
293 break;
294
295 default:
296 qCWarning(Render::Rendering) << "vertexAttribPointer: Unhandled type";
297 Q_UNREACHABLE();
298 }
299}
300
301void GraphicsHelperES2::readBuffer(GLenum mode)
302{
303 Q_UNUSED(mode)
304 static bool showWarning = true;
305 if (!showWarning)
306 return;
307 showWarning = false;
308 qWarning() << "glReadBuffer not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
309}
310
311void GraphicsHelperES2::drawBuffer(GLenum mode)
312{
313 Q_UNUSED(mode);
314 static bool showWarning = true;
315 if (!showWarning)
316 return;
317 showWarning = false;
318 qWarning() << "glDrawBuffer is not supported with OpenGL ES 2";
319}
320
321void *GraphicsHelperES2::fenceSync()
322{
323 qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
324 return nullptr;
325}
326
327void GraphicsHelperES2::clientWaitSync(void *, GLuint64 )
328{
329 qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
330}
331
332void GraphicsHelperES2::waitSync(void *)
333{
334 qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
335}
336
337bool GraphicsHelperES2::wasSyncSignaled(void *)
338{
339 qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
340 return false;
341}
342
343void GraphicsHelperES2::deleteSync(void *)
344{
345 qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
346}
347
348void GraphicsHelperES2::rasterMode(GLenum faceMode, GLenum rasterMode)
349{
350 Q_UNUSED(faceMode);
351 Q_UNUSED(rasterMode);
352 qWarning() << "glPolyonMode is not supported with OpenGL ES";
353}
354
355void GraphicsHelperES2::blendEquation(GLenum mode)
356{
357 m_funcs->glBlendEquation(mode);
358}
359
360void GraphicsHelperES2::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)
361{
362 Q_UNUSED(buf);
363 Q_UNUSED(sfactor);
364 Q_UNUSED(dfactor);
365
366 static bool showWarning = true;
367 if (!showWarning)
368 return;
369 showWarning = false;
370 qWarning() << "glBlendFunci() not supported by OpenGL ES 2.0";
371}
372
373void GraphicsHelperES2::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha)
374{
375 Q_UNUSED(buf);
376 Q_UNUSED(sRGB);
377 Q_UNUSED(dRGB);
378 Q_UNUSED(sAlpha);
379 Q_UNUSED(dAlpha);
380
381 static bool showWarning = true;
382 if (!showWarning)
383 return;
384 showWarning = false;
385 qWarning() << "glBlendFuncSeparatei() not supported by OpenGL ES 2.0";
386}
387
388void GraphicsHelperES2::alphaTest(GLenum, GLenum)
389{
390 qCWarning(Render::Rendering) << Q_FUNC_INFO << "AlphaTest not available with OpenGL ES 2.0";
391}
392
393void GraphicsHelperES2::depthTest(GLenum mode)
394{
395 m_funcs->glEnable(GL_DEPTH_TEST);
396 m_funcs->glDepthFunc(mode);
397}
398
399void GraphicsHelperES2::depthMask(GLenum mode)
400{
401 m_funcs->glDepthMask(mode);
402}
403
404void GraphicsHelperES2::depthRange(GLdouble nearValue, GLdouble farValue)
405{
406 m_funcs->glDepthRangef(static_cast<float>(nearValue), static_cast<float>(farValue));
407}
408
409void GraphicsHelperES2::frontFace(GLenum mode)
410{
411 m_funcs->glFrontFace(mode);
412}
413
414void GraphicsHelperES2::setMSAAEnabled(bool enabled)
415{
416 Q_UNUSED(enabled);
417 static bool showWarning = true;
418 if (!showWarning)
419 return;
420 showWarning = false;
421 qWarning() << "MSAA not available with OpenGL ES 2.0";
422}
423
424void GraphicsHelperES2::setAlphaCoverageEnabled(bool enabled)
425{
426 enabled ? m_funcs->glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE)
427 : m_funcs->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
428}
429
430GLuint GraphicsHelperES2::createFrameBufferObject()
431{
432 GLuint id;
433 m_funcs->glGenFramebuffers(1, &id);
434 return id;
435}
436
437void GraphicsHelperES2::releaseFrameBufferObject(GLuint frameBufferId)
438{
439 m_funcs->glDeleteFramebuffers(1, &frameBufferId);
440}
441
442void GraphicsHelperES2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode)
443{
444 Q_UNUSED(mode)
445 // For ES2 the spec states for target: The symbolic constant must be GL_FRAMEBUFFER
446 // so mode is ignored and is always set to GL_FRAMEBUFFER
447 m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
448}
449
450void GraphicsHelperES2::bindImageTexture(GLuint imageUnit, GLuint texture,
451 GLint mipLevel, GLboolean layered,
452 GLint layer, GLenum access, GLenum format)
453{
454 Q_UNUSED(imageUnit)
455 Q_UNUSED(texture)
456 Q_UNUSED(mipLevel)
457 Q_UNUSED(layered)
458 Q_UNUSED(layer)
459 Q_UNUSED(access)
460 Q_UNUSED(format)
461 qWarning() << "Shader Images are not supported by ES 2.0 (since ES 3.1)";
462
463}
464
465GLuint GraphicsHelperES2::boundFrameBufferObject()
466{
467 GLint id = 0;
468 m_funcs->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &id);
469 return id;
470}
471
472bool GraphicsHelperES2::checkFrameBufferComplete()
473{
474 return (m_funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
475}
476
477bool GraphicsHelperES2::frameBufferNeedsRenderBuffer(const Attachment &attachment)
478{
479 // Use a renderbuffer for depth or stencil attachments since this is
480 // problematic before GLES 3.2. Keep using textures for everything else.
481 // For ES2 individual Depth and Stencil buffers need to be an option because
482 // DepthStencil is an extension.
483 return attachment.m_point == QRenderTargetOutput::DepthStencil ||
484 attachment.m_point == QRenderTargetOutput::Depth ||
485 attachment.m_point == QRenderTargetOutput::Stencil;
486}
487
488void GraphicsHelperES2::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment)
489{
490 GLenum attr = GL_COLOR_ATTACHMENT0;
491
492 if (attachment.m_point == QRenderTargetOutput::Color0)
493 attr = GL_COLOR_ATTACHMENT0;
494 else if (attachment.m_point == QRenderTargetOutput::Depth)
495 attr = GL_DEPTH_ATTACHMENT;
496 else if (attachment.m_point == QRenderTargetOutput::Stencil)
497 attr = GL_STENCIL_ATTACHMENT;
498 else
499 qCritical() << "Unsupported FBO attachment OpenGL ES 2.0";
500
501 const QOpenGLTexture::Target target = texture->target();
502
503 if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face == QAbstractTexture::AllFaces) {
504 qWarning() << "OpenGL ES 2.0 doesn't handle attaching all the faces of a cube map texture at once to an FBO";
505 return;
506 }
507
508 texture->bind();
509 if (target == QOpenGLTexture::Target2D)
510 m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attr, target, texture->textureId(), attachment.m_mipLevel);
511 else if (target == QOpenGLTexture::TargetCubeMap)
512 m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel);
513 else
514 qCritical() << "Unsupported Texture FBO attachment format";
515 texture->release();
516}
517
518void GraphicsHelperES2::bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment)
519{
520 if (attachment.m_point != QRenderTargetOutput::DepthStencil &&
521 attachment.m_point != QRenderTargetOutput::Depth &&
522 attachment.m_point != QRenderTargetOutput::Stencil) {
523 qCritical() << "Renderbuffers only supported for combined depth-stencil, depth, or stencil, but got attachment point"
524 << attachment.m_point;
525 return;
526 }
527
528 renderBuffer->bind();
529 if (attachment.m_point == QRenderTargetOutput::DepthStencil ||
530 attachment.m_point == QRenderTargetOutput::Depth)
531 m_funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer->renderBufferId());
532 if (attachment.m_point == QRenderTargetOutput::DepthStencil ||
533 attachment.m_point == QRenderTargetOutput::Stencil)
534 m_funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer->renderBufferId());
535 renderBuffer->release();
536}
537
538bool GraphicsHelperES2::supportsFeature(GraphicsHelperInterface::Feature feature) const
539{
540 switch (feature) {
541 case RenderBufferDimensionRetrieval:
542 return true;
543 case BlitFramebuffer:
544 return m_supportFramebufferBlit;
545 default:
546 return false;
547 }
548}
549
550void GraphicsHelperES2::drawBuffers(GLsizei, const int *)
551{
552 static bool showWarning = true;
553 if (!showWarning)
554 return;
555 showWarning = false;
556 qWarning() << "drawBuffers is not supported by ES 2.0";
557}
558
559void GraphicsHelperES2::bindFragDataLocation(GLuint , const QHash<QString, int> &)
560{
561 qCritical() << "bindFragDataLocation is not supported by ES 2.0";
562}
563
564void GraphicsHelperES2::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
565{
566 Q_UNUSED(programId);
567 Q_UNUSED(uniformBlockIndex);
568 Q_UNUSED(uniformBlockBinding);
569 static bool showWarning = true;
570 if (!showWarning)
571 return;
572 showWarning = false;
573 qWarning() << "UBO are not supported by ES 2.0 (since ES 3.0)";
574}
575
576void GraphicsHelperES2::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding)
577{
578 Q_UNUSED(programId);
579 Q_UNUSED(shaderStorageBlockIndex);
580 Q_UNUSED(shaderStorageBlockBinding);
581 static bool showWarning = true;
582 if (!showWarning)
583 return;
584 showWarning = false;
585 qWarning() << "SSBO are not supported by ES 2.0 (since ES 3.1)";
586}
587
588void GraphicsHelperES2::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
589{
590 Q_UNUSED(target);
591 Q_UNUSED(index);
592 Q_UNUSED(buffer);
593 static bool showWarning = true;
594 if (!showWarning)
595 return;
596 showWarning = false;
597 qWarning() << "bindBufferBase is not supported by ES 2.0 (since ES 3.0)";
598}
599
600void GraphicsHelperES2::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer)
601{
602 Q_UNUSED(v);
603 Q_UNUSED(description);
604 Q_UNUSED(buffer);
605 static bool showWarning = true;
606 if (!showWarning)
607 return;
608 showWarning = false;
609 qWarning() << "UBO are not supported by ES 2.0 (since ES 3.0)";
610}
611
612uint GraphicsHelperES2::uniformByteSize(const ShaderUniform &description)
613{
614 uint rawByteSize = 0;
615 int arrayStride = qMax(description.m_arrayStride, 0);
616 int matrixStride = qMax(description.m_matrixStride, 0);
617
618 switch (description.m_type) {
619
620 case GL_FLOAT_VEC2:
621 case GL_INT_VEC2:
622 rawByteSize = 8;
623 break;
624
625 case GL_FLOAT_VEC3:
626 case GL_INT_VEC3:
627 rawByteSize = 12;
628 break;
629
630 case GL_FLOAT_VEC4:
631 case GL_INT_VEC4:
632 rawByteSize = 16;
633 break;
634
635 case GL_FLOAT_MAT2:
636 rawByteSize = matrixStride ? 2 * matrixStride : 16;
637 break;
638
639 case GL_FLOAT_MAT3:
640 rawByteSize = matrixStride ? 3 * matrixStride : 36;
641 break;
642
643 case GL_FLOAT_MAT4:
644 rawByteSize = matrixStride ? 4 * matrixStride : 64;
645 break;
646
647 case GL_BOOL:
648 rawByteSize = 1;
649 break;
650
651 case GL_BOOL_VEC2:
652 rawByteSize = 2;
653 break;
654
655 case GL_BOOL_VEC3:
656 rawByteSize = 3;
657 break;
658
659 case GL_BOOL_VEC4:
660 rawByteSize = 4;
661 break;
662
663 case GL_INT:
664 case GL_FLOAT:
665 case GL_SAMPLER_2D:
666 case GL_SAMPLER_CUBE:
667 rawByteSize = 4;
668 break;
669 }
670
671 return arrayStride ? rawByteSize * arrayStride : rawByteSize;
672}
673
674void GraphicsHelperES2::enableClipPlane(int)
675{
676}
677
678void GraphicsHelperES2::disableClipPlane(int)
679{
680}
681
682void GraphicsHelperES2::setClipPlane(int, const QVector3D &, float)
683{
684 static bool showWarning = true;
685 if (!showWarning)
686 return;
687 showWarning = false;
688 qWarning() << "Clip planes not supported by OpenGL ES 2.0";
689}
690
691GLint GraphicsHelperES2::maxClipPlaneCount()
692{
693 return 0;
694}
695
696void GraphicsHelperES2::memoryBarrier(QMemoryBarrier::Operations barriers)
697{
698 Q_UNUSED(barriers);
699 static bool showWarning = true;
700 if (!showWarning)
701 return;
702 showWarning = false;
703 qWarning() << "memory barrier is not supported by OpenGL ES 2.0 (since 4.3)";
704}
705
706void GraphicsHelperES2::enablePrimitiveRestart(int)
707{
708}
709
710void GraphicsHelperES2::enableVertexAttributeArray(int location)
711{
712 m_funcs->glEnableVertexAttribArray(location);
713}
714
715void GraphicsHelperES2::disablePrimitiveRestart()
716{
717}
718
719void GraphicsHelperES2::clearBufferf(GLint drawbuffer, const QVector4D &values)
720{
721 Q_UNUSED(drawbuffer);
722 Q_UNUSED(values);
723 static bool showWarning = true;
724 if (!showWarning)
725 return;
726 showWarning = false;
727 qWarning() << "glClearBuffer*() not supported by OpenGL ES 2.0";
728}
729
730void GraphicsHelperES2::pointSize(bool programmable, GLfloat value)
731{
732 // If this is not a reset to default values, print a warning
733 if (programmable || !qFuzzyCompare(value, 1.0f)) {
734 static bool warned = false;
735 if (!warned) {
736 qWarning() << "glPointSize() and GL_PROGRAM_POINT_SIZE are not supported by ES 2.0";
737 warned = true;
738 }
739 }
740}
741
742void GraphicsHelperES2::enablei(GLenum cap, GLuint index)
743{
744 Q_UNUSED(cap);
745 Q_UNUSED(index);
746 static bool showWarning = true;
747 if (!showWarning)
748 return;
749 showWarning = false;
750 qWarning() << "glEnablei() not supported by OpenGL ES 2.0";
751}
752
753void GraphicsHelperES2::disablei(GLenum cap, GLuint index)
754{
755 Q_UNUSED(cap);
756 Q_UNUSED(index);
757 static bool showWarning = true;
758 if (!showWarning)
759 return;
760 showWarning = false;
761 qWarning() << "glDisablei() not supported by OpenGL ES 2.0";
762}
763
764void GraphicsHelperES2::setSeamlessCubemap(bool enable)
765{
766 Q_UNUSED(enable);
767 static bool showWarning = true;
768 if (!showWarning)
769 return;
770 showWarning = false;
771 qWarning() << "GL_TEXTURE_CUBE_MAP_SEAMLESS not supported by OpenGL ES 2.0";
772}
773
774QSize GraphicsHelperES2::getRenderBufferDimensions(GLuint renderBufferId)
775{
776 GLint width = 0;
777 GLint height = 0;
778
779 m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, renderBufferId);
780 m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
781 m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);
782 m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, 0);
783
784 return QSize(width, height);
785}
786
787QSize GraphicsHelperES2::getTextureDimensions(GLuint textureId, GLenum target, uint level)
788{
789 Q_UNUSED(textureId);
790 Q_UNUSED(target);
791 Q_UNUSED(level);
792 qCritical() << "getTextureDimensions is not supported by ES 2.0";
793 return QSize(0, 0);
794}
795
796void GraphicsHelperES2::dispatchCompute(GLuint wx, GLuint wy, GLuint wz)
797{
798 Q_UNUSED(wx);
799 Q_UNUSED(wy);
800 Q_UNUSED(wz);
801 static bool showWarning = true;
802 if (!showWarning)
803 return;
804 showWarning = false;
805 qWarning() << "Compute Shaders are not supported by ES 2.0 (since ES 3.1)";
806}
807
808char *GraphicsHelperES2::mapBuffer(GLenum target, GLsizeiptr size)
809{
810 Q_UNUSED(target);
811 Q_UNUSED(size);
812 static bool showWarning = true;
813 if (!showWarning)
814 return nullptr;
815 showWarning = false;
816 qWarning() << "Map buffer is not a core requirement for ES 2.0";
817 return nullptr;
818}
819
820GLboolean GraphicsHelperES2::unmapBuffer(GLenum target)
821{
822 Q_UNUSED(target);
823 static bool showWarning = true;
824 if (!showWarning)
825 return false;
826 showWarning = false;
827 qWarning() << "unMap buffer is not a core requirement for ES 2.0";
828 return false;
829}
830
831void GraphicsHelperES2::glUniform1fv(GLint location, GLsizei count, const GLfloat *values)
832{
833 m_funcs->glUniform1fv(location, count, values);
834}
835
836void GraphicsHelperES2::glUniform2fv(GLint location, GLsizei count, const GLfloat *values)
837{
838 m_funcs->glUniform2fv(location, count, values);
839}
840
841void GraphicsHelperES2::glUniform3fv(GLint location, GLsizei count, const GLfloat *values)
842{
843 m_funcs->glUniform3fv(location, count, values);
844}
845
846void GraphicsHelperES2::glUniform4fv(GLint location, GLsizei count, const GLfloat *values)
847{
848 m_funcs->glUniform4fv(location, count, values);
849}
850
851void GraphicsHelperES2::glUniform1iv(GLint location, GLsizei count, const GLint *values)
852{
853 m_funcs->glUniform1iv(location, count, values);
854}
855
856void GraphicsHelperES2::glUniform2iv(GLint location, GLsizei count, const GLint *values)
857{
858 m_funcs->glUniform2iv(location, count, values);
859}
860
861void GraphicsHelperES2::glUniform3iv(GLint location, GLsizei count, const GLint *values)
862{
863 m_funcs->glUniform3iv(location, count, values);
864}
865
866void GraphicsHelperES2::glUniform4iv(GLint location, GLsizei count, const GLint *values)
867{
868 m_funcs->glUniform4iv(location, count, values);
869}
870
871void GraphicsHelperES2::glUniform1uiv(GLint , GLsizei , const GLuint *)
872{
873 static bool showWarning = true;
874 if (!showWarning)
875 return;
876 showWarning = false;
877 qWarning() << "glUniform1uiv not supported by ES 2";
878}
879
880void GraphicsHelperES2::glUniform2uiv(GLint , GLsizei , const GLuint *)
881{
882 static bool showWarning = true;
883 if (!showWarning)
884 return;
885 showWarning = false;
886 qWarning() << "glUniform2uiv not supported by ES 2";
887}
888
889void GraphicsHelperES2::glUniform3uiv(GLint , GLsizei , const GLuint *)
890{
891 static bool showWarning = true;
892 if (!showWarning)
893 return;
894 showWarning = false;
895 qWarning() << "glUniform3uiv not supported by ES 2";
896}
897
898void GraphicsHelperES2::glUniform4uiv(GLint , GLsizei , const GLuint *)
899{
900 static bool showWarning = true;
901 if (!showWarning)
902 return;
903 showWarning = false;
904 qWarning() << "glUniform4uiv not supported by ES 2";
905}
906
907void GraphicsHelperES2::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values)
908{
909 m_funcs->glUniformMatrix2fv(location, count, false, values);
910}
911
912void GraphicsHelperES2::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values)
913{
914 m_funcs->glUniformMatrix3fv(location, count, false, values);
915}
916
917void GraphicsHelperES2::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values)
918{
919 m_funcs->glUniformMatrix4fv(location, count, false, values);
920}
921
922void GraphicsHelperES2::glUniformMatrix2x3fv(GLint , GLsizei , const GLfloat *)
923{
924 static bool showWarning = true;
925 if (!showWarning)
926 return;
927 showWarning = false;
928 qWarning() << "glUniformMatrix2x3fv not supported by ES 2";
929}
930
931void GraphicsHelperES2::glUniformMatrix3x2fv(GLint , GLsizei , const GLfloat *)
932{
933 static bool showWarning = true;
934 if (!showWarning)
935 return;
936 showWarning = false;
937 qWarning() << "glUniformMatrix3x2fv not supported by ES 2";
938}
939
940void GraphicsHelperES2::glUniformMatrix2x4fv(GLint , GLsizei , const GLfloat *)
941{
942 static bool showWarning = true;
943 if (!showWarning)
944 return;
945 showWarning = false;
946 qWarning() << "glUniformMatrix2x4fv not supported by ES 2";
947}
948
949void GraphicsHelperES2::glUniformMatrix4x2fv(GLint , GLsizei , const GLfloat *)
950{
951 static bool showWarning = true;
952 if (!showWarning)
953 return;
954 showWarning = false;
955 qWarning() << "glUniformMatrix4x2fv not supported by ES 2";
956}
957
958void GraphicsHelperES2::glUniformMatrix3x4fv(GLint , GLsizei , const GLfloat *)
959{
960 static bool showWarning = true;
961 if (!showWarning)
962 return;
963 showWarning = false;
964 qWarning() << "glUniformMatrix3x4fv not supported by ES 2";
965}
966
967void GraphicsHelperES2::glUniformMatrix4x3fv(GLint , GLsizei , const GLfloat *)
968{
969 static bool showWarning = true;
970 if (!showWarning)
971 return;
972 showWarning = false;
973 qWarning() << "glUniformMatrix4x3fv not supported by ES 2";
974}
975
976UniformType GraphicsHelperES2::uniformTypeFromGLType(GLenum type)
977{
978 switch (type) {
979 case GL_FLOAT:
980 return UniformType::Float;
981 case GL_FLOAT_VEC2:
982 return UniformType::Vec2;
983 case GL_FLOAT_VEC3:
984 return UniformType::Vec3;
985 case GL_FLOAT_VEC4:
986 return UniformType::Vec4;
987 case GL_FLOAT_MAT2:
988 return UniformType::Mat2;
989 case GL_FLOAT_MAT3:
990 return UniformType::Mat3;
991 case GL_FLOAT_MAT4:
992 return UniformType::Mat4;
993 case GL_INT:
994 return UniformType::Int;
995 case GL_INT_VEC2:
996 return UniformType::IVec2;
997 case GL_INT_VEC3:
998 return UniformType::IVec3;
999 case GL_INT_VEC4:
1000 return UniformType::IVec4;
1001 case GL_BOOL:
1002 return UniformType::Bool;
1003 case GL_BOOL_VEC2:
1004 return UniformType::BVec2;
1005 case GL_BOOL_VEC3:
1006 return UniformType::BVec3;
1007 case GL_BOOL_VEC4:
1008 return UniformType::BVec4;
1009
1010 case GL_SAMPLER_2D:
1011 case GL_SAMPLER_CUBE:
1012 return UniformType::Sampler;
1013 default:
1014 Q_UNREACHABLE();
1015 return UniformType::Float;
1016 }
1017}
1018
1019void GraphicsHelperES2::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
1020{
1021 if (!m_supportFramebufferBlit) {
1022 static bool showWarning = true;
1023 if (!showWarning)
1024 return;
1025 showWarning = false;
1026 qWarning() << "Framebuffer blits are not supported by ES 2.0 (since ES 3.1)";
1027 } else
1028 m_ext->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
1029}
1030
1031} // namespace Render
1032} // namespace Qt3DRender
1033
1034QT_END_NAMESPACE
1035