1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtOpenGL 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 "qglshaderprogram.h"
41#include <private/qopenglextensions_p.h>
42#include "qgl_p.h"
43#include <QtCore/private/qobject_p.h>
44#include <QtCore/qdebug.h>
45#include <QtCore/qfile.h>
46#include <QtCore/qvarlengtharray.h>
47#include <QtCore/qvector.h>
48#include <QDebug>
49
50QT_BEGIN_NAMESPACE
51
52/*!
53 \class QGLShaderProgram
54 \inmodule QtOpenGL
55 \brief The QGLShaderProgram class allows OpenGL shader programs to be linked and used.
56 \since 4.6
57 \obsolete
58 \ingroup painting-3D
59
60 \section1 Introduction
61
62 This class supports shader programs written in the OpenGL Shading
63 Language (GLSL) and in the OpenGL/ES Shading Language (GLSL/ES).
64
65 QGLShader and QGLShaderProgram shelter the programmer from the details of
66 compiling and linking vertex and fragment shaders.
67
68 The following example creates a vertex shader program using the
69 supplied source \c{code}. Once compiled and linked, the shader
70 program is activated in the current QGLContext by calling
71 QGLShaderProgram::bind():
72
73 \snippet code/src_opengl_qglshaderprogram.cpp 0
74
75 \section1 Writing Portable Shaders
76
77 Shader programs can be difficult to reuse across OpenGL implementations
78 because of varying levels of support for standard vertex attributes and
79 uniform variables. In particular, GLSL/ES lacks all of the
80 standard variables that are present on desktop OpenGL systems:
81 \c{gl_Vertex}, \c{gl_Normal}, \c{gl_Color}, and so on. Desktop OpenGL
82 lacks the variable qualifiers \c{highp}, \c{mediump}, and \c{lowp}.
83
84 The QGLShaderProgram class makes the process of writing portable shaders
85 easier by prefixing all shader programs with the following lines on
86 desktop OpenGL:
87
88 \code
89 #define highp
90 #define mediump
91 #define lowp
92 \endcode
93
94 This makes it possible to run most GLSL/ES shader programs
95 on desktop systems. The programmer should restrict themselves
96 to just features that are present in GLSL/ES, and avoid
97 standard variable names that only work on the desktop.
98
99 \section1 Simple Shader Example
100
101 \snippet code/src_opengl_qglshaderprogram.cpp 1
102
103 With the above shader program active, we can draw a green triangle
104 as follows:
105
106 \snippet code/src_opengl_qglshaderprogram.cpp 2
107
108 \section1 Binary Shaders and Programs
109
110 Binary shaders may be specified using \c{glShaderBinary()} on
111 the return value from QGLShader::shaderId(). The QGLShader instance
112 containing the binary can then be added to the shader program with
113 addShader() and linked in the usual fashion with link().
114
115 Binary programs may be specified using \c{glProgramBinaryOES()}
116 on the return value from programId(). Then the application should
117 call link(), which will notice that the program has already been
118 specified and linked, allowing other operations to be performed
119 on the shader program.
120
121 \note This class has been deprecated in favor of QOpenGLShaderProgram.
122
123 \sa QGLShader
124*/
125
126/*!
127 \class QGLShader
128 \inmodule QtOpenGL
129 \brief The QGLShader class allows OpenGL shaders to be compiled.
130 \since 4.6
131 \obsolete
132 \ingroup painting-3D
133
134 This class supports shaders written in the OpenGL Shading Language (GLSL)
135 and in the OpenGL/ES Shading Language (GLSL/ES).
136
137 QGLShader and QGLShaderProgram shelter the programmer from the details of
138 compiling and linking vertex and fragment shaders.
139
140 \note This class has been deprecated in favor of QOpenGLShader.
141
142 \sa QGLShaderProgram
143*/
144
145/*!
146 \enum QGLShader::ShaderTypeBit
147 This enum specifies the type of QGLShader that is being created.
148
149 \value Vertex Vertex shader written in the OpenGL Shading Language (GLSL).
150 \value Fragment Fragment shader written in the OpenGL Shading Language (GLSL).
151 \value Geometry Geometry shaders written in the OpenGL Shading
152 Language (GLSL), based on the GL_EXT_geometry_shader4 extension.
153*/
154
155#ifndef GL_FRAGMENT_SHADER
156#define GL_FRAGMENT_SHADER 0x8B30
157#endif
158#ifndef GL_VERTEX_SHADER
159#define GL_VERTEX_SHADER 0x8B31
160#endif
161#ifndef GL_COMPILE_STATUS
162#define GL_COMPILE_STATUS 0x8B81
163#endif
164#ifndef GL_LINK_STATUS
165#define GL_LINK_STATUS 0x8B82
166#endif
167#ifndef GL_INFO_LOG_LENGTH
168#define GL_INFO_LOG_LENGTH 0x8B84
169#endif
170#ifndef GL_ACTIVE_UNIFORMS
171#define GL_ACTIVE_UNIFORMS 0x8B86
172#endif
173#ifndef GL_ACTIVE_UNIFORM_MAX_LENGTH
174#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
175#endif
176#ifndef GL_ACTIVE_ATTRIBUTES
177#define GL_ACTIVE_ATTRIBUTES 0x8B89
178#endif
179#ifndef GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
180#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
181#endif
182#ifndef GL_CURRENT_VERTEX_ATTRIB
183#define GL_CURRENT_VERTEX_ATTRIB 0x8626
184#endif
185#ifndef GL_SHADER_SOURCE_LENGTH
186#define GL_SHADER_SOURCE_LENGTH 0x8B88
187#endif
188#ifndef GL_SHADER_BINARY_FORMATS
189#define GL_SHADER_BINARY_FORMATS 0x8DF8
190#endif
191#ifndef GL_NUM_SHADER_BINARY_FORMATS
192#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
193#endif
194
195class QGLShaderPrivate : public QObjectPrivate
196{
197 Q_DECLARE_PUBLIC(QGLShader)
198public:
199 QGLShaderPrivate(const QGLContext *ctx, QGLShader::ShaderType type)
200 : shaderGuard(0)
201 , shaderType(type)
202 , compiled(false)
203 , glfuncs(new QOpenGLFunctions(ctx->contextHandle()))
204 {
205 }
206 ~QGLShaderPrivate();
207
208 QGLSharedResourceGuardBase *shaderGuard;
209 QGLShader::ShaderType shaderType;
210 bool compiled;
211 QString log;
212
213 QOpenGLFunctions *glfuncs;
214
215 bool create();
216 bool compile(QGLShader *q);
217 void deleteShader();
218};
219
220namespace {
221 void freeShaderFunc(QGLContext *ctx, GLuint id)
222 {
223 Q_ASSERT(ctx);
224 ctx->contextHandle()->functions()->glDeleteShader(shader: id);
225 }
226}
227
228#define ctx QGLContext::currentContext()
229
230QGLShaderPrivate::~QGLShaderPrivate()
231{
232 delete glfuncs;
233 if (shaderGuard)
234 shaderGuard->free();
235}
236
237bool QGLShaderPrivate::create()
238{
239 QGLContext *context = const_cast<QGLContext *>(QGLContext::currentContext());
240 if (!context)
241 return false;
242
243 if (glfuncs->hasOpenGLFeature(feature: QOpenGLFunctions::Shaders)) {
244 GLuint shader;
245 if (shaderType == QGLShader::Vertex)
246 shader = glfuncs->glCreateShader(GL_VERTEX_SHADER);
247#if !defined(QT_OPENGL_ES_2)
248 else if (shaderType == QGLShader::Geometry
249 && !context->contextHandle()->isOpenGLES())
250 shader = glfuncs->glCreateShader(GL_GEOMETRY_SHADER_EXT);
251#endif
252 else
253 shader = glfuncs->glCreateShader(GL_FRAGMENT_SHADER);
254 if (!shader) {
255 qWarning(msg: "Could not create shader of type %d.", int(shaderType));
256 return false;
257 }
258 shaderGuard = createSharedResourceGuard(context, id: shader, cleanupFunc: freeShaderFunc);
259 return true;
260 } else {
261 return false;
262 }
263}
264
265bool QGLShaderPrivate::compile(QGLShader *q)
266{
267 GLuint shader = shaderGuard ? shaderGuard->id() : 0;
268 if (!shader)
269 return false;
270 glfuncs->glCompileShader(shader);
271 GLint value = 0;
272 glfuncs->glGetShaderiv(shader, GL_COMPILE_STATUS, params: &value);
273 compiled = (value != 0);
274 value = 0;
275 glfuncs->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, params: &value);
276 if (!compiled && value > 1) {
277 char *logbuf = new char [value];
278 GLint len;
279 glfuncs->glGetShaderInfoLog(shader, bufsize: value, length: &len, infolog: logbuf);
280 log = QString::fromLatin1(str: logbuf);
281 QString name = q->objectName();
282
283 const char *types[] = {
284 "Fragment",
285 "Vertex",
286 "Geometry",
287 ""
288 };
289
290 const char *type = types[3];
291 if (shaderType == QGLShader::Fragment)
292 type = types[0];
293 else if (shaderType == QGLShader::Vertex)
294 type = types[1];
295 else if (shaderType == QGLShader::Geometry)
296 type = types[2];
297
298 if (name.isEmpty())
299 qWarning(msg: "QGLShader::compile(%s): %s", type, qPrintable(log));
300 else
301 qWarning(msg: "QGLShader::compile(%s)[%s]: %s", type, qPrintable(name), qPrintable(log));
302
303 delete [] logbuf;
304 }
305 return compiled;
306}
307
308void QGLShaderPrivate::deleteShader()
309{
310 if (shaderGuard) {
311 shaderGuard->free();
312 shaderGuard = 0;
313 }
314}
315
316/*!
317 Constructs a new QGLShader object of the specified \a type
318 and attaches it to \a parent. If shader programs are not supported,
319 QGLShaderProgram::hasOpenGLShaderPrograms() will return false.
320
321 This constructor is normally followed by a call to compileSourceCode()
322 or compileSourceFile().
323
324 The shader will be associated with the current QGLContext.
325
326 \sa compileSourceCode(), compileSourceFile()
327*/
328QGLShader::QGLShader(QGLShader::ShaderType type, QObject *parent)
329 : QObject(*new QGLShaderPrivate(QGLContext::currentContext(), type), parent)
330{
331 Q_D(QGLShader);
332 d->create();
333}
334
335/*!
336 Constructs a new QGLShader object of the specified \a type
337 and attaches it to \a parent. If shader programs are not supported,
338 then QGLShaderProgram::hasOpenGLShaderPrograms() will return false.
339
340 This constructor is normally followed by a call to compileSourceCode()
341 or compileSourceFile().
342
343 The shader will be associated with \a context.
344
345 \sa compileSourceCode(), compileSourceFile()
346*/
347QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent)
348 : QObject(*new QGLShaderPrivate(context ? context : QGLContext::currentContext(), type), parent)
349{
350 Q_D(QGLShader);
351#ifndef QT_NO_DEBUG
352 if (context && !QGLContext::areSharing(context1: context, context2: QGLContext::currentContext())) {
353 qWarning(msg: "QGLShader::QGLShader: \'context\' must be the current context or sharing with it.");
354 return;
355 }
356#endif
357 d->create();
358}
359
360/*!
361 Deletes this shader. If the shader has been attached to a
362 QGLShaderProgram object, then the actual shader will stay around
363 until the QGLShaderProgram is destroyed.
364*/
365QGLShader::~QGLShader()
366{
367}
368
369/*!
370 Returns the type of this shader.
371*/
372QGLShader::ShaderType QGLShader::shaderType() const
373{
374 Q_D(const QGLShader);
375 return d->shaderType;
376}
377
378// The precision qualifiers are useful on OpenGL/ES systems,
379// but usually not present on desktop systems. Define the
380// keywords to empty strings on desktop systems.
381#if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_FORCE_SHADER_DEFINES)
382#define QGL_DEFINE_QUALIFIERS 1
383static const char qualifierDefines[] =
384 "#define lowp\n"
385 "#define mediump\n"
386 "#define highp\n";
387
388#else
389
390// The "highp" qualifier doesn't exist in fragment shaders
391// on all ES platforms. When it doesn't exist, use "mediump".
392#define QGL_REDEFINE_HIGHP 1
393static const char redefineHighp[] =
394 "#ifndef GL_FRAGMENT_PRECISION_HIGH\n"
395 "#define highp mediump\n"
396 "#endif\n";
397#endif
398
399/*!
400 Sets the \a source code for this shader and compiles it.
401 Returns \c true if the source was successfully compiled, false otherwise.
402
403 \sa compileSourceFile()
404*/
405bool QGLShader::compileSourceCode(const char *source)
406{
407 Q_D(QGLShader);
408 if (d->shaderGuard && d->shaderGuard->id()) {
409 QVarLengthArray<const char *, 4> src;
410 QVarLengthArray<GLint, 4> srclen;
411 int headerLen = 0;
412 while (source && source[headerLen] == '#') {
413 // Skip #version and #extension directives at the start of
414 // the shader code. We need to insert the qualifierDefines
415 // and redefineHighp just after them.
416 if (qstrncmp(str1: source + headerLen, str2: "#version", len: 8) != 0 &&
417 qstrncmp(str1: source + headerLen, str2: "#extension", len: 10) != 0) {
418 break;
419 }
420 while (source[headerLen] != '\0' && source[headerLen] != '\n')
421 ++headerLen;
422 if (source[headerLen] == '\n')
423 ++headerLen;
424 }
425 if (headerLen > 0) {
426 src.append(t: source);
427 srclen.append(t: GLint(headerLen));
428 }
429#ifdef QGL_DEFINE_QUALIFIERS
430 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
431 src.append(t: qualifierDefines);
432 srclen.append(t: GLint(sizeof(qualifierDefines) - 1));
433 }
434#endif
435#ifdef QGL_REDEFINE_HIGHP
436 if (d->shaderType == Fragment
437 && QOpenGLContext::currentContext()->isOpenGLES()) {
438 src.append(redefineHighp);
439 srclen.append(GLint(sizeof(redefineHighp) - 1));
440 }
441#endif
442 src.append(t: source + headerLen);
443 srclen.append(t: GLint(qstrlen(str: source + headerLen)));
444 d->glfuncs->glShaderSource(shader: d->shaderGuard->id(), count: src.size(), string: src.data(), length: srclen.data());
445 return d->compile(q: this);
446 } else {
447 return false;
448 }
449}
450
451/*!
452 \overload
453
454 Sets the \a source code for this shader and compiles it.
455 Returns \c true if the source was successfully compiled, false otherwise.
456
457 \sa compileSourceFile()
458*/
459bool QGLShader::compileSourceCode(const QByteArray& source)
460{
461 return compileSourceCode(source: source.constData());
462}
463
464/*!
465 \overload
466
467 Sets the \a source code for this shader and compiles it.
468 Returns \c true if the source was successfully compiled, false otherwise.
469
470 \sa compileSourceFile()
471*/
472bool QGLShader::compileSourceCode(const QString& source)
473{
474 return compileSourceCode(source: source.toLatin1().constData());
475}
476
477/*!
478 Sets the source code for this shader to the contents of \a fileName
479 and compiles it. Returns \c true if the file could be opened and the
480 source compiled, false otherwise.
481
482 \sa compileSourceCode()
483*/
484bool QGLShader::compileSourceFile(const QString& fileName)
485{
486 QFile file(fileName);
487 if (!file.open(flags: QFile::ReadOnly)) {
488 qWarning() << "QGLShader: Unable to open file" << fileName;
489 return false;
490 }
491
492 QByteArray contents = file.readAll();
493 return compileSourceCode(source: contents.constData());
494}
495
496/*!
497 Returns the source code for this shader.
498
499 \sa compileSourceCode()
500*/
501QByteArray QGLShader::sourceCode() const
502{
503 Q_D(const QGLShader);
504 GLuint shader = d->shaderGuard ? d->shaderGuard->id() : 0;
505 if (!shader)
506 return QByteArray();
507 GLint size = 0;
508 d->glfuncs->glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, params: &size);
509 if (size <= 0)
510 return QByteArray();
511 GLint len = 0;
512 char *source = new char [size];
513 d->glfuncs->glGetShaderSource(shader, bufsize: size, length: &len, source);
514 QByteArray src(source);
515 delete [] source;
516 return src;
517}
518
519/*!
520 Returns \c true if this shader has been compiled; false otherwise.
521
522 \sa compileSourceCode(), compileSourceFile()
523*/
524bool QGLShader::isCompiled() const
525{
526 Q_D(const QGLShader);
527 return d->compiled;
528}
529
530/*!
531 Returns the errors and warnings that occurred during the last compile.
532
533 \sa compileSourceCode(), compileSourceFile()
534*/
535QString QGLShader::log() const
536{
537 Q_D(const QGLShader);
538 return d->log;
539}
540
541/*!
542 Returns the OpenGL identifier associated with this shader.
543
544 \sa QGLShaderProgram::programId()
545*/
546GLuint QGLShader::shaderId() const
547{
548 Q_D(const QGLShader);
549 return d->shaderGuard ? d->shaderGuard->id() : 0;
550}
551
552#undef ctx
553
554class ShaderProgramOpenGLFunctions : public QOpenGLFunctions
555{
556public:
557 ShaderProgramOpenGLFunctions()
558 : QOpenGLFunctions()
559 , glProgramParameteri(0)
560 {
561 }
562
563 typedef void (QOPENGLF_APIENTRYP type_glProgramParameteri)(GLuint program, GLenum pname, GLint value);
564
565 void initializeGeometryShaderFunctions()
566 {
567 QOpenGLContext *context = QOpenGLContext::currentContext();
568 if (!context->isOpenGLES()) {
569 glProgramParameteri = (type_glProgramParameteri)
570 context->getProcAddress(procName: "glProgramParameteri");
571
572 if (!glProgramParameteri) {
573 glProgramParameteri = (type_glProgramParameteri)
574 context->getProcAddress(procName: "glProgramParameteriEXT");
575 }
576 }
577 }
578
579 type_glProgramParameteri glProgramParameteri;
580};
581
582class QGLShaderProgramPrivate : public QObjectPrivate
583{
584 Q_DECLARE_PUBLIC(QGLShaderProgram)
585public:
586 QGLShaderProgramPrivate(const QGLContext *)
587 : programGuard(0)
588 , linked(false)
589 , inited(false)
590 , removingShaders(false)
591 , geometryVertexCount(64)
592 , geometryInputType(0)
593 , geometryOutputType(0)
594 , glfuncs(new ShaderProgramOpenGLFunctions)
595 {
596 }
597 ~QGLShaderProgramPrivate();
598
599 QGLSharedResourceGuardBase *programGuard;
600 bool linked;
601 bool inited;
602 bool removingShaders;
603
604 int geometryVertexCount;
605 GLenum geometryInputType;
606 GLenum geometryOutputType;
607
608 QString log;
609 QList<QGLShader *> shaders;
610 QList<QGLShader *> anonShaders;
611
612 ShaderProgramOpenGLFunctions *glfuncs;
613
614 bool hasShader(QGLShader::ShaderType type) const;
615};
616
617namespace {
618 void freeProgramFunc(QGLContext *ctx, GLuint id)
619 {
620 Q_ASSERT(ctx);
621 ctx->contextHandle()->functions()->glDeleteProgram(program: id);
622 }
623}
624
625
626QGLShaderProgramPrivate::~QGLShaderProgramPrivate()
627{
628 delete glfuncs;
629 if (programGuard)
630 programGuard->free();
631}
632
633bool QGLShaderProgramPrivate::hasShader(QGLShader::ShaderType type) const
634{
635 for (QGLShader *shader : shaders) {
636 if (shader->shaderType() == type)
637 return true;
638 }
639 return false;
640}
641
642#define ctx QGLContext::currentContext()
643
644/*!
645 Constructs a new shader program and attaches it to \a parent.
646 The program will be invalid until addShader() is called.
647
648 The shader program will be associated with the current QGLContext.
649
650 \sa addShader()
651*/
652QGLShaderProgram::QGLShaderProgram(QObject *parent)
653 : QObject(*new QGLShaderProgramPrivate(QGLContext::currentContext()), parent)
654{
655}
656
657/*!
658 Constructs a new shader program and attaches it to \a parent.
659 The program will be invalid until addShader() is called.
660
661 The shader program will be associated with \a context.
662
663 \sa addShader()
664*/
665QGLShaderProgram::QGLShaderProgram(const QGLContext *context, QObject *parent)
666 : QObject(*new QGLShaderProgramPrivate(context), parent)
667{
668}
669
670/*!
671 Deletes this shader program.
672*/
673QGLShaderProgram::~QGLShaderProgram()
674{
675}
676
677bool QGLShaderProgram::init()
678{
679 Q_D(QGLShaderProgram);
680 if ((d->programGuard && d->programGuard->id()) || d->inited)
681 return true;
682 d->inited = true;
683 QGLContext *context = const_cast<QGLContext *>(QGLContext::currentContext());
684 if (!context)
685 return false;
686 d->glfuncs->initializeOpenGLFunctions();
687 d->glfuncs->initializeGeometryShaderFunctions();
688 if (d->glfuncs->hasOpenGLFeature(feature: QOpenGLFunctions::Shaders)) {
689 GLuint program = d->glfuncs->glCreateProgram();
690 if (!program) {
691 qWarning(msg: "QGLShaderProgram: could not create shader program");
692 return false;
693 }
694 if (d->programGuard)
695 delete d->programGuard;
696 d->programGuard = createSharedResourceGuard(context, id: program, cleanupFunc: freeProgramFunc);
697 return true;
698 } else {
699 qWarning(msg: "QGLShaderProgram: shader programs are not supported");
700 return false;
701 }
702}
703
704/*!
705 Adds a compiled \a shader to this shader program. Returns \c true
706 if the shader could be added, or false otherwise.
707
708 Ownership of the \a shader object remains with the caller.
709 It will not be deleted when this QGLShaderProgram instance
710 is deleted. This allows the caller to add the same shader
711 to multiple shader programs.
712
713 \sa addShaderFromSourceCode(), addShaderFromSourceFile()
714 \sa removeShader(), link(), removeAllShaders()
715*/
716bool QGLShaderProgram::addShader(QGLShader *shader)
717{
718 Q_D(QGLShaderProgram);
719 if (!init())
720 return false;
721 if (d->shaders.contains(t: shader))
722 return true; // Already added to this shader program.
723 if (d->programGuard && d->programGuard->id() && shader) {
724 if (!shader->d_func()->shaderGuard || !shader->d_func()->shaderGuard->id())
725 return false;
726 if (d->programGuard->group() != shader->d_func()->shaderGuard->group()) {
727 qWarning(msg: "QGLShaderProgram::addShader: Program and shader are not associated with same context.");
728 return false;
729 }
730 d->glfuncs->glAttachShader(program: d->programGuard->id(), shader: shader->d_func()->shaderGuard->id());
731 d->linked = false; // Program needs to be relinked.
732 d->shaders.append(t: shader);
733 connect(sender: shader, SIGNAL(destroyed()), receiver: this, SLOT(shaderDestroyed()));
734 return true;
735 } else {
736 return false;
737 }
738}
739
740/*!
741 Compiles \a source as a shader of the specified \a type and
742 adds it to this shader program. Returns \c true if compilation
743 was successful, false otherwise. The compilation errors
744 and warnings will be made available via log().
745
746 This function is intended to be a short-cut for quickly
747 adding vertex and fragment shaders to a shader program without
748 creating an instance of QGLShader first.
749
750 \sa addShader(), addShaderFromSourceFile()
751 \sa removeShader(), link(), log(), removeAllShaders()
752*/
753bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const char *source)
754{
755 Q_D(QGLShaderProgram);
756 if (!init())
757 return false;
758 QGLShader *shader = new QGLShader(type, this);
759 if (!shader->compileSourceCode(source)) {
760 d->log = shader->log();
761 delete shader;
762 return false;
763 }
764 d->anonShaders.append(t: shader);
765 return addShader(shader);
766}
767
768/*!
769 \overload
770
771 Compiles \a source as a shader of the specified \a type and
772 adds it to this shader program. Returns \c true if compilation
773 was successful, false otherwise. The compilation errors
774 and warnings will be made available via log().
775
776 This function is intended to be a short-cut for quickly
777 adding vertex and fragment shaders to a shader program without
778 creating an instance of QGLShader first.
779
780 \sa addShader(), addShaderFromSourceFile()
781 \sa removeShader(), link(), log(), removeAllShaders()
782*/
783bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const QByteArray& source)
784{
785 return addShaderFromSourceCode(type, source: source.constData());
786}
787
788/*!
789 \overload
790
791 Compiles \a source as a shader of the specified \a type and
792 adds it to this shader program. Returns \c true if compilation
793 was successful, false otherwise. The compilation errors
794 and warnings will be made available via log().
795
796 This function is intended to be a short-cut for quickly
797 adding vertex and fragment shaders to a shader program without
798 creating an instance of QGLShader first.
799
800 \sa addShader(), addShaderFromSourceFile()
801 \sa removeShader(), link(), log(), removeAllShaders()
802*/
803bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const QString& source)
804{
805 return addShaderFromSourceCode(type, source: source.toLatin1().constData());
806}
807
808/*!
809 Compiles the contents of \a fileName as a shader of the specified
810 \a type and adds it to this shader program. Returns \c true if
811 compilation was successful, false otherwise. The compilation errors
812 and warnings will be made available via log().
813
814 This function is intended to be a short-cut for quickly
815 adding vertex and fragment shaders to a shader program without
816 creating an instance of QGLShader first.
817
818 \sa addShader(), addShaderFromSourceCode()
819*/
820bool QGLShaderProgram::addShaderFromSourceFile
821 (QGLShader::ShaderType type, const QString& fileName)
822{
823 Q_D(QGLShaderProgram);
824 if (!init())
825 return false;
826 QGLShader *shader = new QGLShader(type, this);
827 if (!shader->compileSourceFile(fileName)) {
828 d->log = shader->log();
829 delete shader;
830 return false;
831 }
832 d->anonShaders.append(t: shader);
833 return addShader(shader);
834}
835
836/*!
837 Removes \a shader from this shader program. The object is not deleted.
838
839 The shader program must be valid in the current QGLContext.
840
841 \sa addShader(), link(), removeAllShaders()
842*/
843void QGLShaderProgram::removeShader(QGLShader *shader)
844{
845 Q_D(QGLShaderProgram);
846 if (d->programGuard && d->programGuard->id()
847 && shader && shader->d_func()->shaderGuard)
848 {
849 d->glfuncs->glDetachShader(program: d->programGuard->id(), shader: shader->d_func()->shaderGuard->id());
850 }
851 d->linked = false; // Program needs to be relinked.
852 if (shader) {
853 d->shaders.removeAll(t: shader);
854 d->anonShaders.removeAll(t: shader);
855 disconnect(sender: shader, SIGNAL(destroyed()), receiver: this, SLOT(shaderDestroyed()));
856 }
857}
858
859/*!
860 Returns a list of all shaders that have been added to this shader
861 program using addShader().
862
863 \sa addShader(), removeShader()
864*/
865QList<QGLShader *> QGLShaderProgram::shaders() const
866{
867 Q_D(const QGLShaderProgram);
868 return d->shaders;
869}
870
871/*!
872 Removes all of the shaders that were added to this program previously.
873 The QGLShader objects for the shaders will not be deleted if they
874 were constructed externally. QGLShader objects that are constructed
875 internally by QGLShaderProgram will be deleted.
876
877 \sa addShader(), removeShader()
878*/
879void QGLShaderProgram::removeAllShaders()
880{
881 Q_D(QGLShaderProgram);
882 d->removingShaders = true;
883 if (d->programGuard) {
884 if (const auto programGuardId = d->programGuard->id()) {
885 for (QGLShader *shader : qAsConst(t&: d->shaders)) {
886 if (shader && shader->d_func()->shaderGuard)
887 d->glfuncs->glDetachShader(program: programGuardId, shader: shader->d_func()->shaderGuard->id());
888 }
889 }
890 }
891 // Delete shader objects that were created anonymously.
892 qDeleteAll(c: d->anonShaders);
893 d->shaders.clear();
894 d->anonShaders.clear();
895 d->linked = false; // Program needs to be relinked.
896 d->removingShaders = false;
897}
898
899/*!
900 Links together the shaders that were added to this program with
901 addShader(). Returns \c true if the link was successful or
902 false otherwise. If the link failed, the error messages can
903 be retrieved with log().
904
905 Subclasses can override this function to initialize attributes
906 and uniform variables for use in specific shader programs.
907
908 If the shader program was already linked, calling this
909 function again will force it to be re-linked.
910
911 \sa addShader(), log()
912*/
913bool QGLShaderProgram::link()
914{
915 Q_D(QGLShaderProgram);
916 GLuint program = d->programGuard ? d->programGuard->id() : 0;
917 if (!program)
918 return false;
919
920 GLint value;
921 if (d->shaders.isEmpty()) {
922 // If there are no explicit shaders, then it is possible that the
923 // application added a program binary with glProgramBinaryOES(),
924 // or otherwise populated the shaders itself. Check to see if the
925 // program is already linked and bail out if so.
926 value = 0;
927 d->glfuncs->glGetProgramiv(program, GL_LINK_STATUS, params: &value);
928 d->linked = (value != 0);
929 if (d->linked)
930 return true;
931 }
932
933#if !defined(QT_OPENGL_ES_2)
934 // Set up the geometry shader parameters
935 if (!QOpenGLContext::currentContext()->isOpenGLES()
936 && d->glfuncs->glProgramParameteri) {
937 for (QGLShader *shader : qAsConst(t&: d->shaders)) {
938 if (shader->shaderType() & QGLShader::Geometry) {
939 d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_INPUT_TYPE_EXT,
940 d->geometryInputType);
941 d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_OUTPUT_TYPE_EXT,
942 d->geometryOutputType);
943 d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_VERTICES_OUT_EXT,
944 d->geometryVertexCount);
945 break;
946 }
947 }
948 }
949#endif
950
951 d->glfuncs->glLinkProgram(program);
952 value = 0;
953 d->glfuncs->glGetProgramiv(program, GL_LINK_STATUS, params: &value);
954 d->linked = (value != 0);
955 value = 0;
956 d->glfuncs->glGetProgramiv(program, GL_INFO_LOG_LENGTH, params: &value);
957 d->log = QString();
958 if (value > 1) {
959 char *logbuf = new char [value];
960 GLint len;
961 d->glfuncs->glGetProgramInfoLog(program, bufsize: value, length: &len, infolog: logbuf);
962 d->log = QString::fromLatin1(str: logbuf);
963 QString name = objectName();
964 if (!d->linked) {
965 if (name.isEmpty())
966 qWarning() << "QGLShader::link:" << d->log;
967 else
968 qWarning() << "QGLShader::link[" << name << "]:" << d->log;
969 }
970 delete [] logbuf;
971 }
972 return d->linked;
973}
974
975/*!
976 Returns \c true if this shader program has been linked; false otherwise.
977
978 \sa link()
979*/
980bool QGLShaderProgram::isLinked() const
981{
982 Q_D(const QGLShaderProgram);
983 return d->linked;
984}
985
986/*!
987 Returns the errors and warnings that occurred during the last link()
988 or addShader() with explicitly specified source code.
989
990 \sa link()
991*/
992QString QGLShaderProgram::log() const
993{
994 Q_D(const QGLShaderProgram);
995 return d->log;
996}
997
998/*!
999 Binds this shader program to the active QGLContext and makes
1000 it the current shader program. Any previously bound shader program
1001 is released. This is equivalent to calling \c{glUseProgram()} on
1002 programId(). Returns \c true if the program was successfully bound;
1003 false otherwise. If the shader program has not yet been linked,
1004 or it needs to be re-linked, this function will call link().
1005
1006 \sa link(), release()
1007*/
1008bool QGLShaderProgram::bind()
1009{
1010 Q_D(QGLShaderProgram);
1011 GLuint program = d->programGuard ? d->programGuard->id() : 0;
1012 if (!program)
1013 return false;
1014 if (!d->linked && !link())
1015 return false;
1016#ifndef QT_NO_DEBUG
1017 if (d->programGuard->group() != QOpenGLContextGroup::currentContextGroup()) {
1018 qWarning(msg: "QGLShaderProgram::bind: program is not valid in the current context.");
1019 return false;
1020 }
1021#endif
1022 d->glfuncs->glUseProgram(program);
1023 return true;
1024}
1025
1026#undef ctx
1027#define ctx QGLContext::currentContext()
1028
1029/*!
1030 Releases the active shader program from the current QGLContext.
1031 This is equivalent to calling \c{glUseProgram(0)}.
1032
1033 \sa bind()
1034*/
1035void QGLShaderProgram::release()
1036{
1037 Q_D(QGLShaderProgram);
1038#ifndef QT_NO_DEBUG
1039 if (d->programGuard && d->programGuard->group() != QOpenGLContextGroup::currentContextGroup())
1040 qWarning(msg: "QGLShaderProgram::release: program is not valid in the current context.");
1041#endif
1042 d->glfuncs->glUseProgram(program: 0);
1043}
1044
1045/*!
1046 Returns the OpenGL identifier associated with this shader program.
1047
1048 \sa QGLShader::shaderId()
1049*/
1050GLuint QGLShaderProgram::programId() const
1051{
1052 Q_D(const QGLShaderProgram);
1053 GLuint id = d->programGuard ? d->programGuard->id() : 0;
1054 if (id)
1055 return id;
1056
1057 // Create the identifier if we don't have one yet. This is for
1058 // applications that want to create the attached shader configuration
1059 // themselves, particularly those using program binaries.
1060 if (!const_cast<QGLShaderProgram *>(this)->init())
1061 return 0;
1062 return d->programGuard ? d->programGuard->id() : 0;
1063}
1064
1065/*!
1066 Binds the attribute \a name to the specified \a location. This
1067 function can be called before or after the program has been linked.
1068 Any attributes that have not been explicitly bound when the program
1069 is linked will be assigned locations automatically.
1070
1071 When this function is called after the program has been linked,
1072 the program will need to be relinked for the change to take effect.
1073
1074 \sa attributeLocation()
1075*/
1076void QGLShaderProgram::bindAttributeLocation(const char *name, int location)
1077{
1078 Q_D(QGLShaderProgram);
1079 if (!init() || !d->programGuard || !d->programGuard->id())
1080 return;
1081 d->glfuncs->glBindAttribLocation(program: d->programGuard->id(), index: location, name);
1082 d->linked = false; // Program needs to be relinked.
1083}
1084
1085/*!
1086 \overload
1087
1088 Binds the attribute \a name to the specified \a location. This
1089 function can be called before or after the program has been linked.
1090 Any attributes that have not been explicitly bound when the program
1091 is linked will be assigned locations automatically.
1092
1093 When this function is called after the program has been linked,
1094 the program will need to be relinked for the change to take effect.
1095
1096 \sa attributeLocation()
1097*/
1098void QGLShaderProgram::bindAttributeLocation(const QByteArray& name, int location)
1099{
1100 bindAttributeLocation(name: name.constData(), location);
1101}
1102
1103/*!
1104 \overload
1105
1106 Binds the attribute \a name to the specified \a location. This
1107 function can be called before or after the program has been linked.
1108 Any attributes that have not been explicitly bound when the program
1109 is linked will be assigned locations automatically.
1110
1111 When this function is called after the program has been linked,
1112 the program will need to be relinked for the change to take effect.
1113
1114 \sa attributeLocation()
1115*/
1116void QGLShaderProgram::bindAttributeLocation(const QString& name, int location)
1117{
1118 bindAttributeLocation(name: name.toLatin1().constData(), location);
1119}
1120
1121/*!
1122 Returns the location of the attribute \a name within this shader
1123 program's parameter list. Returns -1 if \a name is not a valid
1124 attribute for this shader program.
1125
1126 \sa uniformLocation(), bindAttributeLocation()
1127*/
1128int QGLShaderProgram::attributeLocation(const char *name) const
1129{
1130 Q_D(const QGLShaderProgram);
1131 if (d->linked && d->programGuard && d->programGuard->id()) {
1132 return d->glfuncs->glGetAttribLocation(program: d->programGuard->id(), name);
1133 } else {
1134 qWarning() << "QGLShaderProgram::attributeLocation(" << name
1135 << "): shader program is not linked";
1136 return -1;
1137 }
1138}
1139
1140/*!
1141 \overload
1142
1143 Returns the location of the attribute \a name within this shader
1144 program's parameter list. Returns -1 if \a name is not a valid
1145 attribute for this shader program.
1146
1147 \sa uniformLocation(), bindAttributeLocation()
1148*/
1149int QGLShaderProgram::attributeLocation(const QByteArray& name) const
1150{
1151 return attributeLocation(name: name.constData());
1152}
1153
1154/*!
1155 \overload
1156
1157 Returns the location of the attribute \a name within this shader
1158 program's parameter list. Returns -1 if \a name is not a valid
1159 attribute for this shader program.
1160
1161 \sa uniformLocation(), bindAttributeLocation()
1162*/
1163int QGLShaderProgram::attributeLocation(const QString& name) const
1164{
1165 return attributeLocation(name: name.toLatin1().constData());
1166}
1167
1168/*!
1169 Sets the attribute at \a location in the current context to \a value.
1170
1171 \sa setUniformValue()
1172*/
1173void QGLShaderProgram::setAttributeValue(int location, GLfloat value)
1174{
1175 Q_D(QGLShaderProgram);
1176 Q_UNUSED(d);
1177 if (location != -1)
1178 d->glfuncs->glVertexAttrib1fv(indx: location, values: &value);
1179}
1180
1181/*!
1182 \overload
1183
1184 Sets the attribute called \a name in the current context to \a value.
1185
1186 \sa setUniformValue()
1187*/
1188void QGLShaderProgram::setAttributeValue(const char *name, GLfloat value)
1189{
1190 setAttributeValue(location: attributeLocation(name), value);
1191}
1192
1193/*!
1194 Sets the attribute at \a location in the current context to
1195 the 2D vector (\a x, \a y).
1196
1197 \sa setUniformValue()
1198*/
1199void QGLShaderProgram::setAttributeValue(int location, GLfloat x, GLfloat y)
1200{
1201 Q_D(QGLShaderProgram);
1202 Q_UNUSED(d);
1203 if (location != -1) {
1204 GLfloat values[2] = {x, y};
1205 d->glfuncs->glVertexAttrib2fv(indx: location, values);
1206 }
1207}
1208
1209/*!
1210 \overload
1211
1212 Sets the attribute called \a name in the current context to
1213 the 2D vector (\a x, \a y).
1214
1215 \sa setUniformValue()
1216*/
1217void QGLShaderProgram::setAttributeValue(const char *name, GLfloat x, GLfloat y)
1218{
1219 setAttributeValue(location: attributeLocation(name), x, y);
1220}
1221
1222/*!
1223 Sets the attribute at \a location in the current context to
1224 the 3D vector (\a x, \a y, \a z).
1225
1226 \sa setUniformValue()
1227*/
1228void QGLShaderProgram::setAttributeValue
1229 (int location, GLfloat x, GLfloat y, GLfloat z)
1230{
1231 Q_D(QGLShaderProgram);
1232 Q_UNUSED(d);
1233 if (location != -1) {
1234 GLfloat values[3] = {x, y, z};
1235 d->glfuncs->glVertexAttrib3fv(indx: location, values);
1236 }
1237}
1238
1239/*!
1240 \overload
1241
1242 Sets the attribute called \a name in the current context to
1243 the 3D vector (\a x, \a y, \a z).
1244
1245 \sa setUniformValue()
1246*/
1247void QGLShaderProgram::setAttributeValue
1248 (const char *name, GLfloat x, GLfloat y, GLfloat z)
1249{
1250 setAttributeValue(location: attributeLocation(name), x, y, z);
1251}
1252
1253/*!
1254 Sets the attribute at \a location in the current context to
1255 the 4D vector (\a x, \a y, \a z, \a w).
1256
1257 \sa setUniformValue()
1258*/
1259void QGLShaderProgram::setAttributeValue
1260 (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1261{
1262 Q_D(QGLShaderProgram);
1263 Q_UNUSED(d);
1264 if (location != -1) {
1265 GLfloat values[4] = {x, y, z, w};
1266 d->glfuncs->glVertexAttrib4fv(indx: location, values);
1267 }
1268}
1269
1270/*!
1271 \overload
1272
1273 Sets the attribute called \a name in the current context to
1274 the 4D vector (\a x, \a y, \a z, \a w).
1275
1276 \sa setUniformValue()
1277*/
1278void QGLShaderProgram::setAttributeValue
1279 (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1280{
1281 setAttributeValue(location: attributeLocation(name), x, y, z, w);
1282}
1283
1284/*!
1285 Sets the attribute at \a location in the current context to \a value.
1286
1287 \sa setUniformValue()
1288*/
1289void QGLShaderProgram::setAttributeValue(int location, const QVector2D& value)
1290{
1291 Q_D(QGLShaderProgram);
1292 Q_UNUSED(d);
1293 if (location != -1)
1294 d->glfuncs->glVertexAttrib2fv(indx: location, values: reinterpret_cast<const GLfloat *>(&value));
1295}
1296
1297/*!
1298 \overload
1299
1300 Sets the attribute called \a name in the current context to \a value.
1301
1302 \sa setUniformValue()
1303*/
1304void QGLShaderProgram::setAttributeValue(const char *name, const QVector2D& value)
1305{
1306 setAttributeValue(location: attributeLocation(name), value);
1307}
1308
1309/*!
1310 Sets the attribute at \a location in the current context to \a value.
1311
1312 \sa setUniformValue()
1313*/
1314void QGLShaderProgram::setAttributeValue(int location, const QVector3D& value)
1315{
1316 Q_D(QGLShaderProgram);
1317 Q_UNUSED(d);
1318 if (location != -1)
1319 d->glfuncs->glVertexAttrib3fv(indx: location, values: reinterpret_cast<const GLfloat *>(&value));
1320}
1321
1322/*!
1323 \overload
1324
1325 Sets the attribute called \a name in the current context to \a value.
1326
1327 \sa setUniformValue()
1328*/
1329void QGLShaderProgram::setAttributeValue(const char *name, const QVector3D& value)
1330{
1331 setAttributeValue(location: attributeLocation(name), value);
1332}
1333
1334/*!
1335 Sets the attribute at \a location in the current context to \a value.
1336
1337 \sa setUniformValue()
1338*/
1339void QGLShaderProgram::setAttributeValue(int location, const QVector4D& value)
1340{
1341 Q_D(QGLShaderProgram);
1342 Q_UNUSED(d);
1343 if (location != -1)
1344 d->glfuncs->glVertexAttrib4fv(indx: location, values: reinterpret_cast<const GLfloat *>(&value));
1345}
1346
1347/*!
1348 \overload
1349
1350 Sets the attribute called \a name in the current context to \a value.
1351
1352 \sa setUniformValue()
1353*/
1354void QGLShaderProgram::setAttributeValue(const char *name, const QVector4D& value)
1355{
1356 setAttributeValue(location: attributeLocation(name), value);
1357}
1358
1359/*!
1360 Sets the attribute at \a location in the current context to \a value.
1361
1362 \sa setUniformValue()
1363*/
1364void QGLShaderProgram::setAttributeValue(int location, const QColor& value)
1365{
1366 Q_D(QGLShaderProgram);
1367 Q_UNUSED(d);
1368 if (location != -1) {
1369 GLfloat values[4] = {GLfloat(value.redF()), GLfloat(value.greenF()),
1370 GLfloat(value.blueF()), GLfloat(value.alphaF())};
1371 d->glfuncs->glVertexAttrib4fv(indx: location, values);
1372 }
1373}
1374
1375/*!
1376 \overload
1377
1378 Sets the attribute called \a name in the current context to \a value.
1379
1380 \sa setUniformValue()
1381*/
1382void QGLShaderProgram::setAttributeValue(const char *name, const QColor& value)
1383{
1384 setAttributeValue(location: attributeLocation(name), value);
1385}
1386
1387/*!
1388 Sets the attribute at \a location in the current context to the
1389 contents of \a values, which contains \a columns elements, each
1390 consisting of \a rows elements. The \a rows value should be
1391 1, 2, 3, or 4. This function is typically used to set matrix
1392 values and column vectors.
1393
1394 \sa setUniformValue()
1395*/
1396void QGLShaderProgram::setAttributeValue
1397 (int location, const GLfloat *values, int columns, int rows)
1398{
1399 Q_D(QGLShaderProgram);
1400 Q_UNUSED(d);
1401 if (rows < 1 || rows > 4) {
1402 qWarning() << "QGLShaderProgram::setAttributeValue: rows" << rows << "not supported";
1403 return;
1404 }
1405 if (location != -1) {
1406 while (columns-- > 0) {
1407 if (rows == 1)
1408 d->glfuncs->glVertexAttrib1fv(indx: location, values);
1409 else if (rows == 2)
1410 d->glfuncs->glVertexAttrib2fv(indx: location, values);
1411 else if (rows == 3)
1412 d->glfuncs->glVertexAttrib3fv(indx: location, values);
1413 else
1414 d->glfuncs->glVertexAttrib4fv(indx: location, values);
1415 values += rows;
1416 ++location;
1417 }
1418 }
1419}
1420
1421/*!
1422 \overload
1423
1424 Sets the attribute called \a name in the current context to the
1425 contents of \a values, which contains \a columns elements, each
1426 consisting of \a rows elements. The \a rows value should be
1427 1, 2, 3, or 4. This function is typically used to set matrix
1428 values and column vectors.
1429
1430 \sa setUniformValue()
1431*/
1432void QGLShaderProgram::setAttributeValue
1433 (const char *name, const GLfloat *values, int columns, int rows)
1434{
1435 setAttributeValue(location: attributeLocation(name), values, columns, rows);
1436}
1437
1438/*!
1439 Sets an array of vertex \a values on the attribute at \a location
1440 in this shader program. The \a tupleSize indicates the number of
1441 components per vertex (1, 2, 3, or 4), and the \a stride indicates
1442 the number of bytes between vertices. A default \a stride value
1443 of zero indicates that the vertices are densely packed in \a values.
1444
1445 The array will become active when enableAttributeArray() is called
1446 on the \a location. Otherwise the value specified with
1447 setAttributeValue() for \a location will be used.
1448
1449 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1450 \sa disableAttributeArray()
1451*/
1452void QGLShaderProgram::setAttributeArray
1453 (int location, const GLfloat *values, int tupleSize, int stride)
1454{
1455 Q_D(QGLShaderProgram);
1456 Q_UNUSED(d);
1457 if (location != -1) {
1458 d->glfuncs->glVertexAttribPointer(indx: location, size: tupleSize, GL_FLOAT, GL_FALSE,
1459 stride, ptr: values);
1460 }
1461}
1462
1463/*!
1464 Sets an array of 2D vertex \a values on the attribute at \a location
1465 in this shader program. The \a stride indicates the number of bytes
1466 between vertices. A default \a stride value of zero indicates that
1467 the vertices are densely packed in \a values.
1468
1469 The array will become active when enableAttributeArray() is called
1470 on the \a location. Otherwise the value specified with
1471 setAttributeValue() for \a location will be used.
1472
1473 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1474 \sa disableAttributeArray()
1475*/
1476void QGLShaderProgram::setAttributeArray
1477 (int location, const QVector2D *values, int stride)
1478{
1479 Q_D(QGLShaderProgram);
1480 Q_UNUSED(d);
1481 if (location != -1) {
1482 d->glfuncs->glVertexAttribPointer(indx: location, size: 2, GL_FLOAT, GL_FALSE,
1483 stride, ptr: values);
1484 }
1485}
1486
1487/*!
1488 Sets an array of 3D vertex \a values on the attribute at \a location
1489 in this shader program. The \a stride indicates the number of bytes
1490 between vertices. A default \a stride value of zero indicates that
1491 the vertices are densely packed in \a values.
1492
1493 The array will become active when enableAttributeArray() is called
1494 on the \a location. Otherwise the value specified with
1495 setAttributeValue() for \a location will be used.
1496
1497 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1498 \sa disableAttributeArray()
1499*/
1500void QGLShaderProgram::setAttributeArray
1501 (int location, const QVector3D *values, int stride)
1502{
1503 Q_D(QGLShaderProgram);
1504 Q_UNUSED(d);
1505 if (location != -1) {
1506 d->glfuncs->glVertexAttribPointer(indx: location, size: 3, GL_FLOAT, GL_FALSE,
1507 stride, ptr: values);
1508 }
1509}
1510
1511/*!
1512 Sets an array of 4D vertex \a values on the attribute at \a location
1513 in this shader program. The \a stride indicates the number of bytes
1514 between vertices. A default \a stride value of zero indicates that
1515 the vertices are densely packed in \a values.
1516
1517 The array will become active when enableAttributeArray() is called
1518 on the \a location. Otherwise the value specified with
1519 setAttributeValue() for \a location will be used.
1520
1521 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1522 \sa disableAttributeArray()
1523*/
1524void QGLShaderProgram::setAttributeArray
1525 (int location, const QVector4D *values, int stride)
1526{
1527 Q_D(QGLShaderProgram);
1528 Q_UNUSED(d);
1529 if (location != -1) {
1530 d->glfuncs->glVertexAttribPointer(indx: location, size: 4, GL_FLOAT, GL_FALSE,
1531 stride, ptr: values);
1532 }
1533}
1534
1535/*!
1536 Sets an array of vertex \a values on the attribute at \a location
1537 in this shader program. The \a stride indicates the number of bytes
1538 between vertices. A default \a stride value of zero indicates that
1539 the vertices are densely packed in \a values.
1540
1541 The \a type indicates the type of elements in the \a values array,
1542 usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a tupleSize
1543 indicates the number of components per vertex: 1, 2, 3, or 4.
1544
1545 The array will become active when enableAttributeArray() is called
1546 on the \a location. Otherwise the value specified with
1547 setAttributeValue() for \a location will be used.
1548
1549 The setAttributeBuffer() function can be used to set the attribute
1550 array to an offset within a vertex buffer.
1551
1552 \note Normalization will be enabled. If this is not desired, call
1553 glVertexAttribPointer directly through QGLFunctions.
1554
1555 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1556 \sa disableAttributeArray(), setAttributeBuffer()
1557 \since 4.7
1558*/
1559void QGLShaderProgram::setAttributeArray
1560 (int location, GLenum type, const void *values, int tupleSize, int stride)
1561{
1562 Q_D(QGLShaderProgram);
1563 Q_UNUSED(d);
1564 if (location != -1) {
1565 d->glfuncs->glVertexAttribPointer(indx: location, size: tupleSize, type, GL_TRUE,
1566 stride, ptr: values);
1567 }
1568}
1569
1570/*!
1571 \overload
1572
1573 Sets an array of vertex \a values on the attribute called \a name
1574 in this shader program. The \a tupleSize indicates the number of
1575 components per vertex (1, 2, 3, or 4), and the \a stride indicates
1576 the number of bytes between vertices. A default \a stride value
1577 of zero indicates that the vertices are densely packed in \a values.
1578
1579 The array will become active when enableAttributeArray() is called
1580 on \a name. Otherwise the value specified with setAttributeValue()
1581 for \a name will be used.
1582
1583 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1584 \sa disableAttributeArray()
1585*/
1586void QGLShaderProgram::setAttributeArray
1587 (const char *name, const GLfloat *values, int tupleSize, int stride)
1588{
1589 setAttributeArray(location: attributeLocation(name), values, tupleSize, stride);
1590}
1591
1592/*!
1593 \overload
1594
1595 Sets an array of 2D vertex \a values on the attribute called \a name
1596 in this shader program. The \a stride indicates the number of bytes
1597 between vertices. A default \a stride value of zero indicates that
1598 the vertices are densely packed in \a values.
1599
1600 The array will become active when enableAttributeArray() is called
1601 on \a name. Otherwise the value specified with setAttributeValue()
1602 for \a name will be used.
1603
1604 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1605 \sa disableAttributeArray()
1606*/
1607void QGLShaderProgram::setAttributeArray
1608 (const char *name, const QVector2D *values, int stride)
1609{
1610 setAttributeArray(location: attributeLocation(name), values, stride);
1611}
1612
1613/*!
1614 \overload
1615
1616 Sets an array of 3D vertex \a values on the attribute called \a name
1617 in this shader program. The \a stride indicates the number of bytes
1618 between vertices. A default \a stride value of zero indicates that
1619 the vertices are densely packed in \a values.
1620
1621 The array will become active when enableAttributeArray() is called
1622 on \a name. Otherwise the value specified with setAttributeValue()
1623 for \a name will be used.
1624
1625 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1626 \sa disableAttributeArray()
1627*/
1628void QGLShaderProgram::setAttributeArray
1629 (const char *name, const QVector3D *values, int stride)
1630{
1631 setAttributeArray(location: attributeLocation(name), values, stride);
1632}
1633
1634/*!
1635 \overload
1636
1637 Sets an array of 4D vertex \a values on the attribute called \a name
1638 in this shader program. The \a stride indicates the number of bytes
1639 between vertices. A default \a stride value of zero indicates that
1640 the vertices are densely packed in \a values.
1641
1642 The array will become active when enableAttributeArray() is called
1643 on \a name. Otherwise the value specified with setAttributeValue()
1644 for \a name will be used.
1645
1646 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1647 \sa disableAttributeArray()
1648*/
1649void QGLShaderProgram::setAttributeArray
1650 (const char *name, const QVector4D *values, int stride)
1651{
1652 setAttributeArray(location: attributeLocation(name), values, stride);
1653}
1654
1655/*!
1656 \overload
1657
1658 Sets an array of vertex \a values on the attribute called \a name
1659 in this shader program. The \a stride indicates the number of bytes
1660 between vertices. A default \a stride value of zero indicates that
1661 the vertices are densely packed in \a values.
1662
1663 The \a type indicates the type of elements in the \a values array,
1664 usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a tupleSize
1665 indicates the number of components per vertex: 1, 2, 3, or 4.
1666
1667 The array will become active when enableAttributeArray() is called
1668 on the \a name. Otherwise the value specified with
1669 setAttributeValue() for \a name will be used.
1670
1671 The setAttributeBuffer() function can be used to set the attribute
1672 array to an offset within a vertex buffer.
1673
1674 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1675 \sa disableAttributeArray(), setAttributeBuffer()
1676 \since 4.7
1677*/
1678void QGLShaderProgram::setAttributeArray
1679 (const char *name, GLenum type, const void *values, int tupleSize, int stride)
1680{
1681 setAttributeArray(location: attributeLocation(name), type, values, tupleSize, stride);
1682}
1683
1684/*!
1685 Sets an array of vertex values on the attribute at \a location in
1686 this shader program, starting at a specific \a offset in the
1687 currently bound vertex buffer. The \a stride indicates the number
1688 of bytes between vertices. A default \a stride value of zero
1689 indicates that the vertices are densely packed in the value array.
1690
1691 The \a type indicates the type of elements in the vertex value
1692 array, usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a
1693 tupleSize indicates the number of components per vertex: 1, 2, 3,
1694 or 4.
1695
1696 The array will become active when enableAttributeArray() is called
1697 on the \a location. Otherwise the value specified with
1698 setAttributeValue() for \a location will be used.
1699
1700 \note Normalization will be enabled. If this is not desired, call
1701 glVertexAttribPointer directly though QGLFunctions.
1702
1703 \sa setAttributeArray()
1704 \since 4.7
1705*/
1706void QGLShaderProgram::setAttributeBuffer
1707 (int location, GLenum type, int offset, int tupleSize, int stride)
1708{
1709 Q_D(QGLShaderProgram);
1710 Q_UNUSED(d);
1711 if (location != -1) {
1712 d->glfuncs->glVertexAttribPointer(indx: location, size: tupleSize, type, GL_TRUE, stride,
1713 ptr: reinterpret_cast<const void *>(qintptr(offset)));
1714 }
1715}
1716
1717/*!
1718 \overload
1719
1720 Sets an array of vertex values on the attribute called \a name
1721 in this shader program, starting at a specific \a offset in the
1722 currently bound vertex buffer. The \a stride indicates the number
1723 of bytes between vertices. A default \a stride value of zero
1724 indicates that the vertices are densely packed in the value array.
1725
1726 The \a type indicates the type of elements in the vertex value
1727 array, usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a
1728 tupleSize indicates the number of components per vertex: 1, 2, 3,
1729 or 4.
1730
1731 The array will become active when enableAttributeArray() is called
1732 on the \a name. Otherwise the value specified with
1733 setAttributeValue() for \a name will be used.
1734
1735 \sa setAttributeArray()
1736 \since 4.7
1737*/
1738void QGLShaderProgram::setAttributeBuffer
1739 (const char *name, GLenum type, int offset, int tupleSize, int stride)
1740{
1741 setAttributeBuffer(location: attributeLocation(name), type, offset, tupleSize, stride);
1742}
1743
1744/*!
1745 Enables the vertex array at \a location in this shader program
1746 so that the value set by setAttributeArray() on \a location
1747 will be used by the shader program.
1748
1749 \sa disableAttributeArray(), setAttributeArray(), setAttributeValue()
1750 \sa setUniformValue()
1751*/
1752void QGLShaderProgram::enableAttributeArray(int location)
1753{
1754 Q_D(QGLShaderProgram);
1755 Q_UNUSED(d);
1756 if (location != -1)
1757 d->glfuncs->glEnableVertexAttribArray(index: location);
1758}
1759
1760/*!
1761 \overload
1762
1763 Enables the vertex array called \a name in this shader program
1764 so that the value set by setAttributeArray() on \a name
1765 will be used by the shader program.
1766
1767 \sa disableAttributeArray(), setAttributeArray(), setAttributeValue()
1768 \sa setUniformValue()
1769*/
1770void QGLShaderProgram::enableAttributeArray(const char *name)
1771{
1772 enableAttributeArray(location: attributeLocation(name));
1773}
1774
1775/*!
1776 Disables the vertex array at \a location in this shader program
1777 that was enabled by a previous call to enableAttributeArray().
1778
1779 \sa enableAttributeArray(), setAttributeArray(), setAttributeValue()
1780 \sa setUniformValue()
1781*/
1782void QGLShaderProgram::disableAttributeArray(int location)
1783{
1784 Q_D(QGLShaderProgram);
1785 Q_UNUSED(d);
1786 if (location != -1)
1787 d->glfuncs->glDisableVertexAttribArray(index: location);
1788}
1789
1790/*!
1791 \overload
1792
1793 Disables the vertex array called \a name in this shader program
1794 that was enabled by a previous call to enableAttributeArray().
1795
1796 \sa enableAttributeArray(), setAttributeArray(), setAttributeValue()
1797 \sa setUniformValue()
1798*/
1799void QGLShaderProgram::disableAttributeArray(const char *name)
1800{
1801 disableAttributeArray(location: attributeLocation(name));
1802}
1803
1804/*!
1805 Returns the location of the uniform variable \a name within this shader
1806 program's parameter list. Returns -1 if \a name is not a valid
1807 uniform variable for this shader program.
1808
1809 \sa attributeLocation()
1810*/
1811int QGLShaderProgram::uniformLocation(const char *name) const
1812{
1813 Q_D(const QGLShaderProgram);
1814 Q_UNUSED(d);
1815 if (d->linked && d->programGuard && d->programGuard->id()) {
1816 return d->glfuncs->glGetUniformLocation(program: d->programGuard->id(), name);
1817 } else {
1818 qWarning() << "QGLShaderProgram::uniformLocation(" << name
1819 << "): shader program is not linked";
1820 return -1;
1821 }
1822}
1823
1824/*!
1825 \overload
1826
1827 Returns the location of the uniform variable \a name within this shader
1828 program's parameter list. Returns -1 if \a name is not a valid
1829 uniform variable for this shader program.
1830
1831 \sa attributeLocation()
1832*/
1833int QGLShaderProgram::uniformLocation(const QByteArray& name) const
1834{
1835 return uniformLocation(name: name.constData());
1836}
1837
1838/*!
1839 \overload
1840
1841 Returns the location of the uniform variable \a name within this shader
1842 program's parameter list. Returns -1 if \a name is not a valid
1843 uniform variable for this shader program.
1844
1845 \sa attributeLocation()
1846*/
1847int QGLShaderProgram::uniformLocation(const QString& name) const
1848{
1849 return uniformLocation(name: name.toLatin1().constData());
1850}
1851
1852/*!
1853 Sets the uniform variable at \a location in the current context to \a value.
1854
1855 \sa setAttributeValue()
1856*/
1857void QGLShaderProgram::setUniformValue(int location, GLfloat value)
1858{
1859 Q_D(QGLShaderProgram);
1860 Q_UNUSED(d);
1861 if (location != -1)
1862 d->glfuncs->glUniform1fv(location, count: 1, v: &value);
1863}
1864
1865/*!
1866 \overload
1867
1868 Sets the uniform variable called \a name in the current context
1869 to \a value.
1870
1871 \sa setAttributeValue()
1872*/
1873void QGLShaderProgram::setUniformValue(const char *name, GLfloat value)
1874{
1875 setUniformValue(location: uniformLocation(name), value);
1876}
1877
1878/*!
1879 Sets the uniform variable at \a location in the current context to \a value.
1880
1881 \sa setAttributeValue()
1882*/
1883void QGLShaderProgram::setUniformValue(int location, GLint value)
1884{
1885 Q_D(QGLShaderProgram);
1886 Q_UNUSED(d);
1887 if (location != -1)
1888 d->glfuncs->glUniform1i(location, x: value);
1889}
1890
1891/*!
1892 \overload
1893
1894 Sets the uniform variable called \a name in the current context
1895 to \a value.
1896
1897 \sa setAttributeValue()
1898*/
1899void QGLShaderProgram::setUniformValue(const char *name, GLint value)
1900{
1901 setUniformValue(location: uniformLocation(name), value);
1902}
1903
1904/*!
1905 Sets the uniform variable at \a location in the current context to \a value.
1906 This function should be used when setting sampler values.
1907
1908 \sa setAttributeValue()
1909*/
1910void QGLShaderProgram::setUniformValue(int location, GLuint value)
1911{
1912 Q_D(QGLShaderProgram);
1913 Q_UNUSED(d);
1914 if (location != -1)
1915 d->glfuncs->glUniform1i(location, x: value);
1916}
1917
1918/*!
1919 \overload
1920
1921 Sets the uniform variable called \a name in the current context
1922 to \a value. This function should be used when setting sampler values.
1923
1924 \sa setAttributeValue()
1925*/
1926void QGLShaderProgram::setUniformValue(const char *name, GLuint value)
1927{
1928 setUniformValue(location: uniformLocation(name), value);
1929}
1930
1931/*!
1932 Sets the uniform variable at \a location in the current context to
1933 the 2D vector (\a x, \a y).
1934
1935 \sa setAttributeValue()
1936*/
1937void QGLShaderProgram::setUniformValue(int location, GLfloat x, GLfloat y)
1938{
1939 Q_D(QGLShaderProgram);
1940 Q_UNUSED(d);
1941 if (location != -1) {
1942 GLfloat values[2] = {x, y};
1943 d->glfuncs->glUniform2fv(location, count: 1, v: values);
1944 }
1945}
1946
1947/*!
1948 \overload
1949
1950 Sets the uniform variable called \a name in the current context to
1951 the 2D vector (\a x, \a y).
1952
1953 \sa setAttributeValue()
1954*/
1955void QGLShaderProgram::setUniformValue(const char *name, GLfloat x, GLfloat y)
1956{
1957 setUniformValue(location: uniformLocation(name), x, y);
1958}
1959
1960/*!
1961 Sets the uniform variable at \a location in the current context to
1962 the 3D vector (\a x, \a y, \a z).
1963
1964 \sa setAttributeValue()
1965*/
1966void QGLShaderProgram::setUniformValue
1967 (int location, GLfloat x, GLfloat y, GLfloat z)
1968{
1969 Q_D(QGLShaderProgram);
1970 Q_UNUSED(d);
1971 if (location != -1) {
1972 GLfloat values[3] = {x, y, z};
1973 d->glfuncs->glUniform3fv(location, count: 1, v: values);
1974 }
1975}
1976
1977/*!
1978 \overload
1979
1980 Sets the uniform variable called \a name in the current context to
1981 the 3D vector (\a x, \a y, \a z).
1982
1983 \sa setAttributeValue()
1984*/
1985void QGLShaderProgram::setUniformValue
1986 (const char *name, GLfloat x, GLfloat y, GLfloat z)
1987{
1988 setUniformValue(location: uniformLocation(name), x, y, z);
1989}
1990
1991/*!
1992 Sets the uniform variable at \a location in the current context to
1993 the 4D vector (\a x, \a y, \a z, \a w).
1994
1995 \sa setAttributeValue()
1996*/
1997void QGLShaderProgram::setUniformValue
1998 (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1999{
2000 Q_D(QGLShaderProgram);
2001 Q_UNUSED(d);
2002 if (location != -1) {
2003 GLfloat values[4] = {x, y, z, w};
2004 d->glfuncs->glUniform4fv(location, count: 1, v: values);
2005 }
2006}
2007
2008/*!
2009 \overload
2010
2011 Sets the uniform variable called \a name in the current context to
2012 the 4D vector (\a x, \a y, \a z, \a w).
2013
2014 \sa setAttributeValue()
2015*/
2016void QGLShaderProgram::setUniformValue
2017 (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2018{
2019 setUniformValue(location: uniformLocation(name), x, y, z, w);
2020}
2021
2022/*!
2023 Sets the uniform variable at \a location in the current context to \a value.
2024
2025 \sa setAttributeValue()
2026*/
2027void QGLShaderProgram::setUniformValue(int location, const QVector2D& value)
2028{
2029 Q_D(QGLShaderProgram);
2030 Q_UNUSED(d);
2031 if (location != -1)
2032 d->glfuncs->glUniform2fv(location, count: 1, v: reinterpret_cast<const GLfloat *>(&value));
2033}
2034
2035/*!
2036 \overload
2037
2038 Sets the uniform variable called \a name in the current context
2039 to \a value.
2040
2041 \sa setAttributeValue()
2042*/
2043void QGLShaderProgram::setUniformValue(const char *name, const QVector2D& value)
2044{
2045 setUniformValue(location: uniformLocation(name), value);
2046}
2047
2048/*!
2049 Sets the uniform variable at \a location in the current context to \a value.
2050
2051 \sa setAttributeValue()
2052*/
2053void QGLShaderProgram::setUniformValue(int location, const QVector3D& value)
2054{
2055 Q_D(QGLShaderProgram);
2056 Q_UNUSED(d);
2057 if (location != -1)
2058 d->glfuncs->glUniform3fv(location, count: 1, v: reinterpret_cast<const GLfloat *>(&value));
2059}
2060
2061/*!
2062 \overload
2063
2064 Sets the uniform variable called \a name in the current context
2065 to \a value.
2066
2067 \sa setAttributeValue()
2068*/
2069void QGLShaderProgram::setUniformValue(const char *name, const QVector3D& value)
2070{
2071 setUniformValue(location: uniformLocation(name), value);
2072}
2073
2074/*!
2075 Sets the uniform variable at \a location in the current context to \a value.
2076
2077 \sa setAttributeValue()
2078*/
2079void QGLShaderProgram::setUniformValue(int location, const QVector4D& value)
2080{
2081 Q_D(QGLShaderProgram);
2082 Q_UNUSED(d);
2083 if (location != -1)
2084 d->glfuncs->glUniform4fv(location, count: 1, v: reinterpret_cast<const GLfloat *>(&value));
2085}
2086
2087/*!
2088 \overload
2089
2090 Sets the uniform variable called \a name in the current context
2091 to \a value.
2092
2093 \sa setAttributeValue()
2094*/
2095void QGLShaderProgram::setUniformValue(const char *name, const QVector4D& value)
2096{
2097 setUniformValue(location: uniformLocation(name), value);
2098}
2099
2100/*!
2101 Sets the uniform variable at \a location in the current context to
2102 the red, green, blue, and alpha components of \a color.
2103
2104 \sa setAttributeValue()
2105*/
2106void QGLShaderProgram::setUniformValue(int location, const QColor& color)
2107{
2108 Q_D(QGLShaderProgram);
2109 Q_UNUSED(d);
2110 if (location != -1) {
2111 GLfloat values[4] = {GLfloat(color.redF()), GLfloat(color.greenF()),
2112 GLfloat(color.blueF()), GLfloat(color.alphaF())};
2113 d->glfuncs->glUniform4fv(location, count: 1, v: values);
2114 }
2115}
2116
2117/*!
2118 \overload
2119
2120 Sets the uniform variable called \a name in the current context to
2121 the red, green, blue, and alpha components of \a color.
2122
2123 \sa setAttributeValue()
2124*/
2125void QGLShaderProgram::setUniformValue(const char *name, const QColor& color)
2126{
2127 setUniformValue(location: uniformLocation(name), color);
2128}
2129
2130/*!
2131 Sets the uniform variable at \a location in the current context to
2132 the x and y coordinates of \a point.
2133
2134 \sa setAttributeValue()
2135*/
2136void QGLShaderProgram::setUniformValue(int location, const QPoint& point)
2137{
2138 Q_D(QGLShaderProgram);
2139 Q_UNUSED(d);
2140 if (location != -1) {
2141 GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())};
2142 d->glfuncs->glUniform2fv(location, count: 1, v: values);
2143 }
2144}
2145
2146/*!
2147 \overload
2148
2149 Sets the uniform variable associated with \a name in the current
2150 context to the x and y coordinates of \a point.
2151
2152 \sa setAttributeValue()
2153*/
2154void QGLShaderProgram::setUniformValue(const char *name, const QPoint& point)
2155{
2156 setUniformValue(location: uniformLocation(name), point);
2157}
2158
2159/*!
2160 Sets the uniform variable at \a location in the current context to
2161 the x and y coordinates of \a point.
2162
2163 \sa setAttributeValue()
2164*/
2165void QGLShaderProgram::setUniformValue(int location, const QPointF& point)
2166{
2167 Q_D(QGLShaderProgram);
2168 Q_UNUSED(d);
2169 if (location != -1) {
2170 GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())};
2171 d->glfuncs->glUniform2fv(location, count: 1, v: values);
2172 }
2173}
2174
2175/*!
2176 \overload
2177
2178 Sets the uniform variable associated with \a name in the current
2179 context to the x and y coordinates of \a point.
2180
2181 \sa setAttributeValue()
2182*/
2183void QGLShaderProgram::setUniformValue(const char *name, const QPointF& point)
2184{
2185 setUniformValue(location: uniformLocation(name), point);
2186}
2187
2188/*!
2189 Sets the uniform variable at \a location in the current context to
2190 the width and height of the given \a size.
2191
2192 \sa setAttributeValue()
2193*/
2194void QGLShaderProgram::setUniformValue(int location, const QSize& size)
2195{
2196 Q_D(QGLShaderProgram);
2197 Q_UNUSED(d);
2198 if (location != -1) {
2199 GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())};
2200 d->glfuncs->glUniform2fv(location, count: 1, v: values);
2201 }
2202}
2203
2204/*!
2205 \overload
2206
2207 Sets the uniform variable associated with \a name in the current
2208 context to the width and height of the given \a size.
2209
2210 \sa setAttributeValue()
2211*/
2212void QGLShaderProgram::setUniformValue(const char *name, const QSize& size)
2213{
2214 setUniformValue(location: uniformLocation(name), size);
2215}
2216
2217/*!
2218 Sets the uniform variable at \a location in the current context to
2219 the width and height of the given \a size.
2220
2221 \sa setAttributeValue()
2222*/
2223void QGLShaderProgram::setUniformValue(int location, const QSizeF& size)
2224{
2225 Q_D(QGLShaderProgram);
2226 Q_UNUSED(d);
2227 if (location != -1) {
2228 GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())};
2229 d->glfuncs->glUniform2fv(location, count: 1, v: values);
2230 }
2231}
2232
2233/*!
2234 \overload
2235
2236 Sets the uniform variable associated with \a name in the current
2237 context to the width and height of the given \a size.
2238
2239 \sa setAttributeValue()
2240*/
2241void QGLShaderProgram::setUniformValue(const char *name, const QSizeF& size)
2242{
2243 setUniformValue(location: uniformLocation(name), size);
2244}
2245
2246/*!
2247 Sets the uniform variable at \a location in the current context
2248 to a 2x2 matrix \a value.
2249
2250 \sa setAttributeValue()
2251*/
2252void QGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value)
2253{
2254 Q_D(QGLShaderProgram);
2255 d->glfuncs->glUniformMatrix2fv(location, count: 1, GL_FALSE, value: value.constData());
2256}
2257
2258/*!
2259 \overload
2260
2261 Sets the uniform variable called \a name in the current context
2262 to a 2x2 matrix \a value.
2263
2264 \sa setAttributeValue()
2265*/
2266void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x2& value)
2267{
2268 setUniformValue(location: uniformLocation(name), value);
2269}
2270
2271/*!
2272 Sets the uniform variable at \a location in the current context
2273 to a 2x3 matrix \a value.
2274
2275 \sa setAttributeValue()
2276*/
2277void QGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value)
2278{
2279 Q_D(QGLShaderProgram);
2280 d->glfuncs->glUniform3fv(location, count: 2, v: value.constData());
2281}
2282
2283/*!
2284 \overload
2285
2286 Sets the uniform variable called \a name in the current context
2287 to a 2x3 matrix \a value.
2288
2289 \sa setAttributeValue()
2290*/
2291void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& value)
2292{
2293 setUniformValue(location: uniformLocation(name), value);
2294}
2295
2296/*!
2297 Sets the uniform variable at \a location in the current context
2298 to a 2x4 matrix \a value.
2299
2300 \sa setAttributeValue()
2301*/
2302void QGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value)
2303{
2304 Q_D(QGLShaderProgram);
2305 d->glfuncs->glUniform4fv(location, count: 2, v: value.constData());
2306}
2307
2308/*!
2309 \overload
2310
2311 Sets the uniform variable called \a name in the current context
2312 to a 2x4 matrix \a value.
2313
2314 \sa setAttributeValue()
2315*/
2316void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& value)
2317{
2318 setUniformValue(location: uniformLocation(name), value);
2319}
2320
2321/*!
2322 Sets the uniform variable at \a location in the current context
2323 to a 3x2 matrix \a value.
2324
2325 \sa setAttributeValue()
2326*/
2327void QGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value)
2328{
2329 Q_D(QGLShaderProgram);
2330 d->glfuncs->glUniform2fv(location, count: 3, v: value.constData());
2331}
2332
2333/*!
2334 \overload
2335
2336 Sets the uniform variable called \a name in the current context
2337 to a 3x2 matrix \a value.
2338
2339 \sa setAttributeValue()
2340*/
2341void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x2& value)
2342{
2343 setUniformValue(location: uniformLocation(name), value);
2344}
2345
2346/*!
2347 Sets the uniform variable at \a location in the current context
2348 to a 3x3 matrix \a value.
2349
2350 \sa setAttributeValue()
2351*/
2352void QGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value)
2353{
2354 Q_D(QGLShaderProgram);
2355 d->glfuncs->glUniformMatrix3fv(location, count: 1, GL_FALSE, value: value.constData());
2356}
2357
2358/*!
2359 \overload
2360
2361 Sets the uniform variable called \a name in the current context
2362 to a 3x3 matrix \a value.
2363
2364 \sa setAttributeValue()
2365*/
2366void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x3& value)
2367{
2368 setUniformValue(location: uniformLocation(name), value);
2369}
2370
2371/*!
2372 Sets the uniform variable at \a location in the current context
2373 to a 3x4 matrix \a value.
2374
2375 \sa setAttributeValue()
2376*/
2377void QGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value)
2378{
2379 Q_D(QGLShaderProgram);
2380 d->glfuncs->glUniform4fv(location, count: 3, v: value.constData());
2381}
2382
2383/*!
2384 \overload
2385
2386 Sets the uniform variable called \a name in the current context
2387 to a 3x4 matrix \a value.
2388
2389 \sa setAttributeValue()
2390*/
2391void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& value)
2392{
2393 setUniformValue(location: uniformLocation(name), value);
2394}
2395
2396/*!
2397 Sets the uniform variable at \a location in the current context
2398 to a 4x2 matrix \a value.
2399
2400 \sa setAttributeValue()
2401*/
2402void QGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value)
2403{
2404 Q_D(QGLShaderProgram);
2405 d->glfuncs->glUniform2fv(location, count: 4, v: value.constData());
2406}
2407
2408/*!
2409 \overload
2410
2411 Sets the uniform variable called \a name in the current context
2412 to a 4x2 matrix \a value.
2413
2414 \sa setAttributeValue()
2415*/
2416void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& value)
2417{
2418 setUniformValue(location: uniformLocation(name), value);
2419}
2420
2421/*!
2422 Sets the uniform variable at \a location in the current context
2423 to a 4x3 matrix \a value.
2424
2425 \sa setAttributeValue()
2426*/
2427void QGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value)
2428{
2429 Q_D(QGLShaderProgram);
2430 d->glfuncs->glUniform3fv(location, count: 4, v: value.constData());
2431}
2432
2433/*!
2434 \overload
2435
2436 Sets the uniform variable called \a name in the current context
2437 to a 4x3 matrix \a value.
2438
2439 \sa setAttributeValue()
2440*/
2441void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x3& value)
2442{
2443 setUniformValue(location: uniformLocation(name), value);
2444}
2445
2446/*!
2447 Sets the uniform variable at \a location in the current context
2448 to a 4x4 matrix \a value.
2449
2450 \sa setAttributeValue()
2451*/
2452void QGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value)
2453{
2454 Q_D(QGLShaderProgram);
2455 d->glfuncs->glUniformMatrix4fv(location, count: 1, GL_FALSE, value: value.constData());
2456}
2457
2458/*!
2459 \overload
2460
2461 Sets the uniform variable called \a name in the current context
2462 to a 4x4 matrix \a value.
2463
2464 \sa setAttributeValue()
2465*/
2466void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x4& value)
2467{
2468 setUniformValue(location: uniformLocation(name), value);
2469}
2470
2471/*!
2472 \overload
2473
2474 Sets the uniform variable at \a location in the current context
2475 to a 2x2 matrix \a value. The matrix elements must be specified
2476 in column-major order.
2477
2478 \sa setAttributeValue()
2479 \since 4.7
2480*/
2481void QGLShaderProgram::setUniformValue(int location, const GLfloat value[2][2])
2482{
2483 Q_D(QGLShaderProgram);
2484 if (location != -1)
2485 d->glfuncs->glUniformMatrix2fv(location, count: 1, GL_FALSE, value: value[0]);
2486}
2487
2488/*!
2489 \overload
2490
2491 Sets the uniform variable at \a location in the current context
2492 to a 3x3 matrix \a value. The matrix elements must be specified
2493 in column-major order.
2494
2495 \sa setAttributeValue()
2496 \since 4.7
2497*/
2498void QGLShaderProgram::setUniformValue(int location, const GLfloat value[3][3])
2499{
2500 Q_D(QGLShaderProgram);
2501 if (location != -1)
2502 d->glfuncs->glUniformMatrix3fv(location, count: 1, GL_FALSE, value: value[0]);
2503}
2504
2505/*!
2506 \overload
2507
2508 Sets the uniform variable at \a location in the current context
2509 to a 4x4 matrix \a value. The matrix elements must be specified
2510 in column-major order.
2511
2512 \sa setAttributeValue()
2513*/
2514void QGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4])
2515{
2516 Q_D(QGLShaderProgram);
2517 if (location != -1)
2518 d->glfuncs->glUniformMatrix4fv(location, count: 1, GL_FALSE, value: value[0]);
2519}
2520
2521
2522/*!
2523 \overload
2524
2525 Sets the uniform variable called \a name in the current context
2526 to a 2x2 matrix \a value. The matrix elements must be specified
2527 in column-major order.
2528
2529 \sa setAttributeValue()
2530 \since 4.7
2531*/
2532void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[2][2])
2533{
2534 setUniformValue(location: uniformLocation(name), value);
2535}
2536
2537/*!
2538 \overload
2539
2540 Sets the uniform variable called \a name in the current context
2541 to a 3x3 matrix \a value. The matrix elements must be specified
2542 in column-major order.
2543
2544 \sa setAttributeValue()
2545 \since 4.7
2546*/
2547void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[3][3])
2548{
2549 setUniformValue(location: uniformLocation(name), value);
2550}
2551
2552/*!
2553 \overload
2554
2555 Sets the uniform variable called \a name in the current context
2556 to a 4x4 matrix \a value. The matrix elements must be specified
2557 in column-major order.
2558
2559 \sa setAttributeValue()
2560*/
2561void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[4][4])
2562{
2563 setUniformValue(location: uniformLocation(name), value);
2564}
2565
2566/*!
2567 Sets the uniform variable at \a location in the current context to a
2568 3x3 transformation matrix \a value that is specified as a QTransform value.
2569
2570 To set a QTransform value as a 4x4 matrix in a shader, use
2571 \c{setUniformValue(location, QMatrix4x4(value))}.
2572*/
2573void QGLShaderProgram::setUniformValue(int location, const QTransform& value)
2574{
2575 Q_D(QGLShaderProgram);
2576 if (location != -1) {
2577 GLfloat mat[3][3] = {
2578 {GLfloat(value.m11()), GLfloat(value.m12()), GLfloat(value.m13())},
2579 {GLfloat(value.m21()), GLfloat(value.m22()), GLfloat(value.m23())},
2580 {GLfloat(value.m31()), GLfloat(value.m32()), GLfloat(value.m33())}
2581 };
2582 d->glfuncs->glUniformMatrix3fv(location, count: 1, GL_FALSE, value: mat[0]);
2583 }
2584}
2585
2586/*!
2587 \overload
2588
2589 Sets the uniform variable called \a name in the current context to a
2590 3x3 transformation matrix \a value that is specified as a QTransform value.
2591
2592 To set a QTransform value as a 4x4 matrix in a shader, use
2593 \c{setUniformValue(name, QMatrix4x4(value))}.
2594*/
2595void QGLShaderProgram::setUniformValue
2596 (const char *name, const QTransform& value)
2597{
2598 setUniformValue(location: uniformLocation(name), value);
2599}
2600
2601/*!
2602 Sets the uniform variable array at \a location in the current
2603 context to the \a count elements of \a values.
2604
2605 \sa setAttributeValue()
2606*/
2607void QGLShaderProgram::setUniformValueArray(int location, const GLint *values, int count)
2608{
2609 Q_D(QGLShaderProgram);
2610 if (location != -1)
2611 d->glfuncs->glUniform1iv(location, count, v: values);
2612}
2613
2614/*!
2615 \overload
2616
2617 Sets the uniform variable array called \a name in the current
2618 context to the \a count elements of \a values.
2619
2620 \sa setAttributeValue()
2621*/
2622void QGLShaderProgram::setUniformValueArray
2623 (const char *name, const GLint *values, int count)
2624{
2625 setUniformValueArray(location: uniformLocation(name), values, count);
2626}
2627
2628/*!
2629 Sets the uniform variable array at \a location in the current
2630 context to the \a count elements of \a values. This overload
2631 should be used when setting an array of sampler values.
2632
2633 \sa setAttributeValue()
2634*/
2635void QGLShaderProgram::setUniformValueArray(int location, const GLuint *values, int count)
2636{
2637 Q_D(QGLShaderProgram);
2638 if (location != -1)
2639 d->glfuncs->glUniform1iv(location, count, v: reinterpret_cast<const GLint *>(values));
2640}
2641
2642/*!
2643 \overload
2644
2645 Sets the uniform variable array called \a name in the current
2646 context to the \a count elements of \a values. This overload
2647 should be used when setting an array of sampler values.
2648
2649 \sa setAttributeValue()
2650*/
2651void QGLShaderProgram::setUniformValueArray
2652 (const char *name, const GLuint *values, int count)
2653{
2654 setUniformValueArray(location: uniformLocation(name), values, count);
2655}
2656
2657/*!
2658 Sets the uniform variable array at \a location in the current
2659 context to the \a count elements of \a values. Each element
2660 has \a tupleSize components. The \a tupleSize must be 1, 2, 3, or 4.
2661
2662 \sa setAttributeValue()
2663*/
2664void QGLShaderProgram::setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize)
2665{
2666 Q_D(QGLShaderProgram);
2667 if (location != -1) {
2668 if (tupleSize == 1)
2669 d->glfuncs->glUniform1fv(location, count, v: values);
2670 else if (tupleSize == 2)
2671 d->glfuncs->glUniform2fv(location, count, v: values);
2672 else if (tupleSize == 3)
2673 d->glfuncs->glUniform3fv(location, count, v: values);
2674 else if (tupleSize == 4)
2675 d->glfuncs->glUniform4fv(location, count, v: values);
2676 else
2677 qWarning() << "QGLShaderProgram::setUniformValue: size" << tupleSize << "not supported";
2678 }
2679}
2680
2681/*!
2682 \overload
2683
2684 Sets the uniform variable array called \a name in the current
2685 context to the \a count elements of \a values. Each element
2686 has \a tupleSize components. The \a tupleSize must be 1, 2, 3, or 4.
2687
2688 \sa setAttributeValue()
2689*/
2690void QGLShaderProgram::setUniformValueArray
2691 (const char *name, const GLfloat *values, int count, int tupleSize)
2692{
2693 setUniformValueArray(location: uniformLocation(name), values, count, tupleSize);
2694}
2695
2696/*!
2697 Sets the uniform variable array at \a location in the current
2698 context to the \a count 2D vector elements of \a values.
2699
2700 \sa setAttributeValue()
2701*/
2702void QGLShaderProgram::setUniformValueArray(int location, const QVector2D *values, int count)
2703{
2704 Q_D(QGLShaderProgram);
2705 if (location != -1)
2706 d->glfuncs->glUniform2fv(location, count, v: reinterpret_cast<const GLfloat *>(values));
2707}
2708
2709/*!
2710 \overload
2711
2712 Sets the uniform variable array called \a name in the current
2713 context to the \a count 2D vector elements of \a values.
2714
2715 \sa setAttributeValue()
2716*/
2717void QGLShaderProgram::setUniformValueArray(const char *name, const QVector2D *values, int count)
2718{
2719 setUniformValueArray(location: uniformLocation(name), values, count);
2720}
2721
2722/*!
2723 Sets the uniform variable array at \a location in the current
2724 context to the \a count 3D vector elements of \a values.
2725
2726 \sa setAttributeValue()
2727*/
2728void QGLShaderProgram::setUniformValueArray(int location, const QVector3D *values, int count)
2729{
2730 Q_D(QGLShaderProgram);
2731 if (location != -1)
2732 d->glfuncs->glUniform3fv(location, count, v: reinterpret_cast<const GLfloat *>(values));
2733}
2734
2735/*!
2736 \overload
2737
2738 Sets the uniform variable array called \a name in the current
2739 context to the \a count 3D vector elements of \a values.
2740
2741 \sa setAttributeValue()
2742*/
2743void QGLShaderProgram::setUniformValueArray(const char *name, const QVector3D *values, int count)
2744{
2745 setUniformValueArray(location: uniformLocation(name), values, count);
2746}
2747
2748/*!
2749 Sets the uniform variable array at \a location in the current
2750 context to the \a count 4D vector elements of \a values.
2751
2752 \sa setAttributeValue()
2753*/
2754void QGLShaderProgram::setUniformValueArray(int location, const QVector4D *values, int count)
2755{
2756 Q_D(QGLShaderProgram);
2757 Q_UNUSED(d);
2758 if (location != -1)
2759 d->glfuncs->glUniform4fv(location, count, v: reinterpret_cast<const GLfloat *>(values));
2760}
2761
2762/*!
2763 \overload
2764
2765 Sets the uniform variable array called \a name in the current
2766 context to the \a count 4D vector elements of \a values.
2767
2768 \sa setAttributeValue()
2769*/
2770void QGLShaderProgram::setUniformValueArray(const char *name, const QVector4D *values, int count)
2771{
2772 setUniformValueArray(location: uniformLocation(name), values, count);
2773}
2774
2775// We have to repack matrix arrays from qreal to GLfloat.
2776#define setUniformMatrixArray(func,location,values,count,type,cols,rows) \
2777 if (location == -1 || count <= 0) \
2778 return; \
2779 if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
2780 func(location, count, GL_FALSE, \
2781 reinterpret_cast<const GLfloat *>(values[0].constData())); \
2782 } else { \
2783 QVarLengthArray<GLfloat> temp(cols * rows * count); \
2784 for (int index = 0; index < count; ++index) { \
2785 for (int index2 = 0; index2 < (cols * rows); ++index2) { \
2786 temp.data()[cols * rows * index + index2] = \
2787 values[index].constData()[index2]; \
2788 } \
2789 } \
2790 func(location, count, GL_FALSE, temp.constData()); \
2791 }
2792#define setUniformGenericMatrixArray(colfunc,location,values,count,type,cols,rows) \
2793 if (location == -1 || count <= 0) \
2794 return; \
2795 if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
2796 const GLfloat *data = reinterpret_cast<const GLfloat *> \
2797 (values[0].constData()); \
2798 colfunc(location, count * cols, data); \
2799 } else { \
2800 QVarLengthArray<GLfloat> temp(cols * rows * count); \
2801 for (int index = 0; index < count; ++index) { \
2802 for (int index2 = 0; index2 < (cols * rows); ++index2) { \
2803 temp.data()[cols * rows * index + index2] = \
2804 values[index].constData()[index2]; \
2805 } \
2806 } \
2807 colfunc(location, count * cols, temp.constData()); \
2808 }
2809
2810/*!
2811 Sets the uniform variable array at \a location in the current
2812 context to the \a count 2x2 matrix elements of \a values.
2813
2814 \sa setAttributeValue()
2815*/
2816void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x2 *values, int count)
2817{
2818 Q_D(QGLShaderProgram);
2819 Q_UNUSED(d);
2820 setUniformMatrixArray
2821 (d->glfuncs->glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2);
2822}
2823
2824/*!
2825 \overload
2826
2827 Sets the uniform variable array called \a name in the current
2828 context to the \a count 2x2 matrix elements of \a values.
2829
2830 \sa setAttributeValue()
2831*/
2832void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x2 *values, int count)
2833{
2834 setUniformValueArray(location: uniformLocation(name), values, count);
2835}
2836
2837/*!
2838 Sets the uniform variable array at \a location in the current
2839 context to the \a count 2x3 matrix elements of \a values.
2840
2841 \sa setAttributeValue()
2842*/
2843void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x3 *values, int count)
2844{
2845 Q_D(QGLShaderProgram);
2846 Q_UNUSED(d);
2847 setUniformGenericMatrixArray
2848 (d->glfuncs->glUniform3fv, location, values, count,
2849 QMatrix2x3, 2, 3);
2850}
2851
2852/*!
2853 \overload
2854
2855 Sets the uniform variable array called \a name in the current
2856 context to the \a count 2x3 matrix elements of \a values.
2857
2858 \sa setAttributeValue()
2859*/
2860void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x3 *values, int count)
2861{
2862 setUniformValueArray(location: uniformLocation(name), values, count);
2863}
2864
2865/*!
2866 Sets the uniform variable array at \a location in the current
2867 context to the \a count 2x4 matrix elements of \a values.
2868
2869 \sa setAttributeValue()
2870*/
2871void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x4 *values, int count)
2872{
2873 Q_D(QGLShaderProgram);
2874 Q_UNUSED(d);
2875 setUniformGenericMatrixArray
2876 (d->glfuncs->glUniform4fv, location, values, count,
2877 QMatrix2x4, 2, 4);
2878}
2879
2880/*!
2881 \overload
2882
2883 Sets the uniform variable array called \a name in the current
2884 context to the \a count 2x4 matrix elements of \a values.
2885
2886 \sa setAttributeValue()
2887*/
2888void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x4 *values, int count)
2889{
2890 setUniformValueArray(location: uniformLocation(name), values, count);
2891}
2892
2893/*!
2894 Sets the uniform variable array at \a location in the current
2895 context to the \a count 3x2 matrix elements of \a values.
2896
2897 \sa setAttributeValue()
2898*/
2899void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x2 *values, int count)
2900{
2901 Q_D(QGLShaderProgram);
2902 Q_UNUSED(d);
2903 setUniformGenericMatrixArray
2904 (d->glfuncs->glUniform2fv, location, values, count,
2905 QMatrix3x2, 3, 2);
2906}
2907
2908/*!
2909 \overload
2910
2911 Sets the uniform variable array called \a name in the current
2912 context to the \a count 3x2 matrix elements of \a values.
2913
2914 \sa setAttributeValue()
2915*/
2916void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x2 *values, int count)
2917{
2918 setUniformValueArray(location: uniformLocation(name), values, count);
2919}
2920
2921/*!
2922 Sets the uniform variable array at \a location in the current
2923 context to the \a count 3x3 matrix elements of \a values.
2924
2925 \sa setAttributeValue()
2926*/
2927void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x3 *values, int count)
2928{
2929 Q_D(QGLShaderProgram);
2930 Q_UNUSED(d);
2931 setUniformMatrixArray
2932 (d->glfuncs->glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3);
2933}
2934
2935/*!
2936 \overload
2937
2938 Sets the uniform variable array called \a name in the current
2939 context to the \a count 3x3 matrix elements of \a values.
2940
2941 \sa setAttributeValue()
2942*/
2943void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x3 *values, int count)
2944{
2945 setUniformValueArray(location: uniformLocation(name), values, count);
2946}
2947
2948/*!
2949 Sets the uniform variable array at \a location in the current
2950 context to the \a count 3x4 matrix elements of \a values.
2951
2952 \sa setAttributeValue()
2953*/
2954void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x4 *values, int count)
2955{
2956 Q_D(QGLShaderProgram);
2957 Q_UNUSED(d);
2958 setUniformGenericMatrixArray
2959 (d->glfuncs->glUniform4fv, location, values, count,
2960 QMatrix3x4, 3, 4);
2961}
2962
2963/*!
2964 \overload
2965
2966 Sets the uniform variable array called \a name in the current
2967 context to the \a count 3x4 matrix elements of \a values.
2968
2969 \sa setAttributeValue()
2970*/
2971void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x4 *values, int count)
2972{
2973 setUniformValueArray(location: uniformLocation(name), values, count);
2974}
2975
2976/*!
2977 Sets the uniform variable array at \a location in the current
2978 context to the \a count 4x2 matrix elements of \a values.
2979
2980 \sa setAttributeValue()
2981*/
2982void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x2 *values, int count)
2983{
2984 Q_D(QGLShaderProgram);
2985 Q_UNUSED(d);
2986 setUniformGenericMatrixArray
2987 (d->glfuncs->glUniform2fv, location, values, count,
2988 QMatrix4x2, 4, 2);
2989}
2990
2991/*!
2992 \overload
2993
2994 Sets the uniform variable array called \a name in the current
2995 context to the \a count 4x2 matrix elements of \a values.
2996
2997 \sa setAttributeValue()
2998*/
2999void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x2 *values, int count)
3000{
3001 setUniformValueArray(location: uniformLocation(name), values, count);
3002}
3003
3004/*!
3005 Sets the uniform variable array at \a location in the current
3006 context to the \a count 4x3 matrix elements of \a values.
3007
3008 \sa setAttributeValue()
3009*/
3010void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x3 *values, int count)
3011{
3012 Q_D(QGLShaderProgram);
3013 Q_UNUSED(d);
3014 setUniformGenericMatrixArray
3015 (d->glfuncs->glUniform3fv, location, values, count,
3016 QMatrix4x3, 4, 3);
3017}
3018
3019/*!
3020 \overload
3021
3022 Sets the uniform variable array called \a name in the current
3023 context to the \a count 4x3 matrix elements of \a values.
3024
3025 \sa setAttributeValue()
3026*/
3027void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x3 *values, int count)
3028{
3029 setUniformValueArray(location: uniformLocation(name), values, count);
3030}
3031
3032/*!
3033 Sets the uniform variable array at \a location in the current
3034 context to the \a count 4x4 matrix elements of \a values.
3035
3036 \sa setAttributeValue()
3037*/
3038void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x4 *values, int count)
3039{
3040 Q_D(QGLShaderProgram);
3041 Q_UNUSED(d);
3042 setUniformMatrixArray
3043 (d->glfuncs->glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4);
3044}
3045
3046/*!
3047 \overload
3048
3049 Sets the uniform variable array called \a name in the current
3050 context to the \a count 4x4 matrix elements of \a values.
3051
3052 \sa setAttributeValue()
3053*/
3054void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x4 *values, int count)
3055{
3056 setUniformValueArray(location: uniformLocation(name), values, count);
3057}
3058
3059#undef ctx
3060
3061/*!
3062 Returns the hardware limit for how many vertices a geometry shader
3063 can output.
3064
3065 \since 4.7
3066
3067 \sa setGeometryOutputVertexCount()
3068*/
3069int QGLShaderProgram::maxGeometryOutputVertices() const
3070{
3071 GLint n = 0;
3072#if !defined(QT_OPENGL_ES_2)
3073 Q_D(const QGLShaderProgram);
3074 if (!QOpenGLContext::currentContext()->isOpenGLES())
3075 d->glfuncs->glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, params: &n);
3076#endif
3077 return n;
3078}
3079
3080/*!
3081 Sets the maximum number of vertices the current geometry shader
3082 program will produce, if active, to \a count.
3083
3084 \since 4.7
3085
3086 This parameter takes effect the next time the program is linked.
3087*/
3088void QGLShaderProgram::setGeometryOutputVertexCount(int count)
3089{
3090#ifndef QT_NO_DEBUG
3091 int max = maxGeometryOutputVertices();
3092 if (count > max) {
3093 qWarning(msg: "QGLShaderProgram::setGeometryOutputVertexCount: count: %d higher than maximum: %d",
3094 count, max);
3095 }
3096#endif
3097 d_func()->geometryVertexCount = count;
3098}
3099
3100
3101/*!
3102 Returns the maximum number of vertices the current geometry shader
3103 program will produce, if active.
3104
3105 \since 4.7
3106
3107 This parameter takes effect the ntext time the program is linked.
3108*/
3109int QGLShaderProgram::geometryOutputVertexCount() const
3110{
3111 return d_func()->geometryVertexCount;
3112}
3113
3114
3115/*!
3116 Sets the input type from \a inputType.
3117
3118 This parameter takes effect the next time the program is linked.
3119*/
3120void QGLShaderProgram::setGeometryInputType(GLenum inputType)
3121{
3122 d_func()->geometryInputType = inputType;
3123}
3124
3125
3126/*!
3127 Returns the geometry shader input type, if active.
3128
3129 This parameter takes effect the next time the program is linked.
3130
3131 \since 4.7
3132 */
3133
3134GLenum QGLShaderProgram::geometryInputType() const
3135{
3136 return d_func()->geometryInputType;
3137}
3138
3139
3140/*!
3141 Sets the output type from the geometry shader, if active, to
3142 \a outputType.
3143
3144 This parameter takes effect the next time the program is linked.
3145
3146 \since 4.7
3147*/
3148void QGLShaderProgram::setGeometryOutputType(GLenum outputType)
3149{
3150 d_func()->geometryOutputType = outputType;
3151}
3152
3153
3154/*!
3155 Returns the geometry shader output type, if active.
3156
3157 This parameter takes effect the next time the program is linked.
3158
3159 \since 4.7
3160 */
3161GLenum QGLShaderProgram::geometryOutputType() const
3162{
3163 return d_func()->geometryOutputType;
3164}
3165
3166
3167/*!
3168 Returns \c true if shader programs written in the OpenGL Shading
3169 Language (GLSL) are supported on this system; false otherwise.
3170
3171 The \a context is used to resolve the GLSL extensions.
3172 If \a context is \nullptr, then QGLContext::currentContext() is
3173 used.
3174*/
3175bool QGLShaderProgram::hasOpenGLShaderPrograms(const QGLContext *context)
3176{
3177#if !defined(QT_OPENGL_ES_2)
3178 if (!context)
3179 context = QGLContext::currentContext();
3180 if (!context)
3181 return false;
3182
3183 QOpenGLFunctions functions(context->contextHandle());
3184 return functions.hasOpenGLFeature(feature: QOpenGLFunctions::Shaders);
3185#else
3186 Q_UNUSED(context);
3187 return true;
3188#endif
3189}
3190
3191/*!
3192 \internal
3193*/
3194void QGLShaderProgram::shaderDestroyed()
3195{
3196 Q_D(QGLShaderProgram);
3197 QGLShader *shader = qobject_cast<QGLShader *>(object: sender());
3198 if (shader && !d->removingShaders)
3199 removeShader(shader);
3200}
3201
3202
3203#undef ctx
3204#undef context
3205
3206/*!
3207 Returns \c true if shader programs of type \a type are supported on
3208 this system; false otherwise.
3209
3210 The \a context is used to resolve the GLSL extensions.
3211 If \a context is \nullptr, then QGLContext::currentContext() is
3212 used.
3213
3214 \since 4.7
3215*/
3216bool QGLShader::hasOpenGLShaders(ShaderType type, const QGLContext *context)
3217{
3218 if (!context)
3219 context = QGLContext::currentContext();
3220 if (!context)
3221 return false;
3222
3223 if ((type & ~(Geometry | Vertex | Fragment)) || type == 0)
3224 return false;
3225
3226 QOpenGLFunctions functions(context->contextHandle());
3227 bool resolved = functions.hasOpenGLFeature(feature: QOpenGLFunctions::Shaders);
3228 if (!resolved)
3229 return false;
3230
3231 if ((type & Geometry) && !QByteArray((const char *) functions.glGetString(GL_EXTENSIONS)).contains(c: "GL_EXT_geometry_shader4"))
3232 return false;
3233
3234 return true;
3235}
3236
3237QT_END_NAMESPACE
3238

source code of qtbase/src/opengl/qglshaderprogram.cpp