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

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