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