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

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