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