src/opengl/qglshaderprogram.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include "qglshaderprogram.h"
    42 #include "qglshaderprogram.h"
    43 #include "qglextensions_p.h"
    43 #include "qglextensions_p.h"
    44 #include "qgl_p.h"
    44 #include "qgl_p.h"
       
    45 #include <QtCore/private/qobject_p.h>
    45 #include <QtCore/qdebug.h>
    46 #include <QtCore/qdebug.h>
    46 #include <QtCore/qfile.h>
    47 #include <QtCore/qfile.h>
    47 #include <QtCore/qvarlengtharray.h>
    48 #include <QtCore/qvarlengtharray.h>
    48 #include <QtCore/qvector.h>
    49 #include <QtCore/qvector.h>
    49 
    50 
    66     compiling and linking vertex and fragment shaders.
    67     compiling and linking vertex and fragment shaders.
    67 
    68 
    68     The following example creates a vertex shader program using the
    69     The following example creates a vertex shader program using the
    69     supplied source \c{code}.  Once compiled and linked, the shader
    70     supplied source \c{code}.  Once compiled and linked, the shader
    70     program is activated in the current QGLContext by calling
    71     program is activated in the current QGLContext by calling
    71     QGLShaderProgram::enable():
    72     QGLShaderProgram::bind():
    72 
    73 
    73     \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 0
    74     \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 0
    74 
    75 
    75     \section1 Writing portable shaders
    76     \section1 Writing portable shaders
    76 
    77 
   103     With the above shader program active, we can draw a green triangle
   104     With the above shader program active, we can draw a green triangle
   104     as follows:
   105     as follows:
   105 
   106 
   106     \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 2
   107     \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 2
   107 
   108 
   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
   109     \sa QGLShader
   133 */
   110 */
   134 
   111 
   135 /*!
   112 /*!
   136     \class QGLShader
   113     \class QGLShader
   146 
   123 
   147     \sa QGLShaderProgram
   124     \sa QGLShaderProgram
   148 */
   125 */
   149 
   126 
   150 /*!
   127 /*!
   151     \enum QGLShader::ShaderTypeBits
   128     \enum QGLShader::ShaderTypeBit
   152     This enum specifies the type of QGLShader that is being created.
   129     This enum specifies the type of QGLShader that is being created.
   153 
   130 
   154     \value VertexShader Vertex shader written in the OpenGL Shading Language (GLSL).
   131     \value Vertex Vertex shader written in the OpenGL Shading Language (GLSL).
   155     \value FragmentShader Fragment shader written in the OpenGL Shading Language (GLSL).
   132     \value Fragment 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 */
   133 */
   162 
   134 
   163 #ifndef GL_FRAGMENT_SHADER
   135 #ifndef GL_FRAGMENT_SHADER
   164 #define GL_FRAGMENT_SHADER 0x8B30
   136 #define GL_FRAGMENT_SHADER 0x8B30
   165 #endif
   137 #endif
   198 #endif
   170 #endif
   199 #ifndef GL_NUM_SHADER_BINARY_FORMATS
   171 #ifndef GL_NUM_SHADER_BINARY_FORMATS
   200 #define GL_NUM_SHADER_BINARY_FORMATS      0x8DF9
   172 #define GL_NUM_SHADER_BINARY_FORMATS      0x8DF9
   201 #endif
   173 #endif
   202 
   174 
   203 class QGLShaderPrivate
   175 class QGLShaderPrivate : public QObjectPrivate
   204 {
   176 {
       
   177     Q_DECLARE_PUBLIC(QGLShader)
   205 public:
   178 public:
   206     QGLShaderPrivate(const QGLContext *context, QGLShader::ShaderType type)
   179     QGLShaderPrivate(const QGLContext *context, QGLShader::ShaderType type)
   207         : shaderGuard(context)
   180         : shaderGuard(context)
   208         , shaderType(type)
   181         , shaderType(type)
   209         , compiled(false)
   182         , compiled(false)
   210         , isPartial((type & QGLShader::PartialShader) != 0)
       
   211         , hasPartialSource(false)
       
   212     {
   183     {
   213     }
   184     }
       
   185     ~QGLShaderPrivate();
   214 
   186 
   215     QGLSharedResourceGuard shaderGuard;
   187     QGLSharedResourceGuard shaderGuard;
   216     QGLShader::ShaderType shaderType;
   188     QGLShader::ShaderType shaderType;
   217     bool compiled;
   189     bool compiled;
   218     bool isPartial;
       
   219     bool hasPartialSource;
       
   220     QString log;
   190     QString log;
   221     QByteArray partialSource;
       
   222 
   191 
   223     bool create();
   192     bool create();
   224     bool compile(QGLShader *q);
   193     bool compile(QGLShader *q);
   225     void deleteShader();
   194     void deleteShader();
   226 };
   195 };
   227 
   196 
   228 #define ctx shaderGuard.context()
   197 #define ctx shaderGuard.context()
   229 
   198 
       
   199 QGLShaderPrivate::~QGLShaderPrivate()
       
   200 {
       
   201     if (shaderGuard.id()) {
       
   202         QGLShareContextScope scope(shaderGuard.context());
       
   203         glDeleteShader(shaderGuard.id());
       
   204     }
       
   205 }
       
   206 
   230 bool QGLShaderPrivate::create()
   207 bool QGLShaderPrivate::create()
   231 {
   208 {
   232     const QGLContext *context = shaderGuard.context();
   209     const QGLContext *context = shaderGuard.context();
   233     if (!context)
   210     if (!context)
   234         return false;
   211         return false;
   235     if (isPartial)
       
   236         return true;
       
   237     if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) {
   212     if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) {
   238         GLuint shader;
   213         GLuint shader;
   239         if (shaderType == QGLShader::VertexShader)
   214         if (shaderType == QGLShader::Vertex)
   240             shader = glCreateShader(GL_VERTEX_SHADER);
   215             shader = glCreateShader(GL_VERTEX_SHADER);
   241         else
   216         else
   242             shader = glCreateShader(GL_FRAGMENT_SHADER);
   217             shader = glCreateShader(GL_FRAGMENT_SHADER);
   243         if (!shader) {
   218         if (!shader) {
   244             qWarning() << "QGLShader: could not create shader";
   219             qWarning() << "QGLShader: could not create shader";
   251     }
   226     }
   252 }
   227 }
   253 
   228 
   254 bool QGLShaderPrivate::compile(QGLShader *q)
   229 bool QGLShaderPrivate::compile(QGLShader *q)
   255 {
   230 {
   256     // Partial shaders are compiled during QGLShaderProgram::link().
       
   257     if (isPartial && hasPartialSource) {
       
   258         compiled = true;
       
   259         return true;
       
   260     }
       
   261     GLuint shader = shaderGuard.id();
   231     GLuint shader = shaderGuard.id();
   262     if (!shader)
   232     if (!shader)
   263         return false;
   233         return false;
   264     glCompileShader(shader);
   234     glCompileShader(shader);
   265     GLint value = 0;
   235     GLint value = 0;
   294 #define ctx d->shaderGuard.context()
   264 #define ctx d->shaderGuard.context()
   295 
   265 
   296 /*!
   266 /*!
   297     Constructs a new QGLShader object of the specified \a type
   267     Constructs a new QGLShader object of the specified \a type
   298     and attaches it to \a parent.  If shader programs are not supported,
   268     and attaches it to \a parent.  If shader programs are not supported,
   299     QGLShaderProgram::hasShaderPrograms() will return false.
   269     QGLShaderProgram::hasOpenGLShaderPrograms() will return false.
   300 
   270 
   301     This constructor is normally followed by a call to compile()
   271     This constructor is normally followed by a call to compileSourceCode()
   302     or compileFile().
   272     or compileSourceFile().
   303 
   273 
   304     The shader will be associated with the current QGLContext.
   274     The shader will be associated with the current QGLContext.
   305 
   275 
   306     \sa compile(), compileFile()
   276     \sa compileSourceCode(), compileSourceFile()
   307 */
   277 */
   308 QGLShader::QGLShader(QGLShader::ShaderType type, QObject *parent)
   278 QGLShader::QGLShader(QGLShader::ShaderType type, QObject *parent)
   309     : QObject(parent)
   279     : QObject(*new QGLShaderPrivate(QGLContext::currentContext(), type), parent)
   310 {
   280 {
   311     d = new QGLShaderPrivate(QGLContext::currentContext(), type);
   281     Q_D(QGLShader);
   312     d->create();
   282     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 }
   283 }
   332 
   284 
   333 /*!
   285 /*!
   334     Constructs a new QGLShader object of the specified \a type
   286     Constructs a new QGLShader object of the specified \a type
   335     and attaches it to \a parent.  If shader programs are not supported,
   287     and attaches it to \a parent.  If shader programs are not supported,
   336     then QGLShaderProgram::hasShaderPrograms() will return false.
   288     then QGLShaderProgram::hasOpenGLShaderPrograms() will return false.
   337 
   289 
   338     This constructor is normally followed by a call to compile()
   290     This constructor is normally followed by a call to compileSourceCode()
   339     or compileFile().
   291     or compileSourceFile().
   340 
   292 
   341     The shader will be associated with \a context.
   293     The shader will be associated with \a context.
   342 
   294 
   343     \sa compile(), compileFile()
   295     \sa compileSourceCode(), compileSourceFile()
   344 */
   296 */
   345 QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent)
   297 QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent)
   346     : QObject(parent)
   298     : QObject(*new QGLShaderPrivate(context ? context : QGLContext::currentContext(), type), parent)
   347 {
   299 {
   348     if (!context)
   300     Q_D(QGLShader);
   349         context = QGLContext::currentContext();
       
   350     d = new QGLShaderPrivate(context, type);
       
   351 #ifndef QT_NO_DEBUG
   301 #ifndef QT_NO_DEBUG
   352     if (context && !QGLContext::areSharing(context, QGLContext::currentContext())) {
   302     if (context && !QGLContext::areSharing(context, QGLContext::currentContext())) {
   353         qWarning("QGLShader::QGLShader: \'context\' must be the currect context or sharing with it.");
   303         qWarning("QGLShader::QGLShader: \'context\' must be the current context or sharing with it.");
   354         return;
   304         return;
   355     }
   305     }
   356 #endif
   306 #endif
   357     d->create();
   307     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 }
   308 }
   385 
   309 
   386 /*!
   310 /*!
   387     Deletes this shader.  If the shader has been attached to a
   311     Deletes this shader.  If the shader has been attached to a
   388     QGLShaderProgram object, then the actual shader will stay around
   312     QGLShaderProgram object, then the actual shader will stay around
   389     until the QGLShaderProgram is destroyed.
   313     until the QGLShaderProgram is destroyed.
   390 */
   314 */
   391 QGLShader::~QGLShader()
   315 QGLShader::~QGLShader()
   392 {
   316 {
   393     if (d->shaderGuard.id()) {
       
   394         QGLShareContextScope scope(d->shaderGuard.context());
       
   395         glDeleteShader(d->shaderGuard.id());
       
   396     }
       
   397     delete d;
       
   398 }
   317 }
   399 
   318 
   400 /*!
   319 /*!
   401     Returns the type of this shader.
   320     Returns the type of this shader.
   402 */
   321 */
   403 QGLShader::ShaderType QGLShader::shaderType() const
   322 QGLShader::ShaderType QGLShader::shaderType() const
   404 {
   323 {
       
   324     Q_D(const QGLShader);
   405     return d->shaderType;
   325     return d->shaderType;
   406 }
   326 }
   407 
   327 
   408 // The precision qualifiers are useful on OpenGL/ES systems,
   328 // The precision qualifiers are useful on OpenGL/ES systems,
   409 // but usually not present on desktop systems.  Define the
   329 // but usually not present on desktop systems.  Define the
   428 
   348 
   429 /*!
   349 /*!
   430     Sets the \a source code for this shader and compiles it.
   350     Sets the \a source code for this shader and compiles it.
   431     Returns true if the source was successfully compiled, false otherwise.
   351     Returns true if the source was successfully compiled, false otherwise.
   432 
   352 
   433     If shaderType() is PartialVertexShader or PartialFragmentShader,
   353     \sa compileSourceFile()
   434     then this function will always return true, even if the source code
   354 */
   435     is invalid.  Partial shaders are compiled when QGLShaderProgram::link()
   355 bool QGLShader::compileSourceCode(const char *source)
   436     is called.
   356 {
   437 
   357     Q_D(QGLShader);
   438     \sa compileFile()
   358     if (d->shaderGuard.id()) {
   439 */
   359         QVarLengthArray<const char *, 4> src;
   440 bool QGLShader::compile(const char *source)
   360         QVarLengthArray<GLint, 4> srclen;
   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;
   361         int headerLen = 0;
   449         while (source && source[headerLen] == '#') {
   362         while (source && source[headerLen] == '#') {
   450             // Skip #version and #extension directives at the start of
   363             // Skip #version and #extension directives at the start of
   451             // the shader code.  We need to insert the qualifierDefines
   364             // the shader code.  We need to insert the qualifierDefines
   452             // and redefineHighp just after them.
   365             // and redefineHighp just after them.
   457             while (source[headerLen] != '\0' && source[headerLen] != '\n')
   370             while (source[headerLen] != '\0' && source[headerLen] != '\n')
   458                 ++headerLen;
   371                 ++headerLen;
   459             if (source[headerLen] == '\n')
   372             if (source[headerLen] == '\n')
   460                 ++headerLen;
   373                 ++headerLen;
   461         }
   374         }
   462         QByteArray header;
       
   463         if (headerLen > 0) {
   375         if (headerLen > 0) {
   464             header = QByteArray(source, headerLen);
   376             src.append(source);
   465             src.append(header.constData());
   377             srclen.append(GLint(headerLen));
   466         }
   378         }
   467 #ifdef QGL_DEFINE_QUALIFIERS
   379 #ifdef QGL_DEFINE_QUALIFIERS
   468         src.append(qualifierDefines);
   380         src.append(qualifierDefines);
       
   381         srclen.append(GLint(sizeof(qualifierDefines) - 1));
   469 #endif
   382 #endif
   470 #ifdef QGL_REDEFINE_HIGHP
   383 #ifdef QGL_REDEFINE_HIGHP
   471         if (d->shaderType == FragmentShader ||
   384         if (d->shaderType == Fragment) {
   472                 d->shaderType == PartialFragmentShader)
       
   473             src.append(redefineHighp);
   385             src.append(redefineHighp);
       
   386             srclen.append(GLint(sizeof(redefineHighp) - 1));
       
   387         }
   474 #endif
   388 #endif
   475         src.append(source + headerLen);
   389         src.append(source + headerLen);
   476         glShaderSource(d->shaderGuard.id(), src.size(), src.data(), 0);
   390         srclen.append(GLint(qstrlen(source + headerLen)));
       
   391         glShaderSource(d->shaderGuard.id(), src.size(), src.data(), srclen.data());
   477         return d->compile(this);
   392         return d->compile(this);
   478     } else {
   393     } else {
   479         return false;
   394         return false;
   480     }
   395     }
   481 }
   396 }
   484     \overload
   399     \overload
   485 
   400 
   486     Sets the \a source code for this shader and compiles it.
   401     Sets the \a source code for this shader and compiles it.
   487     Returns true if the source was successfully compiled, false otherwise.
   402     Returns true if the source was successfully compiled, false otherwise.
   488 
   403 
   489     If shaderType() is PartialVertexShader or PartialFragmentShader,
   404     \sa compileSourceFile()
   490     then this function will always return true, even if the source code
   405 */
   491     is invalid.  Partial shaders are compiled when QGLShaderProgram::link()
   406 bool QGLShader::compileSourceCode(const QByteArray& source)
   492     is called.
   407 {
   493 
   408     return compileSourceCode(source.constData());
   494     \sa compileFile()
       
   495 */
       
   496 bool QGLShader::compile(const QByteArray& source)
       
   497 {
       
   498     return compile(source.constData());
       
   499 }
   409 }
   500 
   410 
   501 /*!
   411 /*!
   502     \overload
   412     \overload
   503 
   413 
   504     Sets the \a source code for this shader and compiles it.
   414     Sets the \a source code for this shader and compiles it.
   505     Returns true if the source was successfully compiled, false otherwise.
   415     Returns true if the source was successfully compiled, false otherwise.
   506 
   416 
   507     If shaderType() is PartialVertexShader or PartialFragmentShader,
   417     \sa compileSourceFile()
   508     then this function will always return true, even if the source code
   418 */
   509     is invalid.  Partial shaders are compiled when QGLShaderProgram::link()
   419 bool QGLShader::compileSourceCode(const QString& source)
   510     is called.
   420 {
   511 
   421     return compileSourceCode(source.toLatin1().constData());
   512     \sa compileFile()
       
   513 */
       
   514 bool QGLShader::compile(const QString& source)
       
   515 {
       
   516     return compile(source.toLatin1().constData());
       
   517 }
   422 }
   518 
   423 
   519 /*!
   424 /*!
   520     Sets the source code for this shader to the contents of \a fileName
   425     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
   426     and compiles it.  Returns true if the file could be opened and the
   522     source compiled, false otherwise.
   427     source compiled, false otherwise.
   523 
   428 
   524     If shaderType() is PartialVertexShader or PartialFragmentShader,
   429     \sa compileSourceCode()
   525     then this function will always return true, even if the source code
   430 */
   526     is invalid.  Partial shaders are compiled when QGLShaderProgram::link()
   431 bool QGLShader::compileSourceFile(const QString& fileName)
   527     is called.
       
   528 
       
   529     \sa compile()
       
   530 */
       
   531 bool QGLShader::compileFile(const QString& fileName)
       
   532 {
   432 {
   533     QFile file(fileName);
   433     QFile file(fileName);
   534     if (!file.open(QFile::ReadOnly)) {
   434     if (!file.open(QFile::ReadOnly)) {
   535         qWarning() << "QGLShader: Unable to open file" << fileName;
   435         qWarning() << "QGLShader: Unable to open file" << fileName;
   536         return false;
   436         return false;
   537     }
   437     }
   538 
   438 
   539     QByteArray contents = file.readAll();
   439     QByteArray contents = file.readAll();
   540     return compile(contents.constData());
   440     return compileSourceCode(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 }
   441 }
   629 
   442 
   630 /*!
   443 /*!
   631     Returns the source code for this shader.
   444     Returns the source code for this shader.
   632 
   445 
   633     \sa compile()
   446     \sa compileSourceCode()
   634 */
   447 */
   635 QByteArray QGLShader::sourceCode() const
   448 QByteArray QGLShader::sourceCode() const
   636 {
   449 {
   637     if (d->isPartial)
   450     Q_D(const QGLShader);
   638         return d->partialSource;
       
   639     GLuint shader = d->shaderGuard.id();
   451     GLuint shader = d->shaderGuard.id();
   640     if (!shader)
   452     if (!shader)
   641         return QByteArray();
   453         return QByteArray();
   642     GLint size = 0;
   454     GLint size = 0;
   643     glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &size);
   455     glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &size);
   652 }
   464 }
   653 
   465 
   654 /*!
   466 /*!
   655     Returns true if this shader has been compiled; false otherwise.
   467     Returns true if this shader has been compiled; false otherwise.
   656 
   468 
   657     \sa compile()
   469     \sa compileSourceCode(), compileSourceFile()
   658 */
   470 */
   659 bool QGLShader::isCompiled() const
   471 bool QGLShader::isCompiled() const
   660 {
   472 {
       
   473     Q_D(const QGLShader);
   661     return d->compiled;
   474     return d->compiled;
   662 }
   475 }
   663 
   476 
   664 /*!
   477 /*!
   665     Returns the errors and warnings that occurred during the last compile.
   478     Returns the errors and warnings that occurred during the last compile.
   666 
   479 
   667     \sa compile()
   480     \sa compileSourceCode(), compileSourceFile()
   668 */
   481 */
   669 QString QGLShader::log() const
   482 QString QGLShader::log() const
   670 {
   483 {
       
   484     Q_D(const QGLShader);
   671     return d->log;
   485     return d->log;
   672 }
   486 }
   673 
   487 
   674 /*!
   488 /*!
   675     Returns the OpenGL identifier associated with this shader.
   489     Returns the OpenGL identifier associated with this shader.
   676 
   490 
   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()
   491     \sa QGLShaderProgram::programId()
   682 */
   492 */
   683 GLuint QGLShader::shaderId() const
   493 GLuint QGLShader::shaderId() const
   684 {
   494 {
       
   495     Q_D(const QGLShader);
   685     return d->shaderGuard.id();
   496     return d->shaderGuard.id();
   686 }
   497 }
   687 
   498 
   688 #undef ctx
   499 #undef ctx
   689 #define ctx programGuard.context()
   500 #define ctx programGuard.context()
   690 
   501 
   691 class QGLShaderProgramPrivate
   502 class QGLShaderProgramPrivate : public QObjectPrivate
   692 {
   503 {
       
   504     Q_DECLARE_PUBLIC(QGLShaderProgram)
   693 public:
   505 public:
   694     QGLShaderProgramPrivate(const QGLContext *context)
   506     QGLShaderProgramPrivate(const QGLContext *context)
   695         : programGuard(context)
   507         : programGuard(context)
   696         , linked(false)
   508         , linked(false)
   697         , inited(false)
   509         , inited(false)
   698         , hasPartialShaders(false)
       
   699         , removingShaders(false)
   510         , removingShaders(false)
   700         , vertexShader(0)
   511         , vertexShader(0)
   701         , fragmentShader(0)
   512         , fragmentShader(0)
   702     {
   513     {
   703     }
   514     }
   704     ~QGLShaderProgramPrivate();
   515     ~QGLShaderProgramPrivate();
   705 
   516 
   706     QGLSharedResourceGuard programGuard;
   517     QGLSharedResourceGuard programGuard;
   707     bool linked;
   518     bool linked;
   708     bool inited;
   519     bool inited;
   709     bool hasPartialShaders;
       
   710     bool removingShaders;
   520     bool removingShaders;
   711     QString log;
   521     QString log;
   712     QList<QGLShader *> shaders;
   522     QList<QGLShader *> shaders;
   713     QList<QGLShader *> anonShaders;
   523     QList<QGLShader *> anonShaders;
   714     QGLShader *vertexShader;
   524     QGLShader *vertexShader;
   715     QGLShader *fragmentShader;
   525     QGLShader *fragmentShader;
       
   526 
       
   527     bool hasShader(QGLShader::ShaderType type) const;
   716 };
   528 };
   717 
   529 
   718 QGLShaderProgramPrivate::~QGLShaderProgramPrivate()
   530 QGLShaderProgramPrivate::~QGLShaderProgramPrivate()
   719 {
   531 {
   720     if (programGuard.id()) {
   532     if (programGuard.id()) {
   721         QGLShareContextScope scope(programGuard.context());
   533         QGLShareContextScope scope(programGuard.context());
   722         glDeleteProgram(programGuard.id());
   534         glDeleteProgram(programGuard.id());
   723     }
   535     }
   724 }
   536 }
   725 
   537 
       
   538 bool QGLShaderProgramPrivate::hasShader(QGLShader::ShaderType type) const
       
   539 {
       
   540     foreach (QGLShader *shader, shaders) {
       
   541         if (shader->shaderType() == type)
       
   542             return true;
       
   543     }
       
   544     return false;
       
   545 }
       
   546 
   726 #undef ctx
   547 #undef ctx
   727 #define ctx d->programGuard.context()
   548 #define ctx d->programGuard.context()
   728 
   549 
   729 /*!
   550 /*!
   730     Constructs a new shader program and attaches it to \a parent.
   551     Constructs a new shader program and attaches it to \a parent.
   733     The shader program will be associated with the current QGLContext.
   554     The shader program will be associated with the current QGLContext.
   734 
   555 
   735     \sa addShader()
   556     \sa addShader()
   736 */
   557 */
   737 QGLShaderProgram::QGLShaderProgram(QObject *parent)
   558 QGLShaderProgram::QGLShaderProgram(QObject *parent)
   738     : QObject(parent)
   559     : QObject(*new QGLShaderProgramPrivate(QGLContext::currentContext()), parent)
   739 {
   560 {
   740     d = new QGLShaderProgramPrivate(QGLContext::currentContext());
       
   741 }
   561 }
   742 
   562 
   743 /*!
   563 /*!
   744     Constructs a new shader program and attaches it to \a parent.
   564     Constructs a new shader program and attaches it to \a parent.
   745     The program will be invalid until addShader() is called.
   565     The program will be invalid until addShader() is called.
   747     The shader program will be associated with \a context.
   567     The shader program will be associated with \a context.
   748 
   568 
   749     \sa addShader()
   569     \sa addShader()
   750 */
   570 */
   751 QGLShaderProgram::QGLShaderProgram(const QGLContext *context, QObject *parent)
   571 QGLShaderProgram::QGLShaderProgram(const QGLContext *context, QObject *parent)
   752     : QObject(parent)
   572     : QObject(*new QGLShaderProgramPrivate(context), parent)
   753 {
   573 {
   754     d = new QGLShaderProgramPrivate(context);
       
   755 }
   574 }
   756 
   575 
   757 /*!
   576 /*!
   758     Deletes this shader program.
   577     Deletes this shader program.
   759 */
   578 */
   760 QGLShaderProgram::~QGLShaderProgram()
   579 QGLShaderProgram::~QGLShaderProgram()
   761 {
   580 {
   762     delete d;
       
   763 }
   581 }
   764 
   582 
   765 bool QGLShaderProgram::init()
   583 bool QGLShaderProgram::init()
   766 {
   584 {
       
   585     Q_D(QGLShaderProgram);
   767     if (d->programGuard.id() || d->inited)
   586     if (d->programGuard.id() || d->inited)
   768         return true;
   587         return true;
   769     d->inited = true;
   588     d->inited = true;
   770     const QGLContext *context = d->programGuard.context();
   589     const QGLContext *context = d->programGuard.context();
   771     if (!context) {
   590     if (!context) {
   795     Ownership of the \a shader object remains with the caller.
   614     Ownership of the \a shader object remains with the caller.
   796     It will not be deleted when this QGLShaderProgram instance
   615     It will not be deleted when this QGLShaderProgram instance
   797     is deleted.  This allows the caller to add the same shader
   616     is deleted.  This allows the caller to add the same shader
   798     to multiple shader programs.
   617     to multiple shader programs.
   799 
   618 
       
   619     \sa addShaderFromSourceCode(), addShaderFromSourceFile()
   800     \sa removeShader(), link(), removeAllShaders()
   620     \sa removeShader(), link(), removeAllShaders()
   801 */
   621 */
   802 bool QGLShaderProgram::addShader(QGLShader *shader)
   622 bool QGLShaderProgram::addShader(QGLShader *shader)
   803 {
   623 {
       
   624     Q_D(QGLShaderProgram);
   804     if (!init())
   625     if (!init())
   805         return false;
   626         return false;
   806     if (d->shaders.contains(shader))
   627     if (d->shaders.contains(shader))
   807         return true;    // Already added to this shader program.
   628         return true;    // Already added to this shader program.
   808     if (d->programGuard.id() && shader) {
   629     if (d->programGuard.id() && shader) {
   809         if (!QGLContext::areSharing(shader->d->shaderGuard.context(),
   630         if (!QGLContext::areSharing(shader->d_func()->shaderGuard.context(),
   810                                     d->programGuard.context())) {
   631                                     d->programGuard.context())) {
   811             qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context.");
   632             qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context.");
   812             return false;
   633             return false;
   813         }
   634         }
   814         if (!shader->d->compiled)
   635         if (!shader->d_func()->compiled)
   815             return false;
   636             return false;
   816         if (!shader->d->isPartial) {
   637         if (!shader->d_func()->shaderGuard.id())
   817             if (!shader->d->shaderGuard.id())
   638             return false;
   818                 return false;
   639         glAttachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id());
   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.
   640         d->linked = false;  // Program needs to be relinked.
   824         d->shaders.append(shader);
   641         d->shaders.append(shader);
   825         connect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed()));
   642         connect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed()));
   826         return true;
   643         return true;
   827     } else {
   644     } else {
   837 
   654 
   838     This function is intended to be a short-cut for quickly
   655     This function is intended to be a short-cut for quickly
   839     adding vertex and fragment shaders to a shader program without
   656     adding vertex and fragment shaders to a shader program without
   840     creating an instance of QGLShader first.
   657     creating an instance of QGLShader first.
   841 
   658 
       
   659     \sa addShader(), addShaderFromSourceFile()
   842     \sa removeShader(), link(), log(), removeAllShaders()
   660     \sa removeShader(), link(), log(), removeAllShaders()
   843 */
   661 */
   844 bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const char *source)
   662 bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const char *source)
   845 {
   663 {
       
   664     Q_D(QGLShaderProgram);
   846     if (!init())
   665     if (!init())
   847         return false;
   666         return false;
   848     QGLShader *shader = new QGLShader(type, this);
   667     QGLShader *shader = new QGLShader(type, this);
   849     if (!shader->compile(source)) {
   668     if (!shader->compileSourceCode(source)) {
   850         d->log = shader->log();
   669         d->log = shader->log();
   851         delete shader;
   670         delete shader;
   852         return false;
   671         return false;
   853     }
   672     }
   854     d->anonShaders.append(shader);
   673     d->anonShaders.append(shader);
   865 
   684 
   866     This function is intended to be a short-cut for quickly
   685     This function is intended to be a short-cut for quickly
   867     adding vertex and fragment shaders to a shader program without
   686     adding vertex and fragment shaders to a shader program without
   868     creating an instance of QGLShader first.
   687     creating an instance of QGLShader first.
   869 
   688 
       
   689     \sa addShader(), addShaderFromSourceFile()
   870     \sa removeShader(), link(), log(), removeAllShaders()
   690     \sa removeShader(), link(), log(), removeAllShaders()
   871 */
   691 */
   872 bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const QByteArray& source)
   692 bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const QByteArray& source)
   873 {
   693 {
   874     return addShader(type, source.constData());
   694     return addShaderFromSourceCode(type, source.constData());
   875 }
   695 }
   876 
   696 
   877 /*!
   697 /*!
   878     \overload
   698     \overload
   879 
   699 
   884 
   704 
   885     This function is intended to be a short-cut for quickly
   705     This function is intended to be a short-cut for quickly
   886     adding vertex and fragment shaders to a shader program without
   706     adding vertex and fragment shaders to a shader program without
   887     creating an instance of QGLShader first.
   707     creating an instance of QGLShader first.
   888 
   708 
       
   709     \sa addShader(), addShaderFromSourceFile()
   889     \sa removeShader(), link(), log(), removeAllShaders()
   710     \sa removeShader(), link(), log(), removeAllShaders()
   890 */
   711 */
   891 bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const QString& source)
   712 bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const QString& source)
   892 {
   713 {
   893     return addShader(type, source.toLatin1().constData());
   714     return addShaderFromSourceCode(type, source.toLatin1().constData());
   894 }
   715 }
   895 
   716 
   896 /*!
   717 /*!
   897     Compiles the contents of \a fileName as a shader of the specified
   718     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
   719     \a type and adds it to this shader program.  Returns true if
   901 
   722 
   902     This function is intended to be a short-cut for quickly
   723     This function is intended to be a short-cut for quickly
   903     adding vertex and fragment shaders to a shader program without
   724     adding vertex and fragment shaders to a shader program without
   904     creating an instance of QGLShader first.
   725     creating an instance of QGLShader first.
   905 
   726 
   906     \sa addShader()
   727     \sa addShader(), addShaderFromSourceCode()
   907 */
   728 */
   908 bool QGLShaderProgram::addShaderFromFile
   729 bool QGLShaderProgram::addShaderFromSourceFile
   909     (QGLShader::ShaderType type, const QString& fileName)
   730     (QGLShader::ShaderType type, const QString& fileName)
   910 {
   731 {
       
   732     Q_D(QGLShaderProgram);
   911     if (!init())
   733     if (!init())
   912         return false;
   734         return false;
   913     QGLShader *shader = new QGLShader(type, this);
   735     QGLShader *shader = new QGLShader(type, this);
   914     if (!shader->compileFile(fileName)) {
   736     if (!shader->compileSourceFile(fileName)) {
   915         d->log = shader->log();
   737         d->log = shader->log();
   916         delete shader;
   738         delete shader;
   917         return false;
   739         return false;
   918     }
   740     }
   919     d->anonShaders.append(shader);
   741     d->anonShaders.append(shader);
   925 
   747 
   926     \sa addShader(), link(), removeAllShaders()
   748     \sa addShader(), link(), removeAllShaders()
   927 */
   749 */
   928 void QGLShaderProgram::removeShader(QGLShader *shader)
   750 void QGLShaderProgram::removeShader(QGLShader *shader)
   929 {
   751 {
   930     if (d->programGuard.id() && shader && shader->d->shaderGuard.id()) {
   752     Q_D(QGLShaderProgram);
       
   753     if (d->programGuard.id() && shader && shader->d_func()->shaderGuard.id()) {
   931         QGLShareContextScope scope(d->programGuard.context());
   754         QGLShareContextScope scope(d->programGuard.context());
   932         glDetachShader(d->programGuard.id(), shader->d->shaderGuard.id());
   755         glDetachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id());
   933     }
   756     }
   934     d->linked = false;  // Program needs to be relinked.
   757     d->linked = false;  // Program needs to be relinked.
   935     if (shader) {
   758     if (shader) {
   936         d->shaders.removeAll(shader);
   759         d->shaders.removeAll(shader);
   937         d->anonShaders.removeAll(shader);
   760         d->anonShaders.removeAll(shader);
   945 
   768 
   946     \sa addShader(), removeShader()
   769     \sa addShader(), removeShader()
   947 */
   770 */
   948 QList<QGLShader *> QGLShaderProgram::shaders() const
   771 QList<QGLShader *> QGLShaderProgram::shaders() const
   949 {
   772 {
       
   773     Q_D(const QGLShaderProgram);
   950     return d->shaders;
   774     return d->shaders;
   951 }
   775 }
   952 
   776 
   953 /*!
   777 /*!
   954     Removes all of the shaders that were added to this program previously.
   778     Removes all of the shaders that were added to this program previously.
   958 
   782 
   959     \sa addShader(), removeShader()
   783     \sa addShader(), removeShader()
   960 */
   784 */
   961 void QGLShaderProgram::removeAllShaders()
   785 void QGLShaderProgram::removeAllShaders()
   962 {
   786 {
       
   787     Q_D(QGLShaderProgram);
   963     d->removingShaders = true;
   788     d->removingShaders = true;
   964     foreach (QGLShader *shader, d->shaders) {
   789     foreach (QGLShader *shader, d->shaders) {
   965         if (d->programGuard.id() && shader && shader->d->shaderGuard.id())
   790         if (d->programGuard.id() && shader && shader->d_func()->shaderGuard.id())
   966             glDetachShader(d->programGuard.id(), shader->d->shaderGuard.id());
   791             glDetachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id());
   967     }
   792     }
   968     foreach (QGLShader *shader, d->anonShaders) {
   793     foreach (QGLShader *shader, d->anonShaders) {
   969         // Delete shader objects that were created anonymously.
   794         // Delete shader objects that were created anonymously.
   970         delete shader;
   795         delete shader;
   971     }
   796     }
   973     d->anonShaders.clear();
   798     d->anonShaders.clear();
   974     d->linked = false;  // Program needs to be relinked.
   799     d->linked = false;  // Program needs to be relinked.
   975     d->removingShaders = false;
   800     d->removingShaders = false;
   976 }
   801 }
   977 
   802 
   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 /*!
   803 /*!
  1101     Links together the shaders that were added to this program with
   804     Links together the shaders that were added to this program with
  1102     addShader().  Returns true if the link was successful or
   805     addShader().  Returns true if the link was successful or
  1103     false otherwise.  If the link failed, the error messages can
   806     false otherwise.  If the link failed, the error messages can
  1104     be retrieved with log().
   807     be retrieved with log().
  1111 
   814 
  1112     \sa addShader(), log()
   815     \sa addShader(), log()
  1113 */
   816 */
  1114 bool QGLShaderProgram::link()
   817 bool QGLShaderProgram::link()
  1115 {
   818 {
       
   819     Q_D(QGLShaderProgram);
  1116     GLuint program = d->programGuard.id();
   820     GLuint program = d->programGuard.id();
  1117     if (!program)
   821     if (!program)
  1118         return false;
   822         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);
   823     glLinkProgram(program);
  1165     GLint value = 0;
   824     GLint value = 0;
  1166     glGetProgramiv(program, GL_LINK_STATUS, &value);
   825     glGetProgramiv(program, GL_LINK_STATUS, &value);
  1167     d->linked = (value != 0);
   826     d->linked = (value != 0);
  1168     value = 0;
   827     value = 0;
  1188 
   847 
  1189     \sa link()
   848     \sa link()
  1190 */
   849 */
  1191 bool QGLShaderProgram::isLinked() const
   850 bool QGLShaderProgram::isLinked() const
  1192 {
   851 {
       
   852     Q_D(const QGLShaderProgram);
  1193     return d->linked;
   853     return d->linked;
  1194 }
   854 }
  1195 
   855 
  1196 /*!
   856 /*!
  1197     Returns the errors and warnings that occurred during the last link()
   857     Returns the errors and warnings that occurred during the last link()
  1199 
   859 
  1200     \sa link()
   860     \sa link()
  1201 */
   861 */
  1202 QString QGLShaderProgram::log() const
   862 QString QGLShaderProgram::log() const
  1203 {
   863 {
       
   864     Q_D(const QGLShaderProgram);
  1204     return d->log;
   865     return d->log;
  1205 }
   866 }
  1206 
   867 
  1207 /*!
   868 /*!
  1208     Enable use of this shader program in the currently active QGLContext.
   869     Binds this shader program to the active QGLContext and makes
  1209     Returns true if the program was successfully enabled; false
   870     it the current shader program.  Any previously bound shader program
  1210     otherwise.  If the shader program has not yet been linked,
   871     is released.  This is equivalent to calling \c{glUseProgram()} on
       
   872     programId().  Returns true if the program was successfully bound;
       
   873     false otherwise.  If the shader program has not yet been linked,
  1211     or it needs to be re-linked, this function will call link().
   874     or it needs to be re-linked, this function will call link().
  1212 
   875 
  1213     \sa link(), disable()
   876     \sa link(), release()
  1214 */
   877 */
  1215 bool QGLShaderProgram::enable()
   878 bool QGLShaderProgram::bind()
  1216 {
   879 {
       
   880     Q_D(QGLShaderProgram);
  1217     GLuint program = d->programGuard.id();
   881     GLuint program = d->programGuard.id();
  1218     if (!program)
   882     if (!program)
  1219         return false;
   883         return false;
  1220     if (!d->linked && !link())
   884     if (!d->linked && !link())
  1221         return false;
   885         return false;
       
   886 #ifndef QT_NO_DEBUG
       
   887     if (!QGLContext::areSharing(d->programGuard.context(), QGLContext::currentContext())) {
       
   888         qWarning("QGLShaderProgram::bind: program is not valid in the current context.");
       
   889         return false;
       
   890     }
       
   891 #endif
  1222     glUseProgram(program);
   892     glUseProgram(program);
  1223     return true;
   893     return true;
  1224 }
   894 }
  1225 
   895 
  1226 #undef ctx
   896 #undef ctx
  1227 #define ctx QGLContext::currentContext()
   897 #define ctx QGLContext::currentContext()
  1228 
   898 
  1229 /*!
   899 /*!
  1230     Disables the active shader program in the current QGLContext.
   900     Releases the active shader program from the current QGLContext.
  1231     This is equivalent to calling \c{glUseProgram(0)}.
   901     This is equivalent to calling \c{glUseProgram(0)}.
  1232 
   902 
  1233     \sa enable()
   903     \sa bind()
  1234 */
   904 */
  1235 void QGLShaderProgram::disable()
   905 void QGLShaderProgram::release()
  1236 {
   906 {
       
   907 #ifndef QT_NO_DEBUG
       
   908     Q_D(QGLShaderProgram);
       
   909     if (!QGLContext::areSharing(d->programGuard.context(), QGLContext::currentContext()))
       
   910         qWarning("QGLShaderProgram::release: program is not valid in the current context.");
       
   911 #endif
  1237 #if defined(QT_OPENGL_ES_2)
   912 #if defined(QT_OPENGL_ES_2)
  1238     glUseProgram(0);
   913     glUseProgram(0);
  1239 #else
   914 #else
  1240     if (glUseProgram)
   915     if (glUseProgram)
  1241         glUseProgram(0);
   916         glUseProgram(0);
  1250 
   925 
  1251     \sa QGLShader::shaderId()
   926     \sa QGLShader::shaderId()
  1252 */
   927 */
  1253 GLuint QGLShaderProgram::programId() const
   928 GLuint QGLShaderProgram::programId() const
  1254 {
   929 {
       
   930     Q_D(const QGLShaderProgram);
  1255     return d->programGuard.id();
   931     return d->programGuard.id();
  1256 }
   932 }
  1257 
   933 
  1258 /*!
   934 /*!
  1259     Binds the attribute \a name to the specified \a location.  This
   935     Binds the attribute \a name to the specified \a location.  This
  1263 
   939 
  1264     \sa attributeLocation()
   940     \sa attributeLocation()
  1265 */
   941 */
  1266 void QGLShaderProgram::bindAttributeLocation(const char *name, int location)
   942 void QGLShaderProgram::bindAttributeLocation(const char *name, int location)
  1267 {
   943 {
  1268     glBindAttribLocation(d->programGuard.id(), location, name);
   944     Q_D(QGLShaderProgram);
       
   945     if (!d->linked) {
       
   946         glBindAttribLocation(d->programGuard.id(), location, name);
       
   947     } else {
       
   948         qWarning() << "QGLShaderProgram::bindAttributeLocation(" << name
       
   949                    << "): cannot bind after shader program is linked";
       
   950     }
  1269 }
   951 }
  1270 
   952 
  1271 /*!
   953 /*!
  1272     \overload
   954     \overload
  1273 
   955 
  1278 
   960 
  1279     \sa attributeLocation()
   961     \sa attributeLocation()
  1280 */
   962 */
  1281 void QGLShaderProgram::bindAttributeLocation(const QByteArray& name, int location)
   963 void QGLShaderProgram::bindAttributeLocation(const QByteArray& name, int location)
  1282 {
   964 {
  1283     glBindAttribLocation(d->programGuard.id(), location, name.constData());
   965     bindAttributeLocation(name.constData(), location);
  1284 }
   966 }
  1285 
   967 
  1286 /*!
   968 /*!
  1287     \overload
   969     \overload
  1288 
   970 
  1293 
   975 
  1294     \sa attributeLocation()
   976     \sa attributeLocation()
  1295 */
   977 */
  1296 void QGLShaderProgram::bindAttributeLocation(const QString& name, int location)
   978 void QGLShaderProgram::bindAttributeLocation(const QString& name, int location)
  1297 {
   979 {
  1298     glBindAttribLocation(d->programGuard.id(), location, name.toLatin1().constData());
   980     bindAttributeLocation(name.toLatin1().constData(), location);
  1299 }
   981 }
  1300 
   982 
  1301 /*!
   983 /*!
  1302     Returns the location of the attribute \a name within this shader
   984     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
   985     program's parameter list.  Returns -1 if \a name is not a valid
  1305 
   987 
  1306     \sa uniformLocation(), bindAttributeLocation()
   988     \sa uniformLocation(), bindAttributeLocation()
  1307 */
   989 */
  1308 int QGLShaderProgram::attributeLocation(const char *name) const
   990 int QGLShaderProgram::attributeLocation(const char *name) const
  1309 {
   991 {
       
   992     Q_D(const QGLShaderProgram);
  1310     if (d->linked) {
   993     if (d->linked) {
  1311         return glGetAttribLocation(d->programGuard.id(), name);
   994         return glGetAttribLocation(d->programGuard.id(), name);
  1312     } else {
   995     } else {
  1313         qWarning() << "QGLShaderProgram::attributeLocation(" << name
   996         qWarning() << "QGLShaderProgram::attributeLocation(" << name
  1314                    << "): shader program is not linked";
   997                    << "): shader program is not linked";
  1349 
  1032 
  1350     \sa setUniformValue()
  1033     \sa setUniformValue()
  1351 */
  1034 */
  1352 void QGLShaderProgram::setAttributeValue(int location, GLfloat value)
  1035 void QGLShaderProgram::setAttributeValue(int location, GLfloat value)
  1353 {
  1036 {
       
  1037     Q_D(QGLShaderProgram);
       
  1038     Q_UNUSED(d);
  1354     if (location != -1)
  1039     if (location != -1)
  1355         glVertexAttrib1fv(location, &value);
  1040         glVertexAttrib1fv(location, &value);
  1356 }
  1041 }
  1357 
  1042 
  1358 /*!
  1043 /*!
  1373 
  1058 
  1374     \sa setUniformValue()
  1059     \sa setUniformValue()
  1375 */
  1060 */
  1376 void QGLShaderProgram::setAttributeValue(int location, GLfloat x, GLfloat y)
  1061 void QGLShaderProgram::setAttributeValue(int location, GLfloat x, GLfloat y)
  1377 {
  1062 {
       
  1063     Q_D(QGLShaderProgram);
       
  1064     Q_UNUSED(d);
  1378     if (location != -1) {
  1065     if (location != -1) {
  1379         GLfloat values[2] = {x, y};
  1066         GLfloat values[2] = {x, y};
  1380         glVertexAttrib2fv(location, values);
  1067         glVertexAttrib2fv(location, values);
  1381     }
  1068     }
  1382 }
  1069 }
  1401     \sa setUniformValue()
  1088     \sa setUniformValue()
  1402 */
  1089 */
  1403 void QGLShaderProgram::setAttributeValue
  1090 void QGLShaderProgram::setAttributeValue
  1404         (int location, GLfloat x, GLfloat y, GLfloat z)
  1091         (int location, GLfloat x, GLfloat y, GLfloat z)
  1405 {
  1092 {
       
  1093     Q_D(QGLShaderProgram);
       
  1094     Q_UNUSED(d);
  1406     if (location != -1) {
  1095     if (location != -1) {
  1407         GLfloat values[3] = {x, y, z};
  1096         GLfloat values[3] = {x, y, z};
  1408         glVertexAttrib3fv(location, values);
  1097         glVertexAttrib3fv(location, values);
  1409     }
  1098     }
  1410 }
  1099 }
  1430     \sa setUniformValue()
  1119     \sa setUniformValue()
  1431 */
  1120 */
  1432 void QGLShaderProgram::setAttributeValue
  1121 void QGLShaderProgram::setAttributeValue
  1433         (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  1122         (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  1434 {
  1123 {
       
  1124     Q_D(QGLShaderProgram);
       
  1125     Q_UNUSED(d);
  1435     if (location != -1) {
  1126     if (location != -1) {
  1436         GLfloat values[4] = {x, y, z, w};
  1127         GLfloat values[4] = {x, y, z, w};
  1437         glVertexAttrib4fv(location, values);
  1128         glVertexAttrib4fv(location, values);
  1438     }
  1129     }
  1439 }
  1130 }
  1457 
  1148 
  1458     \sa setUniformValue()
  1149     \sa setUniformValue()
  1459 */
  1150 */
  1460 void QGLShaderProgram::setAttributeValue(int location, const QVector2D& value)
  1151 void QGLShaderProgram::setAttributeValue(int location, const QVector2D& value)
  1461 {
  1152 {
       
  1153     Q_D(QGLShaderProgram);
       
  1154     Q_UNUSED(d);
  1462     if (location != -1)
  1155     if (location != -1)
  1463         glVertexAttrib2fv(location, reinterpret_cast<const GLfloat *>(&value));
  1156         glVertexAttrib2fv(location, reinterpret_cast<const GLfloat *>(&value));
  1464 }
  1157 }
  1465 
  1158 
  1466 /*!
  1159 /*!
  1480 
  1173 
  1481     \sa setUniformValue()
  1174     \sa setUniformValue()
  1482 */
  1175 */
  1483 void QGLShaderProgram::setAttributeValue(int location, const QVector3D& value)
  1176 void QGLShaderProgram::setAttributeValue(int location, const QVector3D& value)
  1484 {
  1177 {
       
  1178     Q_D(QGLShaderProgram);
       
  1179     Q_UNUSED(d);
  1485     if (location != -1)
  1180     if (location != -1)
  1486         glVertexAttrib3fv(location, reinterpret_cast<const GLfloat *>(&value));
  1181         glVertexAttrib3fv(location, reinterpret_cast<const GLfloat *>(&value));
  1487 }
  1182 }
  1488 
  1183 
  1489 /*!
  1184 /*!
  1503 
  1198 
  1504     \sa setUniformValue()
  1199     \sa setUniformValue()
  1505 */
  1200 */
  1506 void QGLShaderProgram::setAttributeValue(int location, const QVector4D& value)
  1201 void QGLShaderProgram::setAttributeValue(int location, const QVector4D& value)
  1507 {
  1202 {
       
  1203     Q_D(QGLShaderProgram);
       
  1204     Q_UNUSED(d);
  1508     if (location != -1)
  1205     if (location != -1)
  1509         glVertexAttrib4fv(location, reinterpret_cast<const GLfloat *>(&value));
  1206         glVertexAttrib4fv(location, reinterpret_cast<const GLfloat *>(&value));
  1510 }
  1207 }
  1511 
  1208 
  1512 /*!
  1209 /*!
  1526 
  1223 
  1527     \sa setUniformValue()
  1224     \sa setUniformValue()
  1528 */
  1225 */
  1529 void QGLShaderProgram::setAttributeValue(int location, const QColor& value)
  1226 void QGLShaderProgram::setAttributeValue(int location, const QColor& value)
  1530 {
  1227 {
       
  1228     Q_D(QGLShaderProgram);
       
  1229     Q_UNUSED(d);
  1531     if (location != -1) {
  1230     if (location != -1) {
  1532         GLfloat values[4] = {value.redF(), value.greenF(), value.blueF(), value.alphaF()};
  1231         GLfloat values[4] = {value.redF(), value.greenF(), value.blueF(), value.alphaF()};
  1533         glVertexAttrib4fv(location, values);
  1232         glVertexAttrib4fv(location, values);
  1534     }
  1233     }
  1535 }
  1234 }
  1556     \sa setUniformValue()
  1255     \sa setUniformValue()
  1557 */
  1256 */
  1558 void QGLShaderProgram::setAttributeValue
  1257 void QGLShaderProgram::setAttributeValue
  1559     (int location, const GLfloat *values, int columns, int rows)
  1258     (int location, const GLfloat *values, int columns, int rows)
  1560 {
  1259 {
       
  1260     Q_D(QGLShaderProgram);
       
  1261     Q_UNUSED(d);
  1561     if (rows < 1 || rows > 4) {
  1262     if (rows < 1 || rows > 4) {
  1562         qWarning() << "QGLShaderProgram::setAttributeValue: rows" << rows << "not supported";
  1263         qWarning() << "QGLShaderProgram::setAttributeValue: rows" << rows << "not supported";
  1563         return;
  1264         return;
  1564     }
  1265     }
  1565     if (location != -1) {
  1266     if (location != -1) {
  1595     setAttributeValue(attributeLocation(name), values, columns, rows);
  1296     setAttributeValue(attributeLocation(name), values, columns, rows);
  1596 }
  1297 }
  1597 
  1298 
  1598 /*!
  1299 /*!
  1599     Sets an array of vertex \a values on the attribute at \a location
  1300     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
  1301     in this shader program.  The \a tupleSize indicates the number of
  1601     components per vertex (1, 2, 3, or 4), and the \a stride indicates
  1302     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
  1303     the number of bytes between vertices.  A default \a stride value
  1603     of zero indicates that the vertices are densely packed in \a values.
  1304     of zero indicates that the vertices are densely packed in \a values.
  1604 
  1305 
  1605     \sa setAttributeValue(), setUniformValue(), disableAttributeArray()
  1306     The array will become active when enableAttributeArray() is called
       
  1307     on the \a location.  Otherwise the value specified with
       
  1308     setAttributeValue() for \a location will be used.
       
  1309 
       
  1310     \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
       
  1311     \sa disableAttributeArray()
  1606 */
  1312 */
  1607 void QGLShaderProgram::setAttributeArray
  1313 void QGLShaderProgram::setAttributeArray
  1608     (int location, const GLfloat *values, int size, int stride)
  1314     (int location, const GLfloat *values, int tupleSize, int stride)
  1609 {
  1315 {
       
  1316     Q_D(QGLShaderProgram);
       
  1317     Q_UNUSED(d);
  1610     if (location != -1) {
  1318     if (location != -1) {
  1611         glVertexAttribPointer(location, size, GL_FLOAT, GL_FALSE,
  1319         glVertexAttribPointer(location, tupleSize, GL_FLOAT, GL_FALSE,
  1612                               stride, values);
  1320                               stride, values);
  1613         glEnableVertexAttribArray(location);
       
  1614     }
  1321     }
  1615 }
  1322 }
  1616 
  1323 
  1617 /*!
  1324 /*!
  1618     Sets an array of 2D vertex \a values on the attribute at \a location
  1325     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
  1326     in this shader program.  The \a stride indicates the number of bytes
  1620     between vertices.  A default \a stride value of zero indicates that
  1327     between vertices.  A default \a stride value of zero indicates that
  1621     the vertices are densely packed in \a values.
  1328     the vertices are densely packed in \a values.
  1622 
  1329 
  1623     \sa setAttributeValue(), setUniformValue(), disableAttributeArray()
  1330     The array will become active when enableAttributeArray() is called
       
  1331     on the \a location.  Otherwise the value specified with
       
  1332     setAttributeValue() for \a location will be used.
       
  1333 
       
  1334     \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
       
  1335     \sa disableAttributeArray()
  1624 */
  1336 */
  1625 void QGLShaderProgram::setAttributeArray
  1337 void QGLShaderProgram::setAttributeArray
  1626         (int location, const QVector2D *values, int stride)
  1338         (int location, const QVector2D *values, int stride)
  1627 {
  1339 {
       
  1340     Q_D(QGLShaderProgram);
       
  1341     Q_UNUSED(d);
  1628     if (location != -1) {
  1342     if (location != -1) {
  1629         glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE,
  1343         glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE,
  1630                               stride, values);
  1344                               stride, values);
  1631         glEnableVertexAttribArray(location);
       
  1632     }
  1345     }
  1633 }
  1346 }
  1634 
  1347 
  1635 /*!
  1348 /*!
  1636     Sets an array of 3D vertex \a values on the attribute at \a location
  1349     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
  1350     in this shader program.  The \a stride indicates the number of bytes
  1638     between vertices.  A default \a stride value of zero indicates that
  1351     between vertices.  A default \a stride value of zero indicates that
  1639     the vertices are densely packed in \a values.
  1352     the vertices are densely packed in \a values.
  1640 
  1353 
  1641     \sa setAttributeValue(), setUniformValue(), disableAttributeArray()
  1354     The array will become active when enableAttributeArray() is called
       
  1355     on the \a location.  Otherwise the value specified with
       
  1356     setAttributeValue() for \a location will be used.
       
  1357 
       
  1358     \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
       
  1359     \sa disableAttributeArray()
  1642 */
  1360 */
  1643 void QGLShaderProgram::setAttributeArray
  1361 void QGLShaderProgram::setAttributeArray
  1644         (int location, const QVector3D *values, int stride)
  1362         (int location, const QVector3D *values, int stride)
  1645 {
  1363 {
       
  1364     Q_D(QGLShaderProgram);
       
  1365     Q_UNUSED(d);
  1646     if (location != -1) {
  1366     if (location != -1) {
  1647         glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE,
  1367         glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE,
  1648                               stride, values);
  1368                               stride, values);
  1649         glEnableVertexAttribArray(location);
       
  1650     }
  1369     }
  1651 }
  1370 }
  1652 
  1371 
  1653 /*!
  1372 /*!
  1654     Sets an array of 4D vertex \a values on the attribute at \a location
  1373     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
  1374     in this shader program.  The \a stride indicates the number of bytes
  1656     between vertices.  A default \a stride value of zero indicates that
  1375     between vertices.  A default \a stride value of zero indicates that
  1657     the vertices are densely packed in \a values.
  1376     the vertices are densely packed in \a values.
  1658 
  1377 
  1659     \sa setAttributeValue(), setUniformValue(), disableAttributeArray()
  1378     The array will become active when enableAttributeArray() is called
       
  1379     on the \a location.  Otherwise the value specified with
       
  1380     setAttributeValue() for \a location will be used.
       
  1381 
       
  1382     \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
       
  1383     \sa disableAttributeArray()
  1660 */
  1384 */
  1661 void QGLShaderProgram::setAttributeArray
  1385 void QGLShaderProgram::setAttributeArray
  1662         (int location, const QVector4D *values, int stride)
  1386         (int location, const QVector4D *values, int stride)
  1663 {
  1387 {
       
  1388     Q_D(QGLShaderProgram);
       
  1389     Q_UNUSED(d);
  1664     if (location != -1) {
  1390     if (location != -1) {
  1665         glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE,
  1391         glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE,
  1666                               stride, values);
  1392                               stride, values);
  1667         glEnableVertexAttribArray(location);
       
  1668     }
  1393     }
  1669 }
  1394 }
  1670 
  1395 
  1671 /*!
  1396 /*!
  1672     \overload
  1397     \overload
  1673 
  1398 
  1674     Sets an array of vertex \a values on the attribute called \a name
  1399     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
  1400     in this shader program.  The \a tupleSize indicates the number of
  1676     components per vertex (1, 2, 3, or 4), and the \a stride indicates
  1401     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
  1402     the number of bytes between vertices.  A default \a stride value
  1678     of zero indicates that the vertices are densely packed in \a values.
  1403     of zero indicates that the vertices are densely packed in \a values.
  1679 
  1404 
  1680     \sa setAttributeValue(), setUniformValue(), disableAttributeArray()
  1405     The array will become active when enableAttributeArray() is called
       
  1406     on \a name.  Otherwise the value specified with setAttributeValue()
       
  1407     for \a name will be used.
       
  1408 
       
  1409     \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
       
  1410     \sa disableAttributeArray()
  1681 */
  1411 */
  1682 void QGLShaderProgram::setAttributeArray
  1412 void QGLShaderProgram::setAttributeArray
  1683     (const char *name, const GLfloat *values, int size, int stride)
  1413     (const char *name, const GLfloat *values, int tupleSize, int stride)
  1684 {
  1414 {
  1685     setAttributeArray(attributeLocation(name), values, size, stride);
  1415     setAttributeArray(attributeLocation(name), values, tupleSize, stride);
  1686 }
  1416 }
  1687 
  1417 
  1688 /*!
  1418 /*!
  1689     \overload
  1419     \overload
  1690 
  1420 
  1691     Sets an array of 2D vertex \a values on the attribute called \a name
  1421     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
  1422     in this shader program.  The \a stride indicates the number of bytes
  1693     between vertices.  A default \a stride value of zero indicates that
  1423     between vertices.  A default \a stride value of zero indicates that
  1694     the vertices are densely packed in \a values.
  1424     the vertices are densely packed in \a values.
  1695 
  1425 
  1696     \sa setAttributeValue(), setUniformValue(), disableAttributeArray()
  1426     The array will become active when enableAttributeArray() is called
       
  1427     on \a name.  Otherwise the value specified with setAttributeValue()
       
  1428     for \a name will be used.
       
  1429 
       
  1430     \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
       
  1431     \sa disableAttributeArray()
  1697 */
  1432 */
  1698 void QGLShaderProgram::setAttributeArray
  1433 void QGLShaderProgram::setAttributeArray
  1699         (const char *name, const QVector2D *values, int stride)
  1434         (const char *name, const QVector2D *values, int stride)
  1700 {
  1435 {
  1701     setAttributeArray(attributeLocation(name), values, stride);
  1436     setAttributeArray(attributeLocation(name), values, stride);
  1707     Sets an array of 3D vertex \a values on the attribute called \a name
  1442     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
  1443     in this shader program.  The \a stride indicates the number of bytes
  1709     between vertices.  A default \a stride value of zero indicates that
  1444     between vertices.  A default \a stride value of zero indicates that
  1710     the vertices are densely packed in \a values.
  1445     the vertices are densely packed in \a values.
  1711 
  1446 
  1712     \sa setAttributeValue(), setUniformValue(), disableAttributeArray()
  1447     The array will become active when enableAttributeArray() is called
       
  1448     on \a name.  Otherwise the value specified with setAttributeValue()
       
  1449     for \a name will be used.
       
  1450 
       
  1451     \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
       
  1452     \sa disableAttributeArray()
  1713 */
  1453 */
  1714 void QGLShaderProgram::setAttributeArray
  1454 void QGLShaderProgram::setAttributeArray
  1715         (const char *name, const QVector3D *values, int stride)
  1455         (const char *name, const QVector3D *values, int stride)
  1716 {
  1456 {
  1717     setAttributeArray(attributeLocation(name), values, stride);
  1457     setAttributeArray(attributeLocation(name), values, stride);
  1723     Sets an array of 4D vertex \a values on the attribute called \a name
  1463     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
  1464     in this shader program.  The \a stride indicates the number of bytes
  1725     between vertices.  A default \a stride value of zero indicates that
  1465     between vertices.  A default \a stride value of zero indicates that
  1726     the vertices are densely packed in \a values.
  1466     the vertices are densely packed in \a values.
  1727 
  1467 
  1728     \sa setAttributeValue(), setUniformValue(), disableAttributeArray()
  1468     The array will become active when enableAttributeArray() is called
       
  1469     on \a name.  Otherwise the value specified with setAttributeValue()
       
  1470     for \a name will be used.
       
  1471 
       
  1472     \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
       
  1473     \sa disableAttributeArray()
  1729 */
  1474 */
  1730 void QGLShaderProgram::setAttributeArray
  1475 void QGLShaderProgram::setAttributeArray
  1731         (const char *name, const QVector4D *values, int stride)
  1476         (const char *name, const QVector4D *values, int stride)
  1732 {
  1477 {
  1733     setAttributeArray(attributeLocation(name), values, stride);
  1478     setAttributeArray(attributeLocation(name), values, stride);
  1734 }
  1479 }
  1735 
  1480 
  1736 /*!
  1481 /*!
       
  1482     Enables the vertex array at \a location in this shader program
       
  1483     so that the value set by setAttributeArray() on \a location
       
  1484     will be used by the shader program.
       
  1485 
       
  1486     \sa disableAttributeArray(), setAttributeArray(), setAttributeValue()
       
  1487     \sa setUniformValue()
       
  1488 */
       
  1489 void QGLShaderProgram::enableAttributeArray(int location)
       
  1490 {
       
  1491     Q_D(QGLShaderProgram);
       
  1492     Q_UNUSED(d);
       
  1493     if (location != -1)
       
  1494         glEnableVertexAttribArray(location);
       
  1495 }
       
  1496 
       
  1497 /*!
       
  1498     \overload
       
  1499 
       
  1500     Enables the vertex array called \a name in this shader program
       
  1501     so that the value set by setAttributeArray() on \a name
       
  1502     will be used by the shader program.
       
  1503 
       
  1504     \sa disableAttributeArray(), setAttributeArray(), setAttributeValue()
       
  1505     \sa setUniformValue()
       
  1506 */
       
  1507 void QGLShaderProgram::enableAttributeArray(const char *name)
       
  1508 {
       
  1509     enableAttributeArray(attributeLocation(name));
       
  1510 }
       
  1511 
       
  1512 /*!
  1737     Disables the vertex array at \a location in this shader program
  1513     Disables the vertex array at \a location in this shader program
  1738     that was enabled by a previous call to setAttributeArray().
  1514     that was enabled by a previous call to enableAttributeArray().
  1739 
  1515 
  1740     \sa setAttributeArray(), setAttributeValue(), setUniformValue()
  1516     \sa enableAttributeArray(), setAttributeArray(), setAttributeValue()
       
  1517     \sa setUniformValue()
  1741 */
  1518 */
  1742 void QGLShaderProgram::disableAttributeArray(int location)
  1519 void QGLShaderProgram::disableAttributeArray(int location)
  1743 {
  1520 {
       
  1521     Q_D(QGLShaderProgram);
       
  1522     Q_UNUSED(d);
  1744     if (location != -1)
  1523     if (location != -1)
  1745         glDisableVertexAttribArray(location);
  1524         glDisableVertexAttribArray(location);
  1746 }
  1525 }
  1747 
  1526 
  1748 /*!
  1527 /*!
  1749     \overload
  1528     \overload
  1750 
  1529 
  1751     Disables the vertex array called \a name in this shader program
  1530     Disables the vertex array called \a name in this shader program
  1752     that was enabled by a previous call to setAttributeArray().
  1531     that was enabled by a previous call to enableAttributeArray().
  1753 
  1532 
  1754     \sa setAttributeArray(), setAttributeValue(), setUniformValue()
  1533     \sa enableAttributeArray(), setAttributeArray(), setAttributeValue()
       
  1534     \sa setUniformValue()
  1755 */
  1535 */
  1756 void QGLShaderProgram::disableAttributeArray(const char *name)
  1536 void QGLShaderProgram::disableAttributeArray(const char *name)
  1757 {
  1537 {
  1758     disableAttributeArray(attributeLocation(name));
  1538     disableAttributeArray(attributeLocation(name));
  1759 }
  1539 }
  1765 
  1545 
  1766     \sa attributeLocation()
  1546     \sa attributeLocation()
  1767 */
  1547 */
  1768 int QGLShaderProgram::uniformLocation(const char *name) const
  1548 int QGLShaderProgram::uniformLocation(const char *name) const
  1769 {
  1549 {
       
  1550     Q_D(const QGLShaderProgram);
       
  1551     Q_UNUSED(d);
  1770     if (d->linked) {
  1552     if (d->linked) {
  1771         return glGetUniformLocation(d->programGuard.id(), name);
  1553         return glGetUniformLocation(d->programGuard.id(), name);
  1772     } else {
  1554     } else {
  1773         qWarning() << "QGLShaderProgram::uniformLocation(" << name
  1555         qWarning() << "QGLShaderProgram::uniformLocation(" << name
  1774                    << "): shader program is not linked";
  1556                    << "): shader program is not linked";
  1809 
  1591 
  1810     \sa setAttributeValue()
  1592     \sa setAttributeValue()
  1811 */
  1593 */
  1812 void QGLShaderProgram::setUniformValue(int location, GLfloat value)
  1594 void QGLShaderProgram::setUniformValue(int location, GLfloat value)
  1813 {
  1595 {
       
  1596     Q_D(QGLShaderProgram);
       
  1597     Q_UNUSED(d);
  1814     if (location != -1)
  1598     if (location != -1)
  1815         glUniform1fv(location, 1, &value);
  1599         glUniform1fv(location, 1, &value);
  1816 }
  1600 }
  1817 
  1601 
  1818 /*!
  1602 /*!
  1833 
  1617 
  1834     \sa setAttributeValue()
  1618     \sa setAttributeValue()
  1835 */
  1619 */
  1836 void QGLShaderProgram::setUniformValue(int location, GLint value)
  1620 void QGLShaderProgram::setUniformValue(int location, GLint value)
  1837 {
  1621 {
       
  1622     Q_D(QGLShaderProgram);
       
  1623     Q_UNUSED(d);
  1838     if (location != -1)
  1624     if (location != -1)
  1839         glUniform1i(location, value);
  1625         glUniform1i(location, value);
  1840 }
  1626 }
  1841 
  1627 
  1842 /*!
  1628 /*!
  1858 
  1644 
  1859     \sa setAttributeValue()
  1645     \sa setAttributeValue()
  1860 */
  1646 */
  1861 void QGLShaderProgram::setUniformValue(int location, GLuint value)
  1647 void QGLShaderProgram::setUniformValue(int location, GLuint value)
  1862 {
  1648 {
       
  1649     Q_D(QGLShaderProgram);
       
  1650     Q_UNUSED(d);
  1863     if (location != -1)
  1651     if (location != -1)
  1864         glUniform1i(location, value);
  1652         glUniform1i(location, value);
  1865 }
  1653 }
  1866 
  1654 
  1867 /*!
  1655 /*!
  1883 
  1671 
  1884     \sa setAttributeValue()
  1672     \sa setAttributeValue()
  1885 */
  1673 */
  1886 void QGLShaderProgram::setUniformValue(int location, GLfloat x, GLfloat y)
  1674 void QGLShaderProgram::setUniformValue(int location, GLfloat x, GLfloat y)
  1887 {
  1675 {
       
  1676     Q_D(QGLShaderProgram);
       
  1677     Q_UNUSED(d);
  1888     if (location != -1) {
  1678     if (location != -1) {
  1889         GLfloat values[2] = {x, y};
  1679         GLfloat values[2] = {x, y};
  1890         glUniform2fv(location, 1, values);
  1680         glUniform2fv(location, 1, values);
  1891     }
  1681     }
  1892 }
  1682 }
  1911     \sa setAttributeValue()
  1701     \sa setAttributeValue()
  1912 */
  1702 */
  1913 void QGLShaderProgram::setUniformValue
  1703 void QGLShaderProgram::setUniformValue
  1914         (int location, GLfloat x, GLfloat y, GLfloat z)
  1704         (int location, GLfloat x, GLfloat y, GLfloat z)
  1915 {
  1705 {
       
  1706     Q_D(QGLShaderProgram);
       
  1707     Q_UNUSED(d);
  1916     if (location != -1) {
  1708     if (location != -1) {
  1917         GLfloat values[3] = {x, y, z};
  1709         GLfloat values[3] = {x, y, z};
  1918         glUniform3fv(location, 1, values);
  1710         glUniform3fv(location, 1, values);
  1919     }
  1711     }
  1920 }
  1712 }
  1940     \sa setAttributeValue()
  1732     \sa setAttributeValue()
  1941 */
  1733 */
  1942 void QGLShaderProgram::setUniformValue
  1734 void QGLShaderProgram::setUniformValue
  1943         (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  1735         (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  1944 {
  1736 {
       
  1737     Q_D(QGLShaderProgram);
       
  1738     Q_UNUSED(d);
  1945     if (location != -1) {
  1739     if (location != -1) {
  1946         GLfloat values[4] = {x, y, z, w};
  1740         GLfloat values[4] = {x, y, z, w};
  1947         glUniform4fv(location, 1, values);
  1741         glUniform4fv(location, 1, values);
  1948     }
  1742     }
  1949 }
  1743 }
  1967 
  1761 
  1968     \sa setAttributeValue()
  1762     \sa setAttributeValue()
  1969 */
  1763 */
  1970 void QGLShaderProgram::setUniformValue(int location, const QVector2D& value)
  1764 void QGLShaderProgram::setUniformValue(int location, const QVector2D& value)
  1971 {
  1765 {
       
  1766     Q_D(QGLShaderProgram);
       
  1767     Q_UNUSED(d);
  1972     if (location != -1)
  1768     if (location != -1)
  1973         glUniform2fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
  1769         glUniform2fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
  1974 }
  1770 }
  1975 
  1771 
  1976 /*!
  1772 /*!
  1991 
  1787 
  1992     \sa setAttributeValue()
  1788     \sa setAttributeValue()
  1993 */
  1789 */
  1994 void QGLShaderProgram::setUniformValue(int location, const QVector3D& value)
  1790 void QGLShaderProgram::setUniformValue(int location, const QVector3D& value)
  1995 {
  1791 {
       
  1792     Q_D(QGLShaderProgram);
       
  1793     Q_UNUSED(d);
  1996     if (location != -1)
  1794     if (location != -1)
  1997         glUniform3fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
  1795         glUniform3fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
  1998 }
  1796 }
  1999 
  1797 
  2000 /*!
  1798 /*!
  2015 
  1813 
  2016     \sa setAttributeValue()
  1814     \sa setAttributeValue()
  2017 */
  1815 */
  2018 void QGLShaderProgram::setUniformValue(int location, const QVector4D& value)
  1816 void QGLShaderProgram::setUniformValue(int location, const QVector4D& value)
  2019 {
  1817 {
       
  1818     Q_D(QGLShaderProgram);
       
  1819     Q_UNUSED(d);
  2020     if (location != -1)
  1820     if (location != -1)
  2021         glUniform4fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
  1821         glUniform4fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
  2022 }
  1822 }
  2023 
  1823 
  2024 /*!
  1824 /*!
  2040 
  1840 
  2041     \sa setAttributeValue()
  1841     \sa setAttributeValue()
  2042 */
  1842 */
  2043 void QGLShaderProgram::setUniformValue(int location, const QColor& color)
  1843 void QGLShaderProgram::setUniformValue(int location, const QColor& color)
  2044 {
  1844 {
       
  1845     Q_D(QGLShaderProgram);
       
  1846     Q_UNUSED(d);
  2045     if (location != -1) {
  1847     if (location != -1) {
  2046         GLfloat values[4] = {color.redF(), color.greenF(), color.blueF(), color.alphaF()};
  1848         GLfloat values[4] = {color.redF(), color.greenF(), color.blueF(), color.alphaF()};
  2047         glUniform4fv(location, 1, values);
  1849         glUniform4fv(location, 1, values);
  2048     }
  1850     }
  2049 }
  1851 }
  2067 
  1869 
  2068     \sa setAttributeValue()
  1870     \sa setAttributeValue()
  2069 */
  1871 */
  2070 void QGLShaderProgram::setUniformValue(int location, const QPoint& point)
  1872 void QGLShaderProgram::setUniformValue(int location, const QPoint& point)
  2071 {
  1873 {
       
  1874     Q_D(QGLShaderProgram);
       
  1875     Q_UNUSED(d);
  2072     if (location != -1) {
  1876     if (location != -1) {
  2073         GLfloat values[4] = {point.x(), point.y()};
  1877         GLfloat values[4] = {point.x(), point.y()};
  2074         glUniform2fv(location, 1, values);
  1878         glUniform2fv(location, 1, values);
  2075     }
  1879     }
  2076 }
  1880 }
  2094 
  1898 
  2095     \sa setAttributeValue()
  1899     \sa setAttributeValue()
  2096 */
  1900 */
  2097 void QGLShaderProgram::setUniformValue(int location, const QPointF& point)
  1901 void QGLShaderProgram::setUniformValue(int location, const QPointF& point)
  2098 {
  1902 {
       
  1903     Q_D(QGLShaderProgram);
       
  1904     Q_UNUSED(d);
  2099     if (location != -1) {
  1905     if (location != -1) {
  2100         GLfloat values[4] = {point.x(), point.y()};
  1906         GLfloat values[4] = {point.x(), point.y()};
  2101         glUniform2fv(location, 1, values);
  1907         glUniform2fv(location, 1, values);
  2102     }
  1908     }
  2103 }
  1909 }
  2121 
  1927 
  2122     \sa setAttributeValue()
  1928     \sa setAttributeValue()
  2123 */
  1929 */
  2124 void QGLShaderProgram::setUniformValue(int location, const QSize& size)
  1930 void QGLShaderProgram::setUniformValue(int location, const QSize& size)
  2125 {
  1931 {
       
  1932     Q_D(QGLShaderProgram);
       
  1933     Q_UNUSED(d);
  2126     if (location != -1) {
  1934     if (location != -1) {
  2127         GLfloat values[4] = {size.width(), size.width()};
  1935         GLfloat values[4] = {size.width(), size.width()};
  2128         glUniform2fv(location, 1, values);
  1936         glUniform2fv(location, 1, values);
  2129     }
  1937     }
  2130 }
  1938 }
  2148 
  1956 
  2149     \sa setAttributeValue()
  1957     \sa setAttributeValue()
  2150 */
  1958 */
  2151 void QGLShaderProgram::setUniformValue(int location, const QSizeF& size)
  1959 void QGLShaderProgram::setUniformValue(int location, const QSizeF& size)
  2152 {
  1960 {
       
  1961     Q_D(QGLShaderProgram);
       
  1962     Q_UNUSED(d);
  2153     if (location != -1) {
  1963     if (location != -1) {
  2154         GLfloat values[4] = {size.width(), size.height()};
  1964         GLfloat values[4] = {size.width(), size.height()};
  2155         glUniform2fv(location, 1, values);
  1965         glUniform2fv(location, 1, values);
  2156     }
  1966     }
  2157 }
  1967 }
  2227 
  2037 
  2228     \sa setAttributeValue()
  2038     \sa setAttributeValue()
  2229 */
  2039 */
  2230 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value)
  2040 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value)
  2231 {
  2041 {
       
  2042     Q_D(QGLShaderProgram);
       
  2043     Q_UNUSED(d);
  2232     setUniformMatrix(glUniformMatrix2fv, location, value, 2, 2);
  2044     setUniformMatrix(glUniformMatrix2fv, location, value, 2, 2);
  2233 }
  2045 }
  2234 
  2046 
  2235 /*!
  2047 /*!
  2236     \overload
  2048     \overload
  2251 
  2063 
  2252     \sa setAttributeValue()
  2064     \sa setAttributeValue()
  2253 */
  2065 */
  2254 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value)
  2066 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value)
  2255 {
  2067 {
       
  2068     Q_D(QGLShaderProgram);
       
  2069     Q_UNUSED(d);
  2256     setUniformGenericMatrix
  2070     setUniformGenericMatrix
  2257         (glUniformMatrix2x3fv, glUniform3fv, location, value, 2, 3);
  2071         (glUniformMatrix2x3fv, glUniform3fv, location, value, 2, 3);
  2258 }
  2072 }
  2259 
  2073 
  2260 /*!
  2074 /*!
  2276 
  2090 
  2277     \sa setAttributeValue()
  2091     \sa setAttributeValue()
  2278 */
  2092 */
  2279 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value)
  2093 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value)
  2280 {
  2094 {
       
  2095     Q_D(QGLShaderProgram);
       
  2096     Q_UNUSED(d);
  2281     setUniformGenericMatrix
  2097     setUniformGenericMatrix
  2282         (glUniformMatrix2x4fv, glUniform4fv, location, value, 2, 4);
  2098         (glUniformMatrix2x4fv, glUniform4fv, location, value, 2, 4);
  2283 }
  2099 }
  2284 
  2100 
  2285 /*!
  2101 /*!
  2301 
  2117 
  2302     \sa setAttributeValue()
  2118     \sa setAttributeValue()
  2303 */
  2119 */
  2304 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value)
  2120 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value)
  2305 {
  2121 {
       
  2122     Q_D(QGLShaderProgram);
       
  2123     Q_UNUSED(d);
  2306     setUniformGenericMatrix
  2124     setUniformGenericMatrix
  2307         (glUniformMatrix3x2fv, glUniform2fv, location, value, 3, 2);
  2125         (glUniformMatrix3x2fv, glUniform2fv, location, value, 3, 2);
  2308 }
  2126 }
  2309 
  2127 
  2310 /*!
  2128 /*!
  2326 
  2144 
  2327     \sa setAttributeValue()
  2145     \sa setAttributeValue()
  2328 */
  2146 */
  2329 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value)
  2147 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value)
  2330 {
  2148 {
       
  2149     Q_D(QGLShaderProgram);
       
  2150     Q_UNUSED(d);
  2331     setUniformMatrix(glUniformMatrix3fv, location, value, 3, 3);
  2151     setUniformMatrix(glUniformMatrix3fv, location, value, 3, 3);
  2332 }
  2152 }
  2333 
  2153 
  2334 /*!
  2154 /*!
  2335     \overload
  2155     \overload
  2350 
  2170 
  2351     \sa setAttributeValue()
  2171     \sa setAttributeValue()
  2352 */
  2172 */
  2353 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value)
  2173 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value)
  2354 {
  2174 {
       
  2175     Q_D(QGLShaderProgram);
       
  2176     Q_UNUSED(d);
  2355     setUniformGenericMatrix
  2177     setUniformGenericMatrix
  2356         (glUniformMatrix3x4fv, glUniform4fv, location, value, 3, 4);
  2178         (glUniformMatrix3x4fv, glUniform4fv, location, value, 3, 4);
  2357 }
  2179 }
  2358 
  2180 
  2359 /*!
  2181 /*!
  2375 
  2197 
  2376     \sa setAttributeValue()
  2198     \sa setAttributeValue()
  2377 */
  2199 */
  2378 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value)
  2200 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value)
  2379 {
  2201 {
       
  2202     Q_D(QGLShaderProgram);
       
  2203     Q_UNUSED(d);
  2380     setUniformGenericMatrix
  2204     setUniformGenericMatrix
  2381         (glUniformMatrix4x2fv, glUniform2fv, location, value, 4, 2);
  2205         (glUniformMatrix4x2fv, glUniform2fv, location, value, 4, 2);
  2382 }
  2206 }
  2383 
  2207 
  2384 /*!
  2208 /*!
  2400 
  2224 
  2401     \sa setAttributeValue()
  2225     \sa setAttributeValue()
  2402 */
  2226 */
  2403 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value)
  2227 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value)
  2404 {
  2228 {
       
  2229     Q_D(QGLShaderProgram);
       
  2230     Q_UNUSED(d);
  2405     setUniformGenericMatrix
  2231     setUniformGenericMatrix
  2406         (glUniformMatrix4x3fv, glUniform3fv, location, value, 4, 3);
  2232         (glUniformMatrix4x3fv, glUniform3fv, location, value, 4, 3);
  2407 }
  2233 }
  2408 
  2234 
  2409 /*!
  2235 /*!
  2425 
  2251 
  2426     \sa setAttributeValue()
  2252     \sa setAttributeValue()
  2427 */
  2253 */
  2428 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value)
  2254 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value)
  2429 {
  2255 {
       
  2256     Q_D(QGLShaderProgram);
       
  2257     Q_UNUSED(d);
  2430     setUniformMatrix(glUniformMatrix4fv, location, value, 4, 4);
  2258     setUniformMatrix(glUniformMatrix4fv, location, value, 4, 4);
  2431 }
  2259 }
  2432 
  2260 
  2433 /*!
  2261 /*!
  2434     \overload
  2262     \overload
  2452 
  2280 
  2453     \sa setAttributeValue()
  2281     \sa setAttributeValue()
  2454 */
  2282 */
  2455 void QGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4])
  2283 void QGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4])
  2456 {
  2284 {
       
  2285     Q_D(QGLShaderProgram);
       
  2286     Q_UNUSED(d);
  2457     if (location != -1)
  2287     if (location != -1)
  2458         glUniformMatrix4fv(location, 1, GL_FALSE, value[0]);
  2288         glUniformMatrix4fv(location, 1, GL_FALSE, value[0]);
  2459 }
  2289 }
  2460 
  2290 
  2461 /*!
  2291 /*!
  2479     To set a QTransform value as a 4x4 matrix in a shader, use
  2309     To set a QTransform value as a 4x4 matrix in a shader, use
  2480     \c{setUniformValue(location, QMatrix4x4(value))}.
  2310     \c{setUniformValue(location, QMatrix4x4(value))}.
  2481 */
  2311 */
  2482 void QGLShaderProgram::setUniformValue(int location, const QTransform& value)
  2312 void QGLShaderProgram::setUniformValue(int location, const QTransform& value)
  2483 {
  2313 {
       
  2314     Q_D(QGLShaderProgram);
       
  2315     Q_UNUSED(d);
  2484     if (location != -1) {
  2316     if (location != -1) {
  2485         GLfloat mat[3][3] = {
  2317         GLfloat mat[3][3] = {
  2486             {value.m11(), value.m12(), value.m13()},
  2318             {value.m11(), value.m12(), value.m13()},
  2487             {value.m21(), value.m22(), value.m23()},
  2319             {value.m21(), value.m22(), value.m23()},
  2488             {value.m31(), value.m32(), value.m33()}
  2320             {value.m31(), value.m32(), value.m33()}
  2512 
  2344 
  2513     \sa setAttributeValue()
  2345     \sa setAttributeValue()
  2514 */
  2346 */
  2515 void QGLShaderProgram::setUniformValueArray(int location, const GLint *values, int count)
  2347 void QGLShaderProgram::setUniformValueArray(int location, const GLint *values, int count)
  2516 {
  2348 {
       
  2349     Q_D(QGLShaderProgram);
       
  2350     Q_UNUSED(d);
  2517     if (location != -1)
  2351     if (location != -1)
  2518         glUniform1iv(location, count, values);
  2352         glUniform1iv(location, count, values);
  2519 }
  2353 }
  2520 
  2354 
  2521 /*!
  2355 /*!
  2539 
  2373 
  2540     \sa setAttributeValue()
  2374     \sa setAttributeValue()
  2541 */
  2375 */
  2542 void QGLShaderProgram::setUniformValueArray(int location, const GLuint *values, int count)
  2376 void QGLShaderProgram::setUniformValueArray(int location, const GLuint *values, int count)
  2543 {
  2377 {
       
  2378     Q_D(QGLShaderProgram);
       
  2379     Q_UNUSED(d);
  2544     if (location != -1)
  2380     if (location != -1)
  2545         glUniform1iv(location, count, reinterpret_cast<const GLint *>(values));
  2381         glUniform1iv(location, count, reinterpret_cast<const GLint *>(values));
  2546 }
  2382 }
  2547 
  2383 
  2548 /*!
  2384 /*!
  2561 }
  2397 }
  2562 
  2398 
  2563 /*!
  2399 /*!
  2564     Sets the uniform variable array at \a location in the current
  2400     Sets the uniform variable array at \a location in the current
  2565     context to the \a count elements of \a values.  Each element
  2401     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.
  2402     has \a tupleSize components.  The \a tupleSize must be 1, 2, 3, or 4.
  2567 
  2403 
  2568     \sa setAttributeValue()
  2404     \sa setAttributeValue()
  2569 */
  2405 */
  2570 void QGLShaderProgram::setUniformValueArray(int location, const GLfloat *values, int count, int size)
  2406 void QGLShaderProgram::setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize)
  2571 {
  2407 {
       
  2408     Q_D(QGLShaderProgram);
       
  2409     Q_UNUSED(d);
  2572     if (location != -1) {
  2410     if (location != -1) {
  2573         if (size == 1)
  2411         if (tupleSize == 1)
  2574             glUniform1fv(location, count, values);
  2412             glUniform1fv(location, count, values);
  2575         else if (size == 2)
  2413         else if (tupleSize == 2)
  2576             glUniform2fv(location, count, values);
  2414             glUniform2fv(location, count, values);
  2577         else if (size == 3)
  2415         else if (tupleSize == 3)
  2578             glUniform3fv(location, count, values);
  2416             glUniform3fv(location, count, values);
  2579         else if (size == 4)
  2417         else if (tupleSize == 4)
  2580             glUniform4fv(location, count, values);
  2418             glUniform4fv(location, count, values);
  2581         else
  2419         else
  2582             qWarning() << "QGLShaderProgram::setUniformValue: size" << size << "not supported";
  2420             qWarning() << "QGLShaderProgram::setUniformValue: size" << tupleSize << "not supported";
  2583     }
  2421     }
  2584 }
  2422 }
  2585 
  2423 
  2586 /*!
  2424 /*!
  2587     \overload
  2425     \overload
  2588 
  2426 
  2589     Sets the uniform variable array called \a name in the current
  2427     Sets the uniform variable array called \a name in the current
  2590     context to the \a count elements of \a values.  Each element
  2428     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.
  2429     has \a tupleSize components.  The \a tupleSize must be 1, 2, 3, or 4.
  2592 
  2430 
  2593     \sa setAttributeValue()
  2431     \sa setAttributeValue()
  2594 */
  2432 */
  2595 void QGLShaderProgram::setUniformValueArray
  2433 void QGLShaderProgram::setUniformValueArray
  2596         (const char *name, const GLfloat *values, int count, int size)
  2434         (const char *name, const GLfloat *values, int count, int tupleSize)
  2597 {
  2435 {
  2598     setUniformValueArray(uniformLocation(name), values, count, size);
  2436     setUniformValueArray(uniformLocation(name), values, count, tupleSize);
  2599 }
  2437 }
  2600 
  2438 
  2601 /*!
  2439 /*!
  2602     Sets the uniform variable array at \a location in the current
  2440     Sets the uniform variable array at \a location in the current
  2603     context to the \a count 2D vector elements of \a values.
  2441     context to the \a count 2D vector elements of \a values.
  2604 
  2442 
  2605     \sa setAttributeValue()
  2443     \sa setAttributeValue()
  2606 */
  2444 */
  2607 void QGLShaderProgram::setUniformValueArray(int location, const QVector2D *values, int count)
  2445 void QGLShaderProgram::setUniformValueArray(int location, const QVector2D *values, int count)
  2608 {
  2446 {
       
  2447     Q_D(QGLShaderProgram);
       
  2448     Q_UNUSED(d);
  2609     if (location != -1)
  2449     if (location != -1)
  2610         glUniform2fv(location, count, reinterpret_cast<const GLfloat *>(values));
  2450         glUniform2fv(location, count, reinterpret_cast<const GLfloat *>(values));
  2611 }
  2451 }
  2612 
  2452 
  2613 /*!
  2453 /*!
  2629 
  2469 
  2630     \sa setAttributeValue()
  2470     \sa setAttributeValue()
  2631 */
  2471 */
  2632 void QGLShaderProgram::setUniformValueArray(int location, const QVector3D *values, int count)
  2472 void QGLShaderProgram::setUniformValueArray(int location, const QVector3D *values, int count)
  2633 {
  2473 {
       
  2474     Q_D(QGLShaderProgram);
       
  2475     Q_UNUSED(d);
  2634     if (location != -1)
  2476     if (location != -1)
  2635         glUniform3fv(location, count, reinterpret_cast<const GLfloat *>(values));
  2477         glUniform3fv(location, count, reinterpret_cast<const GLfloat *>(values));
  2636 }
  2478 }
  2637 
  2479 
  2638 /*!
  2480 /*!
  2654 
  2496 
  2655     \sa setAttributeValue()
  2497     \sa setAttributeValue()
  2656 */
  2498 */
  2657 void QGLShaderProgram::setUniformValueArray(int location, const QVector4D *values, int count)
  2499 void QGLShaderProgram::setUniformValueArray(int location, const QVector4D *values, int count)
  2658 {
  2500 {
       
  2501     Q_D(QGLShaderProgram);
       
  2502     Q_UNUSED(d);
  2659     if (location != -1)
  2503     if (location != -1)
  2660         glUniform4fv(location, count, reinterpret_cast<const GLfloat *>(values));
  2504         glUniform4fv(location, count, reinterpret_cast<const GLfloat *>(values));
  2661 }
  2505 }
  2662 
  2506 
  2663 /*!
  2507 /*!
  2740 
  2584 
  2741     \sa setAttributeValue()
  2585     \sa setAttributeValue()
  2742 */
  2586 */
  2743 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x2 *values, int count)
  2587 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x2 *values, int count)
  2744 {
  2588 {
       
  2589     Q_D(QGLShaderProgram);
       
  2590     Q_UNUSED(d);
  2745     setUniformMatrixArray
  2591     setUniformMatrixArray
  2746         (glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2);
  2592         (glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2);
  2747 }
  2593 }
  2748 
  2594 
  2749 /*!
  2595 /*!
  2765 
  2611 
  2766     \sa setAttributeValue()
  2612     \sa setAttributeValue()
  2767 */
  2613 */
  2768 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x3 *values, int count)
  2614 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x3 *values, int count)
  2769 {
  2615 {
       
  2616     Q_D(QGLShaderProgram);
       
  2617     Q_UNUSED(d);
  2770     setUniformGenericMatrixArray
  2618     setUniformGenericMatrixArray
  2771         (glUniformMatrix2x3fv, glUniform3fv, location, values, count,
  2619         (glUniformMatrix2x3fv, glUniform3fv, location, values, count,
  2772          QMatrix2x3, 2, 3);
  2620          QMatrix2x3, 2, 3);
  2773 }
  2621 }
  2774 
  2622 
  2791 
  2639 
  2792     \sa setAttributeValue()
  2640     \sa setAttributeValue()
  2793 */
  2641 */
  2794 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x4 *values, int count)
  2642 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x4 *values, int count)
  2795 {
  2643 {
       
  2644     Q_D(QGLShaderProgram);
       
  2645     Q_UNUSED(d);
  2796     setUniformGenericMatrixArray
  2646     setUniformGenericMatrixArray
  2797         (glUniformMatrix2x4fv, glUniform4fv, location, values, count,
  2647         (glUniformMatrix2x4fv, glUniform4fv, location, values, count,
  2798          QMatrix2x4, 2, 4);
  2648          QMatrix2x4, 2, 4);
  2799 }
  2649 }
  2800 
  2650 
  2817 
  2667 
  2818     \sa setAttributeValue()
  2668     \sa setAttributeValue()
  2819 */
  2669 */
  2820 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x2 *values, int count)
  2670 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x2 *values, int count)
  2821 {
  2671 {
       
  2672     Q_D(QGLShaderProgram);
       
  2673     Q_UNUSED(d);
  2822     setUniformGenericMatrixArray
  2674     setUniformGenericMatrixArray
  2823         (glUniformMatrix3x2fv, glUniform2fv, location, values, count,
  2675         (glUniformMatrix3x2fv, glUniform2fv, location, values, count,
  2824          QMatrix3x2, 3, 2);
  2676          QMatrix3x2, 3, 2);
  2825 }
  2677 }
  2826 
  2678 
  2843 
  2695 
  2844     \sa setAttributeValue()
  2696     \sa setAttributeValue()
  2845 */
  2697 */
  2846 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x3 *values, int count)
  2698 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x3 *values, int count)
  2847 {
  2699 {
       
  2700     Q_D(QGLShaderProgram);
       
  2701     Q_UNUSED(d);
  2848     setUniformMatrixArray
  2702     setUniformMatrixArray
  2849         (glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3);
  2703         (glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3);
  2850 }
  2704 }
  2851 
  2705 
  2852 /*!
  2706 /*!
  2868 
  2722 
  2869     \sa setAttributeValue()
  2723     \sa setAttributeValue()
  2870 */
  2724 */
  2871 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x4 *values, int count)
  2725 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x4 *values, int count)
  2872 {
  2726 {
       
  2727     Q_D(QGLShaderProgram);
       
  2728     Q_UNUSED(d);
  2873     setUniformGenericMatrixArray
  2729     setUniformGenericMatrixArray
  2874         (glUniformMatrix3x4fv, glUniform4fv, location, values, count,
  2730         (glUniformMatrix3x4fv, glUniform4fv, location, values, count,
  2875          QMatrix3x4, 3, 4);
  2731          QMatrix3x4, 3, 4);
  2876 }
  2732 }
  2877 
  2733 
  2894 
  2750 
  2895     \sa setAttributeValue()
  2751     \sa setAttributeValue()
  2896 */
  2752 */
  2897 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x2 *values, int count)
  2753 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x2 *values, int count)
  2898 {
  2754 {
       
  2755     Q_D(QGLShaderProgram);
       
  2756     Q_UNUSED(d);
  2899     setUniformGenericMatrixArray
  2757     setUniformGenericMatrixArray
  2900         (glUniformMatrix4x2fv, glUniform2fv, location, values, count,
  2758         (glUniformMatrix4x2fv, glUniform2fv, location, values, count,
  2901          QMatrix4x2, 4, 2);
  2759          QMatrix4x2, 4, 2);
  2902 }
  2760 }
  2903 
  2761 
  2920 
  2778 
  2921     \sa setAttributeValue()
  2779     \sa setAttributeValue()
  2922 */
  2780 */
  2923 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x3 *values, int count)
  2781 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x3 *values, int count)
  2924 {
  2782 {
       
  2783     Q_D(QGLShaderProgram);
       
  2784     Q_UNUSED(d);
  2925     setUniformGenericMatrixArray
  2785     setUniformGenericMatrixArray
  2926         (glUniformMatrix4x3fv, glUniform3fv, location, values, count,
  2786         (glUniformMatrix4x3fv, glUniform3fv, location, values, count,
  2927          QMatrix4x3, 4, 3);
  2787          QMatrix4x3, 4, 3);
  2928 }
  2788 }
  2929 
  2789 
  2946 
  2806 
  2947     \sa setAttributeValue()
  2807     \sa setAttributeValue()
  2948 */
  2808 */
  2949 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x4 *values, int count)
  2809 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x4 *values, int count)
  2950 {
  2810 {
       
  2811     Q_D(QGLShaderProgram);
       
  2812     Q_UNUSED(d);
  2951     setUniformMatrixArray
  2813     setUniformMatrixArray
  2952         (glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4);
  2814         (glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4);
  2953 }
  2815 }
  2954 
  2816 
  2955 /*!
  2817 /*!
  2972     Language (GLSL) are supported on this system; false otherwise.
  2834     Language (GLSL) are supported on this system; false otherwise.
  2973 
  2835 
  2974     The \a context is used to resolve the GLSL extensions.
  2836     The \a context is used to resolve the GLSL extensions.
  2975     If \a context is null, then QGLContext::currentContext() is used.
  2837     If \a context is null, then QGLContext::currentContext() is used.
  2976 */
  2838 */
  2977 bool QGLShaderProgram::hasShaderPrograms(const QGLContext *context)
  2839 bool QGLShaderProgram::hasOpenGLShaderPrograms(const QGLContext *context)
  2978 {
  2840 {
  2979 #if !defined(QT_OPENGL_ES_2)
  2841 #if !defined(QT_OPENGL_ES_2)
  2980     if (!context)
  2842     if (!context)
  2981         context = QGLContext::currentContext();
  2843         context = QGLContext::currentContext();
  2982     if (!context)
  2844     if (!context)
  2991 /*!
  2853 /*!
  2992     \internal
  2854     \internal
  2993 */
  2855 */
  2994 void QGLShaderProgram::shaderDestroyed()
  2856 void QGLShaderProgram::shaderDestroyed()
  2995 {
  2857 {
       
  2858     Q_D(QGLShaderProgram);
  2996     QGLShader *shader = qobject_cast<QGLShader *>(sender());
  2859     QGLShader *shader = qobject_cast<QGLShader *>(sender());
  2997     if (shader && !d->removingShaders)
  2860     if (shader && !d->removingShaders)
  2998         removeShader(shader);
  2861         removeShader(shader);
  2999 }
  2862 }
  3000 
  2863 
       
  2864 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
       
  2865 /*! \internal */
       
  2866 void QGLShaderProgram::setUniformValue(int location, QMacCompatGLint value)
       
  2867 {
       
  2868     setUniformValue(location, GLint(value));
       
  2869 }
       
  2870 
       
  2871 /*! \internal */
       
  2872 void QGLShaderProgram::setUniformValue(int location, QMacCompatGLuint value)
       
  2873 {
       
  2874     setUniformValue(location, GLuint(value));
       
  2875 }
       
  2876 
       
  2877 /*! \internal */
       
  2878 void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLint value)
       
  2879 {
       
  2880     setUniformValue(name, GLint(value));
       
  2881 }
       
  2882 
       
  2883 /*! \internal */
       
  2884 void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLuint value)
       
  2885 {
       
  2886     setUniformValue(name, GLuint(value));
       
  2887 }
       
  2888 
       
  2889 /*! \internal */
       
  2890 void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLint *values, int count)
       
  2891 {
       
  2892     setUniformValueArray(location, (const GLint *)values, count);
       
  2893 }
       
  2894 
       
  2895 /*! \internal */
       
  2896 void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLuint *values, int count)
       
  2897 {
       
  2898     setUniformValueArray(location, (const GLuint *)values, count);
       
  2899 }
       
  2900 
       
  2901 /*! \internal */
       
  2902 void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLint *values, int count)
       
  2903 {
       
  2904     setUniformValueArray(name, (const GLint *)values, count);
       
  2905 }
       
  2906 
       
  2907 /*! \internal */
       
  2908 void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLuint *values, int count)
       
  2909 {
       
  2910     setUniformValueArray(name, (const GLuint *)values, count);
       
  2911 }
  3001 #endif
  2912 #endif
  3002 
  2913 
       
  2914 #endif // !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
       
  2915 
  3003 QT_END_NAMESPACE
  2916 QT_END_NAMESPACE