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