util/src/opengl/qglshaderprogram.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtOpenGL module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qglshaderprogram.h"
       
    43 #include "qglextensions_p.h"
       
    44 #include "qgl_p.h"
       
    45 #include <QtCore/private/qobject_p.h>
       
    46 #include <QtCore/qdebug.h>
       
    47 #include <QtCore/qfile.h>
       
    48 #include <QtCore/qvarlengtharray.h>
       
    49 #include <QtCore/qvector.h>
       
    50 
       
    51 QT_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 
       
   188 class QGLShaderPrivate : public QObjectPrivate
       
   189 {
       
   190     Q_DECLARE_PUBLIC(QGLShader)
       
   191 public:
       
   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 
       
   212 QGLShaderPrivate::~QGLShaderPrivate()
       
   213 {
       
   214     if (shaderGuard.id()) {
       
   215         QGLShareContextScope scope(shaderGuard.context());
       
   216         glDeleteShader(shaderGuard.id());
       
   217     }
       
   218 }
       
   219 
       
   220 bool 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 
       
   242 bool 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 
       
   268 void 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 */
       
   291 QGLShader::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 */
       
   310 QGLShader::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 */
       
   328 QGLShader::~QGLShader()
       
   329 {
       
   330 }
       
   331 
       
   332 /*!
       
   333     Returns the type of this shader.
       
   334 */
       
   335 QGLShader::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
       
   346 static 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
       
   356 static 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 */
       
   368 bool 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 */
       
   419 bool 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 */
       
   432 bool 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 */
       
   444 bool 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 */
       
   461 QByteArray 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 */
       
   484 bool 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 */
       
   495 QString 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 */
       
   506 GLuint 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 
       
   515 class QGLShaderProgramPrivate : public QObjectPrivate
       
   516 {
       
   517     Q_DECLARE_PUBLIC(QGLShaderProgram)
       
   518 public:
       
   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 
       
   543 QGLShaderProgramPrivate::~QGLShaderProgramPrivate()
       
   544 {
       
   545     if (programGuard.id()) {
       
   546         QGLShareContextScope scope(programGuard.context());
       
   547         glDeleteProgram(programGuard.id());
       
   548     }
       
   549 }
       
   550 
       
   551 bool 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 */
       
   571 QGLShaderProgram::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 */
       
   584 QGLShaderProgram::QGLShaderProgram(const QGLContext *context, QObject *parent)
       
   585     : QObject(*new QGLShaderProgramPrivate(context), parent)
       
   586 {
       
   587 }
       
   588 
       
   589 /*!
       
   590     Deletes this shader program.
       
   591 */
       
   592 QGLShaderProgram::~QGLShaderProgram()
       
   593 {
       
   594 }
       
   595 
       
   596 bool 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 */
       
   635 bool 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 */
       
   673 bool 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 */
       
   703 bool 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 */
       
   723 bool 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 */
       
   740 bool 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 */
       
   761 void 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 */
       
   782 QList<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 */
       
   796 void 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 */
       
   828 bool 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 */
       
   873 bool 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 */
       
   885 QString 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 */
       
   901 bool 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 */
       
   928 void 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 */
       
   951 GLuint 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 */
       
   974 void 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 */
       
   995 void 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 */
       
  1010 void 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 */
       
  1022 int 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 */
       
  1043 int 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 */
       
  1057 int 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 */
       
  1067 void 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 */
       
  1082 void 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 */
       
  1093 void 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 */
       
  1111 void 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 */
       
  1122 void 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 */
       
  1141 void 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 */
       
  1153 void 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 */
       
  1172 void 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 */
       
  1183 void 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 */
       
  1198 void 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 */
       
  1208 void 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 */
       
  1223 void 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 */
       
  1233 void 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 */
       
  1248 void 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 */
       
  1258 void 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 */
       
  1275 void 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 */
       
  1289 void 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 */
       
  1325 void 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 */
       
  1345 void 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 */
       
  1369 void 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 */
       
  1393 void 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 */
       
  1417 void 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 */
       
  1444 void 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 */
       
  1465 void 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 */
       
  1486 void 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 */
       
  1507 void 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 */
       
  1521 void 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 */
       
  1539 void 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 */
       
  1551 void 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 */
       
  1568 void 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 */
       
  1580 int 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 */
       
  1602 int 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 */
       
  1616 int 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 */
       
  1626 void 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 */
       
  1642 void 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 */
       
  1652 void 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 */
       
  1668 void 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 */
       
  1679 void 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 */
       
  1695 void 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 */
       
  1706 void 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 */
       
  1724 void 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 */
       
  1735 void 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 */
       
  1754 void 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 */
       
  1766 void 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 */
       
  1785 void 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 */
       
  1796 void 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 */
       
  1812 void 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 */
       
  1822 void 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 */
       
  1838 void 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 */
       
  1848 void 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 */
       
  1864 void 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 */
       
  1875 void 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 */
       
  1893 void 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 */
       
  1904 void 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 */
       
  1922 void 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 */
       
  1933 void 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 */
       
  1951 void 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 */
       
  1962 void 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 */
       
  1980 void 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 */
       
  1991 void 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 */
       
  2009 void 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 */
       
  2072 void 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 */
       
  2087 void 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 */
       
  2098 void 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 */
       
  2114 void 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 */
       
  2125 void 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 */
       
  2141 void 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 */
       
  2152 void 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 */
       
  2168 void 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 */
       
  2179 void 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 */
       
  2194 void 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 */
       
  2205 void 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 */
       
  2221 void 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 */
       
  2232 void 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 */
       
  2248 void 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 */
       
  2259 void 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 */
       
  2275 void 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 */
       
  2286 void 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 */
       
  2301 void 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 */
       
  2315 void 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 */
       
  2332 void 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 */
       
  2344 void 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 */
       
  2367 void 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 */
       
  2379 void 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 */
       
  2395 void 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 */
       
  2408 void 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 */
       
  2425 void 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 */
       
  2438 void 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 */
       
  2465 void 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 */
       
  2477 void 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 */
       
  2493 void 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 */
       
  2504 void 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 */
       
  2520 void 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 */
       
  2531 void 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 */
       
  2547 void 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 */
       
  2619 void 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 */
       
  2635 void 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 */
       
  2646 void 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 */
       
  2663 void 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 */
       
  2674 void 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 */
       
  2691 void 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 */
       
  2702 void 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 */
       
  2719 void 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 */
       
  2730 void 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 */
       
  2746 void 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 */
       
  2757 void 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 */
       
  2774 void 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 */
       
  2785 void 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 */
       
  2802 void 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 */
       
  2813 void 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 */
       
  2830 void 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 */
       
  2841 void 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 */
       
  2857 void 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 */
       
  2871 bool 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 */
       
  2888 void 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 */
       
  2898 void QGLShaderProgram::setUniformValue(int location, QMacCompatGLint value)
       
  2899 {
       
  2900     setUniformValue(location, GLint(value));
       
  2901 }
       
  2902 
       
  2903 /*! \internal */
       
  2904 void QGLShaderProgram::setUniformValue(int location, QMacCompatGLuint value)
       
  2905 {
       
  2906     setUniformValue(location, GLuint(value));
       
  2907 }
       
  2908 
       
  2909 /*! \internal */
       
  2910 void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLint value)
       
  2911 {
       
  2912     setUniformValue(name, GLint(value));
       
  2913 }
       
  2914 
       
  2915 /*! \internal */
       
  2916 void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLuint value)
       
  2917 {
       
  2918     setUniformValue(name, GLuint(value));
       
  2919 }
       
  2920 
       
  2921 /*! \internal */
       
  2922 void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLint *values, int count)
       
  2923 {
       
  2924     setUniformValueArray(location, (const GLint *)values, count);
       
  2925 }
       
  2926 
       
  2927 /*! \internal */
       
  2928 void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLuint *values, int count)
       
  2929 {
       
  2930     setUniformValueArray(location, (const GLuint *)values, count);
       
  2931 }
       
  2932 
       
  2933 /*! \internal */
       
  2934 void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLint *values, int count)
       
  2935 {
       
  2936     setUniformValueArray(name, (const GLint *)values, count);
       
  2937 }
       
  2938 
       
  2939 /*! \internal */
       
  2940 void 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 
       
  2948 QT_END_NAMESPACE