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

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

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

  • Property svn:eol-style set to native
File size: 82.7 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 When this function is called after the program has been linked,
973 the program will need to be relinked for the change to take effect.
974
975 \sa attributeLocation()
976*/
977void QGLShaderProgram::bindAttributeLocation(const char *name, int location)
978{
979 Q_D(QGLShaderProgram);
980 if (!init())
981 return;
982 glBindAttribLocation(d->programGuard.id(), location, name);
983 d->linked = false; // Program needs to be relinked.
984}
985
986/*!
987 \overload
988
989 Binds the attribute \a name to the specified \a location. This
990 function can be called before or after the program has been linked.
991 Any attributes that have not been explicitly bound when the program
992 is linked will be assigned locations automatically.
993
994 When this function is called after the program has been linked,
995 the program will need to be relinked for the change to take effect.
996
997 \sa attributeLocation()
998*/
999void QGLShaderProgram::bindAttributeLocation(const QByteArray& name, int location)
1000{
1001 bindAttributeLocation(name.constData(), location);
1002}
1003
1004/*!
1005 \overload
1006
1007 Binds the attribute \a name to the specified \a location. This
1008 function can be called before or after the program has been linked.
1009 Any attributes that have not been explicitly bound when the program
1010 is linked will be assigned locations automatically.
1011
1012 When this function is called after the program has been linked,
1013 the program will need to be relinked for the change to take effect.
1014
1015 \sa attributeLocation()
1016*/
1017void QGLShaderProgram::bindAttributeLocation(const QString& name, int location)
1018{
1019 bindAttributeLocation(name.toLatin1().constData(), location);
1020}
1021
1022/*!
1023 Returns the location of the attribute \a name within this shader
1024 program's parameter list. Returns -1 if \a name is not a valid
1025 attribute for this shader program.
1026
1027 \sa uniformLocation(), bindAttributeLocation()
1028*/
1029int QGLShaderProgram::attributeLocation(const char *name) const
1030{
1031 Q_D(const QGLShaderProgram);
1032 if (d->linked) {
1033 return glGetAttribLocation(d->programGuard.id(), name);
1034 } else {
1035 qWarning() << "QGLShaderProgram::attributeLocation(" << name
1036 << "): shader program is not linked";
1037 return -1;
1038 }
1039}
1040
1041/*!
1042 \overload
1043
1044 Returns the location of the attribute \a name within this shader
1045 program's parameter list. Returns -1 if \a name is not a valid
1046 attribute for this shader program.
1047
1048 \sa uniformLocation(), bindAttributeLocation()
1049*/
1050int QGLShaderProgram::attributeLocation(const QByteArray& name) const
1051{
1052 return attributeLocation(name.constData());
1053}
1054
1055/*!
1056 \overload
1057
1058 Returns the location of the attribute \a name within this shader
1059 program's parameter list. Returns -1 if \a name is not a valid
1060 attribute for this shader program.
1061
1062 \sa uniformLocation(), bindAttributeLocation()
1063*/
1064int QGLShaderProgram::attributeLocation(const QString& name) const
1065{
1066 return attributeLocation(name.toLatin1().constData());
1067}
1068
1069/*!
1070 Sets the attribute at \a location in the current context to \a value.
1071
1072 \sa setUniformValue()
1073*/
1074void QGLShaderProgram::setAttributeValue(int location, GLfloat value)
1075{
1076 Q_D(QGLShaderProgram);
1077 Q_UNUSED(d);
1078 if (location != -1)
1079 glVertexAttrib1fv(location, &value);
1080}
1081
1082/*!
1083 \overload
1084
1085 Sets the attribute called \a name in the current context to \a value.
1086
1087 \sa setUniformValue()
1088*/
1089void QGLShaderProgram::setAttributeValue(const char *name, GLfloat value)
1090{
1091 setAttributeValue(attributeLocation(name), value);
1092}
1093
1094/*!
1095 Sets the attribute at \a location in the current context to
1096 the 2D vector (\a x, \a y).
1097
1098 \sa setUniformValue()
1099*/
1100void QGLShaderProgram::setAttributeValue(int location, GLfloat x, GLfloat y)
1101{
1102 Q_D(QGLShaderProgram);
1103 Q_UNUSED(d);
1104 if (location != -1) {
1105 GLfloat values[2] = {x, y};
1106 glVertexAttrib2fv(location, values);
1107 }
1108}
1109
1110/*!
1111 \overload
1112
1113 Sets the attribute called \a name in the current context to
1114 the 2D vector (\a x, \a y).
1115
1116 \sa setUniformValue()
1117*/
1118void QGLShaderProgram::setAttributeValue(const char *name, GLfloat x, GLfloat y)
1119{
1120 setAttributeValue(attributeLocation(name), x, y);
1121}
1122
1123/*!
1124 Sets the attribute at \a location in the current context to
1125 the 3D vector (\a x, \a y, \a z).
1126
1127 \sa setUniformValue()
1128*/
1129void QGLShaderProgram::setAttributeValue
1130 (int location, GLfloat x, GLfloat y, GLfloat z)
1131{
1132 Q_D(QGLShaderProgram);
1133 Q_UNUSED(d);
1134 if (location != -1) {
1135 GLfloat values[3] = {x, y, z};
1136 glVertexAttrib3fv(location, values);
1137 }
1138}
1139
1140/*!
1141 \overload
1142
1143 Sets the attribute called \a name in the current context to
1144 the 3D vector (\a x, \a y, \a z).
1145
1146 \sa setUniformValue()
1147*/
1148void QGLShaderProgram::setAttributeValue
1149 (const char *name, GLfloat x, GLfloat y, GLfloat z)
1150{
1151 setAttributeValue(attributeLocation(name), x, y, z);
1152}
1153
1154/*!
1155 Sets the attribute at \a location in the current context to
1156 the 4D vector (\a x, \a y, \a z, \a w).
1157
1158 \sa setUniformValue()
1159*/
1160void QGLShaderProgram::setAttributeValue
1161 (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1162{
1163 Q_D(QGLShaderProgram);
1164 Q_UNUSED(d);
1165 if (location != -1) {
1166 GLfloat values[4] = {x, y, z, w};
1167 glVertexAttrib4fv(location, values);
1168 }
1169}
1170
1171/*!
1172 \overload
1173
1174 Sets the attribute called \a name in the current context to
1175 the 4D vector (\a x, \a y, \a z, \a w).
1176
1177 \sa setUniformValue()
1178*/
1179void QGLShaderProgram::setAttributeValue
1180 (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1181{
1182 setAttributeValue(attributeLocation(name), x, y, z, w);
1183}
1184
1185/*!
1186 Sets the attribute at \a location in the current context to \a value.
1187
1188 \sa setUniformValue()
1189*/
1190void QGLShaderProgram::setAttributeValue(int location, const QVector2D& value)
1191{
1192 Q_D(QGLShaderProgram);
1193 Q_UNUSED(d);
1194 if (location != -1)
1195 glVertexAttrib2fv(location, reinterpret_cast<const GLfloat *>(&value));
1196}
1197
1198/*!
1199 \overload
1200
1201 Sets the attribute called \a name in the current context to \a value.
1202
1203 \sa setUniformValue()
1204*/
1205void QGLShaderProgram::setAttributeValue(const char *name, const QVector2D& value)
1206{
1207 setAttributeValue(attributeLocation(name), value);
1208}
1209
1210/*!
1211 Sets the attribute at \a location in the current context to \a value.
1212
1213 \sa setUniformValue()
1214*/
1215void QGLShaderProgram::setAttributeValue(int location, const QVector3D& value)
1216{
1217 Q_D(QGLShaderProgram);
1218 Q_UNUSED(d);
1219 if (location != -1)
1220 glVertexAttrib3fv(location, reinterpret_cast<const GLfloat *>(&value));
1221}
1222
1223/*!
1224 \overload
1225
1226 Sets the attribute called \a name in the current context to \a value.
1227
1228 \sa setUniformValue()
1229*/
1230void QGLShaderProgram::setAttributeValue(const char *name, const QVector3D& value)
1231{
1232 setAttributeValue(attributeLocation(name), value);
1233}
1234
1235/*!
1236 Sets the attribute at \a location in the current context to \a value.
1237
1238 \sa setUniformValue()
1239*/
1240void QGLShaderProgram::setAttributeValue(int location, const QVector4D& value)
1241{
1242 Q_D(QGLShaderProgram);
1243 Q_UNUSED(d);
1244 if (location != -1)
1245 glVertexAttrib4fv(location, reinterpret_cast<const GLfloat *>(&value));
1246}
1247
1248/*!
1249 \overload
1250
1251 Sets the attribute called \a name in the current context to \a value.
1252
1253 \sa setUniformValue()
1254*/
1255void QGLShaderProgram::setAttributeValue(const char *name, const QVector4D& value)
1256{
1257 setAttributeValue(attributeLocation(name), value);
1258}
1259
1260/*!
1261 Sets the attribute at \a location in the current context to \a value.
1262
1263 \sa setUniformValue()
1264*/
1265void QGLShaderProgram::setAttributeValue(int location, const QColor& value)
1266{
1267 Q_D(QGLShaderProgram);
1268 Q_UNUSED(d);
1269 if (location != -1) {
1270 GLfloat values[4] = {value.redF(), value.greenF(), value.blueF(), value.alphaF()};
1271 glVertexAttrib4fv(location, values);
1272 }
1273}
1274
1275/*!
1276 \overload
1277
1278 Sets the attribute called \a name in the current context to \a value.
1279
1280 \sa setUniformValue()
1281*/
1282void QGLShaderProgram::setAttributeValue(const char *name, const QColor& value)
1283{
1284 setAttributeValue(attributeLocation(name), value);
1285}
1286
1287/*!
1288 Sets the attribute at \a location in the current context to the
1289 contents of \a values, which contains \a columns elements, each
1290 consisting of \a rows elements. The \a rows value should be
1291 1, 2, 3, or 4. This function is typically used to set matrix
1292 values and column vectors.
1293
1294 \sa setUniformValue()
1295*/
1296void QGLShaderProgram::setAttributeValue
1297 (int location, const GLfloat *values, int columns, int rows)
1298{
1299 Q_D(QGLShaderProgram);
1300 Q_UNUSED(d);
1301 if (rows < 1 || rows > 4) {
1302 qWarning() << "QGLShaderProgram::setAttributeValue: rows" << rows << "not supported";
1303 return;
1304 }
1305 if (location != -1) {
1306 while (columns-- > 0) {
1307 if (rows == 1)
1308 glVertexAttrib1fv(location, values);
1309 else if (rows == 2)
1310 glVertexAttrib2fv(location, values);
1311 else if (rows == 3)
1312 glVertexAttrib3fv(location, values);
1313 else
1314 glVertexAttrib4fv(location, values);
1315 values += rows;
1316 ++location;
1317 }
1318 }
1319}
1320
1321/*!
1322 \overload
1323
1324 Sets the attribute called \a name in the current context to the
1325 contents of \a values, which contains \a columns elements, each
1326 consisting of \a rows elements. The \a rows value should be
1327 1, 2, 3, or 4. This function is typically used to set matrix
1328 values and column vectors.
1329
1330 \sa setUniformValue()
1331*/
1332void QGLShaderProgram::setAttributeValue
1333 (const char *name, const GLfloat *values, int columns, int rows)
1334{
1335 setAttributeValue(attributeLocation(name), values, columns, rows);
1336}
1337
1338/*!
1339 Sets an array of vertex \a values on the attribute at \a location
1340 in this shader program. The \a tupleSize indicates the number of
1341 components per vertex (1, 2, 3, or 4), and the \a stride indicates
1342 the number of bytes between vertices. A default \a stride value
1343 of zero indicates that the vertices are densely packed in \a values.
1344
1345 The array will become active when enableAttributeArray() is called
1346 on the \a location. Otherwise the value specified with
1347 setAttributeValue() for \a location will be used.
1348
1349 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1350 \sa disableAttributeArray()
1351*/
1352void QGLShaderProgram::setAttributeArray
1353 (int location, const GLfloat *values, int tupleSize, int stride)
1354{
1355 Q_D(QGLShaderProgram);
1356 Q_UNUSED(d);
1357 if (location != -1) {
1358 glVertexAttribPointer(location, tupleSize, GL_FLOAT, GL_FALSE,
1359 stride, values);
1360 }
1361}
1362
1363/*!
1364 Sets an array of 2D vertex \a values on the attribute at \a location
1365 in this shader program. The \a stride indicates the number of bytes
1366 between vertices. A default \a stride value of zero indicates that
1367 the vertices are densely packed in \a values.
1368
1369 The array will become active when enableAttributeArray() is called
1370 on the \a location. Otherwise the value specified with
1371 setAttributeValue() for \a location will be used.
1372
1373 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1374 \sa disableAttributeArray()
1375*/
1376void QGLShaderProgram::setAttributeArray
1377 (int location, const QVector2D *values, int stride)
1378{
1379 Q_D(QGLShaderProgram);
1380 Q_UNUSED(d);
1381 if (location != -1) {
1382 glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE,
1383 stride, values);
1384 }
1385}
1386
1387/*!
1388 Sets an array of 3D vertex \a values on the attribute at \a location
1389 in this shader program. The \a stride indicates the number of bytes
1390 between vertices. A default \a stride value of zero indicates that
1391 the vertices are densely packed in \a values.
1392
1393 The array will become active when enableAttributeArray() is called
1394 on the \a location. Otherwise the value specified with
1395 setAttributeValue() for \a location will be used.
1396
1397 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1398 \sa disableAttributeArray()
1399*/
1400void QGLShaderProgram::setAttributeArray
1401 (int location, const QVector3D *values, int stride)
1402{
1403 Q_D(QGLShaderProgram);
1404 Q_UNUSED(d);
1405 if (location != -1) {
1406 glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE,
1407 stride, values);
1408 }
1409}
1410
1411/*!
1412 Sets an array of 4D vertex \a values on the attribute at \a location
1413 in this shader program. The \a stride indicates the number of bytes
1414 between vertices. A default \a stride value of zero indicates that
1415 the vertices are densely packed in \a values.
1416
1417 The array will become active when enableAttributeArray() is called
1418 on the \a location. Otherwise the value specified with
1419 setAttributeValue() for \a location will be used.
1420
1421 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1422 \sa disableAttributeArray()
1423*/
1424void QGLShaderProgram::setAttributeArray
1425 (int location, const QVector4D *values, int stride)
1426{
1427 Q_D(QGLShaderProgram);
1428 Q_UNUSED(d);
1429 if (location != -1) {
1430 glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE,
1431 stride, values);
1432 }
1433}
1434
1435/*!
1436 \overload
1437
1438 Sets an array of vertex \a values on the attribute called \a name
1439 in this shader program. The \a tupleSize indicates the number of
1440 components per vertex (1, 2, 3, or 4), and the \a stride indicates
1441 the number of bytes between vertices. A default \a stride value
1442 of zero indicates that the vertices are densely packed in \a values.
1443
1444 The array will become active when enableAttributeArray() is called
1445 on \a name. Otherwise the value specified with setAttributeValue()
1446 for \a name will be used.
1447
1448 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1449 \sa disableAttributeArray()
1450*/
1451void QGLShaderProgram::setAttributeArray
1452 (const char *name, const GLfloat *values, int tupleSize, int stride)
1453{
1454 setAttributeArray(attributeLocation(name), values, tupleSize, stride);
1455}
1456
1457/*!
1458 \overload
1459
1460 Sets an array of 2D vertex \a values on the attribute called \a name
1461 in this shader program. The \a stride indicates the number of bytes
1462 between vertices. A default \a stride value of zero indicates that
1463 the vertices are densely packed in \a values.
1464
1465 The array will become active when enableAttributeArray() is called
1466 on \a name. Otherwise the value specified with setAttributeValue()
1467 for \a name will be used.
1468
1469 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1470 \sa disableAttributeArray()
1471*/
1472void QGLShaderProgram::setAttributeArray
1473 (const char *name, const QVector2D *values, int stride)
1474{
1475 setAttributeArray(attributeLocation(name), values, stride);
1476}
1477
1478/*!
1479 \overload
1480
1481 Sets an array of 3D vertex \a values on the attribute called \a name
1482 in this shader program. The \a stride indicates the number of bytes
1483 between vertices. A default \a stride value of zero indicates that
1484 the vertices are densely packed in \a values.
1485
1486 The array will become active when enableAttributeArray() is called
1487 on \a name. Otherwise the value specified with setAttributeValue()
1488 for \a name will be used.
1489
1490 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1491 \sa disableAttributeArray()
1492*/
1493void QGLShaderProgram::setAttributeArray
1494 (const char *name, const QVector3D *values, int stride)
1495{
1496 setAttributeArray(attributeLocation(name), values, stride);
1497}
1498
1499/*!
1500 \overload
1501
1502 Sets an array of 4D vertex \a values on the attribute called \a name
1503 in this shader program. The \a stride indicates the number of bytes
1504 between vertices. A default \a stride value of zero indicates that
1505 the vertices are densely packed in \a values.
1506
1507 The array will become active when enableAttributeArray() is called
1508 on \a name. Otherwise the value specified with setAttributeValue()
1509 for \a name will be used.
1510
1511 \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
1512 \sa disableAttributeArray()
1513*/
1514void QGLShaderProgram::setAttributeArray
1515 (const char *name, const QVector4D *values, int stride)
1516{
1517 setAttributeArray(attributeLocation(name), values, stride);
1518}
1519
1520/*!
1521 Enables the vertex array at \a location in this shader program
1522 so that the value set by setAttributeArray() on \a location
1523 will be used by the shader program.
1524
1525 \sa disableAttributeArray(), setAttributeArray(), setAttributeValue()
1526 \sa setUniformValue()
1527*/
1528void QGLShaderProgram::enableAttributeArray(int location)
1529{
1530 Q_D(QGLShaderProgram);
1531 Q_UNUSED(d);
1532 if (location != -1)
1533 glEnableVertexAttribArray(location);
1534}
1535
1536/*!
1537 \overload
1538
1539 Enables the vertex array called \a name in this shader program
1540 so that the value set by setAttributeArray() on \a name
1541 will be used by the shader program.
1542
1543 \sa disableAttributeArray(), setAttributeArray(), setAttributeValue()
1544 \sa setUniformValue()
1545*/
1546void QGLShaderProgram::enableAttributeArray(const char *name)
1547{
1548 enableAttributeArray(attributeLocation(name));
1549}
1550
1551/*!
1552 Disables the vertex array at \a location in this shader program
1553 that was enabled by a previous call to enableAttributeArray().
1554
1555 \sa enableAttributeArray(), setAttributeArray(), setAttributeValue()
1556 \sa setUniformValue()
1557*/
1558void QGLShaderProgram::disableAttributeArray(int location)
1559{
1560 Q_D(QGLShaderProgram);
1561 Q_UNUSED(d);
1562 if (location != -1)
1563 glDisableVertexAttribArray(location);
1564}
1565
1566/*!
1567 \overload
1568
1569 Disables the vertex array called \a name in this shader program
1570 that was enabled by a previous call to enableAttributeArray().
1571
1572 \sa enableAttributeArray(), setAttributeArray(), setAttributeValue()
1573 \sa setUniformValue()
1574*/
1575void QGLShaderProgram::disableAttributeArray(const char *name)
1576{
1577 disableAttributeArray(attributeLocation(name));
1578}
1579
1580/*!
1581 Returns the location of the uniform variable \a name within this shader
1582 program's parameter list. Returns -1 if \a name is not a valid
1583 uniform variable for this shader program.
1584
1585 \sa attributeLocation()
1586*/
1587int QGLShaderProgram::uniformLocation(const char *name) const
1588{
1589 Q_D(const QGLShaderProgram);
1590 Q_UNUSED(d);
1591 if (d->linked) {
1592 return glGetUniformLocation(d->programGuard.id(), name);
1593 } else {
1594 qWarning() << "QGLShaderProgram::uniformLocation(" << name
1595 << "): shader program is not linked";
1596 return -1;
1597 }
1598}
1599
1600/*!
1601 \overload
1602
1603 Returns the location of the uniform variable \a name within this shader
1604 program's parameter list. Returns -1 if \a name is not a valid
1605 uniform variable for this shader program.
1606
1607 \sa attributeLocation()
1608*/
1609int QGLShaderProgram::uniformLocation(const QByteArray& name) const
1610{
1611 return uniformLocation(name.constData());
1612}
1613
1614/*!
1615 \overload
1616
1617 Returns the location of the uniform variable \a name within this shader
1618 program's parameter list. Returns -1 if \a name is not a valid
1619 uniform variable for this shader program.
1620
1621 \sa attributeLocation()
1622*/
1623int QGLShaderProgram::uniformLocation(const QString& name) const
1624{
1625 return uniformLocation(name.toLatin1().constData());
1626}
1627
1628/*!
1629 Sets the uniform variable at \a location in the current context to \a value.
1630
1631 \sa setAttributeValue()
1632*/
1633void QGLShaderProgram::setUniformValue(int location, GLfloat value)
1634{
1635 Q_D(QGLShaderProgram);
1636 Q_UNUSED(d);
1637 if (location != -1)
1638 glUniform1fv(location, 1, &value);
1639}
1640
1641/*!
1642 \overload
1643
1644 Sets the uniform variable called \a name in the current context
1645 to \a value.
1646
1647 \sa setAttributeValue()
1648*/
1649void QGLShaderProgram::setUniformValue(const char *name, GLfloat value)
1650{
1651 setUniformValue(uniformLocation(name), value);
1652}
1653
1654/*!
1655 Sets the uniform variable at \a location in the current context to \a value.
1656
1657 \sa setAttributeValue()
1658*/
1659void QGLShaderProgram::setUniformValue(int location, GLint value)
1660{
1661 Q_D(QGLShaderProgram);
1662 Q_UNUSED(d);
1663 if (location != -1)
1664 glUniform1i(location, value);
1665}
1666
1667/*!
1668 \overload
1669
1670 Sets the uniform variable called \a name in the current context
1671 to \a value.
1672
1673 \sa setAttributeValue()
1674*/
1675void QGLShaderProgram::setUniformValue(const char *name, GLint value)
1676{
1677 setUniformValue(uniformLocation(name), value);
1678}
1679
1680/*!
1681 Sets the uniform variable at \a location in the current context to \a value.
1682 This function should be used when setting sampler values.
1683
1684 \sa setAttributeValue()
1685*/
1686void QGLShaderProgram::setUniformValue(int location, GLuint value)
1687{
1688 Q_D(QGLShaderProgram);
1689 Q_UNUSED(d);
1690 if (location != -1)
1691 glUniform1i(location, value);
1692}
1693
1694/*!
1695 \overload
1696
1697 Sets the uniform variable called \a name in the current context
1698 to \a value. This function should be used when setting sampler values.
1699
1700 \sa setAttributeValue()
1701*/
1702void QGLShaderProgram::setUniformValue(const char *name, GLuint value)
1703{
1704 setUniformValue(uniformLocation(name), value);
1705}
1706
1707/*!
1708 Sets the uniform variable at \a location in the current context to
1709 the 2D vector (\a x, \a y).
1710
1711 \sa setAttributeValue()
1712*/
1713void QGLShaderProgram::setUniformValue(int location, GLfloat x, GLfloat y)
1714{
1715 Q_D(QGLShaderProgram);
1716 Q_UNUSED(d);
1717 if (location != -1) {
1718 GLfloat values[2] = {x, y};
1719 glUniform2fv(location, 1, values);
1720 }
1721}
1722
1723/*!
1724 \overload
1725
1726 Sets the uniform variable called \a name in the current context to
1727 the 2D vector (\a x, \a y).
1728
1729 \sa setAttributeValue()
1730*/
1731void QGLShaderProgram::setUniformValue(const char *name, GLfloat x, GLfloat y)
1732{
1733 setUniformValue(uniformLocation(name), x, y);
1734}
1735
1736/*!
1737 Sets the uniform variable at \a location in the current context to
1738 the 3D vector (\a x, \a y, \a z).
1739
1740 \sa setAttributeValue()
1741*/
1742void QGLShaderProgram::setUniformValue
1743 (int location, GLfloat x, GLfloat y, GLfloat z)
1744{
1745 Q_D(QGLShaderProgram);
1746 Q_UNUSED(d);
1747 if (location != -1) {
1748 GLfloat values[3] = {x, y, z};
1749 glUniform3fv(location, 1, values);
1750 }
1751}
1752
1753/*!
1754 \overload
1755
1756 Sets the uniform variable called \a name in the current context to
1757 the 3D vector (\a x, \a y, \a z).
1758
1759 \sa setAttributeValue()
1760*/
1761void QGLShaderProgram::setUniformValue
1762 (const char *name, GLfloat x, GLfloat y, GLfloat z)
1763{
1764 setUniformValue(uniformLocation(name), x, y, z);
1765}
1766
1767/*!
1768 Sets the uniform variable at \a location in the current context to
1769 the 4D vector (\a x, \a y, \a z, \a w).
1770
1771 \sa setAttributeValue()
1772*/
1773void QGLShaderProgram::setUniformValue
1774 (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1775{
1776 Q_D(QGLShaderProgram);
1777 Q_UNUSED(d);
1778 if (location != -1) {
1779 GLfloat values[4] = {x, y, z, w};
1780 glUniform4fv(location, 1, values);
1781 }
1782}
1783
1784/*!
1785 \overload
1786
1787 Sets the uniform variable called \a name in the current context to
1788 the 4D vector (\a x, \a y, \a z, \a w).
1789
1790 \sa setAttributeValue()
1791*/
1792void QGLShaderProgram::setUniformValue
1793 (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1794{
1795 setUniformValue(uniformLocation(name), x, y, z, w);
1796}
1797
1798/*!
1799 Sets the uniform variable at \a location in the current context to \a value.
1800
1801 \sa setAttributeValue()
1802*/
1803void QGLShaderProgram::setUniformValue(int location, const QVector2D& value)
1804{
1805 Q_D(QGLShaderProgram);
1806 Q_UNUSED(d);
1807 if (location != -1)
1808 glUniform2fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
1809}
1810
1811/*!
1812 \overload
1813
1814 Sets the uniform variable called \a name in the current context
1815 to \a value.
1816
1817 \sa setAttributeValue()
1818*/
1819void QGLShaderProgram::setUniformValue(const char *name, const QVector2D& value)
1820{
1821 setUniformValue(uniformLocation(name), value);
1822}
1823
1824/*!
1825 Sets the uniform variable at \a location in the current context to \a value.
1826
1827 \sa setAttributeValue()
1828*/
1829void QGLShaderProgram::setUniformValue(int location, const QVector3D& value)
1830{
1831 Q_D(QGLShaderProgram);
1832 Q_UNUSED(d);
1833 if (location != -1)
1834 glUniform3fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
1835}
1836
1837/*!
1838 \overload
1839
1840 Sets the uniform variable called \a name in the current context
1841 to \a value.
1842
1843 \sa setAttributeValue()
1844*/
1845void QGLShaderProgram::setUniformValue(const char *name, const QVector3D& value)
1846{
1847 setUniformValue(uniformLocation(name), value);
1848}
1849
1850/*!
1851 Sets the uniform variable at \a location in the current context to \a value.
1852
1853 \sa setAttributeValue()
1854*/
1855void QGLShaderProgram::setUniformValue(int location, const QVector4D& value)
1856{
1857 Q_D(QGLShaderProgram);
1858 Q_UNUSED(d);
1859 if (location != -1)
1860 glUniform4fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
1861}
1862
1863/*!
1864 \overload
1865
1866 Sets the uniform variable called \a name in the current context
1867 to \a value.
1868
1869 \sa setAttributeValue()
1870*/
1871void QGLShaderProgram::setUniformValue(const char *name, const QVector4D& value)
1872{
1873 setUniformValue(uniformLocation(name), value);
1874}
1875
1876/*!
1877 Sets the uniform variable at \a location in the current context to
1878 the red, green, blue, and alpha components of \a color.
1879
1880 \sa setAttributeValue()
1881*/
1882void QGLShaderProgram::setUniformValue(int location, const QColor& color)
1883{
1884 Q_D(QGLShaderProgram);
1885 Q_UNUSED(d);
1886 if (location != -1) {
1887 GLfloat values[4] = {color.redF(), color.greenF(), color.blueF(), color.alphaF()};
1888 glUniform4fv(location, 1, values);
1889 }
1890}
1891
1892/*!
1893 \overload
1894
1895 Sets the uniform variable called \a name in the current context to
1896 the red, green, blue, and alpha components of \a color.
1897
1898 \sa setAttributeValue()
1899*/
1900void QGLShaderProgram::setUniformValue(const char *name, const QColor& color)
1901{
1902 setUniformValue(uniformLocation(name), color);
1903}
1904
1905/*!
1906 Sets the uniform variable at \a location in the current context to
1907 the x and y coordinates of \a point.
1908
1909 \sa setAttributeValue()
1910*/
1911void QGLShaderProgram::setUniformValue(int location, const QPoint& point)
1912{
1913 Q_D(QGLShaderProgram);
1914 Q_UNUSED(d);
1915 if (location != -1) {
1916 GLfloat values[4] = {point.x(), point.y()};
1917 glUniform2fv(location, 1, values);
1918 }
1919}
1920
1921/*!
1922 \overload
1923
1924 Sets the uniform variable associated with \a name in the current
1925 context to the x and y coordinates of \a point.
1926
1927 \sa setAttributeValue()
1928*/
1929void QGLShaderProgram::setUniformValue(const char *name, const QPoint& point)
1930{
1931 setUniformValue(uniformLocation(name), point);
1932}
1933
1934/*!
1935 Sets the uniform variable at \a location in the current context to
1936 the x and y coordinates of \a point.
1937
1938 \sa setAttributeValue()
1939*/
1940void QGLShaderProgram::setUniformValue(int location, const QPointF& point)
1941{
1942 Q_D(QGLShaderProgram);
1943 Q_UNUSED(d);
1944 if (location != -1) {
1945 GLfloat values[4] = {point.x(), point.y()};
1946 glUniform2fv(location, 1, values);
1947 }
1948}
1949
1950/*!
1951 \overload
1952
1953 Sets the uniform variable associated with \a name in the current
1954 context to the x and y coordinates of \a point.
1955
1956 \sa setAttributeValue()
1957*/
1958void QGLShaderProgram::setUniformValue(const char *name, const QPointF& point)
1959{
1960 setUniformValue(uniformLocation(name), point);
1961}
1962
1963/*!
1964 Sets the uniform variable at \a location in the current context to
1965 the width and height of the given \a size.
1966
1967 \sa setAttributeValue()
1968*/
1969void QGLShaderProgram::setUniformValue(int location, const QSize& size)
1970{
1971 Q_D(QGLShaderProgram);
1972 Q_UNUSED(d);
1973 if (location != -1) {
1974 GLfloat values[4] = {size.width(), size.width()};
1975 glUniform2fv(location, 1, values);
1976 }
1977}
1978
1979/*!
1980 \overload
1981
1982 Sets the uniform variable associated with \a name in the current
1983 context to the width and height of the given \a size.
1984
1985 \sa setAttributeValue()
1986*/
1987void QGLShaderProgram::setUniformValue(const char *name, const QSize& size)
1988{
1989 setUniformValue(uniformLocation(name), size);
1990}
1991
1992/*!
1993 Sets the uniform variable at \a location in the current context to
1994 the width and height of the given \a size.
1995
1996 \sa setAttributeValue()
1997*/
1998void QGLShaderProgram::setUniformValue(int location, const QSizeF& size)
1999{
2000 Q_D(QGLShaderProgram);
2001 Q_UNUSED(d);
2002 if (location != -1) {
2003 GLfloat values[4] = {size.width(), size.height()};
2004 glUniform2fv(location, 1, values);
2005 }
2006}
2007
2008/*!
2009 \overload
2010
2011 Sets the uniform variable associated with \a name in the current
2012 context to the width and height of the given \a size.
2013
2014 \sa setAttributeValue()
2015*/
2016void QGLShaderProgram::setUniformValue(const char *name, const QSizeF& size)
2017{
2018 setUniformValue(uniformLocation(name), size);
2019}
2020
2021// We have to repack matrices from qreal to GLfloat.
2022#define setUniformMatrix(func,location,value,cols,rows) \
2023 if (location == -1) \
2024 return; \
2025 if (sizeof(qreal) == sizeof(GLfloat)) { \
2026 func(location, 1, GL_FALSE, \
2027 reinterpret_cast<const GLfloat *>(value.constData())); \
2028 } else { \
2029 GLfloat mat[cols * rows]; \
2030 const qreal *data = value.constData(); \
2031 for (int i = 0; i < cols * rows; ++i) \
2032 mat[i] = data[i]; \
2033 func(location, 1, GL_FALSE, mat); \
2034 }
2035#if !defined(QT_OPENGL_ES_2)
2036#define setUniformGenericMatrix(func,colfunc,location,value,cols,rows) \
2037 if (location == -1) \
2038 return; \
2039 if (sizeof(qreal) == sizeof(GLfloat)) { \
2040 const GLfloat *data = reinterpret_cast<const GLfloat *> \
2041 (value.constData()); \
2042 if (func) \
2043 func(location, 1, GL_FALSE, data); \
2044 else \
2045 colfunc(location, cols, data); \
2046 } else { \
2047 GLfloat mat[cols * rows]; \
2048 const qreal *data = value.constData(); \
2049 for (int i = 0; i < cols * rows; ++i) \
2050 mat[i] = data[i]; \
2051 if (func) \
2052 func(location, 1, GL_FALSE, mat); \
2053 else \
2054 colfunc(location, cols, mat); \
2055 }
2056#else
2057#define setUniformGenericMatrix(func,colfunc,location,value,cols,rows) \
2058 if (location == -1) \
2059 return; \
2060 if (sizeof(qreal) == sizeof(GLfloat)) { \
2061 const GLfloat *data = reinterpret_cast<const GLfloat *> \
2062 (value.constData()); \
2063 colfunc(location, cols, data); \
2064 } else { \
2065 GLfloat mat[cols * rows]; \
2066 const qreal *data = value.constData(); \
2067 for (int i = 0; i < cols * rows; ++i) \
2068 mat[i] = data[i]; \
2069 colfunc(location, cols, mat); \
2070 }
2071#endif
2072
2073/*!
2074 Sets the uniform variable at \a location in the current context
2075 to a 2x2 matrix \a value.
2076
2077 \sa setAttributeValue()
2078*/
2079void QGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value)
2080{
2081 Q_D(QGLShaderProgram);
2082 Q_UNUSED(d);
2083 setUniformMatrix(glUniformMatrix2fv, location, value, 2, 2);
2084}
2085
2086/*!
2087 \overload
2088
2089 Sets the uniform variable called \a name in the current context
2090 to a 2x2 matrix \a value.
2091
2092 \sa setAttributeValue()
2093*/
2094void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x2& value)
2095{
2096 setUniformValue(uniformLocation(name), value);
2097}
2098
2099/*!
2100 Sets the uniform variable at \a location in the current context
2101 to a 2x3 matrix \a value.
2102
2103 \sa setAttributeValue()
2104*/
2105void QGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value)
2106{
2107 Q_D(QGLShaderProgram);
2108 Q_UNUSED(d);
2109 setUniformGenericMatrix
2110 (glUniformMatrix2x3fv, glUniform3fv, location, value, 2, 3);
2111}
2112
2113/*!
2114 \overload
2115
2116 Sets the uniform variable called \a name in the current context
2117 to a 2x3 matrix \a value.
2118
2119 \sa setAttributeValue()
2120*/
2121void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& value)
2122{
2123 setUniformValue(uniformLocation(name), value);
2124}
2125
2126/*!
2127 Sets the uniform variable at \a location in the current context
2128 to a 2x4 matrix \a value.
2129
2130 \sa setAttributeValue()
2131*/
2132void QGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value)
2133{
2134 Q_D(QGLShaderProgram);
2135 Q_UNUSED(d);
2136 setUniformGenericMatrix
2137 (glUniformMatrix2x4fv, glUniform4fv, location, value, 2, 4);
2138}
2139
2140/*!
2141 \overload
2142
2143 Sets the uniform variable called \a name in the current context
2144 to a 2x4 matrix \a value.
2145
2146 \sa setAttributeValue()
2147*/
2148void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& value)
2149{
2150 setUniformValue(uniformLocation(name), value);
2151}
2152
2153/*!
2154 Sets the uniform variable at \a location in the current context
2155 to a 3x2 matrix \a value.
2156
2157 \sa setAttributeValue()
2158*/
2159void QGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value)
2160{
2161 Q_D(QGLShaderProgram);
2162 Q_UNUSED(d);
2163 setUniformGenericMatrix
2164 (glUniformMatrix3x2fv, glUniform2fv, location, value, 3, 2);
2165}
2166
2167/*!
2168 \overload
2169
2170 Sets the uniform variable called \a name in the current context
2171 to a 3x2 matrix \a value.
2172
2173 \sa setAttributeValue()
2174*/
2175void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x2& value)
2176{
2177 setUniformValue(uniformLocation(name), value);
2178}
2179
2180/*!
2181 Sets the uniform variable at \a location in the current context
2182 to a 3x3 matrix \a value.
2183
2184 \sa setAttributeValue()
2185*/
2186void QGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value)
2187{
2188 Q_D(QGLShaderProgram);
2189 Q_UNUSED(d);
2190 setUniformMatrix(glUniformMatrix3fv, location, value, 3, 3);
2191}
2192
2193/*!
2194 \overload
2195
2196 Sets the uniform variable called \a name in the current context
2197 to a 3x3 matrix \a value.
2198
2199 \sa setAttributeValue()
2200*/
2201void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x3& value)
2202{
2203 setUniformValue(uniformLocation(name), value);
2204}
2205
2206/*!
2207 Sets the uniform variable at \a location in the current context
2208 to a 3x4 matrix \a value.
2209
2210 \sa setAttributeValue()
2211*/
2212void QGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value)
2213{
2214 Q_D(QGLShaderProgram);
2215 Q_UNUSED(d);
2216 setUniformGenericMatrix
2217 (glUniformMatrix3x4fv, glUniform4fv, location, value, 3, 4);
2218}
2219
2220/*!
2221 \overload
2222
2223 Sets the uniform variable called \a name in the current context
2224 to a 3x4 matrix \a value.
2225
2226 \sa setAttributeValue()
2227*/
2228void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& value)
2229{
2230 setUniformValue(uniformLocation(name), value);
2231}
2232
2233/*!
2234 Sets the uniform variable at \a location in the current context
2235 to a 4x2 matrix \a value.
2236
2237 \sa setAttributeValue()
2238*/
2239void QGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value)
2240{
2241 Q_D(QGLShaderProgram);
2242 Q_UNUSED(d);
2243 setUniformGenericMatrix
2244 (glUniformMatrix4x2fv, glUniform2fv, location, value, 4, 2);
2245}
2246
2247/*!
2248 \overload
2249
2250 Sets the uniform variable called \a name in the current context
2251 to a 4x2 matrix \a value.
2252
2253 \sa setAttributeValue()
2254*/
2255void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& value)
2256{
2257 setUniformValue(uniformLocation(name), value);
2258}
2259
2260/*!
2261 Sets the uniform variable at \a location in the current context
2262 to a 4x3 matrix \a value.
2263
2264 \sa setAttributeValue()
2265*/
2266void QGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value)
2267{
2268 Q_D(QGLShaderProgram);
2269 Q_UNUSED(d);
2270 setUniformGenericMatrix
2271 (glUniformMatrix4x3fv, glUniform3fv, location, value, 4, 3);
2272}
2273
2274/*!
2275 \overload
2276
2277 Sets the uniform variable called \a name in the current context
2278 to a 4x3 matrix \a value.
2279
2280 \sa setAttributeValue()
2281*/
2282void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x3& value)
2283{
2284 setUniformValue(uniformLocation(name), value);
2285}
2286
2287/*!
2288 Sets the uniform variable at \a location in the current context
2289 to a 4x4 matrix \a value.
2290
2291 \sa setAttributeValue()
2292*/
2293void QGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value)
2294{
2295 Q_D(QGLShaderProgram);
2296 Q_UNUSED(d);
2297 setUniformMatrix(glUniformMatrix4fv, location, value, 4, 4);
2298}
2299
2300/*!
2301 \overload
2302
2303 Sets the uniform variable called \a name in the current context
2304 to a 4x4 matrix \a value.
2305
2306 \sa setAttributeValue()
2307*/
2308void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x4& value)
2309{
2310 setUniformValue(uniformLocation(name), value);
2311}
2312
2313/*!
2314 \overload
2315
2316 Sets the uniform variable at \a location in the current context
2317 to a 4x4 matrix \a value. The matrix elements must be specified
2318 in column-major order.
2319
2320 \sa setAttributeValue()
2321*/
2322void QGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4])
2323{
2324 Q_D(QGLShaderProgram);
2325 Q_UNUSED(d);
2326 if (location != -1)
2327 glUniformMatrix4fv(location, 1, GL_FALSE, value[0]);
2328}
2329
2330/*!
2331 \overload
2332
2333 Sets the uniform variable called \a name in the current context
2334 to a 4x4 matrix \a value. The matrix elements must be specified
2335 in column-major order.
2336
2337 \sa setAttributeValue()
2338*/
2339void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[4][4])
2340{
2341 setUniformValue(uniformLocation(name), value);
2342}
2343
2344/*!
2345 Sets the uniform variable at \a location in the current context to a
2346 3x3 transformation matrix \a value that is specified as a QTransform value.
2347
2348 To set a QTransform value as a 4x4 matrix in a shader, use
2349 \c{setUniformValue(location, QMatrix4x4(value))}.
2350*/
2351void QGLShaderProgram::setUniformValue(int location, const QTransform& value)
2352{
2353 Q_D(QGLShaderProgram);
2354 Q_UNUSED(d);
2355 if (location != -1) {
2356 GLfloat mat[3][3] = {
2357 {value.m11(), value.m12(), value.m13()},
2358 {value.m21(), value.m22(), value.m23()},
2359 {value.m31(), value.m32(), value.m33()}
2360 };
2361 glUniformMatrix3fv(location, 1, GL_FALSE, mat[0]);
2362 }
2363}
2364
2365/*!
2366 \overload
2367
2368 Sets the uniform variable called \a name in the current context to a
2369 3x3 transformation matrix \a value that is specified as a QTransform value.
2370
2371 To set a QTransform value as a 4x4 matrix in a shader, use
2372 \c{setUniformValue(name, QMatrix4x4(value))}.
2373*/
2374void QGLShaderProgram::setUniformValue
2375 (const char *name, const QTransform& value)
2376{
2377 setUniformValue(uniformLocation(name), value);
2378}
2379
2380/*!
2381 Sets the uniform variable array at \a location in the current
2382 context to the \a count elements of \a values.
2383
2384 \sa setAttributeValue()
2385*/
2386void QGLShaderProgram::setUniformValueArray(int location, const GLint *values, int count)
2387{
2388 Q_D(QGLShaderProgram);
2389 Q_UNUSED(d);
2390 if (location != -1)
2391 glUniform1iv(location, count, values);
2392}
2393
2394/*!
2395 \overload
2396
2397 Sets the uniform variable array called \a name in the current
2398 context to the \a count elements of \a values.
2399
2400 \sa setAttributeValue()
2401*/
2402void QGLShaderProgram::setUniformValueArray
2403 (const char *name, const GLint *values, int count)
2404{
2405 setUniformValueArray(uniformLocation(name), values, count);
2406}
2407
2408/*!
2409 Sets the uniform variable array at \a location in the current
2410 context to the \a count elements of \a values. This overload
2411 should be used when setting an array of sampler values.
2412
2413 \sa setAttributeValue()
2414*/
2415void QGLShaderProgram::setUniformValueArray(int location, const GLuint *values, int count)
2416{
2417 Q_D(QGLShaderProgram);
2418 Q_UNUSED(d);
2419 if (location != -1)
2420 glUniform1iv(location, count, reinterpret_cast<const GLint *>(values));
2421}
2422
2423/*!
2424 \overload
2425
2426 Sets the uniform variable array called \a name in the current
2427 context to the \a count elements of \a values. This overload
2428 should be used when setting an array of sampler values.
2429
2430 \sa setAttributeValue()
2431*/
2432void QGLShaderProgram::setUniformValueArray
2433 (const char *name, const GLuint *values, int count)
2434{
2435 setUniformValueArray(uniformLocation(name), values, count);
2436}
2437
2438/*!
2439 Sets the uniform variable array at \a location in the current
2440 context to the \a count elements of \a values. Each element
2441 has \a tupleSize components. The \a tupleSize must be 1, 2, 3, or 4.
2442
2443 \sa setAttributeValue()
2444*/
2445void QGLShaderProgram::setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize)
2446{
2447 Q_D(QGLShaderProgram);
2448 Q_UNUSED(d);
2449 if (location != -1) {
2450 if (tupleSize == 1)
2451 glUniform1fv(location, count, values);
2452 else if (tupleSize == 2)
2453 glUniform2fv(location, count, values);
2454 else if (tupleSize == 3)
2455 glUniform3fv(location, count, values);
2456 else if (tupleSize == 4)
2457 glUniform4fv(location, count, values);
2458 else
2459 qWarning() << "QGLShaderProgram::setUniformValue: size" << tupleSize << "not supported";
2460 }
2461}
2462
2463/*!
2464 \overload
2465
2466 Sets the uniform variable array called \a name in the current
2467 context to the \a count elements of \a values. Each element
2468 has \a tupleSize components. The \a tupleSize must be 1, 2, 3, or 4.
2469
2470 \sa setAttributeValue()
2471*/
2472void QGLShaderProgram::setUniformValueArray
2473 (const char *name, const GLfloat *values, int count, int tupleSize)
2474{
2475 setUniformValueArray(uniformLocation(name), values, count, tupleSize);
2476}
2477
2478/*!
2479 Sets the uniform variable array at \a location in the current
2480 context to the \a count 2D vector elements of \a values.
2481
2482 \sa setAttributeValue()
2483*/
2484void QGLShaderProgram::setUniformValueArray(int location, const QVector2D *values, int count)
2485{
2486 Q_D(QGLShaderProgram);
2487 Q_UNUSED(d);
2488 if (location != -1)
2489 glUniform2fv(location, count, reinterpret_cast<const GLfloat *>(values));
2490}
2491
2492/*!
2493 \overload
2494
2495 Sets the uniform variable array called \a name in the current
2496 context to the \a count 2D vector elements of \a values.
2497
2498 \sa setAttributeValue()
2499*/
2500void QGLShaderProgram::setUniformValueArray(const char *name, const QVector2D *values, int count)
2501{
2502 setUniformValueArray(uniformLocation(name), values, count);
2503}
2504
2505/*!
2506 Sets the uniform variable array at \a location in the current
2507 context to the \a count 3D vector elements of \a values.
2508
2509 \sa setAttributeValue()
2510*/
2511void QGLShaderProgram::setUniformValueArray(int location, const QVector3D *values, int count)
2512{
2513 Q_D(QGLShaderProgram);
2514 Q_UNUSED(d);
2515 if (location != -1)
2516 glUniform3fv(location, count, reinterpret_cast<const GLfloat *>(values));
2517}
2518
2519/*!
2520 \overload
2521
2522 Sets the uniform variable array called \a name in the current
2523 context to the \a count 3D vector elements of \a values.
2524
2525 \sa setAttributeValue()
2526*/
2527void QGLShaderProgram::setUniformValueArray(const char *name, const QVector3D *values, int count)
2528{
2529 setUniformValueArray(uniformLocation(name), values, count);
2530}
2531
2532/*!
2533 Sets the uniform variable array at \a location in the current
2534 context to the \a count 4D vector elements of \a values.
2535
2536 \sa setAttributeValue()
2537*/
2538void QGLShaderProgram::setUniformValueArray(int location, const QVector4D *values, int count)
2539{
2540 Q_D(QGLShaderProgram);
2541 Q_UNUSED(d);
2542 if (location != -1)
2543 glUniform4fv(location, count, reinterpret_cast<const GLfloat *>(values));
2544}
2545
2546/*!
2547 \overload
2548
2549 Sets the uniform variable array called \a name in the current
2550 context to the \a count 4D vector elements of \a values.
2551
2552 \sa setAttributeValue()
2553*/
2554void QGLShaderProgram::setUniformValueArray(const char *name, const QVector4D *values, int count)
2555{
2556 setUniformValueArray(uniformLocation(name), values, count);
2557}
2558
2559// We have to repack matrix arrays from qreal to GLfloat.
2560#define setUniformMatrixArray(func,location,values,count,type,cols,rows) \
2561 if (location == -1 || count <= 0) \
2562 return; \
2563 if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
2564 func(location, count, GL_FALSE, \
2565 reinterpret_cast<const GLfloat *>(values[0].constData())); \
2566 } else { \
2567 QVarLengthArray<GLfloat> temp(cols * rows * count); \
2568 for (int index = 0; index < count; ++index) { \
2569 for (int index2 = 0; index2 < (cols * rows); ++index2) { \
2570 temp.data()[cols * rows * index + index2] = \
2571 values[index].constData()[index2]; \
2572 } \
2573 } \
2574 func(location, count, GL_FALSE, temp.constData()); \
2575 }
2576#if !defined(QT_OPENGL_ES_2)
2577#define setUniformGenericMatrixArray(func,colfunc,location,values,count,type,cols,rows) \
2578 if (location == -1 || count <= 0) \
2579 return; \
2580 if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
2581 const GLfloat *data = reinterpret_cast<const GLfloat *> \
2582 (values[0].constData()); \
2583 if (func) \
2584 func(location, count, GL_FALSE, data); \
2585 else \
2586 colfunc(location, count * cols, data); \
2587 } else { \
2588 QVarLengthArray<GLfloat> temp(cols * rows * count); \
2589 for (int index = 0; index < count; ++index) { \
2590 for (int index2 = 0; index2 < (cols * rows); ++index2) { \
2591 temp.data()[cols * rows * index + index2] = \
2592 values[index].constData()[index2]; \
2593 } \
2594 } \
2595 if (func) \
2596 func(location, count, GL_FALSE, temp.constData()); \
2597 else \
2598 colfunc(location, count * cols, temp.constData()); \
2599 }
2600#else
2601#define setUniformGenericMatrixArray(func,colfunc,location,values,count,type,cols,rows) \
2602 if (location == -1 || count <= 0) \
2603 return; \
2604 if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
2605 const GLfloat *data = reinterpret_cast<const GLfloat *> \
2606 (values[0].constData()); \
2607 colfunc(location, count * cols, data); \
2608 } else { \
2609 QVarLengthArray<GLfloat> temp(cols * rows * count); \
2610 for (int index = 0; index < count; ++index) { \
2611 for (int index2 = 0; index2 < (cols * rows); ++index2) { \
2612 temp.data()[cols * rows * index + index2] = \
2613 values[index].constData()[index2]; \
2614 } \
2615 } \
2616 colfunc(location, count * cols, temp.constData()); \
2617 }
2618#endif
2619
2620/*!
2621 Sets the uniform variable array at \a location in the current
2622 context to the \a count 2x2 matrix elements of \a values.
2623
2624 \sa setAttributeValue()
2625*/
2626void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x2 *values, int count)
2627{
2628 Q_D(QGLShaderProgram);
2629 Q_UNUSED(d);
2630 setUniformMatrixArray
2631 (glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2);
2632}
2633
2634/*!
2635 \overload
2636
2637 Sets the uniform variable array called \a name in the current
2638 context to the \a count 2x2 matrix elements of \a values.
2639
2640 \sa setAttributeValue()
2641*/
2642void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x2 *values, int count)
2643{
2644 setUniformValueArray(uniformLocation(name), values, count);
2645}
2646
2647/*!
2648 Sets the uniform variable array at \a location in the current
2649 context to the \a count 2x3 matrix elements of \a values.
2650
2651 \sa setAttributeValue()
2652*/
2653void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x3 *values, int count)
2654{
2655 Q_D(QGLShaderProgram);
2656 Q_UNUSED(d);
2657 setUniformGenericMatrixArray
2658 (glUniformMatrix2x3fv, glUniform3fv, location, values, count,
2659 QMatrix2x3, 2, 3);
2660}
2661
2662/*!
2663 \overload
2664
2665 Sets the uniform variable array called \a name in the current
2666 context to the \a count 2x3 matrix elements of \a values.
2667
2668 \sa setAttributeValue()
2669*/
2670void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x3 *values, int count)
2671{
2672 setUniformValueArray(uniformLocation(name), values, count);
2673}
2674
2675/*!
2676 Sets the uniform variable array at \a location in the current
2677 context to the \a count 2x4 matrix elements of \a values.
2678
2679 \sa setAttributeValue()
2680*/
2681void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x4 *values, int count)
2682{
2683 Q_D(QGLShaderProgram);
2684 Q_UNUSED(d);
2685 setUniformGenericMatrixArray
2686 (glUniformMatrix2x4fv, glUniform4fv, location, values, count,
2687 QMatrix2x4, 2, 4);
2688}
2689
2690/*!
2691 \overload
2692
2693 Sets the uniform variable array called \a name in the current
2694 context to the \a count 2x4 matrix elements of \a values.
2695
2696 \sa setAttributeValue()
2697*/
2698void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x4 *values, int count)
2699{
2700 setUniformValueArray(uniformLocation(name), values, count);
2701}
2702
2703/*!
2704 Sets the uniform variable array at \a location in the current
2705 context to the \a count 3x2 matrix elements of \a values.
2706
2707 \sa setAttributeValue()
2708*/
2709void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x2 *values, int count)
2710{
2711 Q_D(QGLShaderProgram);
2712 Q_UNUSED(d);
2713 setUniformGenericMatrixArray
2714 (glUniformMatrix3x2fv, glUniform2fv, location, values, count,
2715 QMatrix3x2, 3, 2);
2716}
2717
2718/*!
2719 \overload
2720
2721 Sets the uniform variable array called \a name in the current
2722 context to the \a count 3x2 matrix elements of \a values.
2723
2724 \sa setAttributeValue()
2725*/
2726void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x2 *values, int count)
2727{
2728 setUniformValueArray(uniformLocation(name), values, count);
2729}
2730
2731/*!
2732 Sets the uniform variable array at \a location in the current
2733 context to the \a count 3x3 matrix elements of \a values.
2734
2735 \sa setAttributeValue()
2736*/
2737void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x3 *values, int count)
2738{
2739 Q_D(QGLShaderProgram);
2740 Q_UNUSED(d);
2741 setUniformMatrixArray
2742 (glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3);
2743}
2744
2745/*!
2746 \overload
2747
2748 Sets the uniform variable array called \a name in the current
2749 context to the \a count 3x3 matrix elements of \a values.
2750
2751 \sa setAttributeValue()
2752*/
2753void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x3 *values, int count)
2754{
2755 setUniformValueArray(uniformLocation(name), values, count);
2756}
2757
2758/*!
2759 Sets the uniform variable array at \a location in the current
2760 context to the \a count 3x4 matrix elements of \a values.
2761
2762 \sa setAttributeValue()
2763*/
2764void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x4 *values, int count)
2765{
2766 Q_D(QGLShaderProgram);
2767 Q_UNUSED(d);
2768 setUniformGenericMatrixArray
2769 (glUniformMatrix3x4fv, glUniform4fv, location, values, count,
2770 QMatrix3x4, 3, 4);
2771}
2772
2773/*!
2774 \overload
2775
2776 Sets the uniform variable array called \a name in the current
2777 context to the \a count 3x4 matrix elements of \a values.
2778
2779 \sa setAttributeValue()
2780*/
2781void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x4 *values, int count)
2782{
2783 setUniformValueArray(uniformLocation(name), values, count);
2784}
2785
2786/*!
2787 Sets the uniform variable array at \a location in the current
2788 context to the \a count 4x2 matrix elements of \a values.
2789
2790 \sa setAttributeValue()
2791*/
2792void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x2 *values, int count)
2793{
2794 Q_D(QGLShaderProgram);
2795 Q_UNUSED(d);
2796 setUniformGenericMatrixArray
2797 (glUniformMatrix4x2fv, glUniform2fv, location, values, count,
2798 QMatrix4x2, 4, 2);
2799}
2800
2801/*!
2802 \overload
2803
2804 Sets the uniform variable array called \a name in the current
2805 context to the \a count 4x2 matrix elements of \a values.
2806
2807 \sa setAttributeValue()
2808*/
2809void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x2 *values, int count)
2810{
2811 setUniformValueArray(uniformLocation(name), values, count);
2812}
2813
2814/*!
2815 Sets the uniform variable array at \a location in the current
2816 context to the \a count 4x3 matrix elements of \a values.
2817
2818 \sa setAttributeValue()
2819*/
2820void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x3 *values, int count)
2821{
2822 Q_D(QGLShaderProgram);
2823 Q_UNUSED(d);
2824 setUniformGenericMatrixArray
2825 (glUniformMatrix4x3fv, glUniform3fv, location, values, count,
2826 QMatrix4x3, 4, 3);
2827}
2828
2829/*!
2830 \overload
2831
2832 Sets the uniform variable array called \a name in the current
2833 context to the \a count 4x3 matrix elements of \a values.
2834
2835 \sa setAttributeValue()
2836*/
2837void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x3 *values, int count)
2838{
2839 setUniformValueArray(uniformLocation(name), values, count);
2840}
2841
2842/*!
2843 Sets the uniform variable array at \a location in the current
2844 context to the \a count 4x4 matrix elements of \a values.
2845
2846 \sa setAttributeValue()
2847*/
2848void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x4 *values, int count)
2849{
2850 Q_D(QGLShaderProgram);
2851 Q_UNUSED(d);
2852 setUniformMatrixArray
2853 (glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4);
2854}
2855
2856/*!
2857 \overload
2858
2859 Sets the uniform variable array called \a name in the current
2860 context to the \a count 4x4 matrix elements of \a values.
2861
2862 \sa setAttributeValue()
2863*/
2864void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x4 *values, int count)
2865{
2866 setUniformValueArray(uniformLocation(name), values, count);
2867}
2868
2869#undef ctx
2870
2871/*!
2872 Returns true if shader programs written in the OpenGL Shading
2873 Language (GLSL) are supported on this system; false otherwise.
2874
2875 The \a context is used to resolve the GLSL extensions.
2876 If \a context is null, then QGLContext::currentContext() is used.
2877*/
2878bool QGLShaderProgram::hasOpenGLShaderPrograms(const QGLContext *context)
2879{
2880#if !defined(QT_OPENGL_ES_2)
2881 if (!context)
2882 context = QGLContext::currentContext();
2883 if (!context)
2884 return false;
2885 return qt_resolve_glsl_extensions(const_cast<QGLContext *>(context));
2886#else
2887 Q_UNUSED(context);
2888 return true;
2889#endif
2890}
2891
2892/*!
2893 \internal
2894*/
2895void QGLShaderProgram::shaderDestroyed()
2896{
2897 Q_D(QGLShaderProgram);
2898 QGLShader *shader = qobject_cast<QGLShader *>(sender());
2899 if (shader && !d->removingShaders)
2900 removeShader(shader);
2901}
2902
2903#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
2904/*! \internal */
2905void QGLShaderProgram::setUniformValue(int location, QMacCompatGLint value)
2906{
2907 setUniformValue(location, GLint(value));
2908}
2909
2910/*! \internal */
2911void QGLShaderProgram::setUniformValue(int location, QMacCompatGLuint value)
2912{
2913 setUniformValue(location, GLuint(value));
2914}
2915
2916/*! \internal */
2917void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLint value)
2918{
2919 setUniformValue(name, GLint(value));
2920}
2921
2922/*! \internal */
2923void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLuint value)
2924{
2925 setUniformValue(name, GLuint(value));
2926}
2927
2928/*! \internal */
2929void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLint *values, int count)
2930{
2931 setUniformValueArray(location, (const GLint *)values, count);
2932}
2933
2934/*! \internal */
2935void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLuint *values, int count)
2936{
2937 setUniformValueArray(location, (const GLuint *)values, count);
2938}
2939
2940/*! \internal */
2941void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLint *values, int count)
2942{
2943 setUniformValueArray(name, (const GLint *)values, count);
2944}
2945
2946/*! \internal */
2947void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLuint *values, int count)
2948{
2949 setUniformValueArray(name, (const GLuint *)values, count);
2950}
2951#endif
2952
2953#endif // !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
2954
2955QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.