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