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

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