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