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

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

trunk: Merged in qt 4.6.2 sources.

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