source: trunk/src/opengl/qglshaderprogram.cpp@ 890

Last change on this file since 890 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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