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

Last change on this file since 595 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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