1// Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
2// Copyright (C) 2016 Svenn-Arne Dragly.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "graphicshelperes3_p.h"
6#include <private/attachmentpack_p.h>
7#include <qgraphicsutils_p.h>
8#include <logging_p.h>
9#include <QOpenGLExtraFunctions>
10
11QT_BEGIN_NAMESPACE
12
13// ES 3.0+
14#ifndef GL_SAMPLER_3D
15#define GL_SAMPLER_3D 0x8B5F
16#endif
17#ifndef GL_SAMPLER_2D_SHADOW
18#define GL_SAMPLER_2D_SHADOW 0x8B62
19#endif
20#ifndef GL_SAMPLER_CUBE_SHADOW
21#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
22#endif
23#ifndef GL_SAMPLER_2D_ARRAY
24#define GL_SAMPLER_2D_ARRAY 0x8DC1
25#endif
26#ifndef GL_SAMPLER_2D_ARRAY_SHADOW
27#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
28#endif
29#ifndef GL_FLOAT_MAT2x3
30#define GL_FLOAT_MAT2x3 0x8B65
31#endif
32#ifndef GL_FLOAT_MAT2x4
33#define GL_FLOAT_MAT2x4 0x8B66
34#endif
35#ifndef GL_FLOAT_MAT3x2
36#define GL_FLOAT_MAT3x2 0x8B67
37#endif
38#ifndef GL_FLOAT_MAT3x4
39#define GL_FLOAT_MAT3x4 0x8B68
40#endif
41#ifndef GL_FLOAT_MAT4x2
42#define GL_FLOAT_MAT4x2 0x8B69
43#endif
44#ifndef GL_FLOAT_MAT4x3
45#define GL_FLOAT_MAT4x3 0x8B6A
46#endif
47#ifndef GL_UNSIGNED_INT_VEC2
48#define GL_UNSIGNED_INT_VEC2 0x8DC6
49#endif
50#ifndef GL_UNSIGNED_INT_VEC3
51#define GL_UNSIGNED_INT_VEC3 0x8DC7
52#endif
53#ifndef GL_UNSIGNED_INT_VEC4
54#define GL_UNSIGNED_INT_VEC4 0x8DC8
55#endif
56#ifndef GL_INT_SAMPLER_2D
57#define GL_INT_SAMPLER_2D 0x8DCA
58#endif
59#ifndef GL_INT_SAMPLER_3D
60#define GL_INT_SAMPLER_3D 0x8DCB
61#endif
62#ifndef GL_INT_SAMPLER_CUBE
63#define GL_INT_SAMPLER_CUBE 0x8DCC
64#endif
65#ifndef GL_INT_SAMPLER_2D_ARRAY
66#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
67#endif
68#ifndef GL_UNSIGNED_INT_SAMPLER_2D
69#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
70#endif
71#ifndef GL_UNSIGNED_INT_SAMPLER_3D
72#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
73#endif
74#ifndef GL_UNSIGNED_INT_SAMPLER_CUBE
75#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
76#endif
77#ifndef GL_UNSIGNED_INT_SAMPLER_2D_ARRAY
78#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
79#endif
80
81#ifndef GL_ACTIVE_UNIFORM_BLOCKS
82#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
83#endif
84#ifndef GL_UNIFORM_BLOCK_INDEX
85#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
86#endif
87#ifndef GL_UNIFORM_OFFSET
88#define GL_UNIFORM_OFFSET 0x8A3B
89#endif
90#ifndef GL_UNIFORM_ARRAY_STRIDE
91#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
92#endif
93#ifndef GL_UNIFORM_MATRIX_STRIDE
94#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
95#endif
96#ifndef GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS
97#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
98#endif
99#ifndef GL_UNIFORM_BLOCK_BINDING
100#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
101#endif
102#ifndef GL_UNIFORM_BLOCK_DATA_SIZE
103#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
104#endif
105
106#ifndef GL_DRAW_FRAMEBUFFER
107#define GL_DRAW_FRAMEBUFFER 0x8CA9
108#endif
109
110#ifndef GL_READ_FRAMEBUFFER
111#define GL_READ_FRAMEBUFFER 0x8CA8
112#endif
113
114#ifndef GL_SIGNALED
115#define GL_SIGNALED 0x9119
116#endif
117
118#ifndef GL_SYNC_STATUS
119#define GL_SYNC_STATUS 0x9114
120#endif
121
122#ifndef GL_TIMEOUT_IGNORED
123#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
124#endif
125
126#ifndef GL_SYNC_GPU_COMMANDS_COMPLETE
127#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
128#endif
129
130#ifndef GL_SYNC_FLUSH_COMMANDS_BIT
131#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
132#endif
133
134namespace Qt3DRender {
135namespace Render {
136namespace OpenGL {
137
138GraphicsHelperES3::GraphicsHelperES3()
139{
140}
141
142GraphicsHelperES3::~GraphicsHelperES3()
143{
144}
145
146void GraphicsHelperES3::initializeHelper(QOpenGLContext *context,
147 QAbstractOpenGLFunctions *functions)
148{
149 GraphicsHelperES2::initializeHelper(context, functions);
150 m_extraFuncs = context->extraFunctions();
151 Q_ASSERT(m_extraFuncs);
152}
153
154void GraphicsHelperES3::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType,
155 GLsizei primitiveCount,
156 GLint indexType,
157 void *indices,
158 GLsizei instances,
159 GLint baseVertex,
160 GLint baseInstance)
161{
162 if (baseInstance != 0)
163 qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 3";
164
165 if (baseVertex != 0)
166 qWarning() << "glDrawElementsInstancedBaseVertex is not supported with OpenGL ES 3";
167
168 m_extraFuncs->glDrawElementsInstanced(mode: primitiveType,
169 count: primitiveCount,
170 type: indexType,
171 indices,
172 instancecount: instances);
173}
174
175void GraphicsHelperES3::vertexAttribDivisor(GLuint index, GLuint divisor)
176{
177 m_extraFuncs->glVertexAttribDivisor(index, divisor);
178}
179
180void GraphicsHelperES3::vertexAttributePointer(GLenum shaderDataType,
181 GLuint index,
182 GLint size,
183 GLenum type,
184 GLboolean normalized,
185 GLsizei stride,
186 const GLvoid *pointer)
187{
188 switch (shaderDataType) {
189 case GL_FLOAT:
190 case GL_FLOAT_VEC2:
191 case GL_FLOAT_VEC3:
192 case GL_FLOAT_VEC4:
193 case GL_FLOAT_MAT2:
194 case GL_FLOAT_MAT2x3:
195 case GL_FLOAT_MAT2x4:
196 case GL_FLOAT_MAT3:
197 case GL_FLOAT_MAT3x2:
198 case GL_FLOAT_MAT3x4:
199 case GL_FLOAT_MAT4x2:
200 case GL_FLOAT_MAT4x3:
201 case GL_FLOAT_MAT4:
202 m_funcs->glVertexAttribPointer(indx: index, size, type, normalized, stride, ptr: pointer);
203 break;
204
205 case GL_INT:
206 case GL_INT_VEC2:
207 case GL_INT_VEC3:
208 case GL_INT_VEC4:
209 case GL_UNSIGNED_INT:
210 case GL_UNSIGNED_INT_VEC2:
211 case GL_UNSIGNED_INT_VEC3:
212 case GL_UNSIGNED_INT_VEC4:
213 m_extraFuncs->glVertexAttribIPointer(index, size, type, stride, pointer);
214 break;
215
216 default:
217 qCWarning(Rendering) << "vertexAttribPointer: Unhandled type";
218 Q_UNREACHABLE();
219 }
220}
221
222void GraphicsHelperES3::drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances)
223{
224 m_extraFuncs->glDrawArraysInstanced(mode: primitiveType,
225 first,
226 count,
227 instancecount: instances);
228}
229
230void GraphicsHelperES3::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance)
231{
232 if (baseInstance != 0)
233 qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 3";
234
235 m_extraFuncs->glDrawArraysInstanced(mode: primitiveType,
236 first,
237 count,
238 instancecount: instances);
239}
240
241void GraphicsHelperES3::readBuffer(GLenum mode)
242{
243 m_extraFuncs->glReadBuffer(src: mode);
244}
245
246void GraphicsHelperES3::drawBuffer(GLenum mode)
247{
248 Q_UNUSED(mode);
249 qWarning() << "glDrawBuffer is not supported with OpenGL ES 3";
250}
251
252void GraphicsHelperES3::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment)
253{
254 GLenum attr = GL_COLOR_ATTACHMENT0;
255
256 if (attachment.m_point <= QRenderTargetOutput::Color15)
257 attr = GL_COLOR_ATTACHMENT0 + attachment.m_point;
258 else if (attachment.m_point == QRenderTargetOutput::Depth)
259 attr = GL_DEPTH_ATTACHMENT;
260 else if (attachment.m_point == QRenderTargetOutput::Stencil)
261 attr = GL_STENCIL_ATTACHMENT;
262 else
263 qCritical() << "Unsupported FBO attachment OpenGL ES 3.0";
264
265 const QOpenGLTexture::Target target = texture->target();
266
267 if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face == QAbstractTexture::AllFaces) {
268 qWarning() << "OpenGL ES 3.0 doesn't handle attaching all the faces of a cube map texture at once to an FBO";
269 return;
270 }
271
272 texture->bind();
273 if (target == QOpenGLTexture::Target2D)
274 m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attachment: attr, textarget: target, texture: texture->textureId(), level: attachment.m_mipLevel);
275 else if (target == QOpenGLTexture::TargetCubeMap)
276 m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attachment: attr, textarget: attachment.m_face, texture: texture->textureId(), level: attachment.m_mipLevel);
277 else
278 qCritical() << "Unsupported Texture FBO attachment format";
279 texture->release();
280}
281
282void GraphicsHelperES3::bindFrameBufferObject(GLuint frameBufferId, GraphicsHelperInterface::FBOBindMode mode)
283{
284 switch (mode) {
285 case FBODraw:
286 m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: frameBufferId);
287 return;
288 case FBORead:
289 m_funcs->glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer: frameBufferId);
290 return;
291 case FBOReadAndDraw:
292 default:
293 m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, framebuffer: frameBufferId);
294 return;
295 }
296}
297
298bool GraphicsHelperES3::supportsFeature(GraphicsHelperInterface::Feature feature) const
299{
300 switch (feature) {
301 case RenderBufferDimensionRetrieval:
302 case MRT:
303 case BlitFramebuffer:
304 case UniformBufferObject:
305 case MapBuffer:
306 case Fences:
307 return true;
308 default:
309 return false;
310 }
311}
312
313void GraphicsHelperES3::drawBuffers(GLsizei n, const int *bufs)
314{
315 QVarLengthArray<GLenum, 16> drawBufs(n);
316
317 for (int i = 0; i < n; i++)
318 drawBufs[i] = GL_COLOR_ATTACHMENT0 + bufs[i];
319 m_extraFuncs->glDrawBuffers(n, bufs: drawBufs.constData());
320}
321
322UniformType GraphicsHelperES3::uniformTypeFromGLType(GLenum glType)
323{
324 switch (glType) {
325 case GL_SAMPLER_3D:
326 case GL_SAMPLER_2D_SHADOW:
327 case GL_SAMPLER_CUBE_SHADOW:
328 case GL_SAMPLER_2D_ARRAY:
329 case GL_SAMPLER_2D_ARRAY_SHADOW:
330 return UniformType::Sampler;
331 default:
332 return GraphicsHelperES2::uniformTypeFromGLType(glType);
333 }
334}
335
336uint GraphicsHelperES3::uniformByteSize(const ShaderUniform &description)
337{
338 uint rawByteSize = 0;
339 int arrayStride = qMax(a: description.m_arrayStride, b: 0);
340 int matrixStride = qMax(a: description.m_matrixStride, b: 0);
341
342 switch (description.m_type) {
343
344 case GL_FLOAT_VEC2:
345 case GL_INT_VEC2:
346 case GL_UNSIGNED_INT_VEC2:
347 rawByteSize = 8;
348 break;
349
350 case GL_FLOAT_VEC3:
351 case GL_INT_VEC3:
352 case GL_UNSIGNED_INT_VEC3:
353 rawByteSize = 12;
354 break;
355
356 case GL_FLOAT_VEC4:
357 case GL_INT_VEC4:
358 case GL_UNSIGNED_INT_VEC4:
359 rawByteSize = 16;
360 break;
361
362 case GL_FLOAT_MAT2:
363 rawByteSize = matrixStride ? 2 * matrixStride : 16;
364 break;
365
366 case GL_FLOAT_MAT2x4:
367 rawByteSize = matrixStride ? 2 * matrixStride : 32;
368 break;
369
370 case GL_FLOAT_MAT4x2:
371 rawByteSize = matrixStride ? 4 * matrixStride : 32;
372 break;
373
374 case GL_FLOAT_MAT3:
375 rawByteSize = matrixStride ? 3 * matrixStride : 36;
376 break;
377
378 case GL_FLOAT_MAT2x3:
379 rawByteSize = matrixStride ? 2 * matrixStride : 24;
380 break;
381
382 case GL_FLOAT_MAT3x2:
383 rawByteSize = matrixStride ? 3 * matrixStride : 24;
384 break;
385
386 case GL_FLOAT_MAT4:
387 rawByteSize = matrixStride ? 4 * matrixStride : 64;
388 break;
389
390 case GL_FLOAT_MAT4x3:
391 rawByteSize = matrixStride ? 4 * matrixStride : 48;
392 break;
393
394 case GL_FLOAT_MAT3x4:
395 rawByteSize = matrixStride ? 3 * matrixStride : 48;
396 break;
397
398 case GL_BOOL:
399 rawByteSize = 1;
400 break;
401
402 case GL_BOOL_VEC2:
403 rawByteSize = 2;
404 break;
405
406 case GL_BOOL_VEC3:
407 rawByteSize = 3;
408 break;
409
410 case GL_BOOL_VEC4:
411 rawByteSize = 4;
412 break;
413
414 case GL_INT:
415 case GL_FLOAT:
416 case GL_UNSIGNED_INT:
417 case GL_SAMPLER_2D:
418 case GL_SAMPLER_3D:
419 case GL_SAMPLER_CUBE:
420 case GL_INT_SAMPLER_2D:
421 case GL_INT_SAMPLER_3D:
422 case GL_INT_SAMPLER_CUBE:
423 case GL_UNSIGNED_INT_SAMPLER_2D:
424 case GL_UNSIGNED_INT_SAMPLER_3D:
425 case GL_UNSIGNED_INT_SAMPLER_CUBE:
426 case GL_SAMPLER_2D_SHADOW:
427 case GL_SAMPLER_CUBE_SHADOW:
428 case GL_SAMPLER_2D_ARRAY:
429 case GL_INT_SAMPLER_2D_ARRAY:
430 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
431 case GL_SAMPLER_2D_ARRAY_SHADOW:
432 rawByteSize = 4;
433 break;
434 }
435
436 return arrayStride ? rawByteSize * arrayStride : rawByteSize;
437}
438
439void *GraphicsHelperES3::fenceSync()
440{
441 return m_extraFuncs->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, flags: 0);
442}
443
444void GraphicsHelperES3::clientWaitSync(void *sync, GLuint64 nanoSecTimeout)
445{
446 m_extraFuncs->glClientWaitSync(sync: static_cast<GLsync>(sync), GL_SYNC_FLUSH_COMMANDS_BIT, timeout: nanoSecTimeout);
447}
448
449void GraphicsHelperES3::waitSync(void *sync)
450{
451 m_extraFuncs->glWaitSync(sync: static_cast<GLsync>(sync), flags: 0, GL_TIMEOUT_IGNORED);
452}
453
454bool GraphicsHelperES3::wasSyncSignaled(void *sync)
455{
456 GLint v;
457 m_extraFuncs->glGetSynciv(sync: static_cast<GLsync>(sync),
458 GL_SYNC_STATUS,
459 bufSize: sizeof(v),
460 length: nullptr,
461 values: &v);
462 return v == GL_SIGNALED;
463}
464
465void GraphicsHelperES3::deleteSync(void *sync)
466{
467 m_extraFuncs->glDeleteSync(sync: static_cast<GLsync>(sync));
468}
469
470void GraphicsHelperES3::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
471{
472 m_extraFuncs->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
473}
474
475void GraphicsHelperES3::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
476{
477 m_extraFuncs->glBindBufferBase(target, index, buffer);
478}
479
480bool GraphicsHelperES3::frameBufferNeedsRenderBuffer(const Attachment &attachment)
481{
482 // Use a renderbuffer for combined depth+stencil attachments since this is
483 // problematic before GLES 3.2. Keep using textures for everything else.
484 return attachment.m_point == QRenderTargetOutput::DepthStencil;
485}
486
487void GraphicsHelperES3::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
488{
489 m_extraFuncs->glUniformBlockBinding(program: programId, uniformBlockIndex, uniformBlockBinding);
490}
491
492void GraphicsHelperES3::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer)
493{
494 char *bufferData = buffer.data();
495
496 switch (description.m_type) {
497
498 case GL_FLOAT: {
499 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 1);
500 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 1);
501 break;
502 }
503
504 case GL_FLOAT_VEC2: {
505 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 2);
506 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 2);
507 break;
508 }
509
510 case GL_FLOAT_VEC3: {
511 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 3);
512 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 3);
513 break;
514 }
515
516 case GL_FLOAT_VEC4: {
517 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 4);
518 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 4);
519 break;
520 }
521
522 case GL_FLOAT_MAT2: {
523 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 4);
524 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 2, rows: 2);
525 break;
526 }
527
528 case GL_FLOAT_MAT2x3: {
529 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 6);
530 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 2, rows: 3);
531 break;
532 }
533
534 case GL_FLOAT_MAT2x4: {
535 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 8);
536 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 2, rows: 4);
537 break;
538 }
539
540 case GL_FLOAT_MAT3: {
541 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 9);
542 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 3, rows: 3);
543 break;
544 }
545
546 case GL_FLOAT_MAT3x2: {
547 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 6);
548 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 3, rows: 2);
549 break;
550 }
551
552 case GL_FLOAT_MAT3x4: {
553 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 12);
554 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 3, rows: 4);
555 break;
556 }
557
558 case GL_FLOAT_MAT4: {
559 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 16);
560 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 4, rows: 4);
561 break;
562 }
563
564 case GL_FLOAT_MAT4x2: {
565 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 8);
566 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 4, rows: 2);
567 break;
568 }
569
570 case GL_FLOAT_MAT4x3: {
571 const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, count: description.m_size, tupleSize: 12);
572 QGraphicsUtils::fillDataMatrixArray(buffer: bufferData, data, description, cols: 4, rows: 3);
573 break;
574 }
575
576 case GL_INT: {
577 const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, count: description.m_size, tupleSize: 1);
578 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 1);
579 break;
580 }
581
582 case GL_INT_VEC2: {
583 const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, count: description.m_size, tupleSize: 2);
584 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 2);
585 break;
586 }
587
588 case GL_INT_VEC3: {
589 const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, count: description.m_size, tupleSize: 3);
590 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 3);
591 break;
592 }
593
594 case GL_INT_VEC4: {
595 const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, count: description.m_size, tupleSize: 4);
596 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 4);
597 break;
598 }
599
600 case GL_UNSIGNED_INT: {
601 const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, count: description.m_size, tupleSize: 1);
602 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 1);
603 break;
604 }
605
606 case GL_UNSIGNED_INT_VEC2: {
607 const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, count: description.m_size, tupleSize: 2);
608 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 2);
609 break;
610 }
611
612 case GL_UNSIGNED_INT_VEC3: {
613 const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, count: description.m_size, tupleSize: 3);
614 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 3);
615 break;
616 }
617
618 case GL_UNSIGNED_INT_VEC4: {
619 const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, count: description.m_size, tupleSize: 4);
620 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 4);
621 break;
622 }
623
624 case GL_BOOL: {
625 const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, count: description.m_size, tupleSize: 1);
626 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 1);
627 break;
628 }
629
630 case GL_BOOL_VEC2: {
631 const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, count: description.m_size, tupleSize: 2);
632 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 2);
633 break;
634 }
635
636 case GL_BOOL_VEC3: {
637 const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, count: description.m_size, tupleSize: 3);
638 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 3);
639 break;
640 }
641
642 case GL_BOOL_VEC4: {
643 const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, count: description.m_size, tupleSize: 4);
644 QGraphicsUtils::fillDataArray(buffer: bufferData, data, description, tupleSize: 4);
645 break;
646 }
647
648 // note: only GLES 3.0 supported types, not the same as OpenGL proper
649 // (also, no MS samplers before ES 3.1)
650 case GL_SAMPLER_2D:
651 case GL_SAMPLER_3D:
652 case GL_SAMPLER_CUBE:
653 case GL_INT_SAMPLER_2D:
654 case GL_INT_SAMPLER_3D:
655 case GL_INT_SAMPLER_CUBE:
656 case GL_UNSIGNED_INT_SAMPLER_2D:
657 case GL_UNSIGNED_INT_SAMPLER_3D:
658 case GL_UNSIGNED_INT_SAMPLER_CUBE:
659 case GL_SAMPLER_2D_SHADOW:
660 case GL_SAMPLER_CUBE_SHADOW:
661 case GL_SAMPLER_2D_ARRAY:
662 case GL_INT_SAMPLER_2D_ARRAY:
663 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
664 case GL_SAMPLER_2D_ARRAY_SHADOW:
665 {
666 Q_ASSERT(description.m_size == 1);
667 int value = v.toInt();
668 QGraphicsUtils::fillDataArray<GLint>(buffer: bufferData, data: &value, description, tupleSize: 1);
669 break;
670 }
671
672 default:
673 qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name;
674 break;
675 }
676}
677
678char *GraphicsHelperES3::mapBuffer(GLenum target, GLsizeiptr size)
679{
680 return static_cast<char*>(m_extraFuncs->glMapBufferRange(target, offset: 0, length: size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
681}
682
683GLboolean GraphicsHelperES3::unmapBuffer(GLenum target)
684{
685 return m_extraFuncs->glUnmapBuffer(target);
686}
687
688std::vector<ShaderUniform> GraphicsHelperES3::programUniformsAndLocations(GLuint programId)
689{
690 std::vector<ShaderUniform> uniforms;
691
692 GLint nbrActiveUniforms = 0;
693 m_funcs->glGetProgramiv(program: programId, GL_ACTIVE_UNIFORMS, params: &nbrActiveUniforms);
694 uniforms.reserve(n: nbrActiveUniforms);
695 char uniformName[256];
696 for (GLint i = 0; i < nbrActiveUniforms; i++) {
697 ShaderUniform uniform;
698 GLsizei uniformNameLength = 0;
699 // Size is 1 for scalar and more for struct or arrays
700 // Type is the GL Type
701 m_funcs->glGetActiveUniform(program: programId, index: i, bufsize: sizeof(uniformName) - 1, length: &uniformNameLength,
702 size: &uniform.m_size, type: &uniform.m_type, name: uniformName);
703 uniformName[sizeof(uniformName) - 1] = '\0';
704 uniform.m_location = m_funcs->glGetUniformLocation(program: programId, name: uniformName);
705 uniform.m_name = QString::fromUtf8(utf8: uniformName, size: uniformNameLength);
706 m_extraFuncs->glGetActiveUniformsiv(program: programId, uniformCount: 1, uniformIndices: (GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, params: &uniform.m_blockIndex);
707 m_extraFuncs->glGetActiveUniformsiv(program: programId, uniformCount: 1, uniformIndices: (GLuint*)&i, GL_UNIFORM_OFFSET, params: &uniform.m_offset);
708 m_extraFuncs->glGetActiveUniformsiv(program: programId, uniformCount: 1, uniformIndices: (GLuint*)&i, GL_UNIFORM_ARRAY_STRIDE, params: &uniform.m_arrayStride);
709 m_extraFuncs->glGetActiveUniformsiv(program: programId, uniformCount: 1, uniformIndices: (GLuint*)&i, GL_UNIFORM_MATRIX_STRIDE, params: &uniform.m_matrixStride);
710 uniform.m_rawByteSize = uniformByteSize(description: uniform);
711 uniforms.push_back(x: uniform);
712 qCDebug(Rendering) << uniform.m_name << "size" << uniform.m_size
713 << " offset" << uniform.m_offset
714 << " rawSize" << uniform.m_rawByteSize;
715 }
716
717 return uniforms;
718}
719
720std::vector<ShaderUniformBlock> GraphicsHelperES3::programUniformBlocks(GLuint programId)
721{
722 std::vector<ShaderUniformBlock> blocks;
723 GLint nbrActiveUniformsBlocks = 0;
724 m_extraFuncs->glGetProgramiv(program: programId, GL_ACTIVE_UNIFORM_BLOCKS, params: &nbrActiveUniformsBlocks);
725 blocks.reserve(n: nbrActiveUniformsBlocks);
726 for (GLint i = 0; i < nbrActiveUniformsBlocks; i++) {
727 QByteArray uniformBlockName(256, '\0');
728 GLsizei length = 0;
729 ShaderUniformBlock uniformBlock;
730 m_extraFuncs->glGetActiveUniformBlockName(program: programId, uniformBlockIndex: i, bufSize: 256, length: &length, uniformBlockName: uniformBlockName.data());
731 uniformBlock.m_name = QString::fromUtf8(ba: uniformBlockName.left(len: length));
732 uniformBlock.m_index = i;
733 m_extraFuncs->glGetActiveUniformBlockiv(program: programId, uniformBlockIndex: i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, params: &uniformBlock.m_activeUniformsCount);
734 m_extraFuncs->glGetActiveUniformBlockiv(program: programId, uniformBlockIndex: i, GL_UNIFORM_BLOCK_BINDING, params: &uniformBlock.m_binding);
735 m_extraFuncs->glGetActiveUniformBlockiv(program: programId, uniformBlockIndex: i, GL_UNIFORM_BLOCK_DATA_SIZE, params: &uniformBlock.m_size);
736 blocks.push_back(x: uniformBlock);
737 }
738 return blocks;
739}
740
741} // namespace OpenGL
742} // namespace Render
743} // namespace Qt3DRender
744
745QT_END_NAMESPACE
746

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