Qt 4.8
qglshaderprogram.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtOpenGL module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qglshaderprogram.h"
43 #include "qglextensions_p.h"
44 #include "qgl_p.h"
45 #include <QtCore/private/qobject_p.h>
46 #include <QtCore/qdebug.h>
47 #include <QtCore/qfile.h>
48 #include <QtCore/qvarlengtharray.h>
49 #include <QtCore/qvector.h>
50 
52 
53 #if !defined(QT_OPENGL_ES_1)
54 
159 #ifndef GL_FRAGMENT_SHADER
160 #define GL_FRAGMENT_SHADER 0x8B30
161 #endif
162 #ifndef GL_VERTEX_SHADER
163 #define GL_VERTEX_SHADER 0x8B31
164 #endif
165 #ifndef GL_COMPILE_STATUS
166 #define GL_COMPILE_STATUS 0x8B81
167 #endif
168 #ifndef GL_LINK_STATUS
169 #define GL_LINK_STATUS 0x8B82
170 #endif
171 #ifndef GL_INFO_LOG_LENGTH
172 #define GL_INFO_LOG_LENGTH 0x8B84
173 #endif
174 #ifndef GL_ACTIVE_UNIFORMS
175 #define GL_ACTIVE_UNIFORMS 0x8B86
176 #endif
177 #ifndef GL_ACTIVE_UNIFORM_MAX_LENGTH
178 #define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
179 #endif
180 #ifndef GL_ACTIVE_ATTRIBUTES
181 #define GL_ACTIVE_ATTRIBUTES 0x8B89
182 #endif
183 #ifndef GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
184 #define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
185 #endif
186 #ifndef GL_CURRENT_VERTEX_ATTRIB
187 #define GL_CURRENT_VERTEX_ATTRIB 0x8626
188 #endif
189 #ifndef GL_SHADER_SOURCE_LENGTH
190 #define GL_SHADER_SOURCE_LENGTH 0x8B88
191 #endif
192 #ifndef GL_SHADER_BINARY_FORMATS
193 #define GL_SHADER_BINARY_FORMATS 0x8DF8
194 #endif
195 #ifndef GL_NUM_SHADER_BINARY_FORMATS
196 #define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
197 #endif
198 
200 {
202 public:
203  QGLShaderPrivate(const QGLContext *context, QGLShader::ShaderType type)
204  : shaderGuard(context)
205  , shaderType(type)
206  , compiled(false)
207  {
208  }
210 
212  QGLShader::ShaderType shaderType;
213  bool compiled;
215 
216  bool create();
217  bool compile(QGLShader *q);
218  void deleteShader();
219 };
220 
221 #define ctx shaderGuard.context()
222 
224 {
225  if (shaderGuard.id()) {
228  }
229 }
230 
232 {
233  const QGLContext *context = shaderGuard.context();
234  if (!context)
235  return false;
236  if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) {
237  GLuint shader;
240  else if (shaderType == QGLShader::Geometry)
242  else
244  if (!shader) {
245  qWarning() << "QGLShader: could not create shader";
246  return false;
247  }
248  shaderGuard.setId(shader);
249  return true;
250  } else {
251  return false;
252  }
253 }
254 
256 {
257  GLuint shader = shaderGuard.id();
258  if (!shader)
259  return false;
260  glCompileShader(shader);
261  GLint value = 0;
262  glGetShaderiv(shader, GL_COMPILE_STATUS, &value);
263  compiled = (value != 0);
264  value = 0;
265  glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &value);
266  if (!compiled && value > 1) {
267  char *logbuf = new char [value];
268  GLint len;
269  glGetShaderInfoLog(shader, value, &len, logbuf);
270  log = QString::fromLatin1(logbuf);
271  QString name = q->objectName();
272 
273  const char *types[] = {
274  "Fragment",
275  "Vertex",
276  "Geometry",
277  ""
278  };
279 
280  const char *type = types[3];
282  type = types[0];
283  else if (shaderType == QGLShader::Vertex)
284  type = types[1];
285  else if (shaderType == QGLShader::Geometry)
286  type = types[2];
287 
288  if (name.isEmpty())
289  qWarning("QGLShader::compile(%s): %s", type, qPrintable(log));
290  else
291  qWarning("QGLShader::compile(%s)[%s]: %s", type, qPrintable(name), qPrintable(log));
292 
293  delete [] logbuf;
294  }
295  return compiled;
296 }
297 
299 {
300  if (shaderGuard.id()) {
302  shaderGuard.setId(0);
303  }
304 }
305 
306 #undef ctx
307 #define ctx d->shaderGuard.context()
308 
321 QGLShader::QGLShader(QGLShader::ShaderType type, QObject *parent)
322  : QObject(*new QGLShaderPrivate(QGLContext::currentContext(), type), parent)
323 {
324  Q_D(QGLShader);
325  d->create();
326 }
327 
340 QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent)
341  : QObject(*new QGLShaderPrivate(context ? context : QGLContext::currentContext(), type), parent)
342 {
343  Q_D(QGLShader);
344 #ifndef QT_NO_DEBUG
345  if (context && !QGLContext::areSharing(context, QGLContext::currentContext())) {
346  qWarning("QGLShader::QGLShader: \'context\' must be the current context or sharing with it.");
347  return;
348  }
349 #endif
350  d->create();
351 }
352 
359 {
360 }
361 
365 QGLShader::ShaderType QGLShader::shaderType() const
366 {
367  Q_D(const QGLShader);
368  return d->shaderType;
369 }
370 
371 // The precision qualifiers are useful on OpenGL/ES systems,
372 // but usually not present on desktop systems. Define the
373 // keywords to empty strings on desktop systems.
374 #ifndef QT_OPENGL_ES
375 #define QGL_DEFINE_QUALIFIERS 1
376 static const char qualifierDefines[] =
377  "#define lowp\n"
378  "#define mediump\n"
379  "#define highp\n";
380 #endif
381 
382 // The "highp" qualifier doesn't exist in fragment shaders
383 // on all ES platforms. When it doesn't exist, use "mediump".
384 #ifdef QT_OPENGL_ES
385 #define QGL_REDEFINE_HIGHP 1
386 static const char redefineHighp[] =
387  "#ifndef GL_FRAGMENT_PRECISION_HIGH\n"
388  "#define highp mediump\n"
389  "#endif\n";
390 #endif
391 
398 bool QGLShader::compileSourceCode(const char *source)
399 {
400  Q_D(QGLShader);
401  if (d->shaderGuard.id()) {
404  int headerLen = 0;
405  while (source && source[headerLen] == '#') {
406  // Skip #version and #extension directives at the start of
407  // the shader code. We need to insert the qualifierDefines
408  // and redefineHighp just after them.
409  if (qstrncmp(source + headerLen, "#version", 8) != 0 &&
410  qstrncmp(source + headerLen, "#extension", 10) != 0) {
411  break;
412  }
413  while (source[headerLen] != '\0' && source[headerLen] != '\n')
414  ++headerLen;
415  if (source[headerLen] == '\n')
416  ++headerLen;
417  }
418  if (headerLen > 0) {
419  src.append(source);
420  srclen.append(GLint(headerLen));
421  }
422 #ifdef QGL_DEFINE_QUALIFIERS
424  srclen.append(GLint(sizeof(qualifierDefines) - 1));
425 #endif
426 #ifdef QGL_REDEFINE_HIGHP
427  if (d->shaderType == Fragment) {
428  src.append(redefineHighp);
429  srclen.append(GLint(sizeof(redefineHighp) - 1));
430  }
431 #endif
432  src.append(source + headerLen);
433  srclen.append(GLint(qstrlen(source + headerLen)));
434  glShaderSource(d->shaderGuard.id(), src.size(), src.data(), srclen.data());
435  return d->compile(this);
436  } else {
437  return false;
438  }
439 }
440 
453 {
454  return compileSourceCode(source.constData());
455 }
456 
469 {
470  return compileSourceCode(source.toLatin1().constData());
471 }
472 
481 {
482  QFile file(fileName);
483  if (!file.open(QFile::ReadOnly)) {
484  qWarning() << "QGLShader: Unable to open file" << fileName;
485  return false;
486  }
487 
488  QByteArray contents = file.readAll();
489  return compileSourceCode(contents.constData());
490 }
491 
498 {
499  Q_D(const QGLShader);
500  GLuint shader = d->shaderGuard.id();
501  if (!shader)
502  return QByteArray();
503  GLint size = 0;
504  glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &size);
505  if (size <= 0)
506  return QByteArray();
507  GLint len = 0;
508  char *source = new char [size];
509  glGetShaderSource(shader, size, &len, source);
510  QByteArray src(source);
511  delete [] source;
512  return src;
513 }
514 
521 {
522  Q_D(const QGLShader);
523  return d->compiled;
524 }
525 
532 {
533  Q_D(const QGLShader);
534  return d->log;
535 }
536 
542 GLuint QGLShader::shaderId() const
543 {
544  Q_D(const QGLShader);
545  return d->shaderGuard.id();
546 }
547 
548 
549 
550 
551 
552 #undef ctx
553 #define ctx programGuard.context()
554 
556 {
558 public:
560  : programGuard(context)
561  , linked(false)
562  , inited(false)
563  , removingShaders(false)
564  , geometryVertexCount(64)
565  , geometryInputType(0)
566  , geometryOutputType(0)
567  {
568  }
570 
572  bool linked;
573  bool inited;
575 
579 
583 
584  bool hasShader(QGLShader::ShaderType type) const;
585 };
586 
588 {
589  if (programGuard.id()) {
590  QGLShareContextScope scope(programGuard.context());
591  glDeleteProgram(programGuard.id());
592  }
593 }
594 
595 bool QGLShaderProgramPrivate::hasShader(QGLShader::ShaderType type) const
596 {
597  foreach (QGLShader *shader, shaders) {
598  if (shader->shaderType() == type)
599  return true;
600  }
601  return false;
602 }
603 
604 #undef ctx
605 #define ctx d->programGuard.context()
606 
616  : QObject(*new QGLShaderProgramPrivate(QGLContext::currentContext()), parent)
617 {
618 }
619 
629  : QObject(*new QGLShaderProgramPrivate(context), parent)
630 {
631 }
632 
637 {
638 }
639 
641 {
643  if (d->programGuard.id() || d->inited)
644  return true;
645  d->inited = true;
646  const QGLContext *context = d->programGuard.context();
647  if (!context) {
648  context = QGLContext::currentContext();
649  d->programGuard.setContext(context);
650  }
651 
652  if (!context)
653  return false;
654  if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) {
655  GLuint program = glCreateProgram();
656  if (!program) {
657  qWarning() << "QGLShaderProgram: could not create shader program";
658  return false;
659  }
660  d->programGuard.setId(program);
661  return true;
662  } else {
663  qWarning() << "QGLShaderProgram: shader programs are not supported";
664  return false;
665  }
666 }
667 
681 {
683  if (!init())
684  return false;
685  if (d->shaders.contains(shader))
686  return true; // Already added to this shader program.
687  if (d->programGuard.id() && shader) {
688  if (!QGLContext::areSharing(shader->d_func()->shaderGuard.context(),
689  d->programGuard.context())) {
690  qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context.");
691  return false;
692  }
693  if (!shader->d_func()->shaderGuard.id())
694  return false;
695  glAttachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id());
696  d->linked = false; // Program needs to be relinked.
697  d->shaders.append(shader);
698  connect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed()));
699  return true;
700  } else {
701  return false;
702  }
703 }
704 
718 bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const char *source)
719 {
721  if (!init())
722  return false;
723  QGLShader *shader = new QGLShader(type, this);
724  if (!shader->compileSourceCode(source)) {
725  d->log = shader->log();
726  delete shader;
727  return false;
728  }
729  d->anonShaders.append(shader);
730  return addShader(shader);
731 }
732 
751 bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const QByteArray& source)
752 {
753  return addShaderFromSourceCode(type, source.constData());
754 }
755 
774 bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const QString& source)
775 {
776  return addShaderFromSourceCode(type, source.toLatin1().constData());
777 }
778 
792  (QGLShader::ShaderType type, const QString& fileName)
793 {
795  if (!init())
796  return false;
797  QGLShader *shader = new QGLShader(type, this);
798  if (!shader->compileSourceFile(fileName)) {
799  d->log = shader->log();
800  delete shader;
801  return false;
802  }
803  d->anonShaders.append(shader);
804  return addShader(shader);
805 }
806 
813 {
815  if (d->programGuard.id() && shader && shader->d_func()->shaderGuard.id()) {
816  QGLShareContextScope scope(d->programGuard.context());
817  glDetachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id());
818  }
819  d->linked = false; // Program needs to be relinked.
820  if (shader) {
821  d->shaders.removeAll(shader);
822  d->anonShaders.removeAll(shader);
823  disconnect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed()));
824  }
825 }
826 
834 {
835  Q_D(const QGLShaderProgram);
836  return d->shaders;
837 }
838 
848 {
850  d->removingShaders = true;
851  foreach (QGLShader *shader, d->shaders) {
852  if (d->programGuard.id() && shader && shader->d_func()->shaderGuard.id())
853  glDetachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id());
854  }
855  foreach (QGLShader *shader, d->anonShaders) {
856  // Delete shader objects that were created anonymously.
857  delete shader;
858  }
859  d->shaders.clear();
860  d->anonShaders.clear();
861  d->linked = false; // Program needs to be relinked.
862  d->removingShaders = false;
863 }
864 
880 {
882  GLuint program = d->programGuard.id();
883  if (!program)
884  return false;
885 
886  GLint value;
887  if (d->shaders.isEmpty()) {
888  // If there are no explicit shaders, then it is possible that the
889  // application added a program binary with glProgramBinaryOES(),
890  // or otherwise populated the shaders itself. Check to see if the
891  // program is already linked and bail out if so.
892  value = 0;
893  glGetProgramiv(program, GL_LINK_STATUS, &value);
894  d->linked = (value != 0);
895  if (d->linked)
896  return true;
897  }
898 
899  // Set up the geometry shader parameters
901  foreach (QGLShader *shader, d->shaders) {
902  if (shader->shaderType() & QGLShader::Geometry) {
904  d->geometryInputType);
906  d->geometryOutputType);
908  d->geometryVertexCount);
909  break;
910  }
911  }
912  }
913 
914  glLinkProgram(program);
915  value = 0;
916  glGetProgramiv(program, GL_LINK_STATUS, &value);
917  d->linked = (value != 0);
918  value = 0;
919  glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value);
920  d->log = QString();
921  if (value > 1) {
922  char *logbuf = new char [value];
923  GLint len;
924  glGetProgramInfoLog(program, value, &len, logbuf);
925  d->log = QString::fromLatin1(logbuf);
926  QString name = objectName();
927  if (name.isEmpty())
928  qWarning() << "QGLShader::link:" << d->log;
929  else
930  qWarning() << "QGLShader::link[" << name << "]:" << d->log;
931  delete [] logbuf;
932  }
933  return d->linked;
934 }
935 
942 {
943  Q_D(const QGLShaderProgram);
944  return d->linked;
945 }
946 
954 {
955  Q_D(const QGLShaderProgram);
956  return d->log;
957 }
958 
970 {
972  GLuint program = d->programGuard.id();
973  if (!program)
974  return false;
975  if (!d->linked && !link())
976  return false;
977 #ifndef QT_NO_DEBUG
978  if (!QGLContext::areSharing(d->programGuard.context(), QGLContext::currentContext())) {
979  qWarning("QGLShaderProgram::bind: program is not valid in the current context.");
980  return false;
981  }
982 #endif
983  glUseProgram(program);
984  return true;
985 }
986 
987 #undef ctx
988 #define ctx QGLContext::currentContext()
989 
997 {
998 #ifndef QT_NO_DEBUG
1000  if (!QGLContext::areSharing(d->programGuard.context(), QGLContext::currentContext()))
1001  qWarning("QGLShaderProgram::release: program is not valid in the current context.");
1002 #endif
1003 #if defined(QT_OPENGL_ES_2)
1004  glUseProgram(0);
1005 #else
1006  if (glUseProgram)
1007  glUseProgram(0);
1008 #endif
1009 }
1010 
1011 #undef ctx
1012 #define ctx d->programGuard.context()
1013 
1020 {
1021  Q_D(const QGLShaderProgram);
1022  GLuint id = d->programGuard.id();
1023  if (id)
1024  return id;
1025 
1026  // Create the identifier if we don't have one yet. This is for
1027  // applications that want to create the attached shader configuration
1028  // themselves, particularly those using program binaries.
1029  if (!const_cast<QGLShaderProgram *>(this)->init())
1030  return 0;
1031  return d->programGuard.id();
1032 }
1033 
1046 {
1048  if (!init())
1049  return;
1050  glBindAttribLocation(d->programGuard.id(), location, name);
1051  d->linked = false; // Program needs to be relinked.
1052 }
1053 
1071 {
1073 }
1074 
1092 {
1094 }
1095 
1104 {
1105  Q_D(const QGLShaderProgram);
1106  if (d->linked) {
1107  return glGetAttribLocation(d->programGuard.id(), name);
1108  } else {
1109  qWarning() << "QGLShaderProgram::attributeLocation(" << name
1110  << "): shader program is not linked";
1111  return -1;
1112  }
1113 }
1114 
1128 {
1129  return attributeLocation(name.constData());
1130 }
1131 
1145 {
1146  return attributeLocation(name.toLatin1().constData());
1147 }
1148 
1155 {
1157  Q_UNUSED(d);
1158  if (location != -1)
1159  glVertexAttrib1fv(location, &value);
1160 }
1161 
1172 void QGLShaderProgram::setAttributeValue(const char *name, GLfloat value)
1173 {
1174  setAttributeValue(attributeLocation(name), value);
1175 }
1176 
1183 void QGLShaderProgram::setAttributeValue(int location, GLfloat x, GLfloat y)
1184 {
1186  Q_UNUSED(d);
1187  if (location != -1) {
1188  GLfloat values[2] = {x, y};
1189  glVertexAttrib2fv(location, values);
1190  }
1191 }
1192 
1204 void QGLShaderProgram::setAttributeValue(const char *name, GLfloat x, GLfloat y)
1205 {
1206  setAttributeValue(attributeLocation(name), x, y);
1207 }
1208 
1216  (int location, GLfloat x, GLfloat y, GLfloat z)
1217 {
1219  Q_UNUSED(d);
1220  if (location != -1) {
1221  GLfloat values[3] = {x, y, z};
1222  glVertexAttrib3fv(location, values);
1223  }
1224 }
1225 
1238  (const char *name, GLfloat x, GLfloat y, GLfloat z)
1239 {
1240  setAttributeValue(attributeLocation(name), x, y, z);
1241 }
1242 
1250  (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1251 {
1253  Q_UNUSED(d);
1254  if (location != -1) {
1255  GLfloat values[4] = {x, y, z, w};
1256  glVertexAttrib4fv(location, values);
1257  }
1258 }
1259 
1272  (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1273 {
1274  setAttributeValue(attributeLocation(name), x, y, z, w);
1275 }
1276 
1282 void QGLShaderProgram::setAttributeValue(int location, const QVector2D& value)
1283 {
1285  Q_UNUSED(d);
1286  if (location != -1)
1287  glVertexAttrib2fv(location, reinterpret_cast<const GLfloat *>(&value));
1288 }
1289 
1300 void QGLShaderProgram::setAttributeValue(const char *name, const QVector2D& value)
1301 {
1302  setAttributeValue(attributeLocation(name), value);
1303 }
1304 
1310 void QGLShaderProgram::setAttributeValue(int location, const QVector3D& value)
1311 {
1313  Q_UNUSED(d);
1314  if (location != -1)
1315  glVertexAttrib3fv(location, reinterpret_cast<const GLfloat *>(&value));
1316 }
1317 
1328 void QGLShaderProgram::setAttributeValue(const char *name, const QVector3D& value)
1329 {
1330  setAttributeValue(attributeLocation(name), value);
1331 }
1332 
1338 void QGLShaderProgram::setAttributeValue(int location, const QVector4D& value)
1339 {
1341  Q_UNUSED(d);
1342  if (location != -1)
1343  glVertexAttrib4fv(location, reinterpret_cast<const GLfloat *>(&value));
1344 }
1345 
1356 void QGLShaderProgram::setAttributeValue(const char *name, const QVector4D& value)
1357 {
1358  setAttributeValue(attributeLocation(name), value);
1359 }
1360 
1366 void QGLShaderProgram::setAttributeValue(int location, const QColor& value)
1367 {
1369  Q_UNUSED(d);
1370  if (location != -1) {
1371  GLfloat values[4] = {GLfloat(value.redF()), GLfloat(value.greenF()),
1372  GLfloat(value.blueF()), GLfloat(value.alphaF())};
1373  glVertexAttrib4fv(location, values);
1374  }
1375 }
1376 
1387 void QGLShaderProgram::setAttributeValue(const char *name, const QColor& value)
1388 {
1389  setAttributeValue(attributeLocation(name), value);
1390 }
1391 
1402  (int location, const GLfloat *values, int columns, int rows)
1403 {
1405  Q_UNUSED(d);
1406  if (rows < 1 || rows > 4) {
1407  qWarning() << "QGLShaderProgram::setAttributeValue: rows" << rows << "not supported";
1408  return;
1409  }
1410  if (location != -1) {
1411  while (columns-- > 0) {
1412  if (rows == 1)
1413  glVertexAttrib1fv(location, values);
1414  else if (rows == 2)
1415  glVertexAttrib2fv(location, values);
1416  else if (rows == 3)
1417  glVertexAttrib3fv(location, values);
1418  else
1419  glVertexAttrib4fv(location, values);
1420  values += rows;
1421  ++location;
1422  }
1423  }
1424 }
1425 
1441  (const char *name, const GLfloat *values, int columns, int rows)
1442 {
1443  setAttributeValue(attributeLocation(name), values, columns, rows);
1444 }
1445 
1461  (int location, const GLfloat *values, int tupleSize, int stride)
1462 {
1464  Q_UNUSED(d);
1465  if (location != -1) {
1466  glVertexAttribPointer(location, tupleSize, GL_FLOAT, GL_FALSE,
1467  stride, values);
1468  }
1469 }
1470 
1485  (int location, const QVector2D *values, int stride)
1486 {
1488  Q_UNUSED(d);
1489  if (location != -1) {
1490  glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE,
1491  stride, values);
1492  }
1493 }
1494 
1509  (int location, const QVector3D *values, int stride)
1510 {
1512  Q_UNUSED(d);
1513  if (location != -1) {
1514  glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE,
1515  stride, values);
1516  }
1517 }
1518 
1533  (int location, const QVector4D *values, int stride)
1534 {
1536  Q_UNUSED(d);
1537  if (location != -1) {
1538  glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE,
1539  stride, values);
1540  }
1541 }
1542 
1565  (int location, GLenum type, const void *values, int tupleSize, int stride)
1566 {
1568  Q_UNUSED(d);
1569  if (location != -1) {
1570  glVertexAttribPointer(location, tupleSize, type, GL_TRUE,
1571  stride, values);
1572  }
1573 }
1574 
1595  (const char *name, const GLfloat *values, int tupleSize, int stride)
1596 {
1597  setAttributeArray(attributeLocation(name), values, tupleSize, stride);
1598 }
1599 
1619  (const char *name, const QVector2D *values, int stride)
1620 {
1621  setAttributeArray(attributeLocation(name), values, stride);
1622 }
1623 
1643  (const char *name, const QVector3D *values, int stride)
1644 {
1645  setAttributeArray(attributeLocation(name), values, stride);
1646 }
1647 
1667  (const char *name, const QVector4D *values, int stride)
1668 {
1669  setAttributeArray(attributeLocation(name), values, stride);
1670 }
1671 
1699  (const char *name, GLenum type, const void *values, int tupleSize, int stride)
1700 {
1701  setAttributeArray(attributeLocation(name), type, values, tupleSize, stride);
1702 }
1703 
1724  (int location, GLenum type, int offset, int tupleSize, int stride)
1725 {
1727  Q_UNUSED(d);
1728  if (location != -1) {
1729  glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride,
1730  reinterpret_cast<const void *>(offset));
1731  }
1732 }
1733 
1759  (const char *name, GLenum type, int offset, int tupleSize, int stride)
1760 {
1761  setAttributeBuffer(attributeLocation(name), type, offset, tupleSize, stride);
1762 }
1763 
1773 {
1775  Q_UNUSED(d);
1776  if (location != -1)
1777  glEnableVertexAttribArray(location);
1778 }
1779 
1794 {
1796 }
1797 
1806 {
1808  Q_UNUSED(d);
1809  if (location != -1)
1810  glDisableVertexAttribArray(location);
1811 }
1812 
1826 {
1828 }
1829 
1837 int QGLShaderProgram::uniformLocation(const char *name) const
1838 {
1839  Q_D(const QGLShaderProgram);
1840  Q_UNUSED(d);
1841  if (d->linked) {
1842  return glGetUniformLocation(d->programGuard.id(), name);
1843  } else {
1844  qWarning() << "QGLShaderProgram::uniformLocation(" << name
1845  << "): shader program is not linked";
1846  return -1;
1847  }
1848 }
1849 
1863 {
1864  return uniformLocation(name.constData());
1865 }
1866 
1880 {
1881  return uniformLocation(name.toLatin1().constData());
1882 }
1883 
1889 void QGLShaderProgram::setUniformValue(int location, GLfloat value)
1890 {
1892  Q_UNUSED(d);
1893  if (location != -1)
1894  glUniform1fv(location, 1, &value);
1895 }
1896 
1908 void QGLShaderProgram::setUniformValue(const char *name, GLfloat value)
1909 {
1910  setUniformValue(uniformLocation(name), value);
1911 }
1912 
1918 void QGLShaderProgram::setUniformValue(int location, GLint value)
1919 {
1921  Q_UNUSED(d);
1922  if (location != -1)
1923  glUniform1i(location, value);
1924 }
1925 
1937 void QGLShaderProgram::setUniformValue(const char *name, GLint value)
1938 {
1939  setUniformValue(uniformLocation(name), value);
1940 }
1941 
1948 void QGLShaderProgram::setUniformValue(int location, GLuint value)
1949 {
1951  Q_UNUSED(d);
1952  if (location != -1)
1953  glUniform1i(location, value);
1954 }
1955 
1967 void QGLShaderProgram::setUniformValue(const char *name, GLuint value)
1968 {
1969  setUniformValue(uniformLocation(name), value);
1970 }
1971 
1978 void QGLShaderProgram::setUniformValue(int location, GLfloat x, GLfloat y)
1979 {
1981  Q_UNUSED(d);
1982  if (location != -1) {
1983  GLfloat values[2] = {x, y};
1984  glUniform2fv(location, 1, values);
1985  }
1986 }
1987 
1999 void QGLShaderProgram::setUniformValue(const char *name, GLfloat x, GLfloat y)
2000 {
2001  setUniformValue(uniformLocation(name), x, y);
2002 }
2003 
2011  (int location, GLfloat x, GLfloat y, GLfloat z)
2012 {
2014  Q_UNUSED(d);
2015  if (location != -1) {
2016  GLfloat values[3] = {x, y, z};
2017  glUniform3fv(location, 1, values);
2018  }
2019 }
2020 
2033  (const char *name, GLfloat x, GLfloat y, GLfloat z)
2034 {
2035  setUniformValue(uniformLocation(name), x, y, z);
2036 }
2037 
2045  (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2046 {
2048  Q_UNUSED(d);
2049  if (location != -1) {
2050  GLfloat values[4] = {x, y, z, w};
2051  glUniform4fv(location, 1, values);
2052  }
2053 }
2054 
2067  (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2068 {
2069  setUniformValue(uniformLocation(name), x, y, z, w);
2070 }
2071 
2077 void QGLShaderProgram::setUniformValue(int location, const QVector2D& value)
2078 {
2080  Q_UNUSED(d);
2081  if (location != -1)
2082  glUniform2fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
2083 }
2084 
2096 void QGLShaderProgram::setUniformValue(const char *name, const QVector2D& value)
2097 {
2098  setUniformValue(uniformLocation(name), value);
2099 }
2100 
2106 void QGLShaderProgram::setUniformValue(int location, const QVector3D& value)
2107 {
2109  Q_UNUSED(d);
2110  if (location != -1)
2111  glUniform3fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
2112 }
2113 
2125 void QGLShaderProgram::setUniformValue(const char *name, const QVector3D& value)
2126 {
2127  setUniformValue(uniformLocation(name), value);
2128 }
2129 
2135 void QGLShaderProgram::setUniformValue(int location, const QVector4D& value)
2136 {
2138  Q_UNUSED(d);
2139  if (location != -1)
2140  glUniform4fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
2141 }
2142 
2154 void QGLShaderProgram::setUniformValue(const char *name, const QVector4D& value)
2155 {
2156  setUniformValue(uniformLocation(name), value);
2157 }
2158 
2165 void QGLShaderProgram::setUniformValue(int location, const QColor& color)
2166 {
2168  Q_UNUSED(d);
2169  if (location != -1) {
2170  GLfloat values[4] = {GLfloat(color.redF()), GLfloat(color.greenF()),
2171  GLfloat(color.blueF()), GLfloat(color.alphaF())};
2172  glUniform4fv(location, 1, values);
2173  }
2174 }
2175 
2187 void QGLShaderProgram::setUniformValue(const char *name, const QColor& color)
2188 {
2189  setUniformValue(uniformLocation(name), color);
2190 }
2191 
2198 void QGLShaderProgram::setUniformValue(int location, const QPoint& point)
2199 {
2201  Q_UNUSED(d);
2202  if (location != -1) {
2203  GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())};
2204  glUniform2fv(location, 1, values);
2205  }
2206 }
2207 
2219 void QGLShaderProgram::setUniformValue(const char *name, const QPoint& point)
2220 {
2221  setUniformValue(uniformLocation(name), point);
2222 }
2223 
2230 void QGLShaderProgram::setUniformValue(int location, const QPointF& point)
2231 {
2233  Q_UNUSED(d);
2234  if (location != -1) {
2235  GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())};
2236  glUniform2fv(location, 1, values);
2237  }
2238 }
2239 
2251 void QGLShaderProgram::setUniformValue(const char *name, const QPointF& point)
2252 {
2253  setUniformValue(uniformLocation(name), point);
2254 }
2255 
2262 void QGLShaderProgram::setUniformValue(int location, const QSize& size)
2263 {
2265  Q_UNUSED(d);
2266  if (location != -1) {
2267  GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())};
2268  glUniform2fv(location, 1, values);
2269  }
2270 }
2271 
2283 void QGLShaderProgram::setUniformValue(const char *name, const QSize& size)
2284 {
2285  setUniformValue(uniformLocation(name), size);
2286 }
2287 
2294 void QGLShaderProgram::setUniformValue(int location, const QSizeF& size)
2295 {
2297  Q_UNUSED(d);
2298  if (location != -1) {
2299  GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())};
2300  glUniform2fv(location, 1, values);
2301  }
2302 }
2303 
2315 void QGLShaderProgram::setUniformValue(const char *name, const QSizeF& size)
2316 {
2317  setUniformValue(uniformLocation(name), size);
2318 }
2319 
2320 // We have to repack matrices from qreal to GLfloat.
2321 #define setUniformMatrix(func,location,value,cols,rows) \
2322  if (location == -1) \
2323  return; \
2324  if (sizeof(qreal) == sizeof(GLfloat)) { \
2325  func(location, 1, GL_FALSE, \
2326  reinterpret_cast<const GLfloat *>(value.constData())); \
2327  } else { \
2328  GLfloat mat[cols * rows]; \
2329  const qreal *data = value.constData(); \
2330  for (int i = 0; i < cols * rows; ++i) \
2331  mat[i] = data[i]; \
2332  func(location, 1, GL_FALSE, mat); \
2333  }
2334 #if !defined(QT_OPENGL_ES_2)
2335 #define setUniformGenericMatrix(func,colfunc,location,value,cols,rows) \
2336  if (location == -1) \
2337  return; \
2338  if (sizeof(qreal) == sizeof(GLfloat)) { \
2339  const GLfloat *data = reinterpret_cast<const GLfloat *> \
2340  (value.constData()); \
2341  if (func) \
2342  func(location, 1, GL_FALSE, data); \
2343  else \
2344  colfunc(location, cols, data); \
2345  } else { \
2346  GLfloat mat[cols * rows]; \
2347  const qreal *data = value.constData(); \
2348  for (int i = 0; i < cols * rows; ++i) \
2349  mat[i] = data[i]; \
2350  if (func) \
2351  func(location, 1, GL_FALSE, mat); \
2352  else \
2353  colfunc(location, cols, mat); \
2354  }
2355 #else
2356 #define setUniformGenericMatrix(func,colfunc,location,value,cols,rows) \
2357  if (location == -1) \
2358  return; \
2359  if (sizeof(qreal) == sizeof(GLfloat)) { \
2360  const GLfloat *data = reinterpret_cast<const GLfloat *> \
2361  (value.constData()); \
2362  colfunc(location, cols, data); \
2363  } else { \
2364  GLfloat mat[cols * rows]; \
2365  const qreal *data = value.constData(); \
2366  for (int i = 0; i < cols * rows; ++i) \
2367  mat[i] = data[i]; \
2368  colfunc(location, cols, mat); \
2369  }
2370 #endif
2371 
2378 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value)
2379 {
2381  Q_UNUSED(d);
2382  setUniformMatrix(glUniformMatrix2fv, location, value, 2, 2);
2383 }
2384 
2396 void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x2& value)
2397 {
2398  setUniformValue(uniformLocation(name), value);
2399 }
2400 
2407 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value)
2408 {
2410  Q_UNUSED(d);
2412  (glUniformMatrix2x3fv, glUniform3fv, location, value, 2, 3);
2413 }
2414 
2426 void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& value)
2427 {
2428  setUniformValue(uniformLocation(name), value);
2429 }
2430 
2437 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value)
2438 {
2440  Q_UNUSED(d);
2442  (glUniformMatrix2x4fv, glUniform4fv, location, value, 2, 4);
2443 }
2444 
2456 void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& value)
2457 {
2458  setUniformValue(uniformLocation(name), value);
2459 }
2460 
2467 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value)
2468 {
2470  Q_UNUSED(d);
2472  (glUniformMatrix3x2fv, glUniform2fv, location, value, 3, 2);
2473 }
2474 
2486 void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x2& value)
2487 {
2488  setUniformValue(uniformLocation(name), value);
2489 }
2490 
2497 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value)
2498 {
2500  Q_UNUSED(d);
2501  setUniformMatrix(glUniformMatrix3fv, location, value, 3, 3);
2502 }
2503 
2515 void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x3& value)
2516 {
2517  setUniformValue(uniformLocation(name), value);
2518 }
2519 
2526 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value)
2527 {
2529  Q_UNUSED(d);
2531  (glUniformMatrix3x4fv, glUniform4fv, location, value, 3, 4);
2532 }
2533 
2545 void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& value)
2546 {
2547  setUniformValue(uniformLocation(name), value);
2548 }
2549 
2556 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value)
2557 {
2559  Q_UNUSED(d);
2561  (glUniformMatrix4x2fv, glUniform2fv, location, value, 4, 2);
2562 }
2563 
2575 void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& value)
2576 {
2577  setUniformValue(uniformLocation(name), value);
2578 }
2579 
2586 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value)
2587 {
2589  Q_UNUSED(d);
2591  (glUniformMatrix4x3fv, glUniform3fv, location, value, 4, 3);
2592 }
2593 
2605 void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x3& value)
2606 {
2607  setUniformValue(uniformLocation(name), value);
2608 }
2609 
2616 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value)
2617 {
2619  Q_UNUSED(d);
2620  setUniformMatrix(glUniformMatrix4fv, location, value, 4, 4);
2621 }
2622 
2634 void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x4& value)
2635 {
2636  setUniformValue(uniformLocation(name), value);
2637 }
2638 
2652 void QGLShaderProgram::setUniformValue(int location, const GLfloat value[2][2])
2653 {
2655  Q_UNUSED(d);
2656  if (location != -1)
2657  glUniformMatrix2fv(location, 1, GL_FALSE, value[0]);
2658 }
2659 
2673 void QGLShaderProgram::setUniformValue(int location, const GLfloat value[3][3])
2674 {
2676  Q_UNUSED(d);
2677  if (location != -1)
2678  glUniformMatrix3fv(location, 1, GL_FALSE, value[0]);
2679 }
2680 
2693 void QGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4])
2694 {
2696  Q_UNUSED(d);
2697  if (location != -1)
2698  glUniformMatrix4fv(location, 1, GL_FALSE, value[0]);
2699 }
2700 
2701 
2715 void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[2][2])
2716 {
2717  setUniformValue(uniformLocation(name), value);
2718 }
2719 
2733 void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[3][3])
2734 {
2735  setUniformValue(uniformLocation(name), value);
2736 }
2737 
2750 void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[4][4])
2751 {
2752  setUniformValue(uniformLocation(name), value);
2753 }
2754 
2762 void QGLShaderProgram::setUniformValue(int location, const QTransform& value)
2763 {
2765  Q_UNUSED(d);
2766  if (location != -1) {
2767  GLfloat mat[3][3] = {
2768  {GLfloat(value.m11()), GLfloat(value.m12()), GLfloat(value.m13())},
2769  {GLfloat(value.m21()), GLfloat(value.m22()), GLfloat(value.m23())},
2770  {GLfloat(value.m31()), GLfloat(value.m32()), GLfloat(value.m33())}
2771  };
2772  glUniformMatrix3fv(location, 1, GL_FALSE, mat[0]);
2773  }
2774 }
2775 
2789  (const char *name, const QTransform& value)
2790 {
2791  setUniformValue(uniformLocation(name), value);
2792 }
2793 
2800 void QGLShaderProgram::setUniformValueArray(int location, const GLint *values, int count)
2801 {
2803  Q_UNUSED(d);
2804  if (location != -1)
2805  glUniform1iv(location, count, values);
2806 }
2807 
2820  (const char *name, const GLint *values, int count)
2821 {
2822  setUniformValueArray(uniformLocation(name), values, count);
2823 }
2824 
2832 void QGLShaderProgram::setUniformValueArray(int location, const GLuint *values, int count)
2833 {
2835  Q_UNUSED(d);
2836  if (location != -1)
2837  glUniform1iv(location, count, reinterpret_cast<const GLint *>(values));
2838 }
2839 
2853  (const char *name, const GLuint *values, int count)
2854 {
2855  setUniformValueArray(uniformLocation(name), values, count);
2856 }
2857 
2865 void QGLShaderProgram::setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize)
2866 {
2868  Q_UNUSED(d);
2869  if (location != -1) {
2870  if (tupleSize == 1)
2871  glUniform1fv(location, count, values);
2872  else if (tupleSize == 2)
2873  glUniform2fv(location, count, values);
2874  else if (tupleSize == 3)
2875  glUniform3fv(location, count, values);
2876  else if (tupleSize == 4)
2877  glUniform4fv(location, count, values);
2878  else
2879  qWarning() << "QGLShaderProgram::setUniformValue: size" << tupleSize << "not supported";
2880  }
2881 }
2882 
2896  (const char *name, const GLfloat *values, int count, int tupleSize)
2897 {
2898  setUniformValueArray(uniformLocation(name), values, count, tupleSize);
2899 }
2900 
2907 void QGLShaderProgram::setUniformValueArray(int location, const QVector2D *values, int count)
2908 {
2910  Q_UNUSED(d);
2911  if (location != -1)
2912  glUniform2fv(location, count, reinterpret_cast<const GLfloat *>(values));
2913 }
2914 
2926 void QGLShaderProgram::setUniformValueArray(const char *name, const QVector2D *values, int count)
2927 {
2928  setUniformValueArray(uniformLocation(name), values, count);
2929 }
2930 
2937 void QGLShaderProgram::setUniformValueArray(int location, const QVector3D *values, int count)
2938 {
2940  Q_UNUSED(d);
2941  if (location != -1)
2942  glUniform3fv(location, count, reinterpret_cast<const GLfloat *>(values));
2943 }
2944 
2956 void QGLShaderProgram::setUniformValueArray(const char *name, const QVector3D *values, int count)
2957 {
2958  setUniformValueArray(uniformLocation(name), values, count);
2959 }
2960 
2967 void QGLShaderProgram::setUniformValueArray(int location, const QVector4D *values, int count)
2968 {
2970  Q_UNUSED(d);
2971  if (location != -1)
2972  glUniform4fv(location, count, reinterpret_cast<const GLfloat *>(values));
2973 }
2974 
2986 void QGLShaderProgram::setUniformValueArray(const char *name, const QVector4D *values, int count)
2987 {
2988  setUniformValueArray(uniformLocation(name), values, count);
2989 }
2990 
2991 // We have to repack matrix arrays from qreal to GLfloat.
2992 #define setUniformMatrixArray(func,location,values,count,type,cols,rows) \
2993  if (location == -1 || count <= 0) \
2994  return; \
2995  if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
2996  func(location, count, GL_FALSE, \
2997  reinterpret_cast<const GLfloat *>(values[0].constData())); \
2998  } else { \
2999  QVarLengthArray<GLfloat> temp(cols * rows * count); \
3000  for (int index = 0; index < count; ++index) { \
3001  for (int index2 = 0; index2 < (cols * rows); ++index2) { \
3002  temp.data()[cols * rows * index + index2] = \
3003  values[index].constData()[index2]; \
3004  } \
3005  } \
3006  func(location, count, GL_FALSE, temp.constData()); \
3007  }
3008 #if !defined(QT_OPENGL_ES_2)
3009 #define setUniformGenericMatrixArray(func,colfunc,location,values,count,type,cols,rows) \
3010  if (location == -1 || count <= 0) \
3011  return; \
3012  if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
3013  const GLfloat *data = reinterpret_cast<const GLfloat *> \
3014  (values[0].constData()); \
3015  if (func) \
3016  func(location, count, GL_FALSE, data); \
3017  else \
3018  colfunc(location, count * cols, data); \
3019  } else { \
3020  QVarLengthArray<GLfloat> temp(cols * rows * count); \
3021  for (int index = 0; index < count; ++index) { \
3022  for (int index2 = 0; index2 < (cols * rows); ++index2) { \
3023  temp.data()[cols * rows * index + index2] = \
3024  values[index].constData()[index2]; \
3025  } \
3026  } \
3027  if (func) \
3028  func(location, count, GL_FALSE, temp.constData()); \
3029  else \
3030  colfunc(location, count * cols, temp.constData()); \
3031  }
3032 #else
3033 #define setUniformGenericMatrixArray(func,colfunc,location,values,count,type,cols,rows) \
3034  if (location == -1 || count <= 0) \
3035  return; \
3036  if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
3037  const GLfloat *data = reinterpret_cast<const GLfloat *> \
3038  (values[0].constData()); \
3039  colfunc(location, count * cols, data); \
3040  } else { \
3041  QVarLengthArray<GLfloat> temp(cols * rows * count); \
3042  for (int index = 0; index < count; ++index) { \
3043  for (int index2 = 0; index2 < (cols * rows); ++index2) { \
3044  temp.data()[cols * rows * index + index2] = \
3045  values[index].constData()[index2]; \
3046  } \
3047  } \
3048  colfunc(location, count * cols, temp.constData()); \
3049  }
3050 #endif
3051 
3058 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x2 *values, int count)
3059 {
3061  Q_UNUSED(d);
3063  (glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2);
3064 }
3065 
3077 void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x2 *values, int count)
3078 {
3079  setUniformValueArray(uniformLocation(name), values, count);
3080 }
3081 
3088 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x3 *values, int count)
3089 {
3091  Q_UNUSED(d);
3093  (glUniformMatrix2x3fv, glUniform3fv, location, values, count,
3094  QMatrix2x3, 2, 3);
3095 }
3096 
3108 void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x3 *values, int count)
3109 {
3110  setUniformValueArray(uniformLocation(name), values, count);
3111 }
3112 
3119 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x4 *values, int count)
3120 {
3122  Q_UNUSED(d);
3124  (glUniformMatrix2x4fv, glUniform4fv, location, values, count,
3125  QMatrix2x4, 2, 4);
3126 }
3127 
3139 void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x4 *values, int count)
3140 {
3141  setUniformValueArray(uniformLocation(name), values, count);
3142 }
3143 
3150 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x2 *values, int count)
3151 {
3153  Q_UNUSED(d);
3155  (glUniformMatrix3x2fv, glUniform2fv, location, values, count,
3156  QMatrix3x2, 3, 2);
3157 }
3158 
3170 void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x2 *values, int count)
3171 {
3172  setUniformValueArray(uniformLocation(name), values, count);
3173 }
3174 
3181 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x3 *values, int count)
3182 {
3184  Q_UNUSED(d);
3186  (glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3);
3187 }
3188 
3200 void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x3 *values, int count)
3201 {
3202  setUniformValueArray(uniformLocation(name), values, count);
3203 }
3204 
3211 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x4 *values, int count)
3212 {
3214  Q_UNUSED(d);
3216  (glUniformMatrix3x4fv, glUniform4fv, location, values, count,
3217  QMatrix3x4, 3, 4);
3218 }
3219 
3231 void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x4 *values, int count)
3232 {
3233  setUniformValueArray(uniformLocation(name), values, count);
3234 }
3235 
3242 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x2 *values, int count)
3243 {
3245  Q_UNUSED(d);
3247  (glUniformMatrix4x2fv, glUniform2fv, location, values, count,
3248  QMatrix4x2, 4, 2);
3249 }
3250 
3262 void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x2 *values, int count)
3263 {
3264  setUniformValueArray(uniformLocation(name), values, count);
3265 }
3266 
3273 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x3 *values, int count)
3274 {
3276  Q_UNUSED(d);
3278  (glUniformMatrix4x3fv, glUniform3fv, location, values, count,
3279  QMatrix4x3, 4, 3);
3280 }
3281 
3293 void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x3 *values, int count)
3294 {
3295  setUniformValueArray(uniformLocation(name), values, count);
3296 }
3297 
3304 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x4 *values, int count)
3305 {
3307  Q_UNUSED(d);
3309  (glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4);
3310 }
3311 
3323 void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x4 *values, int count)
3324 {
3325  setUniformValueArray(uniformLocation(name), values, count);
3326 }
3327 
3328 #undef ctx
3329 
3339 {
3340  GLint n;
3341  glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
3342  return n;
3343 }
3344 
3354 {
3355 #ifndef QT_NO_DEBUG
3356  int max = maxGeometryOutputVertices();
3357  if (count > max) {
3358  qWarning("QGLShaderProgram::setGeometryOutputVertexCount: count: %d higher than maximum: %d",
3359  count, max);
3360  }
3361 #endif
3362  d_func()->geometryVertexCount = count;
3363 }
3364 
3365 
3375 {
3376  return d_func()->geometryVertexCount;
3377 }
3378 
3379 
3386 {
3387  d_func()->geometryInputType = inputType;
3388 }
3389 
3390 
3400 {
3401  return d_func()->geometryInputType;
3402 }
3403 
3404 
3414 {
3415  d_func()->geometryOutputType = outputType;
3416 }
3417 
3418 
3427 {
3428  return d_func()->geometryOutputType;
3429 }
3430 
3431 
3440 {
3441 #if !defined(QT_OPENGL_ES_2)
3442  if (!context)
3443  context = QGLContext::currentContext();
3444  if (!context)
3445  return false;
3446  return qt_resolve_glsl_extensions(const_cast<QGLContext *>(context));
3447 #else
3448  Q_UNUSED(context);
3449  return true;
3450 #endif
3451 }
3452 
3457 {
3459  QGLShader *shader = qobject_cast<QGLShader *>(sender());
3460  if (shader && !d->removingShaders)
3461  removeShader(shader);
3462 }
3463 
3464 
3465 #undef ctx
3466 #undef context
3467 
3477 bool QGLShader::hasOpenGLShaders(ShaderType type, const QGLContext *context)
3478 {
3479  if (!context)
3480  context = QGLContext::currentContext();
3481  if (!context)
3482  return false;
3483 
3484  if ((type & ~(Geometry | Vertex | Fragment)) || type == 0)
3485  return false;
3486 
3487  bool resolved = qt_resolve_glsl_extensions(const_cast<QGLContext *>(context));
3488  if (!resolved)
3489  return false;
3490 
3491  if ((type & Geometry) && !QByteArray((const char *) glGetString(GL_EXTENSIONS)).contains("GL_EXT_geometry_shader4"))
3492  return false;
3493 
3494  return true;
3495 }
3496 
3497 
3498 
3499 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
3500 
3502  (int location, QMacCompatGLenum type, const void *values, int tupleSize, int stride)
3503 {
3504  setAttributeArray(location, GLenum(type), values, tupleSize, stride);
3505 }
3506 
3509  (const char *name, QMacCompatGLenum type, const void *values, int tupleSize, int stride)
3510 {
3511  setAttributeArray(name, GLenum(type), values, tupleSize, stride);
3512 }
3513 
3516  (int location, QMacCompatGLenum type, int offset, int tupleSize, int stride)
3517 {
3518  setAttributeBuffer(location, GLenum(type), offset, tupleSize, stride);
3519 }
3520 
3523  (const char *name, QMacCompatGLenum type, int offset, int tupleSize, int stride)
3524 {
3525  setAttributeBuffer(name, GLenum(type), offset, tupleSize, stride);
3526 }
3527 
3529 void QGLShaderProgram::setUniformValue(int location, QMacCompatGLint value)
3530 {
3531  setUniformValue(location, GLint(value));
3532 }
3533 
3535 void QGLShaderProgram::setUniformValue(int location, QMacCompatGLuint value)
3536 {
3537  setUniformValue(location, GLuint(value));
3538 }
3539 
3541 void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLint value)
3542 {
3543  setUniformValue(name, GLint(value));
3544 }
3545 
3547 void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLuint value)
3548 {
3549  setUniformValue(name, GLuint(value));
3550 }
3551 
3553 void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLint *values, int count)
3554 {
3555  setUniformValueArray(location, (const GLint *)values, count);
3556 }
3557 
3559 void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLuint *values, int count)
3560 {
3561  setUniformValueArray(location, (const GLuint *)values, count);
3562 }
3563 
3565 void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLint *values, int count)
3566 {
3567  setUniformValueArray(name, (const GLint *)values, count);
3568 }
3569 
3571 void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLuint *values, int count)
3572 {
3573  setUniformValueArray(name, (const GLuint *)values, count);
3574 }
3575 #endif
3576 
3577 #endif // !defined(QT_OPENGL_ES_1)
3578 
GLenum geometryInputType() const
Returns the geometry shader input type, if active.
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
void bindAttributeLocation(const char *name, int location)
Binds the attribute name to the specified location.
int maxGeometryOutputVertices() const
Returns the hardware limit for how many vertices a geometry shader can output.
void setGeometryOutputType(GLenum outputType)
Sets the output type from the geometry shader, if active, to outputType.
void disableAttributeArray(int location)
Disables the vertex array at location in this shader program that was enabled by a previous call to e...
qreal alphaF() const
Returns the alpha color component of this color.
Definition: qcolor.cpp:1106
The QVector3D class represents a vector or vertex in 3D space.
Definition: qvector3d.h:60
const QGLContext * context() const
Definition: qgl_p.h:873
#define GL_COMPILE_STATUS
int type
Definition: qmetatype.cpp:239
bool compile(QGLShader *q)
#define glCreateProgram
#define glUseProgram
bool compileSourceCode(const char *source)
Sets the source code for this shader and compiles it.
#define glUniform3fv
GLuint id() const
Definition: qgl_p.h:880
void removeAllShaders()
Removes all of the shaders that were added to this program previously.
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
The QGenericMatrix class is a template class that represents a NxM transformation matrix with N colum...
#define GL_TRUE
#define glUniform1iv
qreal m32() const
Returns the vertical translation factor.
Definition: qtransform.h:265
void setAttributeArray(int location, const GLfloat *values, int tupleSize, int stride=0)
Sets an array of vertex values on the attribute at location in this shader program.
GLuint programId() const
Returns the OpenGL identifier associated with this shader program.
#define glGetShaderSource
qreal greenF() const
Returns the green color component of this color.
Definition: qcolor.cpp:1241
bool open(OpenMode flags)
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition: qfile.cpp:1064
#define GL_GEOMETRY_INPUT_TYPE_EXT
#define glUniform2fv
qreal width() const
Returns the width.
Definition: qsize.h:284
qreal m21() const
Returns the horizontal shearing factor.
Definition: qtransform.h:249
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
The QVector4D class represents a vector or vertex in 4D space.
Definition: qvector4d.h:60
#define SLOT(a)
Definition: qobjectdefs.h:226
virtual ~QGLShaderProgram()
Deletes this shader program.
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
qreal height() const
Returns the height.
Definition: qsize.h:287
qreal m22() const
Returns the vertical scaling factor.
Definition: qtransform.h:253
#define setUniformMatrixArray(func, location, values, count, type, cols, rows)
#define glBindAttribLocation
#define GL_VERTEX_SHADER
#define glVertexAttribPointer
Definition: glfunctions.h:71
#define setUniformMatrix(func, location, value, cols, rows)
#define glVertexAttrib3fv
#define glVertexAttrib2fv
int uniformLocation(const char *name) const
Returns the location of the uniform variable name within this shader program&#39;s parameter list...
QString log() const
Returns the errors and warnings that occurred during the last link() or addShader() with explicitly s...
bool isCompiled() const
Returns true if this shader has been compiled; false otherwise.
#define glEnableVertexAttribArray
QGLShader::ShaderType shaderType() const
Returns the type of this shader.
The QString class provides a Unicode character string.
Definition: qstring.h:83
T * qobject_cast(QObject *object)
Definition: qobject.h:375
GLuint shaderId() const
Returns the OpenGL identifier associated with this shader.
#define glVertexAttrib1fv
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_D(Class)
Definition: qglobal.h:2482
QGLSharedResourceGuard shaderGuard
The QSizeF class defines the size of a two-dimensional object using floating point precision...
Definition: qsize.h:202
#define glUniformMatrix3x2fv
void append(const T &t)
QByteArray sourceCode() const
Returns the source code for this shader.
#define glGetAttribLocation
#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT
bool qt_resolve_glsl_extensions(QGLContext *ctx)
static const char qualifierDefines[]
#define glVertexAttrib4fv
qreal x() const
Returns the x-coordinate of this point.
Definition: qpoint.h:282
static const QGLContext * currentContext()
Returns the current context, i.e.
Definition: qgl.cpp:3545
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
Definition: qobject.cpp:2327
#define glShaderSource
bool addShaderFromSourceCode(QGLShader::ShaderType type, const char *source)
Compiles source as a shader of the specified type and adds it to this shader program.
static bool areSharing(const QGLContext *context1, const QGLContext *context2)
Returns true if context1 and context2 are sharing their GL resources such as textures, shader programs, etc; otherwise returns false.
Definition: qgl.cpp:3319
void setAttributeBuffer(int location, GLenum type, int offset, int tupleSize, int stride=0)
Sets an array of vertex values on the attribute at location in this shader program, starting at a specific offset in the currently bound vertex buffer.
void setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize)
Sets the uniform variable array at location in the current context to the count elements of values...
#define SIGNAL(a)
Definition: qobjectdefs.h:227
qreal m12() const
Returns the vertical shearing factor.
Definition: qtransform.h:241
#define glUniformMatrix3fv
#define glLinkProgram
#define GL_FALSE
QGLShaderPrivate(const QGLContext *context, QGLShader::ShaderType type)
int width() const
Returns the width.
Definition: qsize.h:126
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void destroyed(QObject *=0)
This signal is emitted immediately before the object obj is destroyed, and can not be blocked...
void setGeometryOutputVertexCount(int count)
Sets the maximum number of vertices the current geometry shader program will produce, if active, to count.
int attributeLocation(const char *name) const
Returns the location of the attribute name within this shader program&#39;s parameter list...
The QGLContext class encapsulates an OpenGL rendering context.
Definition: qgl.h:310
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
QGLShaderProgram(QObject *parent=0)
Constructs a new shader program and attaches it to parent.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
#define glUniformMatrix2x3fv
QList< QGLShader * > shaders
const char * name
The QGLShader class allows OpenGL shaders to be compiled.
bool hasShader(QGLShader::ShaderType type) const
#define GL_SHADER_SOURCE_LENGTH
Q_CORE_EXPORT void qWarning(const char *,...)
void removeShader(QGLShader *shader)
Removes shader from this shader program.
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition: qmatrix4x4.h:63
The QVector2D class represents a vector or vertex in 2D space.
Definition: qvector2d.h:60
#define glAttachShader
#define GL_FLOAT
void release()
Releases the active shader program from the current QGLContext.
#define GL_INFO_LOG_LENGTH
#define glGetShaderInfoLog
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
#define setUniformGenericMatrixArray(func, colfunc, location, values, count, type, cols, rows)
quint16 values[128]
#define glUniformMatrix2x4fv
QGLShader::ShaderType shaderType
#define GL_FRAGMENT_SHADER
#define glUniformMatrix4x2fv
#define glUniform4fv
#define glGetProgramiv
#define setUniformGenericMatrix(func, colfunc, location, value, cols, rows)
#define GL_EXTENSIONS
qreal m31() const
Returns the horizontal translation factor.
Definition: qtransform.h:261
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
virtual bool link()
Links together the shaders that were added to this program with addShader().
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
Disconnects signal in object sender from method in object receiver.
Definition: qobject.cpp:2895
static bool hasOpenGLShaders(ShaderType type, const QGLContext *context=0)
Returns true if shader programs of type type are supported on this system; false otherwise.
uint qstrlen(const char *str)
Definition: qbytearray.h:79
void setId(GLuint id)
Definition: qgl_p.h:885
QString log() const
Returns the errors and warnings that occurred during the last compile.
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
#define glUniform1i
#define glUniformMatrix3x4fv
void setUniformValue(int location, GLfloat value)
Sets the uniform variable at location in the current context to value.
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
unsigned int GLenum
Definition: main.cpp:50
GLenum geometryOutputType() const
Returns the geometry shader output type, if active.
static const struct @32 types[]
#define glDetachShader
QGLShader(QGLShader::ShaderType type, QObject *parent=0)
Constructs a new QGLShader object of the specified type and attaches it to parent.
#define glDisableVertexAttribArray
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
#define glUniformMatrix4fv
#define glProgramParameteriEXT
qreal redF() const
Returns the red color component of this color.
Definition: qcolor.cpp:1213
#define GL_GEOMETRY_OUTPUT_TYPE_EXT
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
QGLShaderProgramPrivate(const QGLContext *context)
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
#define glCreateShader
QGLSharedResourceGuard programGuard
qreal m23() const
Returns the vertical projection factor.
Definition: qtransform.h:257
#define glDeleteProgram
int qstrncmp(const char *str1, const char *str2, uint len)
Definition: qbytearray.h:101
QString objectName() const
int height() const
Returns the height.
Definition: qsize.h:129
qreal blueF() const
Returns the blue color component of this color.
Definition: qcolor.cpp:1269
QByteArray readAll()
Reads all available data from the device, and returns it as a QByteArray.
Definition: qiodevice.cpp:1025
#define glGetUniformLocation
void setAttributeValue(int location, GLfloat value)
Sets the attribute at location in the current context to value.
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
bool addShader(QGLShader *shader)
Adds a compiled shader to this shader program.
qreal y() const
Returns the y-coordinate of this point.
Definition: qpoint.h:287
#define glGetShaderiv
#define GL_LINK_STATUS
QObject * parent
Definition: qobject.h:92
typedef GLint
Definition: glfunctions.h:67
#define GL_GEOMETRY_SHADER_EXT
#define GL_GEOMETRY_VERTICES_OUT_EXT
bool addShaderFromSourceFile(QGLShader::ShaderType type, const QString &fileName)
Compiles the contents of fileName as a shader of the specified type and adds it to this shader progra...
#define glCompileShader
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
void setGeometryInputType(GLenum inputType)
Sets the input type from inputType.
bool compileSourceFile(const QString &fileName)
Sets the source code for this shader to the contents of fileName and compiles it. ...
qreal m13() const
Returns the horizontal projection factor.
Definition: qtransform.h:245
bool bind()
Binds this shader program to the active QGLContext and makes it the current shader program...
QList< QGLShader * > shaders() const
Returns a list of all shaders that have been added to this shader program using addShader().
#define glUniformMatrix4x3fv
#define glUniformMatrix2fv
int geometryOutputVertexCount() const
Returns the maximum number of vertices the current geometry shader program will produce, if active.
#define qPrintable(string)
Definition: qglobal.h:1750
void enableAttributeArray(int location)
Enables the vertex array at location in this shader program so that the value set by setAttributeArra...
The QGLShaderProgram class allows OpenGL shader programs to be linked and used.
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
static QString fileName(const QString &fileUrl)
static bool hasOpenGLShaderPrograms(const QGLContext *context=0)
Returns true if shader programs written in the OpenGL Shading Language (GLSL) are supported on this s...
virtual ~QGLShader()
Deletes this shader.
bool isLinked() const
Returns true if this shader program has been linked; false otherwise.
QList< QGLShader * > anonShaders
#define glUniform1fv
qreal m11() const
Returns the horizontal scaling factor.
Definition: qtransform.h:237
qreal m33() const
Returns the division factor.
Definition: qtransform.h:269
#define glGetProgramInfoLog
int size() const
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:65
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
#define glDeleteShader