6#include "private/qopenglcontext_p.h"
7#include <QtOpenGL/QOpenGLVersionFunctionsFactory>
8#include <QtCore/private/qobject_p.h>
9#include <QtCore/qdebug.h>
10#include <QtCore/qfile.h>
11#include <QtCore/qlist.h>
12#include <QtCore/qloggingcategory.h>
13#include <QtCore/qvarlengtharray.h>
14#include <QtGui/private/qopenglprogrambinarycache_p.h>
15#include <QtGui/qtransform.h>
16#include <QtGui/QColor>
17#include <QtGui/QSurfaceFormat>
19#if !QT_CONFIG(opengles2)
20#include <QtOpenGL/qopenglfunctions_4_0_core.h>
28using namespace Qt::StringLiterals;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
153
154
155
156
157
158
159
160
161
162
163
164
165
166
169#ifndef GL_GEOMETRY_SHADER
170#define GL_GEOMETRY_SHADER 0x8DD9
172#ifndef GL_TESS_CONTROL_SHADER
173#define GL_TESS_CONTROL_SHADER 0x8E88
175#ifndef GL_TESS_EVALUATION_SHADER
176#define GL_TESS_EVALUATION_SHADER 0x8E87
178#ifndef GL_COMPUTE_SHADER
179#define GL_COMPUTE_SHADER 0x91B9
181#ifndef GL_MAX_GEOMETRY_OUTPUT_VERTICES
182#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
184#ifndef GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS
185#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
187#ifndef GL_PATCH_VERTICES
188#define GL_PATCH_VERTICES 0x8E72
190#ifndef GL_PATCH_DEFAULT_OUTER_LEVEL
191#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74
193#ifndef GL_PATCH_DEFAULT_INNER_LEVEL
194#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
197#if !QT_CONFIG(opengles2)
198static inline bool isFormatGLES(
const QSurfaceFormat &f)
200 return (f.renderableType() == QSurfaceFormat::OpenGLES);
206 return f.version() >= std::pair(3, 2);
211#if !QT_CONFIG(opengles2)
212 if (!isFormatGLES(f))
213 return f.version() >= std::pair(4, 3);
215 return f.version() >= std::pair(3, 1);
217 return f.version() >= std::pair(3, 1);
223#if !QT_CONFIG(opengles2)
224 if (!isFormatGLES(f))
225 return f.version() >= std::pair(4, 0);
227 return f.version() >= std::pair(3, 2);
229 return f.version() >= std::pair(3, 2);
235 Q_DECLARE_PUBLIC(QOpenGLShader)
276 void freeShaderFunc(QOpenGLFunctions *funcs, GLuint id)
278 funcs->glDeleteShader(id);
291 QOpenGLContext *context =
const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
295 if (shaderType == QOpenGLShader::Vertex) {
296 shader = glfuncs->glCreateShader(GL_VERTEX_SHADER);
297 }
else if (shaderType == QOpenGLShader::Geometry && supportsGeometryShaders) {
299 }
else if (shaderType == QOpenGLShader::TessellationControl && supportsTessellationShaders) {
301 }
else if (shaderType == QOpenGLShader::TessellationEvaluation && supportsTessellationShaders) {
303 }
else if (shaderType == QOpenGLShader::Compute && supportsComputeShaders) {
305 }
else if (shaderType == QOpenGLShader::Fragment) {
306 shader = glfuncs->glCreateShader(GL_FRAGMENT_SHADER);
309 qWarning(
"QOpenGLShader: could not create shader");
312 shaderGuard =
new QOpenGLSharedResourceGuard(context, shader, freeShaderFunc);
318 GLuint shader = shaderGuard ? shaderGuard->id() : 0;
323 glfuncs->glCompileShader(shader);
327 glfuncs->glGetShaderiv(shader, GL_COMPILE_STATUS, &value);
328 compiled = (value != 0);
332 QString name = q->objectName();
334 const char *types[] = {
338 "Tessellation Control",
339 "Tessellation Evaluation",
344 const char *type = types[6];
345 switch (shaderType) {
346 case QOpenGLShader::Fragment:
347 type = types[0];
break;
348 case QOpenGLShader::Vertex:
349 type = types[1];
break;
350 case QOpenGLShader::Geometry:
351 type = types[2];
break;
352 case QOpenGLShader::TessellationControl:
353 type = types[3];
break;
354 case QOpenGLShader::TessellationEvaluation:
355 type = types[4];
break;
356 case QOpenGLShader::Compute:
357 type = types[5];
break;
361 GLint infoLogLength = 0;
362 GLint sourceCodeLength = 0;
363 char *logBuffer =
nullptr;
364 char *sourceCodeBuffer =
nullptr;
367 glfuncs->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
369 if (infoLogLength > 1) {
371 logBuffer =
new char [infoLogLength];
372 glfuncs->glGetShaderInfoLog(shader, infoLogLength, &temp, logBuffer);
376 glfuncs->glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceCodeLength);
378 if (sourceCodeLength > 1) {
380 sourceCodeBuffer =
new char [sourceCodeLength];
381 glfuncs->glGetShaderSource(shader, sourceCodeLength, &temp, sourceCodeBuffer);
385 log = QString::fromLatin1(logBuffer);
390 qWarning(
"QOpenGLShader::compile(%s): %s", type, qPrintable(log));
392 qWarning(
"QOpenGLShader::compile(%s)[%s]: %s", type, qPrintable(name), qPrintable(log));
395 if (sourceCodeBuffer) {
396 qWarning(
"*** Problematic %s shader source code ***\n"
399 type, qUtf16Printable(QString::fromLatin1(sourceCodeBuffer)));
404 delete [] sourceCodeBuffer;
414 shaderGuard =
nullptr;
419
420
421
422
423
424
425
426
427
428
429
430QOpenGLShader::QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent)
431 : QObject(*
new QOpenGLShaderPrivate(QOpenGLContext::currentContext(), type), parent)
438
439
440
441
442QOpenGLShader::~QOpenGLShader()
447
448
449QOpenGLShader::ShaderType QOpenGLShader::shaderType()
const
451 Q_D(
const QOpenGLShader);
452 return d->shaderType;
460#if QT_CONFIG(opengles2) && !defined(QT_OPENGL_FORCE_SHADER_DEFINES)
463#define QOpenGL_REDEFINE_HIGHP 1
464static const char redefineHighp[] =
465 "#ifndef GL_FRAGMENT_PRECISION_HIGH\n"
466 "#define highp mediump\n"
472 "#ifdef GL_KHR_blend_equation_advanced\n"
473 "#extension GL_ARB_fragment_coord_conventions : enable\n"
474 "#extension GL_KHR_blend_equation_advanced : enable\n"
506 PreprocessorDirective,
511 } state = StartOfLine;
513 const char *c = source;
516 case PreprocessorDirective:
517 if (*c ==
' ' || *c ==
'\t')
519 if (!strncmp(c,
"version", strlen(
"version"))) {
521 c += strlen(
"version");
522 while (*c && *c !=
'\n')
524 int splitPosition = c - source + 1;
525 int linePosition =
int(
std::count(source, c,
'\n')) + 1;
527 }
else if (*c ==
'/')
528 state = CommentStarting;
535 if (*c ==
' ' || *c ==
'\t')
537 else if (*c ==
'#') {
538 state = PreprocessorDirective;
545 state = CommentStarting;
549 case CommentStarting:
551 state = MultiLineComment;
553 state = SingleLineComment;
557 case MultiLineComment:
559 state = CommentEnding;
561 case SingleLineComment:
569 state = MultiLineComment;
579
580
581
582
583
584bool QOpenGLShader::compileSourceCode(
const char *source)
595 if (d->shaderGuard && d->shaderGuard->id() && source) {
596 const QVersionDirectivePosition versionDirectivePosition = findVersionDirectivePosition(source);
598 QVarLengthArray<
const char *, 5> sourceChunks;
599 QVarLengthArray<GLint, 5> sourceChunkLengths;
600 QOpenGLContext *ctx = QOpenGLContext::currentContext();
602 if (versionDirectivePosition.hasPosition()) {
604 sourceChunks.append(source);
605 sourceChunkLengths.append(GLint(versionDirectivePosition.position));
608 if (ctx->format().profile() == QSurfaceFormat::CompatibilityProfile) {
609 const char *vendor =
reinterpret_cast<
const char *>(ctx->functions()->glGetString(GL_VENDOR));
610 if (vendor && !strcmp(vendor,
"Intel")) {
611 static const char version110[] =
"#version 110\n";
612 sourceChunks.append(version110);
613 sourceChunkLengths.append(GLint(
sizeof(version110)) - 1);
617 if (d->shaderType == Fragment) {
618 sourceChunks.append(blendEquationAdvancedHeader);
619 sourceChunkLengths.append(GLint(
sizeof(blendEquationAdvancedHeader) - 1));
624 const QSurfaceFormat currentSurfaceFormat = ctx->format();
625 QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(QOpenGLContext::currentContext());
626 if (currentSurfaceFormat.renderableType() == QSurfaceFormat::OpenGL
627 || ctx_d->workaround_missingPrecisionQualifiers
628#ifdef QT_OPENGL_FORCE_SHADER_DEFINES
632 sourceChunks.append(qualifierDefines);
633 sourceChunkLengths.append(GLint(
sizeof(qualifierDefines) - 1));
636#ifdef QOpenGL_REDEFINE_HIGHP
637 if (d->shaderType == Fragment && !ctx_d->workaround_missingPrecisionQualifiers
638 && QOpenGLContext::currentContext()->isOpenGLES()) {
639 sourceChunks.append(redefineHighp);
640 sourceChunkLengths.append(GLint(
sizeof(redefineHighp) - 1));
644 QByteArray lineDirective;
647 const char *version =
reinterpret_cast<
const char *>(ctx->functions()->glGetString(GL_VERSION));
648 if (!version || !strstr(version,
"2.1 Mesa 8")) {
650 lineDirective = QStringLiteral(
"#line %1\n").arg(versionDirectivePosition.line).toUtf8();
651 sourceChunks.append(lineDirective.constData());
652 sourceChunkLengths.append(GLint(lineDirective.size()));
656 sourceChunks.append(source + versionDirectivePosition.position);
657 sourceChunkLengths.append(GLint(qstrlen(source + versionDirectivePosition.position)));
659 d->glfuncs->glShaderSource(d->shaderGuard->id(), sourceChunks.size(), sourceChunks.data(), sourceChunkLengths.data());
660 return d->compile(
this);
667
668
669
670
671
672
673
674bool QOpenGLShader::compileSourceCode(
const QByteArray& source)
676 return compileSourceCode(source.constData());
680
681
682
683
684
685
686
687bool QOpenGLShader::compileSourceCode(
const QString& source)
689 return compileSourceCode(source.toLatin1().constData());
693
694
695
696
697
698
699bool QOpenGLShader::compileSourceFile(
const QString& fileName)
701 QFile file(fileName);
702 if (!file.open(QFile::ReadOnly)) {
703 qWarning() <<
"QOpenGLShader: Unable to open file" << fileName;
707 QByteArray contents = file.readAll();
708 return compileSourceCode(contents.constData());
712
713
714
715
716QByteArray QOpenGLShader::sourceCode()
const
718 Q_D(
const QOpenGLShader);
719 GLuint shader = d->shaderGuard ? d->shaderGuard->id() : 0;
723 d->glfuncs->glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &size);
727 char *source =
new char [size];
728 d->glfuncs->glGetShaderSource(shader, size, &len, source);
729 QByteArray src(source);
735
736
737
738
739bool QOpenGLShader::isCompiled()
const
741 Q_D(
const QOpenGLShader);
746
747
748
749
750QString QOpenGLShader::log()
const
752 Q_D(
const QOpenGLShader);
757
758
759
760
761GLuint QOpenGLShader::shaderId()
const
763 Q_D(
const QOpenGLShader);
764 return d->shaderGuard ? d->shaderGuard->id() : 0;
769 Q_DECLARE_PUBLIC(QOpenGLShaderProgram)
777#if !QT_CONFIG(opengles2)
795#if !QT_CONFIG(opengles2)
811 void freeProgramFunc(QOpenGLFunctions *funcs, GLuint id)
813 funcs->glDeleteProgram(id);
822 programGuard->free();
827 for (QOpenGLShader *shader : shaders) {
828 if (shader->shaderType() == type)
835
836
837
838
839
840
841
842QOpenGLShaderProgram::QOpenGLShaderProgram(QObject *parent)
843 : QObject(*
new QOpenGLShaderProgramPrivate, parent)
848
849
850QOpenGLShaderProgram::~QOpenGLShaderProgram()
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869bool QOpenGLShaderProgram::create()
874bool QOpenGLShaderProgram::init()
876 Q_D(QOpenGLShaderProgram);
877 if ((d->programGuard && d->programGuard->id()) || d->inited)
880 QOpenGLContext *context =
const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
883 d->glfuncs->initializeOpenGLFunctions();
885#if !QT_CONFIG(opengles2)
886 if (!context->isOpenGLES() && context->format().version() >= std::pair(4, 0)) {
887 d->tessellationFuncs = QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_4_0_Core>(context);
888 d->tessellationFuncs->initializeOpenGLFunctions();
892 GLuint program = d->glfuncs->glCreateProgram();
894 qWarning(
"QOpenGLShaderProgram: could not create shader program");
898 delete d->programGuard;
899 d->programGuard =
new QOpenGLSharedResourceGuard(context, program, freeProgramFunc);
904
905
906
907
908
909
910
911
912
913
914
915bool QOpenGLShaderProgram::addShader(QOpenGLShader *shader)
917 Q_D(QOpenGLShaderProgram);
920 if (d->shaders.contains(shader))
922 if (d->programGuard && d->programGuard->id() && shader) {
923 if (!shader->d_func()->shaderGuard || !shader->d_func()->shaderGuard->id())
925 if (d->programGuard->group() != shader->d_func()->shaderGuard->group()) {
926 qWarning(
"QOpenGLShaderProgram::addShader: Program and shader are not associated with same context.");
929 d->glfuncs->glAttachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
931 d->shaders.append(shader);
932 connect(shader, SIGNAL(destroyed()),
this, SLOT(shaderDestroyed()));
940
941
942
943
944
945
946
947
948
949
950
951
952bool QOpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::ShaderType type,
const char *source)
954 Q_D(QOpenGLShaderProgram);
957 QOpenGLShader *shader =
new QOpenGLShader(type,
this);
958 if (!shader->compileSourceCode(source)) {
959 d->log = shader->log();
963 d->anonShaders.append(shader);
964 return addShader(shader);
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982bool QOpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::ShaderType type,
const QByteArray& source)
984 return addShaderFromSourceCode(type, source.constData());
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002bool QOpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::ShaderType type,
const QString& source)
1004 return addShaderFromSourceCode(type, source.toLatin1().constData());
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019bool QOpenGLShaderProgram::addShaderFromSourceFile
1020 (QOpenGLShader::ShaderType type,
const QString& fileName)
1022 Q_D(QOpenGLShaderProgram);
1025 QOpenGLShader *shader =
new QOpenGLShader(type,
this);
1026 if (!shader->compileSourceFile(fileName)) {
1027 d->log = shader->log();
1031 d->anonShaders.append(shader);
1032 return addShader(shader);
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053bool QOpenGLShaderProgram::addCacheableShaderFromSourceCode(QOpenGLShader::ShaderType type,
const char *source)
1055 Q_D(QOpenGLShaderProgram);
1058 if (d->isCacheDisabled())
1059 return addShaderFromSourceCode(type, source);
1061 return addCacheableShaderFromSourceCode(type, QByteArray(source));
1067 case QOpenGLShader::Vertex:
1068 return QShader::VertexStage;
1069 case QOpenGLShader::Fragment:
1070 return QShader::FragmentStage;
1071 case QOpenGLShader::Geometry:
1072 return QShader::GeometryStage;
1073 case QOpenGLShader::TessellationControl:
1074 return QShader::TessellationControlStage;
1075 case QOpenGLShader::TessellationEvaluation:
1076 return QShader::TessellationEvaluationStage;
1077 case QOpenGLShader::Compute:
1078 return QShader::ComputeStage;
1080 return QShader::VertexStage;
1086 case QShader::VertexStage:
1087 return QOpenGLShader::Vertex;
1088 case QShader::TessellationControlStage:
1089 return QOpenGLShader::TessellationControl;
1090 case QShader::TessellationEvaluationStage:
1091 return QOpenGLShader::TessellationEvaluation;
1092 case QShader::GeometryStage:
1093 return QOpenGLShader::Geometry;
1094 case QShader::FragmentStage:
1095 return QOpenGLShader::Fragment;
1096 case QShader::ComputeStage:
1097 return QOpenGLShader::Compute;
1099 return QOpenGLShader::Vertex;
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122bool QOpenGLShaderProgram::addCacheableShaderFromSourceCode(QOpenGLShader::ShaderType type,
const QByteArray &source)
1124 Q_D(QOpenGLShaderProgram);
1127 if (d->isCacheDisabled())
1128 return addShaderFromSourceCode(type, source);
1130 d->binaryProgram.shaders.append(QOpenGLProgramBinaryCache::ShaderDesc(qt_shaderTypeToStage(type), source));
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150bool QOpenGLShaderProgram::addCacheableShaderFromSourceCode(QOpenGLShader::ShaderType type,
const QString &source)
1152 Q_D(QOpenGLShaderProgram);
1155 if (d->isCacheDisabled())
1156 return addShaderFromSourceCode(type, source);
1158 return addCacheableShaderFromSourceCode(type, source.toUtf8().constData());
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179bool QOpenGLShaderProgram::addCacheableShaderFromSourceFile(QOpenGLShader::ShaderType type,
const QString &fileName)
1181 Q_D(QOpenGLShaderProgram);
1184 if (d->isCacheDisabled())
1185 return addShaderFromSourceFile(type, fileName);
1187 QOpenGLProgramBinaryCache::ShaderDesc shader(qt_shaderTypeToStage(type));
1195 if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
1196 shader.source = f.readAll();
1199 qWarning(
"QOpenGLShaderProgram: Unable to open file %s", qPrintable(fileName));
1202 d->binaryProgram.shaders.append(shader);
1207
1208
1209
1210
1211
1212
1213void QOpenGLShaderProgram::removeShader(QOpenGLShader *shader)
1215 Q_D(QOpenGLShaderProgram);
1216 if (d->programGuard && d->programGuard->id()
1217 && shader && shader->d_func()->shaderGuard)
1219 d->glfuncs->glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
1223 d->shaders.removeAll(shader);
1224 d->anonShaders.removeAll(shader);
1225 disconnect(shader, SIGNAL(destroyed()),
this, SLOT(shaderDestroyed()));
1230
1231
1232
1233
1234
1235QList<QOpenGLShader *> QOpenGLShaderProgram::shaders()
const
1237 Q_D(
const QOpenGLShaderProgram);
1242
1243
1244
1245
1246
1247
1248
1249void QOpenGLShaderProgram::removeAllShaders()
1251 Q_D(QOpenGLShaderProgram);
1252 d->removingShaders =
true;
1253 for (QOpenGLShader *shader : std::as_const(d->shaders)) {
1254 if (d->programGuard && d->programGuard->id()
1255 && shader && shader->d_func()->shaderGuard)
1257 d->glfuncs->glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
1261 qDeleteAll(d->anonShaders);
1263 d->anonShaders.clear();
1264 d->binaryProgram = QOpenGLProgramBinaryCache::ProgramDesc();
1266 d->removingShaders =
false;
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293bool QOpenGLShaderProgram::link()
1295 Q_D(QOpenGLShaderProgram);
1296 GLuint program = d->programGuard ? d->programGuard->id() : 0;
1300 if (!d->linkBinaryRecursion && d->shaders.isEmpty() && !d->binaryProgram.shaders.isEmpty())
1301 return d->linkBinary();
1304 if (d->shaders.isEmpty()) {
1312 d->glfuncs->glGetProgramiv(program, GL_LINK_STATUS, &value);
1313 d->linked = (value != 0);
1318 d->glfuncs->glLinkProgram(program);
1320 d->glfuncs->glGetProgramiv(program, GL_LINK_STATUS, &value);
1321 d->linked = (value != 0);
1323 d->glfuncs->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value);
1326 char *logbuf =
new char [value];
1328 d->glfuncs->glGetProgramInfoLog(program, value, &len, logbuf);
1329 d->log = QString::fromLatin1(logbuf);
1330 if (!d->linked && !d->linkBinaryRecursion) {
1331 QString name = objectName();
1333 qWarning(
"QOpenGLShader::link: %ls", qUtf16Printable(d->log));
1335 qWarning(
"QOpenGLShader::link[%ls]: %ls", qUtf16Printable(name), qUtf16Printable(d->log));
1343
1344
1345
1346
1347bool QOpenGLShaderProgram::isLinked()
const
1349 Q_D(
const QOpenGLShaderProgram);
1354
1355
1356
1357
1358
1359QString QOpenGLShaderProgram::log()
const
1361 Q_D(
const QOpenGLShaderProgram);
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375bool QOpenGLShaderProgram::bind()
1377 Q_D(QOpenGLShaderProgram);
1378 GLuint program = d->programGuard ? d->programGuard->id() : 0;
1381 if (!d->linked && !link())
1384 if (d->programGuard->group() != QOpenGLContextGroup::currentContextGroup()) {
1385 qWarning(
"QOpenGLShaderProgram::bind: program is not valid in the current context.");
1389 d->glfuncs->glUseProgram(program);
1394
1395
1396
1397
1398
1399void QOpenGLShaderProgram::release()
1401 Q_D(QOpenGLShaderProgram);
1403 if (d->programGuard && d->programGuard->group() != QOpenGLContextGroup::currentContextGroup())
1404 qWarning(
"QOpenGLShaderProgram::release: program is not valid in the current context.");
1406 d->glfuncs->glUseProgram(0);
1410
1411
1412
1413
1414GLuint QOpenGLShaderProgram::programId()
const
1416 Q_D(
const QOpenGLShaderProgram);
1417 GLuint id = d->programGuard ? d->programGuard->id() : 0;
1424 if (!
const_cast<QOpenGLShaderProgram *>(
this)->init())
1426 return d->programGuard ? d->programGuard->id() : 0;
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440void QOpenGLShaderProgram::bindAttributeLocation(
const char *name,
int location)
1442 Q_D(QOpenGLShaderProgram);
1443 if (!init() || !d->programGuard || !d->programGuard->id())
1445 d->glfuncs->glBindAttribLocation(d->programGuard->id(), location, name);
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462void QOpenGLShaderProgram::bindAttributeLocation(
const QByteArray& name,
int location)
1464 bindAttributeLocation(name.constData(), location);
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480void QOpenGLShaderProgram::bindAttributeLocation(
const QString& name,
int location)
1482 bindAttributeLocation(name.toLatin1().constData(), location);
1486
1487
1488
1489
1490
1491
1492int QOpenGLShaderProgram::attributeLocation(
const char *name)
const
1494 Q_D(
const QOpenGLShaderProgram);
1495 if (d->linked && d->programGuard && d->programGuard->id()) {
1496 return d->glfuncs->glGetAttribLocation(d->programGuard->id(), name);
1498 qWarning(
"QOpenGLShaderProgram::attributeLocation(%s): shader program is not linked", name);
1504
1505
1506
1507
1508
1509
1510
1511
1512int QOpenGLShaderProgram::attributeLocation(
const QByteArray& name)
const
1514 return attributeLocation(name.constData());
1518
1519
1520
1521
1522
1523
1524
1525
1526int QOpenGLShaderProgram::attributeLocation(
const QString& name)
const
1528 return attributeLocation(name.toLatin1().constData());
1532
1533
1534
1535
1536void QOpenGLShaderProgram::setAttributeValue(
int location, GLfloat value)
1538 Q_D(QOpenGLShaderProgram);
1540 d->glfuncs->glVertexAttrib1fv(location, &value);
1544
1545
1546
1547
1548
1549
1550void QOpenGLShaderProgram::setAttributeValue(
const char *name, GLfloat value)
1552 setAttributeValue(attributeLocation(name), value);
1556
1557
1558
1559
1560
1561void QOpenGLShaderProgram::setAttributeValue(
int location, GLfloat x, GLfloat y)
1563 Q_D(QOpenGLShaderProgram);
1564 if (location != -1) {
1565 GLfloat values[2] = {x, y};
1566 d->glfuncs->glVertexAttrib2fv(location, values);
1571
1572
1573
1574
1575
1576
1577
1578void QOpenGLShaderProgram::setAttributeValue(
const char *name, GLfloat x, GLfloat y)
1580 setAttributeValue(attributeLocation(name), x, y);
1584
1585
1586
1587
1588
1589void QOpenGLShaderProgram::setAttributeValue
1590 (
int location, GLfloat x, GLfloat y, GLfloat z)
1592 Q_D(QOpenGLShaderProgram);
1594 if (location != -1) {
1595 GLfloat values[3] = {x, y, z};
1596 d->glfuncs->glVertexAttrib3fv(location, values);
1601
1602
1603
1604
1605
1606
1607
1608void QOpenGLShaderProgram::setAttributeValue
1609 (
const char *name, GLfloat x, GLfloat y, GLfloat z)
1611 setAttributeValue(attributeLocation(name), x, y, z);
1615
1616
1617
1618
1619
1620void QOpenGLShaderProgram::setAttributeValue
1621 (
int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1623 Q_D(QOpenGLShaderProgram);
1624 if (location != -1) {
1625 GLfloat values[4] = {x, y, z, w};
1626 d->glfuncs->glVertexAttrib4fv(location, values);
1631
1632
1633
1634
1635
1636
1637
1638void QOpenGLShaderProgram::setAttributeValue
1639 (
const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1641 setAttributeValue(attributeLocation(name), x, y, z, w);
1645
1646
1647
1648
1649void QOpenGLShaderProgram::setAttributeValue(
int location,
const QVector2D& value)
1651 Q_D(QOpenGLShaderProgram);
1653 d->glfuncs->glVertexAttrib2fv(location,
reinterpret_cast<
const GLfloat *>(&value));
1657
1658
1659
1660
1661
1662
1663void QOpenGLShaderProgram::setAttributeValue(
const char *name,
const QVector2D& value)
1665 setAttributeValue(attributeLocation(name), value);
1669
1670
1671
1672
1673void QOpenGLShaderProgram::setAttributeValue(
int location,
const QVector3D& value)
1675 Q_D(QOpenGLShaderProgram);
1678 d->glfuncs->glVertexAttrib3fv(location,
reinterpret_cast<
const GLfloat *>(&value));
1682
1683
1684
1685
1686
1687
1688void QOpenGLShaderProgram::setAttributeValue(
const char *name,
const QVector3D& value)
1690 setAttributeValue(attributeLocation(name), value);
1694
1695
1696
1697
1698void QOpenGLShaderProgram::setAttributeValue(
int location,
const QVector4D& value)
1700 Q_D(QOpenGLShaderProgram);
1703 d->glfuncs->glVertexAttrib4fv(location,
reinterpret_cast<
const GLfloat *>(&value));
1707
1708
1709
1710
1711
1712
1713void QOpenGLShaderProgram::setAttributeValue(
const char *name,
const QVector4D& value)
1715 setAttributeValue(attributeLocation(name), value);
1719
1720
1721
1722
1723void QOpenGLShaderProgram::setAttributeValue(
int location,
const QColor& value)
1725 Q_D(QOpenGLShaderProgram);
1727 if (location != -1) {
1728 GLfloat values[4] = {GLfloat(value.redF()), GLfloat(value.greenF()),
1729 GLfloat(value.blueF()), GLfloat(value.alphaF())};
1730 d->glfuncs->glVertexAttrib4fv(location, values);
1735
1736
1737
1738
1739
1740
1741void QOpenGLShaderProgram::setAttributeValue(
const char *name,
const QColor& value)
1743 setAttributeValue(attributeLocation(name), value);
1747
1748
1749
1750
1751
1752
1753
1754
1755void QOpenGLShaderProgram::setAttributeValue
1756 (
int location,
const GLfloat *values,
int columns,
int rows)
1758 Q_D(QOpenGLShaderProgram);
1760 if (rows < 1 || rows > 4) {
1761 qWarning(
"QOpenGLShaderProgram::setAttributeValue: rows %d not supported", rows);
1764 if (location != -1) {
1765 while (columns-- > 0) {
1767 d->glfuncs->glVertexAttrib1fv(location, values);
1769 d->glfuncs->glVertexAttrib2fv(location, values);
1771 d->glfuncs->glVertexAttrib3fv(location, values);
1773 d->glfuncs->glVertexAttrib4fv(location, values);
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791void QOpenGLShaderProgram::setAttributeValue
1792 (
const char *name,
const GLfloat *values,
int columns,
int rows)
1794 setAttributeValue(attributeLocation(name), values, columns, rows);
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811void QOpenGLShaderProgram::setAttributeArray
1812 (
int location,
const GLfloat *values,
int tupleSize,
int stride)
1814 Q_D(QOpenGLShaderProgram);
1816 if (location != -1) {
1817 d->glfuncs->glVertexAttribPointer(location, tupleSize, GL_FLOAT, GL_FALSE,
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835void QOpenGLShaderProgram::setAttributeArray
1836 (
int location,
const QVector2D *values,
int stride)
1838 Q_D(QOpenGLShaderProgram);
1840 if (location != -1) {
1841 d->glfuncs->glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE,
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859void QOpenGLShaderProgram::setAttributeArray
1860 (
int location,
const QVector3D *values,
int stride)
1862 Q_D(QOpenGLShaderProgram);
1864 if (location != -1) {
1865 d->glfuncs->glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE,
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883void QOpenGLShaderProgram::setAttributeArray
1884 (
int location,
const QVector4D *values,
int stride)
1886 Q_D(QOpenGLShaderProgram);
1888 if (location != -1) {
1889 d->glfuncs->glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE,
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917void QOpenGLShaderProgram::setAttributeArray
1918 (
int location, GLenum type,
const void *values,
int tupleSize,
int stride)
1920 Q_D(QOpenGLShaderProgram);
1922 if (location != -1) {
1923 d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE,
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944void QOpenGLShaderProgram::setAttributeArray
1945 (
const char *name,
const GLfloat *values,
int tupleSize,
int stride)
1947 setAttributeArray(attributeLocation(name), values, tupleSize, stride);
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965void QOpenGLShaderProgram::setAttributeArray
1966 (
const char *name,
const QVector2D *values,
int stride)
1968 setAttributeArray(attributeLocation(name), values, stride);
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986void QOpenGLShaderProgram::setAttributeArray
1987 (
const char *name,
const QVector3D *values,
int stride)
1989 setAttributeArray(attributeLocation(name), values, stride);
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007void QOpenGLShaderProgram::setAttributeArray
2008 (
const char *name,
const QVector4D *values,
int stride)
2010 setAttributeArray(attributeLocation(name), values, stride);
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035void QOpenGLShaderProgram::setAttributeArray
2036 (
const char *name, GLenum type,
const void *values,
int tupleSize,
int stride)
2038 setAttributeArray(attributeLocation(name), type, values, tupleSize, stride);
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062void QOpenGLShaderProgram::setAttributeBuffer
2063 (
int location, GLenum type,
int offset,
int tupleSize,
int stride)
2065 Q_D(QOpenGLShaderProgram);
2067 if (location != -1) {
2068 d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride,
2069 reinterpret_cast<
const void *>(qintptr(offset)));
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093void QOpenGLShaderProgram::setAttributeBuffer
2094 (
const char *name, GLenum type,
int offset,
int tupleSize,
int stride)
2096 setAttributeBuffer(attributeLocation(name), type, offset, tupleSize, stride);
2100
2101
2102
2103
2104
2105
2106
2107void QOpenGLShaderProgram::enableAttributeArray(
int location)
2109 Q_D(QOpenGLShaderProgram);
2112 d->glfuncs->glEnableVertexAttribArray(location);
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125void QOpenGLShaderProgram::enableAttributeArray(
const char *name)
2127 enableAttributeArray(attributeLocation(name));
2131
2132
2133
2134
2135
2136
2137void QOpenGLShaderProgram::disableAttributeArray(
int location)
2139 Q_D(QOpenGLShaderProgram);
2142 d->glfuncs->glDisableVertexAttribArray(location);
2146
2147
2148
2149
2150
2151
2152
2153
2154void QOpenGLShaderProgram::disableAttributeArray(
const char *name)
2156 disableAttributeArray(attributeLocation(name));
2160
2161
2162
2163
2164
2165
2166int QOpenGLShaderProgram::uniformLocation(
const char *name)
const
2168 Q_D(
const QOpenGLShaderProgram);
2170 if (d->linked && d->programGuard && d->programGuard->id()) {
2171 return d->glfuncs->glGetUniformLocation(d->programGuard->id(), name);
2173 qWarning(
"QOpenGLShaderProgram::uniformLocation(%s): shader program is not linked", name);
2179
2180
2181
2182
2183
2184
2185
2186
2187int QOpenGLShaderProgram::uniformLocation(
const QByteArray& name)
const
2189 return uniformLocation(name.constData());
2193
2194
2195
2196
2197
2198
2199
2200
2201int QOpenGLShaderProgram::uniformLocation(
const QString& name)
const
2203 return uniformLocation(name.toLatin1().constData());
2207
2208
2209
2210
2211void QOpenGLShaderProgram::setUniformValue(
int location, GLfloat value)
2213 Q_D(QOpenGLShaderProgram);
2216 d->glfuncs->glUniform1fv(location, 1, &value);
2220
2221
2222
2223
2224
2225
2226
2227void QOpenGLShaderProgram::setUniformValue(
const char *name, GLfloat value)
2229 setUniformValue(uniformLocation(name), value);
2233
2234
2235
2236
2237void QOpenGLShaderProgram::setUniformValue(
int location, GLint value)
2239 Q_D(QOpenGLShaderProgram);
2242 d->glfuncs->glUniform1i(location, value);
2246
2247
2248
2249
2250
2251
2252
2253void QOpenGLShaderProgram::setUniformValue(
const char *name, GLint value)
2255 setUniformValue(uniformLocation(name), value);
2259
2260
2261
2262
2263
2264
2265
2266
2267void QOpenGLShaderProgram::setUniformValue(
int location, GLuint value)
2269 Q_D(QOpenGLShaderProgram);
2272 d->glfuncs->glUniform1i(location, value);
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286void QOpenGLShaderProgram::setUniformValue(
const char *name, GLuint value)
2288 setUniformValue(uniformLocation(name), value);
2292
2293
2294
2295
2296
2297void QOpenGLShaderProgram::setUniformValue(
int location, GLfloat x, GLfloat y)
2299 Q_D(QOpenGLShaderProgram);
2301 if (location != -1) {
2302 GLfloat values[2] = {x, y};
2303 d->glfuncs->glUniform2fv(location, 1, values);
2308
2309
2310
2311
2312
2313
2314
2315void QOpenGLShaderProgram::setUniformValue(
const char *name, GLfloat x, GLfloat y)
2317 setUniformValue(uniformLocation(name), x, y);
2321
2322
2323
2324
2325
2326void QOpenGLShaderProgram::setUniformValue
2327 (
int location, GLfloat x, GLfloat y, GLfloat z)
2329 Q_D(QOpenGLShaderProgram);
2331 if (location != -1) {
2332 GLfloat values[3] = {x, y, z};
2333 d->glfuncs->glUniform3fv(location, 1, values);
2338
2339
2340
2341
2342
2343
2344
2345void QOpenGLShaderProgram::setUniformValue
2346 (
const char *name, GLfloat x, GLfloat y, GLfloat z)
2348 setUniformValue(uniformLocation(name), x, y, z);
2352
2353
2354
2355
2356
2357void QOpenGLShaderProgram::setUniformValue
2358 (
int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2360 Q_D(QOpenGLShaderProgram);
2362 if (location != -1) {
2363 GLfloat values[4] = {x, y, z, w};
2364 d->glfuncs->glUniform4fv(location, 1, values);
2369
2370
2371
2372
2373
2374
2375
2376void QOpenGLShaderProgram::setUniformValue
2377 (
const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2379 setUniformValue(uniformLocation(name), x, y, z, w);
2383
2384
2385
2386
2387void QOpenGLShaderProgram::setUniformValue(
int location,
const QVector2D& value)
2389 Q_D(QOpenGLShaderProgram);
2392 d->glfuncs->glUniform2fv(location, 1,
reinterpret_cast<
const GLfloat *>(&value));
2396
2397
2398
2399
2400
2401
2402
2403void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QVector2D& value)
2405 setUniformValue(uniformLocation(name), value);
2409
2410
2411
2412
2413void QOpenGLShaderProgram::setUniformValue(
int location,
const QVector3D& value)
2415 Q_D(QOpenGLShaderProgram);
2418 d->glfuncs->glUniform3fv(location, 1,
reinterpret_cast<
const GLfloat *>(&value));
2422
2423
2424
2425
2426
2427
2428
2429void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QVector3D& value)
2431 setUniformValue(uniformLocation(name), value);
2435
2436
2437
2438
2439void QOpenGLShaderProgram::setUniformValue(
int location,
const QVector4D& value)
2441 Q_D(QOpenGLShaderProgram);
2444 d->glfuncs->glUniform4fv(location, 1,
reinterpret_cast<
const GLfloat *>(&value));
2448
2449
2450
2451
2452
2453
2454
2455void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QVector4D& value)
2457 setUniformValue(uniformLocation(name), value);
2461
2462
2463
2464
2465
2466void QOpenGLShaderProgram::setUniformValue(
int location,
const QColor& color)
2468 Q_D(QOpenGLShaderProgram);
2470 if (location != -1) {
2471 GLfloat values[4] = {GLfloat(color.redF()), GLfloat(color.greenF()),
2472 GLfloat(color.blueF()), GLfloat(color.alphaF())};
2473 d->glfuncs->glUniform4fv(location, 1, values);
2478
2479
2480
2481
2482
2483
2484
2485void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QColor& color)
2487 setUniformValue(uniformLocation(name), color);
2491
2492
2493
2494
2495
2496void QOpenGLShaderProgram::setUniformValue(
int location,
const QPoint& point)
2498 Q_D(QOpenGLShaderProgram);
2500 if (location != -1) {
2501 GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())};
2502 d->glfuncs->glUniform2fv(location, 1, values);
2507
2508
2509
2510
2511
2512
2513
2514void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QPoint& point)
2516 setUniformValue(uniformLocation(name), point);
2520
2521
2522
2523
2524
2525void QOpenGLShaderProgram::setUniformValue(
int location,
const QPointF& point)
2527 Q_D(QOpenGLShaderProgram);
2529 if (location != -1) {
2530 GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())};
2531 d->glfuncs->glUniform2fv(location, 1, values);
2536
2537
2538
2539
2540
2541
2542
2543void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QPointF& point)
2545 setUniformValue(uniformLocation(name), point);
2549
2550
2551
2552
2553
2554void QOpenGLShaderProgram::setUniformValue(
int location,
const QSize& size)
2556 Q_D(QOpenGLShaderProgram);
2558 if (location != -1) {
2559 GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())};
2560 d->glfuncs->glUniform2fv(location, 1, values);
2565
2566
2567
2568
2569
2570
2571
2572void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QSize& size)
2574 setUniformValue(uniformLocation(name), size);
2578
2579
2580
2581
2582
2583void QOpenGLShaderProgram::setUniformValue(
int location,
const QSizeF& size)
2585 Q_D(QOpenGLShaderProgram);
2587 if (location != -1) {
2588 GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())};
2589 d->glfuncs->glUniform2fv(location, 1, values);
2594
2595
2596
2597
2598
2599
2600
2601void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QSizeF& size)
2603 setUniformValue(uniformLocation(name), size);
2607
2608
2609
2610
2611
2612void QOpenGLShaderProgram::setUniformValue(
int location,
const QMatrix2x2& value)
2614 Q_D(QOpenGLShaderProgram);
2616 d->glfuncs->glUniformMatrix2fv(location, 1, GL_FALSE, value.constData());
2620
2621
2622
2623
2624
2625
2626
2627void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QMatrix2x2& value)
2629 setUniformValue(uniformLocation(name), value);
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642void QOpenGLShaderProgram::setUniformValue(
int location,
const QMatrix2x3& value)
2644 Q_D(QOpenGLShaderProgram);
2646 d->glfuncs->glUniform3fv(location, 2, value.constData());
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QMatrix2x3& value)
2663 setUniformValue(uniformLocation(name), value);
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676void QOpenGLShaderProgram::setUniformValue(
int location,
const QMatrix2x4& value)
2678 Q_D(QOpenGLShaderProgram);
2680 d->glfuncs->glUniform4fv(location, 2, value.constData());
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QMatrix2x4& value)
2697 setUniformValue(uniformLocation(name), value);
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710void QOpenGLShaderProgram::setUniformValue(
int location,
const QMatrix3x2& value)
2712 Q_D(QOpenGLShaderProgram);
2714 d->glfuncs->glUniform2fv(location, 3, value.constData());
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QMatrix3x2& value)
2731 setUniformValue(uniformLocation(name), value);
2735
2736
2737
2738
2739
2740void QOpenGLShaderProgram::setUniformValue(
int location,
const QMatrix3x3& value)
2742 Q_D(QOpenGLShaderProgram);
2744 d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, value.constData());
2748
2749
2750
2751
2752
2753
2754
2755void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QMatrix3x3& value)
2757 setUniformValue(uniformLocation(name), value);
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770void QOpenGLShaderProgram::setUniformValue(
int location,
const QMatrix3x4& value)
2772 Q_D(QOpenGLShaderProgram);
2774 d->glfuncs->glUniform4fv(location, 3, value.constData());
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QMatrix3x4& value)
2791 setUniformValue(uniformLocation(name), value);
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804void QOpenGLShaderProgram::setUniformValue(
int location,
const QMatrix4x2& value)
2806 Q_D(QOpenGLShaderProgram);
2808 d->glfuncs->glUniform2fv(location, 4, value.constData());
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QMatrix4x2& value)
2825 setUniformValue(uniformLocation(name), value);
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838void QOpenGLShaderProgram::setUniformValue(
int location,
const QMatrix4x3& value)
2840 Q_D(QOpenGLShaderProgram);
2842 d->glfuncs->glUniform3fv(location, 4, value.constData());
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QMatrix4x3& value)
2859 setUniformValue(uniformLocation(name), value);
2863
2864
2865
2866
2867
2868void QOpenGLShaderProgram::setUniformValue(
int location,
const QMatrix4x4& value)
2870 Q_D(QOpenGLShaderProgram);
2872 d->glfuncs->glUniformMatrix4fv(location, 1, GL_FALSE, value.constData());
2876
2877
2878
2879
2880
2881
2882
2883void QOpenGLShaderProgram::setUniformValue(
const char *name,
const QMatrix4x4& value)
2885 setUniformValue(uniformLocation(name), value);
2889
2890
2891
2892
2893
2894
2895
2896
2897void QOpenGLShaderProgram::setUniformValue(
int location,
const GLfloat value[2][2])
2899 Q_D(QOpenGLShaderProgram);
2902 d->glfuncs->glUniformMatrix2fv(location, 1, GL_FALSE, value[0]);
2906
2907
2908
2909
2910
2911
2912
2913
2914void QOpenGLShaderProgram::setUniformValue(
int location,
const GLfloat value[3][3])
2916 Q_D(QOpenGLShaderProgram);
2919 d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, value[0]);
2923
2924
2925
2926
2927
2928
2929
2930
2931void QOpenGLShaderProgram::setUniformValue(
int location,
const GLfloat value[4][4])
2933 Q_D(QOpenGLShaderProgram);
2936 d->glfuncs->glUniformMatrix4fv(location, 1, GL_FALSE, value[0]);
2941
2942
2943
2944
2945
2946
2947
2948
2949void QOpenGLShaderProgram::setUniformValue(
const char *name,
const GLfloat value[2][2])
2951 setUniformValue(uniformLocation(name), value);
2955
2956
2957
2958
2959
2960
2961
2962
2963void QOpenGLShaderProgram::setUniformValue(
const char *name,
const GLfloat value[3][3])
2965 setUniformValue(uniformLocation(name), value);
2969
2970
2971
2972
2973
2974
2975
2976
2977void QOpenGLShaderProgram::setUniformValue(
const char *name,
const GLfloat value[4][4])
2979 setUniformValue(uniformLocation(name), value);
2983
2984
2985
2986
2987
2988
2989void QOpenGLShaderProgram::setUniformValue(
int location,
const QTransform& value)
2991 Q_D(QOpenGLShaderProgram);
2993 if (location != -1) {
2994 GLfloat mat[3][3] = {
2995 {GLfloat(value.m11()), GLfloat(value.m12()), GLfloat(value.m13())},
2996 {GLfloat(value.m21()), GLfloat(value.m22()), GLfloat(value.m23())},
2997 {GLfloat(value.m31()), GLfloat(value.m32()), GLfloat(value.m33())}
2999 d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, mat[0]);
3004
3005
3006
3007
3008
3009
3010
3011
3012void QOpenGLShaderProgram::setUniformValue
3013 (
const char *name,
const QTransform& value)
3015 setUniformValue(uniformLocation(name), value);
3019
3020
3021
3022
3023
3024void QOpenGLShaderProgram::setUniformValueArray(
int location,
const GLint *values,
int count)
3026 Q_D(QOpenGLShaderProgram);
3029 d->glfuncs->glUniform1iv(location, count, values);
3033
3034
3035
3036
3037
3038
3039
3040void QOpenGLShaderProgram::setUniformValueArray
3041 (
const char *name,
const GLint *values,
int count)
3043 setUniformValueArray(uniformLocation(name), values, count);
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056void QOpenGLShaderProgram::setUniformValueArray(
int location,
const GLuint *values,
int count)
3058 Q_D(QOpenGLShaderProgram);
3061 d->glfuncs->glUniform1iv(location, count,
reinterpret_cast<
const GLint *>(values));
3065
3066
3067
3068
3069
3070
3071
3072
3073void QOpenGLShaderProgram::setUniformValueArray
3074 (
const char *name,
const GLuint *values,
int count)
3076 setUniformValueArray(uniformLocation(name), values, count);
3080
3081
3082
3083
3084
3085
3086void QOpenGLShaderProgram::setUniformValueArray(
int location,
const GLfloat *values,
int count,
int tupleSize)
3088 Q_D(QOpenGLShaderProgram);
3090 if (location != -1) {
3092 d->glfuncs->glUniform1fv(location, count, values);
3093 else if (tupleSize == 2)
3094 d->glfuncs->glUniform2fv(location, count, values);
3095 else if (tupleSize == 3)
3096 d->glfuncs->glUniform3fv(location, count, values);
3097 else if (tupleSize == 4)
3098 d->glfuncs->glUniform4fv(location, count, values);
3100 qWarning(
"QOpenGLShaderProgram::setUniformValue: size %d not supported", tupleSize);
3105
3106
3107
3108
3109
3110
3111
3112
3113void QOpenGLShaderProgram::setUniformValueArray
3114 (
const char *name,
const GLfloat *values,
int count,
int tupleSize)
3116 setUniformValueArray(uniformLocation(name), values, count, tupleSize);
3120
3121
3122
3123
3124
3125void QOpenGLShaderProgram::setUniformValueArray(
int location,
const QVector2D *values,
int count)
3127 Q_D(QOpenGLShaderProgram);
3130 d->glfuncs->glUniform2fv(location, count,
reinterpret_cast<
const GLfloat *>(values));
3134
3135
3136
3137
3138
3139
3140
3141void QOpenGLShaderProgram::setUniformValueArray(
const char *name,
const QVector2D *values,
int count)
3143 setUniformValueArray(uniformLocation(name), values, count);
3147
3148
3149
3150
3151
3152void QOpenGLShaderProgram::setUniformValueArray(
int location,
const QVector3D *values,
int count)
3154 Q_D(QOpenGLShaderProgram);
3157 d->glfuncs->glUniform3fv(location, count,
reinterpret_cast<
const GLfloat *>(values));
3161
3162
3163
3164
3165
3166
3167
3168void QOpenGLShaderProgram::setUniformValueArray(
const char *name,
const QVector3D *values,
int count)
3170 setUniformValueArray(uniformLocation(name), values, count);
3174
3175
3176
3177
3178
3179void QOpenGLShaderProgram::setUniformValueArray(
int location,
const QVector4D *values,
int count)
3181 Q_D(QOpenGLShaderProgram);
3184 d->glfuncs->glUniform4fv(location, count,
reinterpret_cast<
const GLfloat *>(values));
3188
3189
3190
3191
3192
3193
3194
3195void QOpenGLShaderProgram::setUniformValueArray(
const char *name,
const QVector4D *values,
int count)
3197 setUniformValueArray(uniformLocation(name), values, count);
3201#define setUniformMatrixArray(func,location,values,count,type,cols,rows)
3202 if (location == -1
|| count <= 0
)
3204 if (sizeof(type) == sizeof(GLfloat) * cols * rows) {
3205 func(location, count, GL_FALSE,
3206 reinterpret_cast<const GLfloat *>(values[0
].constData()));
3208 QVarLengthArray<GLfloat> temp(cols * rows * count);
3209 for (int index = 0
; index < count; ++index) {
3210 for (int index2 = 0
; index2 < (cols * rows); ++index2) {
3211 temp.data()[cols * rows * index + index2] =
3212 values[index].constData()[index2];
3215 func(location, count, GL_FALSE, temp.constData());
3217#define setUniformGenericMatrixArray(colfunc,location,values,count,type,cols,rows)
3218 if (location == -1
|| count <= 0
)
3220 if (sizeof(type) == sizeof(GLfloat) * cols * rows) {
3221 const GLfloat *data = reinterpret_cast<const GLfloat *>
3222 (values[0
].constData());
3223 colfunc(location, count * cols, data);
3225 QVarLengthArray<GLfloat> temp(cols * rows * count);
3226 for (int index = 0
; index < count; ++index) {
3227 for (int index2 = 0
; index2 < (cols * rows); ++index2) {
3228 temp.data()[cols * rows * index + index2] =
3229 values[index].constData()[index2];
3232 colfunc(location, count * cols, temp.constData());
3236
3237
3238
3239
3240
3241void QOpenGLShaderProgram::setUniformValueArray(
int location,
const QMatrix2x2 *values,
int count)
3243 Q_D(QOpenGLShaderProgram);
3246 (d->glfuncs->glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2);
3250
3251
3252
3253
3254
3255
3256
3257void QOpenGLShaderProgram::setUniformValueArray(
const char *name,
const QMatrix2x2 *values,
int count)
3259 setUniformValueArray(uniformLocation(name), values, count);
3263
3264
3265
3266
3267
3268void QOpenGLShaderProgram::setUniformValueArray(
int location,
const QMatrix2x3 *values,
int count)
3270 Q_D(QOpenGLShaderProgram);
3273 (d->glfuncs->glUniform3fv, location, values, count,
3278
3279
3280
3281
3282
3283
3284
3285void QOpenGLShaderProgram::setUniformValueArray(
const char *name,
const QMatrix2x3 *values,
int count)
3287 setUniformValueArray(uniformLocation(name), values, count);
3291
3292
3293
3294
3295
3296void QOpenGLShaderProgram::setUniformValueArray(
int location,
const QMatrix2x4 *values,
int count)
3298 Q_D(QOpenGLShaderProgram);
3301 (d->glfuncs->glUniform4fv, location, values, count,
3306
3307
3308
3309
3310
3311
3312
3313void QOpenGLShaderProgram::setUniformValueArray(
const char *name,
const QMatrix2x4 *values,
int count)
3315 setUniformValueArray(uniformLocation(name), values, count);
3319
3320
3321
3322
3323
3324void QOpenGLShaderProgram::setUniformValueArray(
int location,
const QMatrix3x2 *values,
int count)
3326 Q_D(QOpenGLShaderProgram);
3329 (d->glfuncs->glUniform2fv, location, values, count,
3334
3335
3336
3337
3338
3339
3340
3341void QOpenGLShaderProgram::setUniformValueArray(
const char *name,
const QMatrix3x2 *values,
int count)
3343 setUniformValueArray(uniformLocation(name), values, count);
3347
3348
3349
3350
3351
3352void QOpenGLShaderProgram::setUniformValueArray(
int location,
const QMatrix3x3 *values,
int count)
3354 Q_D(QOpenGLShaderProgram);
3357 (d->glfuncs->glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3);
3361
3362
3363
3364
3365
3366
3367
3368void QOpenGLShaderProgram::setUniformValueArray(
const char *name,
const QMatrix3x3 *values,
int count)
3370 setUniformValueArray(uniformLocation(name), values, count);
3374
3375
3376
3377
3378
3379void QOpenGLShaderProgram::setUniformValueArray(
int location,
const QMatrix3x4 *values,
int count)
3381 Q_D(QOpenGLShaderProgram);
3384 (d->glfuncs->glUniform4fv, location, values, count,
3389
3390
3391
3392
3393
3394
3395
3396void QOpenGLShaderProgram::setUniformValueArray(
const char *name,
const QMatrix3x4 *values,
int count)
3398 setUniformValueArray(uniformLocation(name), values, count);
3402
3403
3404
3405
3406
3407void QOpenGLShaderProgram::setUniformValueArray(
int location,
const QMatrix4x2 *values,
int count)
3409 Q_D(QOpenGLShaderProgram);
3412 (d->glfuncs->glUniform2fv, location, values, count,
3417
3418
3419
3420
3421
3422
3423
3424void QOpenGLShaderProgram::setUniformValueArray(
const char *name,
const QMatrix4x2 *values,
int count)
3426 setUniformValueArray(uniformLocation(name), values, count);
3430
3431
3432
3433
3434
3435void QOpenGLShaderProgram::setUniformValueArray(
int location,
const QMatrix4x3 *values,
int count)
3437 Q_D(QOpenGLShaderProgram);
3440 (d->glfuncs->glUniform3fv, location, values, count,
3445
3446
3447
3448
3449
3450
3451
3452void QOpenGLShaderProgram::setUniformValueArray(
const char *name,
const QMatrix4x3 *values,
int count)
3454 setUniformValueArray(uniformLocation(name), values, count);
3458
3459
3460
3461
3462
3463void QOpenGLShaderProgram::setUniformValueArray(
int location,
const QMatrix4x4 *values,
int count)
3465 Q_D(QOpenGLShaderProgram);
3468 (d->glfuncs->glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4);
3472
3473
3474
3475
3476
3477
3478
3479void QOpenGLShaderProgram::setUniformValueArray(
const char *name,
const QMatrix4x4 *values,
int count)
3481 setUniformValueArray(uniformLocation(name), values, count);
3485
3486
3487
3488int QOpenGLShaderProgram::maxGeometryOutputVertices()
const
3491 Q_D(
const QOpenGLShaderProgram);
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514void QOpenGLShaderProgram::setPatchVertexCount(
int count)
3516 Q_D(QOpenGLShaderProgram);
3521
3522
3523
3524
3525
3526
3527
3528int QOpenGLShaderProgram::patchVertexCount()
const
3530 int patchVertices = 0;
3531 Q_D(
const QOpenGLShaderProgram);
3533 return patchVertices;
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556void QOpenGLShaderProgram::setDefaultOuterTessellationLevels(
const QList<
float> &levels)
3558#if !QT_CONFIG(opengles2)
3559 Q_D(QOpenGLShaderProgram);
3560 if (d->tessellationFuncs) {
3561 QList<
float> tessLevels = levels;
3565 const int argCount = 4;
3566 if (tessLevels.size() < argCount) {
3567 tessLevels.reserve(argCount);
3568 for (
int i = tessLevels.size(); i < argCount; ++i)
3569 tessLevels.append(1.0f);
3571 d->tessellationFuncs->glPatchParameterfv(GL_PATCH_DEFAULT_OUTER_LEVEL, tessLevels.data());
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596QList<
float> QOpenGLShaderProgram::defaultOuterTessellationLevels()
const
3598#if !QT_CONFIG(opengles2)
3599 QList<
float> tessLevels(4, 1.0f);
3600 Q_D(
const QOpenGLShaderProgram);
3601 if (d->tessellationFuncs)
3602 d->tessellationFuncs->glGetFloatv(GL_PATCH_DEFAULT_OUTER_LEVEL, tessLevels.data());
3605 return QList<
float>();
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629void QOpenGLShaderProgram::setDefaultInnerTessellationLevels(
const QList<
float> &levels)
3631#if !QT_CONFIG(opengles2)
3632 Q_D(QOpenGLShaderProgram);
3633 if (d->tessellationFuncs) {
3634 QList<
float> tessLevels = levels;
3638 const int argCount = 2;
3639 if (tessLevels.size() < argCount) {
3640 tessLevels.reserve(argCount);
3641 for (
int i = tessLevels.size(); i < argCount; ++i)
3642 tessLevels.append(1.0f);
3644 d->tessellationFuncs->glPatchParameterfv(GL_PATCH_DEFAULT_INNER_LEVEL, tessLevels.data());
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669QList<
float> QOpenGLShaderProgram::defaultInnerTessellationLevels()
const
3671#if !QT_CONFIG(opengles2)
3672 QList<
float> tessLevels(2, 1.0f);
3673 Q_D(
const QOpenGLShaderProgram);
3674 if (d->tessellationFuncs)
3675 d->tessellationFuncs->glGetFloatv(GL_PATCH_DEFAULT_INNER_LEVEL, tessLevels.data());
3678 return QList<
float>();
3684
3685
3686
3687
3688
3689
3690
3691bool QOpenGLShaderProgram::hasOpenGLShaderPrograms(QOpenGLContext *context)
3694 context = QOpenGLContext::currentContext();
3697 return QOpenGLFunctions(context).hasOpenGLFeature(QOpenGLFunctions::Shaders);
3701
3702
3703void QOpenGLShaderProgram::shaderDestroyed()
3705 Q_D(QOpenGLShaderProgram);
3706 QOpenGLShader *shader = qobject_cast<QOpenGLShader *>(sender());
3707 if (shader && !d->removingShaders)
3708 removeShader(shader);
3712
3713
3714
3715
3716
3717
3718
3719bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context)
3722 context = QOpenGLContext::currentContext();
3726 if ((type & ~(Geometry | Vertex | Fragment | TessellationControl | TessellationEvaluation | Compute)) || type == 0)
3729 if (type & QOpenGLShader::Geometry)
3730 return supportsGeometry(context->format());
3731 else if (type & (QOpenGLShader::TessellationControl | QOpenGLShader::TessellationEvaluation))
3732 return supportsTessellation(context->format());
3733 else if (type & QOpenGLShader::Compute)
3734 return supportsCompute(context->format());
3743 static QOpenGLProgramBinarySupportCheckWrapper binSupportCheck;
3744 return !binSupportCheck.get(QOpenGLContext::currentContext())->isSupported();
3749 Q_Q(QOpenGLShaderProgram);
3750 for (
const QOpenGLProgramBinaryCache::ShaderDesc &shader : std::as_const(binaryProgram.shaders)) {
3751 auto s = std::make_unique<QOpenGLShader>(qt_shaderStageToType(shader.stage), q);
3752 if (!s->compileSourceCode(shader.source)) {
3756 anonShaders.append(s.release());
3757 if (!q->addShader(anonShaders.last()))
3765 static QOpenGLProgramBinaryCache binCache;
3767 Q_Q(QOpenGLShaderProgram);
3769 const QByteArray cacheKey = binaryProgram.cacheKey();
3770 if (lcOpenGLProgramDiskCache().isEnabled(QtDebugMsg))
3771 qCDebug(lcOpenGLProgramDiskCache,
"program with %d shaders, cache key %s",
3772 int(binaryProgram.shaders.size()), cacheKey.constData());
3774 bool needsCompile =
true;
3775 if (binCache.load(cacheKey, q->programId())) {
3776 qCDebug(lcOpenGLProgramDiskCache,
"Program binary received from cache");
3777 needsCompile =
false;
3780 bool needsSave =
false;
3782 qCDebug(lcOpenGLProgramDiskCache,
"Program binary not in cache, compiling");
3790 bool ok = q->link();
3792 if (ok && needsSave)
3793 binCache.save(cacheKey, q->programId());
3800#include "moc_qopenglshaderprogram.cpp"
QOpenGLSharedResourceGuard * shaderGuard
QOpenGLExtraFunctions * glfuncs
bool supportsComputeShaders
bool supportsGeometryShaders
bool supportsTessellationShaders
bool compile(QOpenGLShader *q)
QOpenGLExtraFunctions * glfuncs
QOpenGLSharedResourceGuard * programGuard
bool hasShader(QOpenGLShader::ShaderType type) const
bool isCacheDisabled() const
QList< QOpenGLShader * > shaders
QOpenGLProgramBinaryCache::ProgramDesc binaryProgram
QList< QOpenGLShader * > anonShaders
#define GL_GEOMETRY_SHADER
#define GL_TESS_CONTROL_SHADER
#define GL_COMPUTE_SHADER
#define GL_TESS_EVALUATION_SHADER
#define GL_MAX_GEOMETRY_OUTPUT_VERTICES
#define GL_PATCH_VERTICES
#define setUniformGenericMatrixArray(colfunc, location, values, count, type, cols, rows)
static const char qualifierDefines[]
static bool supportsTessellation(const QSurfaceFormat &f)
static QVersionDirectivePosition findVersionDirectivePosition(const char *source)
static QShader::Stage qt_shaderTypeToStage(QOpenGLShader::ShaderType type)
static bool supportsGeometry(const QSurfaceFormat &f)
#define setUniformMatrixArray(func, location, values, count, type, cols, rows)
static QOpenGLShader::ShaderType qt_shaderStageToType(QShader::Stage stage)
static bool supportsCompute(const QSurfaceFormat &f)
static const char blendEquationAdvancedHeader[]
constexpr QVersionDirectivePosition(int position=0, int line=-1)
constexpr bool hasPosition() const