changeset 3 | 41300fa6a67c |
parent 0 | 1918ee327afb |
child 4 | 3b1da2848fc7 |
2:56cd8111b7f7 | 3:41300fa6a67c |
---|---|
40 ****************************************************************************/ |
40 ****************************************************************************/ |
41 |
41 |
42 #include "qglshaderprogram.h" |
42 #include "qglshaderprogram.h" |
43 #include "qglextensions_p.h" |
43 #include "qglextensions_p.h" |
44 #include "qgl_p.h" |
44 #include "qgl_p.h" |
45 #include <QtCore/private/qobject_p.h> |
|
45 #include <QtCore/qdebug.h> |
46 #include <QtCore/qdebug.h> |
46 #include <QtCore/qfile.h> |
47 #include <QtCore/qfile.h> |
47 #include <QtCore/qvarlengtharray.h> |
48 #include <QtCore/qvarlengtharray.h> |
48 #include <QtCore/qvector.h> |
49 #include <QtCore/qvector.h> |
49 |
50 |
66 compiling and linking vertex and fragment shaders. |
67 compiling and linking vertex and fragment shaders. |
67 |
68 |
68 The following example creates a vertex shader program using the |
69 The following example creates a vertex shader program using the |
69 supplied source \c{code}. Once compiled and linked, the shader |
70 supplied source \c{code}. Once compiled and linked, the shader |
70 program is activated in the current QGLContext by calling |
71 program is activated in the current QGLContext by calling |
71 QGLShaderProgram::enable(): |
72 QGLShaderProgram::bind(): |
72 |
73 |
73 \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 0 |
74 \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 0 |
74 |
75 |
75 \section1 Writing portable shaders |
76 \section1 Writing portable shaders |
76 |
77 |
103 With the above shader program active, we can draw a green triangle |
104 With the above shader program active, we can draw a green triangle |
104 as follows: |
105 as follows: |
105 |
106 |
106 \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 2 |
107 \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 2 |
107 |
108 |
108 \section1 Partial shaders |
|
109 |
|
110 Desktop GLSL can attach an arbitrary number of vertex and fragment |
|
111 shaders to a shader program. Embedded GLSL/ES on the other hand |
|
112 supports only a single shader of each type on a shader program. |
|
113 |
|
114 Multiple shaders of the same type can be useful when large libraries |
|
115 of shaders are needed. Common functions can be factored out into |
|
116 library shaders that can be reused in multiple shader programs. |
|
117 |
|
118 To support this use of shaders, the application programmer can |
|
119 create shaders with the QGLShader::PartialVertexShader and |
|
120 QGLShader::PartialFragmentShader types. These types direct |
|
121 QGLShader and QGLShaderProgram to delay shader compilation until |
|
122 link time. |
|
123 |
|
124 When link() is called, the sources for the partial shaders are |
|
125 concatenated, and a single vertex or fragment shader is compiled |
|
126 and linked into the shader program. |
|
127 |
|
128 It is more efficient to use the QGLShader::VertexShader and |
|
129 QGLShader::FragmentShader when there is only one shader of that |
|
130 type in the program. |
|
131 |
|
132 \sa QGLShader |
109 \sa QGLShader |
133 */ |
110 */ |
134 |
111 |
135 /*! |
112 /*! |
136 \class QGLShader |
113 \class QGLShader |
146 |
123 |
147 \sa QGLShaderProgram |
124 \sa QGLShaderProgram |
148 */ |
125 */ |
149 |
126 |
150 /*! |
127 /*! |
151 \enum QGLShader::ShaderTypeBits |
128 \enum QGLShader::ShaderTypeBit |
152 This enum specifies the type of QGLShader that is being created. |
129 This enum specifies the type of QGLShader that is being created. |
153 |
130 |
154 \value VertexShader Vertex shader written in the OpenGL Shading Language (GLSL). |
131 \value Vertex Vertex shader written in the OpenGL Shading Language (GLSL). |
155 \value FragmentShader Fragment shader written in the OpenGL Shading Language (GLSL). |
132 \value Fragment Fragment shader written in the OpenGL Shading Language (GLSL). |
156 |
|
157 \value PartialVertexShader Partial vertex shader that will be concatenated with all other partial vertex shaders at link time. |
|
158 \value PartialFragmentShader Partial fragment shader that will be concatenated with all other partial fragment shaders at link time. |
|
159 |
|
160 \omitvalue PartialShader |
|
161 */ |
133 */ |
162 |
134 |
163 #ifndef GL_FRAGMENT_SHADER |
135 #ifndef GL_FRAGMENT_SHADER |
164 #define GL_FRAGMENT_SHADER 0x8B30 |
136 #define GL_FRAGMENT_SHADER 0x8B30 |
165 #endif |
137 #endif |
198 #endif |
170 #endif |
199 #ifndef GL_NUM_SHADER_BINARY_FORMATS |
171 #ifndef GL_NUM_SHADER_BINARY_FORMATS |
200 #define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 |
172 #define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 |
201 #endif |
173 #endif |
202 |
174 |
203 class QGLShaderPrivate |
175 class QGLShaderPrivate : public QObjectPrivate |
204 { |
176 { |
177 Q_DECLARE_PUBLIC(QGLShader) |
|
205 public: |
178 public: |
206 QGLShaderPrivate(const QGLContext *context, QGLShader::ShaderType type) |
179 QGLShaderPrivate(const QGLContext *context, QGLShader::ShaderType type) |
207 : shaderGuard(context) |
180 : shaderGuard(context) |
208 , shaderType(type) |
181 , shaderType(type) |
209 , compiled(false) |
182 , compiled(false) |
210 , isPartial((type & QGLShader::PartialShader) != 0) |
|
211 , hasPartialSource(false) |
|
212 { |
183 { |
213 } |
184 } |
185 ~QGLShaderPrivate(); |
|
214 |
186 |
215 QGLSharedResourceGuard shaderGuard; |
187 QGLSharedResourceGuard shaderGuard; |
216 QGLShader::ShaderType shaderType; |
188 QGLShader::ShaderType shaderType; |
217 bool compiled; |
189 bool compiled; |
218 bool isPartial; |
|
219 bool hasPartialSource; |
|
220 QString log; |
190 QString log; |
221 QByteArray partialSource; |
|
222 |
191 |
223 bool create(); |
192 bool create(); |
224 bool compile(QGLShader *q); |
193 bool compile(QGLShader *q); |
225 void deleteShader(); |
194 void deleteShader(); |
226 }; |
195 }; |
227 |
196 |
228 #define ctx shaderGuard.context() |
197 #define ctx shaderGuard.context() |
229 |
198 |
199 QGLShaderPrivate::~QGLShaderPrivate() |
|
200 { |
|
201 if (shaderGuard.id()) { |
|
202 QGLShareContextScope scope(shaderGuard.context()); |
|
203 glDeleteShader(shaderGuard.id()); |
|
204 } |
|
205 } |
|
206 |
|
230 bool QGLShaderPrivate::create() |
207 bool QGLShaderPrivate::create() |
231 { |
208 { |
232 const QGLContext *context = shaderGuard.context(); |
209 const QGLContext *context = shaderGuard.context(); |
233 if (!context) |
210 if (!context) |
234 return false; |
211 return false; |
235 if (isPartial) |
|
236 return true; |
|
237 if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) { |
212 if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) { |
238 GLuint shader; |
213 GLuint shader; |
239 if (shaderType == QGLShader::VertexShader) |
214 if (shaderType == QGLShader::Vertex) |
240 shader = glCreateShader(GL_VERTEX_SHADER); |
215 shader = glCreateShader(GL_VERTEX_SHADER); |
241 else |
216 else |
242 shader = glCreateShader(GL_FRAGMENT_SHADER); |
217 shader = glCreateShader(GL_FRAGMENT_SHADER); |
243 if (!shader) { |
218 if (!shader) { |
244 qWarning() << "QGLShader: could not create shader"; |
219 qWarning() << "QGLShader: could not create shader"; |
251 } |
226 } |
252 } |
227 } |
253 |
228 |
254 bool QGLShaderPrivate::compile(QGLShader *q) |
229 bool QGLShaderPrivate::compile(QGLShader *q) |
255 { |
230 { |
256 // Partial shaders are compiled during QGLShaderProgram::link(). |
|
257 if (isPartial && hasPartialSource) { |
|
258 compiled = true; |
|
259 return true; |
|
260 } |
|
261 GLuint shader = shaderGuard.id(); |
231 GLuint shader = shaderGuard.id(); |
262 if (!shader) |
232 if (!shader) |
263 return false; |
233 return false; |
264 glCompileShader(shader); |
234 glCompileShader(shader); |
265 GLint value = 0; |
235 GLint value = 0; |
294 #define ctx d->shaderGuard.context() |
264 #define ctx d->shaderGuard.context() |
295 |
265 |
296 /*! |
266 /*! |
297 Constructs a new QGLShader object of the specified \a type |
267 Constructs a new QGLShader object of the specified \a type |
298 and attaches it to \a parent. If shader programs are not supported, |
268 and attaches it to \a parent. If shader programs are not supported, |
299 QGLShaderProgram::hasShaderPrograms() will return false. |
269 QGLShaderProgram::hasOpenGLShaderPrograms() will return false. |
300 |
270 |
301 This constructor is normally followed by a call to compile() |
271 This constructor is normally followed by a call to compileSourceCode() |
302 or compileFile(). |
272 or compileSourceFile(). |
303 |
273 |
304 The shader will be associated with the current QGLContext. |
274 The shader will be associated with the current QGLContext. |
305 |
275 |
306 \sa compile(), compileFile() |
276 \sa compileSourceCode(), compileSourceFile() |
307 */ |
277 */ |
308 QGLShader::QGLShader(QGLShader::ShaderType type, QObject *parent) |
278 QGLShader::QGLShader(QGLShader::ShaderType type, QObject *parent) |
309 : QObject(parent) |
279 : QObject(*new QGLShaderPrivate(QGLContext::currentContext(), type), parent) |
310 { |
280 { |
311 d = new QGLShaderPrivate(QGLContext::currentContext(), type); |
281 Q_D(QGLShader); |
312 d->create(); |
282 d->create(); |
313 } |
|
314 |
|
315 /*! |
|
316 Constructs a new QGLShader object of the specified \a type from the |
|
317 source code in \a fileName and attaches it to \a parent. |
|
318 If the shader could not be loaded, then isCompiled() will return false. |
|
319 |
|
320 The shader will be associated with the current QGLContext. |
|
321 |
|
322 \sa isCompiled() |
|
323 */ |
|
324 QGLShader::QGLShader |
|
325 (const QString& fileName, QGLShader::ShaderType type, QObject *parent) |
|
326 : QObject(parent) |
|
327 { |
|
328 d = new QGLShaderPrivate(QGLContext::currentContext(), type); |
|
329 if (d->create() && !compileFile(fileName)) |
|
330 d->deleteShader(); |
|
331 } |
283 } |
332 |
284 |
333 /*! |
285 /*! |
334 Constructs a new QGLShader object of the specified \a type |
286 Constructs a new QGLShader object of the specified \a type |
335 and attaches it to \a parent. If shader programs are not supported, |
287 and attaches it to \a parent. If shader programs are not supported, |
336 then QGLShaderProgram::hasShaderPrograms() will return false. |
288 then QGLShaderProgram::hasOpenGLShaderPrograms() will return false. |
337 |
289 |
338 This constructor is normally followed by a call to compile() |
290 This constructor is normally followed by a call to compileSourceCode() |
339 or compileFile(). |
291 or compileSourceFile(). |
340 |
292 |
341 The shader will be associated with \a context. |
293 The shader will be associated with \a context. |
342 |
294 |
343 \sa compile(), compileFile() |
295 \sa compileSourceCode(), compileSourceFile() |
344 */ |
296 */ |
345 QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent) |
297 QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent) |
346 : QObject(parent) |
298 : QObject(*new QGLShaderPrivate(context ? context : QGLContext::currentContext(), type), parent) |
347 { |
299 { |
348 if (!context) |
300 Q_D(QGLShader); |
349 context = QGLContext::currentContext(); |
|
350 d = new QGLShaderPrivate(context, type); |
|
351 #ifndef QT_NO_DEBUG |
301 #ifndef QT_NO_DEBUG |
352 if (context && !QGLContext::areSharing(context, QGLContext::currentContext())) { |
302 if (context && !QGLContext::areSharing(context, QGLContext::currentContext())) { |
353 qWarning("QGLShader::QGLShader: \'context\' must be the currect context or sharing with it."); |
303 qWarning("QGLShader::QGLShader: \'context\' must be the current context or sharing with it."); |
354 return; |
304 return; |
355 } |
305 } |
356 #endif |
306 #endif |
357 d->create(); |
307 d->create(); |
358 } |
|
359 |
|
360 /*! |
|
361 Constructs a new QGLShader object of the specified \a type from the |
|
362 source code in \a fileName and attaches it to \a parent. |
|
363 If the shader could not be loaded, then isCompiled() will return false. |
|
364 |
|
365 The shader will be associated with \a context. |
|
366 |
|
367 \sa isCompiled() |
|
368 */ |
|
369 QGLShader::QGLShader |
|
370 (const QString& fileName, QGLShader::ShaderType type, const QGLContext *context, QObject *parent) |
|
371 : QObject(parent) |
|
372 { |
|
373 if (!context) |
|
374 context = QGLContext::currentContext(); |
|
375 d = new QGLShaderPrivate(context, type); |
|
376 #ifndef QT_NO_DEBUG |
|
377 if (context && !QGLContext::areSharing(context, QGLContext::currentContext())) { |
|
378 qWarning("QGLShader::QGLShader: \'context\' must be currect context or sharing with it."); |
|
379 return; |
|
380 } |
|
381 #endif |
|
382 if (d->create() && !compileFile(fileName)) |
|
383 d->deleteShader(); |
|
384 } |
308 } |
385 |
309 |
386 /*! |
310 /*! |
387 Deletes this shader. If the shader has been attached to a |
311 Deletes this shader. If the shader has been attached to a |
388 QGLShaderProgram object, then the actual shader will stay around |
312 QGLShaderProgram object, then the actual shader will stay around |
389 until the QGLShaderProgram is destroyed. |
313 until the QGLShaderProgram is destroyed. |
390 */ |
314 */ |
391 QGLShader::~QGLShader() |
315 QGLShader::~QGLShader() |
392 { |
316 { |
393 if (d->shaderGuard.id()) { |
|
394 QGLShareContextScope scope(d->shaderGuard.context()); |
|
395 glDeleteShader(d->shaderGuard.id()); |
|
396 } |
|
397 delete d; |
|
398 } |
317 } |
399 |
318 |
400 /*! |
319 /*! |
401 Returns the type of this shader. |
320 Returns the type of this shader. |
402 */ |
321 */ |
403 QGLShader::ShaderType QGLShader::shaderType() const |
322 QGLShader::ShaderType QGLShader::shaderType() const |
404 { |
323 { |
324 Q_D(const QGLShader); |
|
405 return d->shaderType; |
325 return d->shaderType; |
406 } |
326 } |
407 |
327 |
408 // The precision qualifiers are useful on OpenGL/ES systems, |
328 // The precision qualifiers are useful on OpenGL/ES systems, |
409 // but usually not present on desktop systems. Define the |
329 // but usually not present on desktop systems. Define the |
428 |
348 |
429 /*! |
349 /*! |
430 Sets the \a source code for this shader and compiles it. |
350 Sets the \a source code for this shader and compiles it. |
431 Returns true if the source was successfully compiled, false otherwise. |
351 Returns true if the source was successfully compiled, false otherwise. |
432 |
352 |
433 If shaderType() is PartialVertexShader or PartialFragmentShader, |
353 \sa compileSourceFile() |
434 then this function will always return true, even if the source code |
354 */ |
435 is invalid. Partial shaders are compiled when QGLShaderProgram::link() |
355 bool QGLShader::compileSourceCode(const char *source) |
436 is called. |
356 { |
437 |
357 Q_D(QGLShader); |
438 \sa compileFile() |
358 if (d->shaderGuard.id()) { |
439 */ |
359 QVarLengthArray<const char *, 4> src; |
440 bool QGLShader::compile(const char *source) |
360 QVarLengthArray<GLint, 4> srclen; |
441 { |
|
442 if (d->isPartial) { |
|
443 d->partialSource = QByteArray(source); |
|
444 d->hasPartialSource = true; |
|
445 return d->compile(this); |
|
446 } else if (d->shaderGuard.id()) { |
|
447 QVarLengthArray<const char *> src; |
|
448 int headerLen = 0; |
361 int headerLen = 0; |
449 while (source && source[headerLen] == '#') { |
362 while (source && source[headerLen] == '#') { |
450 // Skip #version and #extension directives at the start of |
363 // Skip #version and #extension directives at the start of |
451 // the shader code. We need to insert the qualifierDefines |
364 // the shader code. We need to insert the qualifierDefines |
452 // and redefineHighp just after them. |
365 // and redefineHighp just after them. |
457 while (source[headerLen] != '\0' && source[headerLen] != '\n') |
370 while (source[headerLen] != '\0' && source[headerLen] != '\n') |
458 ++headerLen; |
371 ++headerLen; |
459 if (source[headerLen] == '\n') |
372 if (source[headerLen] == '\n') |
460 ++headerLen; |
373 ++headerLen; |
461 } |
374 } |
462 QByteArray header; |
|
463 if (headerLen > 0) { |
375 if (headerLen > 0) { |
464 header = QByteArray(source, headerLen); |
376 src.append(source); |
465 src.append(header.constData()); |
377 srclen.append(GLint(headerLen)); |
466 } |
378 } |
467 #ifdef QGL_DEFINE_QUALIFIERS |
379 #ifdef QGL_DEFINE_QUALIFIERS |
468 src.append(qualifierDefines); |
380 src.append(qualifierDefines); |
381 srclen.append(GLint(sizeof(qualifierDefines) - 1)); |
|
469 #endif |
382 #endif |
470 #ifdef QGL_REDEFINE_HIGHP |
383 #ifdef QGL_REDEFINE_HIGHP |
471 if (d->shaderType == FragmentShader || |
384 if (d->shaderType == Fragment) { |
472 d->shaderType == PartialFragmentShader) |
|
473 src.append(redefineHighp); |
385 src.append(redefineHighp); |
386 srclen.append(GLint(sizeof(redefineHighp) - 1)); |
|
387 } |
|
474 #endif |
388 #endif |
475 src.append(source + headerLen); |
389 src.append(source + headerLen); |
476 glShaderSource(d->shaderGuard.id(), src.size(), src.data(), 0); |
390 srclen.append(GLint(qstrlen(source + headerLen))); |
391 glShaderSource(d->shaderGuard.id(), src.size(), src.data(), srclen.data()); |
|
477 return d->compile(this); |
392 return d->compile(this); |
478 } else { |
393 } else { |
479 return false; |
394 return false; |
480 } |
395 } |
481 } |
396 } |
484 \overload |
399 \overload |
485 |
400 |
486 Sets the \a source code for this shader and compiles it. |
401 Sets the \a source code for this shader and compiles it. |
487 Returns true if the source was successfully compiled, false otherwise. |
402 Returns true if the source was successfully compiled, false otherwise. |
488 |
403 |
489 If shaderType() is PartialVertexShader or PartialFragmentShader, |
404 \sa compileSourceFile() |
490 then this function will always return true, even if the source code |
405 */ |
491 is invalid. Partial shaders are compiled when QGLShaderProgram::link() |
406 bool QGLShader::compileSourceCode(const QByteArray& source) |
492 is called. |
407 { |
493 |
408 return compileSourceCode(source.constData()); |
494 \sa compileFile() |
|
495 */ |
|
496 bool QGLShader::compile(const QByteArray& source) |
|
497 { |
|
498 return compile(source.constData()); |
|
499 } |
409 } |
500 |
410 |
501 /*! |
411 /*! |
502 \overload |
412 \overload |
503 |
413 |
504 Sets the \a source code for this shader and compiles it. |
414 Sets the \a source code for this shader and compiles it. |
505 Returns true if the source was successfully compiled, false otherwise. |
415 Returns true if the source was successfully compiled, false otherwise. |
506 |
416 |
507 If shaderType() is PartialVertexShader or PartialFragmentShader, |
417 \sa compileSourceFile() |
508 then this function will always return true, even if the source code |
418 */ |
509 is invalid. Partial shaders are compiled when QGLShaderProgram::link() |
419 bool QGLShader::compileSourceCode(const QString& source) |
510 is called. |
420 { |
511 |
421 return compileSourceCode(source.toLatin1().constData()); |
512 \sa compileFile() |
|
513 */ |
|
514 bool QGLShader::compile(const QString& source) |
|
515 { |
|
516 return compile(source.toLatin1().constData()); |
|
517 } |
422 } |
518 |
423 |
519 /*! |
424 /*! |
520 Sets the source code for this shader to the contents of \a fileName |
425 Sets the source code for this shader to the contents of \a fileName |
521 and compiles it. Returns true if the file could be opened and the |
426 and compiles it. Returns true if the file could be opened and the |
522 source compiled, false otherwise. |
427 source compiled, false otherwise. |
523 |
428 |
524 If shaderType() is PartialVertexShader or PartialFragmentShader, |
429 \sa compileSourceCode() |
525 then this function will always return true, even if the source code |
430 */ |
526 is invalid. Partial shaders are compiled when QGLShaderProgram::link() |
431 bool QGLShader::compileSourceFile(const QString& fileName) |
527 is called. |
|
528 |
|
529 \sa compile() |
|
530 */ |
|
531 bool QGLShader::compileFile(const QString& fileName) |
|
532 { |
432 { |
533 QFile file(fileName); |
433 QFile file(fileName); |
534 if (!file.open(QFile::ReadOnly)) { |
434 if (!file.open(QFile::ReadOnly)) { |
535 qWarning() << "QGLShader: Unable to open file" << fileName; |
435 qWarning() << "QGLShader: Unable to open file" << fileName; |
536 return false; |
436 return false; |
537 } |
437 } |
538 |
438 |
539 QByteArray contents = file.readAll(); |
439 QByteArray contents = file.readAll(); |
540 return compile(contents.constData()); |
440 return compileSourceCode(contents.constData()); |
541 } |
|
542 |
|
543 /*! |
|
544 Sets the binary code for this shader to the \a length bytes from |
|
545 the array \a binary. The \a format specifies how the binary data |
|
546 should be interpreted by the OpenGL engine. Returns true if the |
|
547 binary was set on the shader; false otherwise. |
|
548 |
|
549 This function cannot be used with PartialVertexShader or |
|
550 PartialFragmentShader. |
|
551 |
|
552 If this function succeeds, then the shader will be considered compiled. |
|
553 |
|
554 \sa shaderBinaryFormats() |
|
555 */ |
|
556 bool QGLShader::setShaderBinary(GLenum format, const void *binary, int length) |
|
557 { |
|
558 #if !defined(QT_OPENGL_ES_2) |
|
559 if (!glShaderBinary) |
|
560 return false; |
|
561 #endif |
|
562 GLuint shader = d->shaderGuard.id(); |
|
563 if (d->isPartial || !shader) |
|
564 return false; |
|
565 glGetError(); // Clear error state. |
|
566 glShaderBinary(1, &shader, format, binary, length); |
|
567 d->compiled = (glGetError() == GL_NO_ERROR); |
|
568 return d->compiled; |
|
569 } |
|
570 |
|
571 /*! |
|
572 Sets the binary code for this shader to the \a length bytes from |
|
573 the array \a binary. The \a format specifies how the binary data |
|
574 should be interpreted by the OpenGL engine. Returns true if the |
|
575 binary was set on the shader; false otherwise. |
|
576 |
|
577 The \a otherShader will also have binary code set on it. This is |
|
578 for the case where \a binary contains both vertex and fragment |
|
579 shader code. |
|
580 |
|
581 This function cannot be used with PartialVertexShader or |
|
582 PartialFragmentShader. |
|
583 |
|
584 If this function succeeds, then the shader will be considered compiled. |
|
585 |
|
586 \sa shaderBinaryFormats() |
|
587 */ |
|
588 bool QGLShader::setShaderBinary |
|
589 (QGLShader& otherShader, GLenum format, const void *binary, int length) |
|
590 { |
|
591 #if !defined(QT_OPENGL_ES_2) |
|
592 if (!glShaderBinary) |
|
593 return false; |
|
594 #endif |
|
595 if (d->isPartial || !d->shaderGuard.id()) |
|
596 return false; |
|
597 if (otherShader.d->isPartial || !otherShader.d->shaderGuard.id()) |
|
598 return false; |
|
599 glGetError(); // Clear error state. |
|
600 GLuint shaders[2]; |
|
601 shaders[0] = d->shaderGuard.id(); |
|
602 shaders[1] = otherShader.d->shaderGuard.id(); |
|
603 glShaderBinary(2, shaders, format, binary, length); |
|
604 d->compiled = (glGetError() == GL_NO_ERROR); |
|
605 otherShader.d->compiled = d->compiled; |
|
606 return d->compiled; |
|
607 } |
|
608 |
|
609 /*! |
|
610 Returns a list of all binary formats that are supported by |
|
611 setShaderBinary() on this system. |
|
612 |
|
613 \sa setShaderBinary() |
|
614 */ |
|
615 QList<GLenum> QGLShader::shaderBinaryFormats() |
|
616 { |
|
617 GLint num; |
|
618 QList<GLenum> list; |
|
619 glGetError(); // Clear error state. |
|
620 glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &num); |
|
621 if (glGetError() != GL_NO_ERROR || num <= 0) |
|
622 return list; |
|
623 QVarLengthArray<GLint> formats(num); |
|
624 glGetIntegerv(GL_SHADER_BINARY_FORMATS, formats.data()); |
|
625 for (GLint i = 0; i < num; ++i) |
|
626 list += (GLenum)(formats[i]); |
|
627 return list; |
|
628 } |
441 } |
629 |
442 |
630 /*! |
443 /*! |
631 Returns the source code for this shader. |
444 Returns the source code for this shader. |
632 |
445 |
633 \sa compile() |
446 \sa compileSourceCode() |
634 */ |
447 */ |
635 QByteArray QGLShader::sourceCode() const |
448 QByteArray QGLShader::sourceCode() const |
636 { |
449 { |
637 if (d->isPartial) |
450 Q_D(const QGLShader); |
638 return d->partialSource; |
|
639 GLuint shader = d->shaderGuard.id(); |
451 GLuint shader = d->shaderGuard.id(); |
640 if (!shader) |
452 if (!shader) |
641 return QByteArray(); |
453 return QByteArray(); |
642 GLint size = 0; |
454 GLint size = 0; |
643 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &size); |
455 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &size); |
652 } |
464 } |
653 |
465 |
654 /*! |
466 /*! |
655 Returns true if this shader has been compiled; false otherwise. |
467 Returns true if this shader has been compiled; false otherwise. |
656 |
468 |
657 \sa compile() |
469 \sa compileSourceCode(), compileSourceFile() |
658 */ |
470 */ |
659 bool QGLShader::isCompiled() const |
471 bool QGLShader::isCompiled() const |
660 { |
472 { |
473 Q_D(const QGLShader); |
|
661 return d->compiled; |
474 return d->compiled; |
662 } |
475 } |
663 |
476 |
664 /*! |
477 /*! |
665 Returns the errors and warnings that occurred during the last compile. |
478 Returns the errors and warnings that occurred during the last compile. |
666 |
479 |
667 \sa compile() |
480 \sa compileSourceCode(), compileSourceFile() |
668 */ |
481 */ |
669 QString QGLShader::log() const |
482 QString QGLShader::log() const |
670 { |
483 { |
484 Q_D(const QGLShader); |
|
671 return d->log; |
485 return d->log; |
672 } |
486 } |
673 |
487 |
674 /*! |
488 /*! |
675 Returns the OpenGL identifier associated with this shader. |
489 Returns the OpenGL identifier associated with this shader. |
676 |
490 |
677 If shaderType() is PartialVertexShader or PartialFragmentShader, |
|
678 this function will always return zero. Partial shaders are |
|
679 created and compiled when QGLShaderProgram::link() is called. |
|
680 |
|
681 \sa QGLShaderProgram::programId() |
491 \sa QGLShaderProgram::programId() |
682 */ |
492 */ |
683 GLuint QGLShader::shaderId() const |
493 GLuint QGLShader::shaderId() const |
684 { |
494 { |
495 Q_D(const QGLShader); |
|
685 return d->shaderGuard.id(); |
496 return d->shaderGuard.id(); |
686 } |
497 } |
687 |
498 |
688 #undef ctx |
499 #undef ctx |
689 #define ctx programGuard.context() |
500 #define ctx programGuard.context() |
690 |
501 |
691 class QGLShaderProgramPrivate |
502 class QGLShaderProgramPrivate : public QObjectPrivate |
692 { |
503 { |
504 Q_DECLARE_PUBLIC(QGLShaderProgram) |
|
693 public: |
505 public: |
694 QGLShaderProgramPrivate(const QGLContext *context) |
506 QGLShaderProgramPrivate(const QGLContext *context) |
695 : programGuard(context) |
507 : programGuard(context) |
696 , linked(false) |
508 , linked(false) |
697 , inited(false) |
509 , inited(false) |
698 , hasPartialShaders(false) |
|
699 , removingShaders(false) |
510 , removingShaders(false) |
700 , vertexShader(0) |
511 , vertexShader(0) |
701 , fragmentShader(0) |
512 , fragmentShader(0) |
702 { |
513 { |
703 } |
514 } |
704 ~QGLShaderProgramPrivate(); |
515 ~QGLShaderProgramPrivate(); |
705 |
516 |
706 QGLSharedResourceGuard programGuard; |
517 QGLSharedResourceGuard programGuard; |
707 bool linked; |
518 bool linked; |
708 bool inited; |
519 bool inited; |
709 bool hasPartialShaders; |
|
710 bool removingShaders; |
520 bool removingShaders; |
711 QString log; |
521 QString log; |
712 QList<QGLShader *> shaders; |
522 QList<QGLShader *> shaders; |
713 QList<QGLShader *> anonShaders; |
523 QList<QGLShader *> anonShaders; |
714 QGLShader *vertexShader; |
524 QGLShader *vertexShader; |
715 QGLShader *fragmentShader; |
525 QGLShader *fragmentShader; |
526 |
|
527 bool hasShader(QGLShader::ShaderType type) const; |
|
716 }; |
528 }; |
717 |
529 |
718 QGLShaderProgramPrivate::~QGLShaderProgramPrivate() |
530 QGLShaderProgramPrivate::~QGLShaderProgramPrivate() |
719 { |
531 { |
720 if (programGuard.id()) { |
532 if (programGuard.id()) { |
721 QGLShareContextScope scope(programGuard.context()); |
533 QGLShareContextScope scope(programGuard.context()); |
722 glDeleteProgram(programGuard.id()); |
534 glDeleteProgram(programGuard.id()); |
723 } |
535 } |
724 } |
536 } |
725 |
537 |
538 bool QGLShaderProgramPrivate::hasShader(QGLShader::ShaderType type) const |
|
539 { |
|
540 foreach (QGLShader *shader, shaders) { |
|
541 if (shader->shaderType() == type) |
|
542 return true; |
|
543 } |
|
544 return false; |
|
545 } |
|
546 |
|
726 #undef ctx |
547 #undef ctx |
727 #define ctx d->programGuard.context() |
548 #define ctx d->programGuard.context() |
728 |
549 |
729 /*! |
550 /*! |
730 Constructs a new shader program and attaches it to \a parent. |
551 Constructs a new shader program and attaches it to \a parent. |
733 The shader program will be associated with the current QGLContext. |
554 The shader program will be associated with the current QGLContext. |
734 |
555 |
735 \sa addShader() |
556 \sa addShader() |
736 */ |
557 */ |
737 QGLShaderProgram::QGLShaderProgram(QObject *parent) |
558 QGLShaderProgram::QGLShaderProgram(QObject *parent) |
738 : QObject(parent) |
559 : QObject(*new QGLShaderProgramPrivate(QGLContext::currentContext()), parent) |
739 { |
560 { |
740 d = new QGLShaderProgramPrivate(QGLContext::currentContext()); |
|
741 } |
561 } |
742 |
562 |
743 /*! |
563 /*! |
744 Constructs a new shader program and attaches it to \a parent. |
564 Constructs a new shader program and attaches it to \a parent. |
745 The program will be invalid until addShader() is called. |
565 The program will be invalid until addShader() is called. |
747 The shader program will be associated with \a context. |
567 The shader program will be associated with \a context. |
748 |
568 |
749 \sa addShader() |
569 \sa addShader() |
750 */ |
570 */ |
751 QGLShaderProgram::QGLShaderProgram(const QGLContext *context, QObject *parent) |
571 QGLShaderProgram::QGLShaderProgram(const QGLContext *context, QObject *parent) |
752 : QObject(parent) |
572 : QObject(*new QGLShaderProgramPrivate(context), parent) |
753 { |
573 { |
754 d = new QGLShaderProgramPrivate(context); |
|
755 } |
574 } |
756 |
575 |
757 /*! |
576 /*! |
758 Deletes this shader program. |
577 Deletes this shader program. |
759 */ |
578 */ |
760 QGLShaderProgram::~QGLShaderProgram() |
579 QGLShaderProgram::~QGLShaderProgram() |
761 { |
580 { |
762 delete d; |
|
763 } |
581 } |
764 |
582 |
765 bool QGLShaderProgram::init() |
583 bool QGLShaderProgram::init() |
766 { |
584 { |
585 Q_D(QGLShaderProgram); |
|
767 if (d->programGuard.id() || d->inited) |
586 if (d->programGuard.id() || d->inited) |
768 return true; |
587 return true; |
769 d->inited = true; |
588 d->inited = true; |
770 const QGLContext *context = d->programGuard.context(); |
589 const QGLContext *context = d->programGuard.context(); |
771 if (!context) { |
590 if (!context) { |
795 Ownership of the \a shader object remains with the caller. |
614 Ownership of the \a shader object remains with the caller. |
796 It will not be deleted when this QGLShaderProgram instance |
615 It will not be deleted when this QGLShaderProgram instance |
797 is deleted. This allows the caller to add the same shader |
616 is deleted. This allows the caller to add the same shader |
798 to multiple shader programs. |
617 to multiple shader programs. |
799 |
618 |
619 \sa addShaderFromSourceCode(), addShaderFromSourceFile() |
|
800 \sa removeShader(), link(), removeAllShaders() |
620 \sa removeShader(), link(), removeAllShaders() |
801 */ |
621 */ |
802 bool QGLShaderProgram::addShader(QGLShader *shader) |
622 bool QGLShaderProgram::addShader(QGLShader *shader) |
803 { |
623 { |
624 Q_D(QGLShaderProgram); |
|
804 if (!init()) |
625 if (!init()) |
805 return false; |
626 return false; |
806 if (d->shaders.contains(shader)) |
627 if (d->shaders.contains(shader)) |
807 return true; // Already added to this shader program. |
628 return true; // Already added to this shader program. |
808 if (d->programGuard.id() && shader) { |
629 if (d->programGuard.id() && shader) { |
809 if (!QGLContext::areSharing(shader->d->shaderGuard.context(), |
630 if (!QGLContext::areSharing(shader->d_func()->shaderGuard.context(), |
810 d->programGuard.context())) { |
631 d->programGuard.context())) { |
811 qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context."); |
632 qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context."); |
812 return false; |
633 return false; |
813 } |
634 } |
814 if (!shader->d->compiled) |
635 if (!shader->d_func()->compiled) |
815 return false; |
636 return false; |
816 if (!shader->d->isPartial) { |
637 if (!shader->d_func()->shaderGuard.id()) |
817 if (!shader->d->shaderGuard.id()) |
638 return false; |
818 return false; |
639 glAttachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id()); |
819 glAttachShader(d->programGuard.id(), shader->d->shaderGuard.id()); |
|
820 } else { |
|
821 d->hasPartialShaders = true; |
|
822 } |
|
823 d->linked = false; // Program needs to be relinked. |
640 d->linked = false; // Program needs to be relinked. |
824 d->shaders.append(shader); |
641 d->shaders.append(shader); |
825 connect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed())); |
642 connect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed())); |
826 return true; |
643 return true; |
827 } else { |
644 } else { |
837 |
654 |
838 This function is intended to be a short-cut for quickly |
655 This function is intended to be a short-cut for quickly |
839 adding vertex and fragment shaders to a shader program without |
656 adding vertex and fragment shaders to a shader program without |
840 creating an instance of QGLShader first. |
657 creating an instance of QGLShader first. |
841 |
658 |
659 \sa addShader(), addShaderFromSourceFile() |
|
842 \sa removeShader(), link(), log(), removeAllShaders() |
660 \sa removeShader(), link(), log(), removeAllShaders() |
843 */ |
661 */ |
844 bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const char *source) |
662 bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const char *source) |
845 { |
663 { |
664 Q_D(QGLShaderProgram); |
|
846 if (!init()) |
665 if (!init()) |
847 return false; |
666 return false; |
848 QGLShader *shader = new QGLShader(type, this); |
667 QGLShader *shader = new QGLShader(type, this); |
849 if (!shader->compile(source)) { |
668 if (!shader->compileSourceCode(source)) { |
850 d->log = shader->log(); |
669 d->log = shader->log(); |
851 delete shader; |
670 delete shader; |
852 return false; |
671 return false; |
853 } |
672 } |
854 d->anonShaders.append(shader); |
673 d->anonShaders.append(shader); |
865 |
684 |
866 This function is intended to be a short-cut for quickly |
685 This function is intended to be a short-cut for quickly |
867 adding vertex and fragment shaders to a shader program without |
686 adding vertex and fragment shaders to a shader program without |
868 creating an instance of QGLShader first. |
687 creating an instance of QGLShader first. |
869 |
688 |
689 \sa addShader(), addShaderFromSourceFile() |
|
870 \sa removeShader(), link(), log(), removeAllShaders() |
690 \sa removeShader(), link(), log(), removeAllShaders() |
871 */ |
691 */ |
872 bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const QByteArray& source) |
692 bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const QByteArray& source) |
873 { |
693 { |
874 return addShader(type, source.constData()); |
694 return addShaderFromSourceCode(type, source.constData()); |
875 } |
695 } |
876 |
696 |
877 /*! |
697 /*! |
878 \overload |
698 \overload |
879 |
699 |
884 |
704 |
885 This function is intended to be a short-cut for quickly |
705 This function is intended to be a short-cut for quickly |
886 adding vertex and fragment shaders to a shader program without |
706 adding vertex and fragment shaders to a shader program without |
887 creating an instance of QGLShader first. |
707 creating an instance of QGLShader first. |
888 |
708 |
709 \sa addShader(), addShaderFromSourceFile() |
|
889 \sa removeShader(), link(), log(), removeAllShaders() |
710 \sa removeShader(), link(), log(), removeAllShaders() |
890 */ |
711 */ |
891 bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const QString& source) |
712 bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const QString& source) |
892 { |
713 { |
893 return addShader(type, source.toLatin1().constData()); |
714 return addShaderFromSourceCode(type, source.toLatin1().constData()); |
894 } |
715 } |
895 |
716 |
896 /*! |
717 /*! |
897 Compiles the contents of \a fileName as a shader of the specified |
718 Compiles the contents of \a fileName as a shader of the specified |
898 \a type and adds it to this shader program. Returns true if |
719 \a type and adds it to this shader program. Returns true if |
901 |
722 |
902 This function is intended to be a short-cut for quickly |
723 This function is intended to be a short-cut for quickly |
903 adding vertex and fragment shaders to a shader program without |
724 adding vertex and fragment shaders to a shader program without |
904 creating an instance of QGLShader first. |
725 creating an instance of QGLShader first. |
905 |
726 |
906 \sa addShader() |
727 \sa addShader(), addShaderFromSourceCode() |
907 */ |
728 */ |
908 bool QGLShaderProgram::addShaderFromFile |
729 bool QGLShaderProgram::addShaderFromSourceFile |
909 (QGLShader::ShaderType type, const QString& fileName) |
730 (QGLShader::ShaderType type, const QString& fileName) |
910 { |
731 { |
732 Q_D(QGLShaderProgram); |
|
911 if (!init()) |
733 if (!init()) |
912 return false; |
734 return false; |
913 QGLShader *shader = new QGLShader(type, this); |
735 QGLShader *shader = new QGLShader(type, this); |
914 if (!shader->compileFile(fileName)) { |
736 if (!shader->compileSourceFile(fileName)) { |
915 d->log = shader->log(); |
737 d->log = shader->log(); |
916 delete shader; |
738 delete shader; |
917 return false; |
739 return false; |
918 } |
740 } |
919 d->anonShaders.append(shader); |
741 d->anonShaders.append(shader); |
925 |
747 |
926 \sa addShader(), link(), removeAllShaders() |
748 \sa addShader(), link(), removeAllShaders() |
927 */ |
749 */ |
928 void QGLShaderProgram::removeShader(QGLShader *shader) |
750 void QGLShaderProgram::removeShader(QGLShader *shader) |
929 { |
751 { |
930 if (d->programGuard.id() && shader && shader->d->shaderGuard.id()) { |
752 Q_D(QGLShaderProgram); |
753 if (d->programGuard.id() && shader && shader->d_func()->shaderGuard.id()) { |
|
931 QGLShareContextScope scope(d->programGuard.context()); |
754 QGLShareContextScope scope(d->programGuard.context()); |
932 glDetachShader(d->programGuard.id(), shader->d->shaderGuard.id()); |
755 glDetachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id()); |
933 } |
756 } |
934 d->linked = false; // Program needs to be relinked. |
757 d->linked = false; // Program needs to be relinked. |
935 if (shader) { |
758 if (shader) { |
936 d->shaders.removeAll(shader); |
759 d->shaders.removeAll(shader); |
937 d->anonShaders.removeAll(shader); |
760 d->anonShaders.removeAll(shader); |
945 |
768 |
946 \sa addShader(), removeShader() |
769 \sa addShader(), removeShader() |
947 */ |
770 */ |
948 QList<QGLShader *> QGLShaderProgram::shaders() const |
771 QList<QGLShader *> QGLShaderProgram::shaders() const |
949 { |
772 { |
773 Q_D(const QGLShaderProgram); |
|
950 return d->shaders; |
774 return d->shaders; |
951 } |
775 } |
952 |
776 |
953 /*! |
777 /*! |
954 Removes all of the shaders that were added to this program previously. |
778 Removes all of the shaders that were added to this program previously. |
958 |
782 |
959 \sa addShader(), removeShader() |
783 \sa addShader(), removeShader() |
960 */ |
784 */ |
961 void QGLShaderProgram::removeAllShaders() |
785 void QGLShaderProgram::removeAllShaders() |
962 { |
786 { |
787 Q_D(QGLShaderProgram); |
|
963 d->removingShaders = true; |
788 d->removingShaders = true; |
964 foreach (QGLShader *shader, d->shaders) { |
789 foreach (QGLShader *shader, d->shaders) { |
965 if (d->programGuard.id() && shader && shader->d->shaderGuard.id()) |
790 if (d->programGuard.id() && shader && shader->d_func()->shaderGuard.id()) |
966 glDetachShader(d->programGuard.id(), shader->d->shaderGuard.id()); |
791 glDetachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id()); |
967 } |
792 } |
968 foreach (QGLShader *shader, d->anonShaders) { |
793 foreach (QGLShader *shader, d->anonShaders) { |
969 // Delete shader objects that were created anonymously. |
794 // Delete shader objects that were created anonymously. |
970 delete shader; |
795 delete shader; |
971 } |
796 } |
973 d->anonShaders.clear(); |
798 d->anonShaders.clear(); |
974 d->linked = false; // Program needs to be relinked. |
799 d->linked = false; // Program needs to be relinked. |
975 d->removingShaders = false; |
800 d->removingShaders = false; |
976 } |
801 } |
977 |
802 |
978 #if defined(QT_OPENGL_ES_2) |
|
979 |
|
980 #ifndef GL_PROGRAM_BINARY_LENGTH_OES |
|
981 #define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 |
|
982 #endif |
|
983 #ifndef GL_NUM_PROGRAM_BINARY_FORMATS_OES |
|
984 #define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE |
|
985 #endif |
|
986 #ifndef GL_PROGRAM_BINARY_FORMATS_OES |
|
987 #define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF |
|
988 #endif |
|
989 |
|
990 #endif |
|
991 |
|
992 /*! |
|
993 Returns the program binary associated with this shader program. |
|
994 The numeric identifier of the program binary format is returned |
|
995 in \a format. The \c OES_get_program_binary extension will need |
|
996 to be supported by the system for binary retrieval to succeed. |
|
997 |
|
998 Returns an empty QByteArray if the program binary cannot be |
|
999 retrieved on this system, or the shader program has not yet |
|
1000 been linked. |
|
1001 |
|
1002 The returned binary can be supplied to setProgramBinary() on the |
|
1003 same machine at some future point to reload the program. It contains |
|
1004 the compiled code of all of the shaders that were attached to the |
|
1005 program at the time programBinary() is called. |
|
1006 |
|
1007 \sa setProgramBinary(), programBinaryFormats() |
|
1008 */ |
|
1009 QByteArray QGLShaderProgram::programBinary(int *format) const |
|
1010 { |
|
1011 #if defined(QT_OPENGL_ES_2) |
|
1012 if (!isLinked()) |
|
1013 return QByteArray(); |
|
1014 |
|
1015 // Get the length of the binary data, bailing out if there is none. |
|
1016 GLint length = 0; |
|
1017 GLuint program = d->programGuard.id(); |
|
1018 glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH_OES, &length); |
|
1019 if (length <= 0) |
|
1020 return QByteArray(); |
|
1021 |
|
1022 // Retrieve the binary data. |
|
1023 QByteArray binary(length, 0); |
|
1024 GLenum binaryFormat; |
|
1025 glGetProgramBinaryOES(program, length, 0, &binaryFormat, binary.data()); |
|
1026 if (format) |
|
1027 *format = (int)binaryFormat; |
|
1028 return binary; |
|
1029 #else |
|
1030 Q_UNUSED(format); |
|
1031 return QByteArray(); |
|
1032 #endif |
|
1033 } |
|
1034 |
|
1035 /*! |
|
1036 Sets the \a binary for this shader program according to \a format. |
|
1037 Returns true if the binary was set, or false if the binary format |
|
1038 is not supported or this system does not support program binaries. |
|
1039 The program will be linked if the load succeeds. |
|
1040 |
|
1041 \sa programBinary(), programBinaryFormats(), isLinked() |
|
1042 */ |
|
1043 bool QGLShaderProgram::setProgramBinary(int format, const QByteArray& binary) |
|
1044 { |
|
1045 #if defined(QT_OPENGL_ES_2) |
|
1046 // Load the binary and check that it was linked correctly. |
|
1047 GLuint program = d->programGuard.id(); |
|
1048 if (!program) |
|
1049 return false; |
|
1050 glProgramBinaryOES(program, (GLenum)format, |
|
1051 binary.constData(), binary.size()); |
|
1052 GLint value = 0; |
|
1053 glGetProgramiv(program, GL_LINK_STATUS, &value); |
|
1054 d->linked = (value != 0); |
|
1055 value = 0; |
|
1056 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value); |
|
1057 d->log = QString(); |
|
1058 if (value > 1) { |
|
1059 char *logbuf = new char [value]; |
|
1060 GLint len; |
|
1061 glGetProgramInfoLog(program, value, &len, logbuf); |
|
1062 d->log = QString::fromLatin1(logbuf); |
|
1063 QString name = objectName(); |
|
1064 if (name.isEmpty()) |
|
1065 qWarning() << "QGLShader::setProgramBinary:" << d->log; |
|
1066 else |
|
1067 qWarning() << "QGLShader::setProgramBinary[" << name << "]:" << d->log; |
|
1068 delete [] logbuf; |
|
1069 } |
|
1070 return d->linked; |
|
1071 #else |
|
1072 Q_UNUSED(format); |
|
1073 Q_UNUSED(binary); |
|
1074 return false; |
|
1075 #endif |
|
1076 } |
|
1077 |
|
1078 /*! |
|
1079 Returns the list of program binary formats that are accepted by |
|
1080 this system for use with setProgramBinary(). |
|
1081 |
|
1082 \sa programBinary(), setProgramBinary() |
|
1083 */ |
|
1084 QList<int> QGLShaderProgram::programBinaryFormats() |
|
1085 { |
|
1086 #if defined(QT_OPENGL_ES_2) |
|
1087 GLint count = 0; |
|
1088 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS_OES, &count); |
|
1089 if (count <= 0) |
|
1090 return QList<int>(); |
|
1091 QVector<int> list; |
|
1092 list.resize(count); |
|
1093 glGetIntegerv(GL_PROGRAM_BINARY_FORMATS_OES, list.data()); |
|
1094 return list.toList(); |
|
1095 #else |
|
1096 return QList<int>(); |
|
1097 #endif |
|
1098 } |
|
1099 |
|
1100 /*! |
803 /*! |
1101 Links together the shaders that were added to this program with |
804 Links together the shaders that were added to this program with |
1102 addShader(). Returns true if the link was successful or |
805 addShader(). Returns true if the link was successful or |
1103 false otherwise. If the link failed, the error messages can |
806 false otherwise. If the link failed, the error messages can |
1104 be retrieved with log(). |
807 be retrieved with log(). |
1111 |
814 |
1112 \sa addShader(), log() |
815 \sa addShader(), log() |
1113 */ |
816 */ |
1114 bool QGLShaderProgram::link() |
817 bool QGLShaderProgram::link() |
1115 { |
818 { |
819 Q_D(QGLShaderProgram); |
|
1116 GLuint program = d->programGuard.id(); |
820 GLuint program = d->programGuard.id(); |
1117 if (!program) |
821 if (!program) |
1118 return false; |
822 return false; |
1119 if (d->hasPartialShaders) { |
|
1120 // Compile the partial vertex and fragment shaders. |
|
1121 QByteArray vertexSource; |
|
1122 QByteArray fragmentSource; |
|
1123 foreach (QGLShader *shader, d->shaders) { |
|
1124 if (shader->shaderType() == QGLShader::PartialVertexShader) |
|
1125 vertexSource += shader->sourceCode(); |
|
1126 else if (shader->shaderType() == QGLShader::PartialFragmentShader) |
|
1127 fragmentSource += shader->sourceCode(); |
|
1128 } |
|
1129 if (vertexSource.isEmpty()) { |
|
1130 if (d->vertexShader) { |
|
1131 glDetachShader(program, d->vertexShader->d->shaderGuard.id()); |
|
1132 delete d->vertexShader; |
|
1133 d->vertexShader = 0; |
|
1134 } |
|
1135 } else { |
|
1136 if (!d->vertexShader) { |
|
1137 d->vertexShader = |
|
1138 new QGLShader(QGLShader::VertexShader, this); |
|
1139 } |
|
1140 if (!d->vertexShader->compile(vertexSource)) { |
|
1141 d->log = d->vertexShader->log(); |
|
1142 return false; |
|
1143 } |
|
1144 glAttachShader(program, d->vertexShader->d->shaderGuard.id()); |
|
1145 } |
|
1146 if (fragmentSource.isEmpty()) { |
|
1147 if (d->fragmentShader) { |
|
1148 glDetachShader(program, d->fragmentShader->d->shaderGuard.id()); |
|
1149 delete d->fragmentShader; |
|
1150 d->fragmentShader = 0; |
|
1151 } |
|
1152 } else { |
|
1153 if (!d->fragmentShader) { |
|
1154 d->fragmentShader = |
|
1155 new QGLShader(QGLShader::FragmentShader, this); |
|
1156 } |
|
1157 if (!d->fragmentShader->compile(fragmentSource)) { |
|
1158 d->log = d->fragmentShader->log(); |
|
1159 return false; |
|
1160 } |
|
1161 glAttachShader(program, d->fragmentShader->d->shaderGuard.id()); |
|
1162 } |
|
1163 } |
|
1164 glLinkProgram(program); |
823 glLinkProgram(program); |
1165 GLint value = 0; |
824 GLint value = 0; |
1166 glGetProgramiv(program, GL_LINK_STATUS, &value); |
825 glGetProgramiv(program, GL_LINK_STATUS, &value); |
1167 d->linked = (value != 0); |
826 d->linked = (value != 0); |
1168 value = 0; |
827 value = 0; |
1188 |
847 |
1189 \sa link() |
848 \sa link() |
1190 */ |
849 */ |
1191 bool QGLShaderProgram::isLinked() const |
850 bool QGLShaderProgram::isLinked() const |
1192 { |
851 { |
852 Q_D(const QGLShaderProgram); |
|
1193 return d->linked; |
853 return d->linked; |
1194 } |
854 } |
1195 |
855 |
1196 /*! |
856 /*! |
1197 Returns the errors and warnings that occurred during the last link() |
857 Returns the errors and warnings that occurred during the last link() |
1199 |
859 |
1200 \sa link() |
860 \sa link() |
1201 */ |
861 */ |
1202 QString QGLShaderProgram::log() const |
862 QString QGLShaderProgram::log() const |
1203 { |
863 { |
864 Q_D(const QGLShaderProgram); |
|
1204 return d->log; |
865 return d->log; |
1205 } |
866 } |
1206 |
867 |
1207 /*! |
868 /*! |
1208 Enable use of this shader program in the currently active QGLContext. |
869 Binds this shader program to the active QGLContext and makes |
1209 Returns true if the program was successfully enabled; false |
870 it the current shader program. Any previously bound shader program |
1210 otherwise. If the shader program has not yet been linked, |
871 is released. This is equivalent to calling \c{glUseProgram()} on |
872 programId(). Returns true if the program was successfully bound; |
|
873 false otherwise. If the shader program has not yet been linked, |
|
1211 or it needs to be re-linked, this function will call link(). |
874 or it needs to be re-linked, this function will call link(). |
1212 |
875 |
1213 \sa link(), disable() |
876 \sa link(), release() |
1214 */ |
877 */ |
1215 bool QGLShaderProgram::enable() |
878 bool QGLShaderProgram::bind() |
1216 { |
879 { |
880 Q_D(QGLShaderProgram); |
|
1217 GLuint program = d->programGuard.id(); |
881 GLuint program = d->programGuard.id(); |
1218 if (!program) |
882 if (!program) |
1219 return false; |
883 return false; |
1220 if (!d->linked && !link()) |
884 if (!d->linked && !link()) |
1221 return false; |
885 return false; |
886 #ifndef QT_NO_DEBUG |
|
887 if (!QGLContext::areSharing(d->programGuard.context(), QGLContext::currentContext())) { |
|
888 qWarning("QGLShaderProgram::bind: program is not valid in the current context."); |
|
889 return false; |
|
890 } |
|
891 #endif |
|
1222 glUseProgram(program); |
892 glUseProgram(program); |
1223 return true; |
893 return true; |
1224 } |
894 } |
1225 |
895 |
1226 #undef ctx |
896 #undef ctx |
1227 #define ctx QGLContext::currentContext() |
897 #define ctx QGLContext::currentContext() |
1228 |
898 |
1229 /*! |
899 /*! |
1230 Disables the active shader program in the current QGLContext. |
900 Releases the active shader program from the current QGLContext. |
1231 This is equivalent to calling \c{glUseProgram(0)}. |
901 This is equivalent to calling \c{glUseProgram(0)}. |
1232 |
902 |
1233 \sa enable() |
903 \sa bind() |
1234 */ |
904 */ |
1235 void QGLShaderProgram::disable() |
905 void QGLShaderProgram::release() |
1236 { |
906 { |
907 #ifndef QT_NO_DEBUG |
|
908 Q_D(QGLShaderProgram); |
|
909 if (!QGLContext::areSharing(d->programGuard.context(), QGLContext::currentContext())) |
|
910 qWarning("QGLShaderProgram::release: program is not valid in the current context."); |
|
911 #endif |
|
1237 #if defined(QT_OPENGL_ES_2) |
912 #if defined(QT_OPENGL_ES_2) |
1238 glUseProgram(0); |
913 glUseProgram(0); |
1239 #else |
914 #else |
1240 if (glUseProgram) |
915 if (glUseProgram) |
1241 glUseProgram(0); |
916 glUseProgram(0); |
1250 |
925 |
1251 \sa QGLShader::shaderId() |
926 \sa QGLShader::shaderId() |
1252 */ |
927 */ |
1253 GLuint QGLShaderProgram::programId() const |
928 GLuint QGLShaderProgram::programId() const |
1254 { |
929 { |
930 Q_D(const QGLShaderProgram); |
|
1255 return d->programGuard.id(); |
931 return d->programGuard.id(); |
1256 } |
932 } |
1257 |
933 |
1258 /*! |
934 /*! |
1259 Binds the attribute \a name to the specified \a location. This |
935 Binds the attribute \a name to the specified \a location. This |
1263 |
939 |
1264 \sa attributeLocation() |
940 \sa attributeLocation() |
1265 */ |
941 */ |
1266 void QGLShaderProgram::bindAttributeLocation(const char *name, int location) |
942 void QGLShaderProgram::bindAttributeLocation(const char *name, int location) |
1267 { |
943 { |
1268 glBindAttribLocation(d->programGuard.id(), location, name); |
944 Q_D(QGLShaderProgram); |
945 if (!d->linked) { |
|
946 glBindAttribLocation(d->programGuard.id(), location, name); |
|
947 } else { |
|
948 qWarning() << "QGLShaderProgram::bindAttributeLocation(" << name |
|
949 << "): cannot bind after shader program is linked"; |
|
950 } |
|
1269 } |
951 } |
1270 |
952 |
1271 /*! |
953 /*! |
1272 \overload |
954 \overload |
1273 |
955 |
1278 |
960 |
1279 \sa attributeLocation() |
961 \sa attributeLocation() |
1280 */ |
962 */ |
1281 void QGLShaderProgram::bindAttributeLocation(const QByteArray& name, int location) |
963 void QGLShaderProgram::bindAttributeLocation(const QByteArray& name, int location) |
1282 { |
964 { |
1283 glBindAttribLocation(d->programGuard.id(), location, name.constData()); |
965 bindAttributeLocation(name.constData(), location); |
1284 } |
966 } |
1285 |
967 |
1286 /*! |
968 /*! |
1287 \overload |
969 \overload |
1288 |
970 |
1293 |
975 |
1294 \sa attributeLocation() |
976 \sa attributeLocation() |
1295 */ |
977 */ |
1296 void QGLShaderProgram::bindAttributeLocation(const QString& name, int location) |
978 void QGLShaderProgram::bindAttributeLocation(const QString& name, int location) |
1297 { |
979 { |
1298 glBindAttribLocation(d->programGuard.id(), location, name.toLatin1().constData()); |
980 bindAttributeLocation(name.toLatin1().constData(), location); |
1299 } |
981 } |
1300 |
982 |
1301 /*! |
983 /*! |
1302 Returns the location of the attribute \a name within this shader |
984 Returns the location of the attribute \a name within this shader |
1303 program's parameter list. Returns -1 if \a name is not a valid |
985 program's parameter list. Returns -1 if \a name is not a valid |
1305 |
987 |
1306 \sa uniformLocation(), bindAttributeLocation() |
988 \sa uniformLocation(), bindAttributeLocation() |
1307 */ |
989 */ |
1308 int QGLShaderProgram::attributeLocation(const char *name) const |
990 int QGLShaderProgram::attributeLocation(const char *name) const |
1309 { |
991 { |
992 Q_D(const QGLShaderProgram); |
|
1310 if (d->linked) { |
993 if (d->linked) { |
1311 return glGetAttribLocation(d->programGuard.id(), name); |
994 return glGetAttribLocation(d->programGuard.id(), name); |
1312 } else { |
995 } else { |
1313 qWarning() << "QGLShaderProgram::attributeLocation(" << name |
996 qWarning() << "QGLShaderProgram::attributeLocation(" << name |
1314 << "): shader program is not linked"; |
997 << "): shader program is not linked"; |
1349 |
1032 |
1350 \sa setUniformValue() |
1033 \sa setUniformValue() |
1351 */ |
1034 */ |
1352 void QGLShaderProgram::setAttributeValue(int location, GLfloat value) |
1035 void QGLShaderProgram::setAttributeValue(int location, GLfloat value) |
1353 { |
1036 { |
1037 Q_D(QGLShaderProgram); |
|
1038 Q_UNUSED(d); |
|
1354 if (location != -1) |
1039 if (location != -1) |
1355 glVertexAttrib1fv(location, &value); |
1040 glVertexAttrib1fv(location, &value); |
1356 } |
1041 } |
1357 |
1042 |
1358 /*! |
1043 /*! |
1373 |
1058 |
1374 \sa setUniformValue() |
1059 \sa setUniformValue() |
1375 */ |
1060 */ |
1376 void QGLShaderProgram::setAttributeValue(int location, GLfloat x, GLfloat y) |
1061 void QGLShaderProgram::setAttributeValue(int location, GLfloat x, GLfloat y) |
1377 { |
1062 { |
1063 Q_D(QGLShaderProgram); |
|
1064 Q_UNUSED(d); |
|
1378 if (location != -1) { |
1065 if (location != -1) { |
1379 GLfloat values[2] = {x, y}; |
1066 GLfloat values[2] = {x, y}; |
1380 glVertexAttrib2fv(location, values); |
1067 glVertexAttrib2fv(location, values); |
1381 } |
1068 } |
1382 } |
1069 } |
1401 \sa setUniformValue() |
1088 \sa setUniformValue() |
1402 */ |
1089 */ |
1403 void QGLShaderProgram::setAttributeValue |
1090 void QGLShaderProgram::setAttributeValue |
1404 (int location, GLfloat x, GLfloat y, GLfloat z) |
1091 (int location, GLfloat x, GLfloat y, GLfloat z) |
1405 { |
1092 { |
1093 Q_D(QGLShaderProgram); |
|
1094 Q_UNUSED(d); |
|
1406 if (location != -1) { |
1095 if (location != -1) { |
1407 GLfloat values[3] = {x, y, z}; |
1096 GLfloat values[3] = {x, y, z}; |
1408 glVertexAttrib3fv(location, values); |
1097 glVertexAttrib3fv(location, values); |
1409 } |
1098 } |
1410 } |
1099 } |
1430 \sa setUniformValue() |
1119 \sa setUniformValue() |
1431 */ |
1120 */ |
1432 void QGLShaderProgram::setAttributeValue |
1121 void QGLShaderProgram::setAttributeValue |
1433 (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) |
1122 (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) |
1434 { |
1123 { |
1124 Q_D(QGLShaderProgram); |
|
1125 Q_UNUSED(d); |
|
1435 if (location != -1) { |
1126 if (location != -1) { |
1436 GLfloat values[4] = {x, y, z, w}; |
1127 GLfloat values[4] = {x, y, z, w}; |
1437 glVertexAttrib4fv(location, values); |
1128 glVertexAttrib4fv(location, values); |
1438 } |
1129 } |
1439 } |
1130 } |
1457 |
1148 |
1458 \sa setUniformValue() |
1149 \sa setUniformValue() |
1459 */ |
1150 */ |
1460 void QGLShaderProgram::setAttributeValue(int location, const QVector2D& value) |
1151 void QGLShaderProgram::setAttributeValue(int location, const QVector2D& value) |
1461 { |
1152 { |
1153 Q_D(QGLShaderProgram); |
|
1154 Q_UNUSED(d); |
|
1462 if (location != -1) |
1155 if (location != -1) |
1463 glVertexAttrib2fv(location, reinterpret_cast<const GLfloat *>(&value)); |
1156 glVertexAttrib2fv(location, reinterpret_cast<const GLfloat *>(&value)); |
1464 } |
1157 } |
1465 |
1158 |
1466 /*! |
1159 /*! |
1480 |
1173 |
1481 \sa setUniformValue() |
1174 \sa setUniformValue() |
1482 */ |
1175 */ |
1483 void QGLShaderProgram::setAttributeValue(int location, const QVector3D& value) |
1176 void QGLShaderProgram::setAttributeValue(int location, const QVector3D& value) |
1484 { |
1177 { |
1178 Q_D(QGLShaderProgram); |
|
1179 Q_UNUSED(d); |
|
1485 if (location != -1) |
1180 if (location != -1) |
1486 glVertexAttrib3fv(location, reinterpret_cast<const GLfloat *>(&value)); |
1181 glVertexAttrib3fv(location, reinterpret_cast<const GLfloat *>(&value)); |
1487 } |
1182 } |
1488 |
1183 |
1489 /*! |
1184 /*! |
1503 |
1198 |
1504 \sa setUniformValue() |
1199 \sa setUniformValue() |
1505 */ |
1200 */ |
1506 void QGLShaderProgram::setAttributeValue(int location, const QVector4D& value) |
1201 void QGLShaderProgram::setAttributeValue(int location, const QVector4D& value) |
1507 { |
1202 { |
1203 Q_D(QGLShaderProgram); |
|
1204 Q_UNUSED(d); |
|
1508 if (location != -1) |
1205 if (location != -1) |
1509 glVertexAttrib4fv(location, reinterpret_cast<const GLfloat *>(&value)); |
1206 glVertexAttrib4fv(location, reinterpret_cast<const GLfloat *>(&value)); |
1510 } |
1207 } |
1511 |
1208 |
1512 /*! |
1209 /*! |
1526 |
1223 |
1527 \sa setUniformValue() |
1224 \sa setUniformValue() |
1528 */ |
1225 */ |
1529 void QGLShaderProgram::setAttributeValue(int location, const QColor& value) |
1226 void QGLShaderProgram::setAttributeValue(int location, const QColor& value) |
1530 { |
1227 { |
1228 Q_D(QGLShaderProgram); |
|
1229 Q_UNUSED(d); |
|
1531 if (location != -1) { |
1230 if (location != -1) { |
1532 GLfloat values[4] = {value.redF(), value.greenF(), value.blueF(), value.alphaF()}; |
1231 GLfloat values[4] = {value.redF(), value.greenF(), value.blueF(), value.alphaF()}; |
1533 glVertexAttrib4fv(location, values); |
1232 glVertexAttrib4fv(location, values); |
1534 } |
1233 } |
1535 } |
1234 } |
1556 \sa setUniformValue() |
1255 \sa setUniformValue() |
1557 */ |
1256 */ |
1558 void QGLShaderProgram::setAttributeValue |
1257 void QGLShaderProgram::setAttributeValue |
1559 (int location, const GLfloat *values, int columns, int rows) |
1258 (int location, const GLfloat *values, int columns, int rows) |
1560 { |
1259 { |
1260 Q_D(QGLShaderProgram); |
|
1261 Q_UNUSED(d); |
|
1561 if (rows < 1 || rows > 4) { |
1262 if (rows < 1 || rows > 4) { |
1562 qWarning() << "QGLShaderProgram::setAttributeValue: rows" << rows << "not supported"; |
1263 qWarning() << "QGLShaderProgram::setAttributeValue: rows" << rows << "not supported"; |
1563 return; |
1264 return; |
1564 } |
1265 } |
1565 if (location != -1) { |
1266 if (location != -1) { |
1595 setAttributeValue(attributeLocation(name), values, columns, rows); |
1296 setAttributeValue(attributeLocation(name), values, columns, rows); |
1596 } |
1297 } |
1597 |
1298 |
1598 /*! |
1299 /*! |
1599 Sets an array of vertex \a values on the attribute at \a location |
1300 Sets an array of vertex \a values on the attribute at \a location |
1600 in this shader program. The \a size indicates the number of |
1301 in this shader program. The \a tupleSize indicates the number of |
1601 components per vertex (1, 2, 3, or 4), and the \a stride indicates |
1302 components per vertex (1, 2, 3, or 4), and the \a stride indicates |
1602 the number of bytes between vertices. A default \a stride value |
1303 the number of bytes between vertices. A default \a stride value |
1603 of zero indicates that the vertices are densely packed in \a values. |
1304 of zero indicates that the vertices are densely packed in \a values. |
1604 |
1305 |
1605 \sa setAttributeValue(), setUniformValue(), disableAttributeArray() |
1306 The array will become active when enableAttributeArray() is called |
1307 on the \a location. Otherwise the value specified with |
|
1308 setAttributeValue() for \a location will be used. |
|
1309 |
|
1310 \sa setAttributeValue(), setUniformValue(), enableAttributeArray() |
|
1311 \sa disableAttributeArray() |
|
1606 */ |
1312 */ |
1607 void QGLShaderProgram::setAttributeArray |
1313 void QGLShaderProgram::setAttributeArray |
1608 (int location, const GLfloat *values, int size, int stride) |
1314 (int location, const GLfloat *values, int tupleSize, int stride) |
1609 { |
1315 { |
1316 Q_D(QGLShaderProgram); |
|
1317 Q_UNUSED(d); |
|
1610 if (location != -1) { |
1318 if (location != -1) { |
1611 glVertexAttribPointer(location, size, GL_FLOAT, GL_FALSE, |
1319 glVertexAttribPointer(location, tupleSize, GL_FLOAT, GL_FALSE, |
1612 stride, values); |
1320 stride, values); |
1613 glEnableVertexAttribArray(location); |
|
1614 } |
1321 } |
1615 } |
1322 } |
1616 |
1323 |
1617 /*! |
1324 /*! |
1618 Sets an array of 2D vertex \a values on the attribute at \a location |
1325 Sets an array of 2D vertex \a values on the attribute at \a location |
1619 in this shader program. The \a stride indicates the number of bytes |
1326 in this shader program. The \a stride indicates the number of bytes |
1620 between vertices. A default \a stride value of zero indicates that |
1327 between vertices. A default \a stride value of zero indicates that |
1621 the vertices are densely packed in \a values. |
1328 the vertices are densely packed in \a values. |
1622 |
1329 |
1623 \sa setAttributeValue(), setUniformValue(), disableAttributeArray() |
1330 The array will become active when enableAttributeArray() is called |
1331 on the \a location. Otherwise the value specified with |
|
1332 setAttributeValue() for \a location will be used. |
|
1333 |
|
1334 \sa setAttributeValue(), setUniformValue(), enableAttributeArray() |
|
1335 \sa disableAttributeArray() |
|
1624 */ |
1336 */ |
1625 void QGLShaderProgram::setAttributeArray |
1337 void QGLShaderProgram::setAttributeArray |
1626 (int location, const QVector2D *values, int stride) |
1338 (int location, const QVector2D *values, int stride) |
1627 { |
1339 { |
1340 Q_D(QGLShaderProgram); |
|
1341 Q_UNUSED(d); |
|
1628 if (location != -1) { |
1342 if (location != -1) { |
1629 glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, |
1343 glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, |
1630 stride, values); |
1344 stride, values); |
1631 glEnableVertexAttribArray(location); |
|
1632 } |
1345 } |
1633 } |
1346 } |
1634 |
1347 |
1635 /*! |
1348 /*! |
1636 Sets an array of 3D vertex \a values on the attribute at \a location |
1349 Sets an array of 3D vertex \a values on the attribute at \a location |
1637 in this shader program. The \a stride indicates the number of bytes |
1350 in this shader program. The \a stride indicates the number of bytes |
1638 between vertices. A default \a stride value of zero indicates that |
1351 between vertices. A default \a stride value of zero indicates that |
1639 the vertices are densely packed in \a values. |
1352 the vertices are densely packed in \a values. |
1640 |
1353 |
1641 \sa setAttributeValue(), setUniformValue(), disableAttributeArray() |
1354 The array will become active when enableAttributeArray() is called |
1355 on the \a location. Otherwise the value specified with |
|
1356 setAttributeValue() for \a location will be used. |
|
1357 |
|
1358 \sa setAttributeValue(), setUniformValue(), enableAttributeArray() |
|
1359 \sa disableAttributeArray() |
|
1642 */ |
1360 */ |
1643 void QGLShaderProgram::setAttributeArray |
1361 void QGLShaderProgram::setAttributeArray |
1644 (int location, const QVector3D *values, int stride) |
1362 (int location, const QVector3D *values, int stride) |
1645 { |
1363 { |
1364 Q_D(QGLShaderProgram); |
|
1365 Q_UNUSED(d); |
|
1646 if (location != -1) { |
1366 if (location != -1) { |
1647 glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, |
1367 glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, |
1648 stride, values); |
1368 stride, values); |
1649 glEnableVertexAttribArray(location); |
|
1650 } |
1369 } |
1651 } |
1370 } |
1652 |
1371 |
1653 /*! |
1372 /*! |
1654 Sets an array of 4D vertex \a values on the attribute at \a location |
1373 Sets an array of 4D vertex \a values on the attribute at \a location |
1655 in this shader program. The \a stride indicates the number of bytes |
1374 in this shader program. The \a stride indicates the number of bytes |
1656 between vertices. A default \a stride value of zero indicates that |
1375 between vertices. A default \a stride value of zero indicates that |
1657 the vertices are densely packed in \a values. |
1376 the vertices are densely packed in \a values. |
1658 |
1377 |
1659 \sa setAttributeValue(), setUniformValue(), disableAttributeArray() |
1378 The array will become active when enableAttributeArray() is called |
1379 on the \a location. Otherwise the value specified with |
|
1380 setAttributeValue() for \a location will be used. |
|
1381 |
|
1382 \sa setAttributeValue(), setUniformValue(), enableAttributeArray() |
|
1383 \sa disableAttributeArray() |
|
1660 */ |
1384 */ |
1661 void QGLShaderProgram::setAttributeArray |
1385 void QGLShaderProgram::setAttributeArray |
1662 (int location, const QVector4D *values, int stride) |
1386 (int location, const QVector4D *values, int stride) |
1663 { |
1387 { |
1388 Q_D(QGLShaderProgram); |
|
1389 Q_UNUSED(d); |
|
1664 if (location != -1) { |
1390 if (location != -1) { |
1665 glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, |
1391 glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, |
1666 stride, values); |
1392 stride, values); |
1667 glEnableVertexAttribArray(location); |
|
1668 } |
1393 } |
1669 } |
1394 } |
1670 |
1395 |
1671 /*! |
1396 /*! |
1672 \overload |
1397 \overload |
1673 |
1398 |
1674 Sets an array of vertex \a values on the attribute called \a name |
1399 Sets an array of vertex \a values on the attribute called \a name |
1675 in this shader program. The \a size indicates the number of |
1400 in this shader program. The \a tupleSize indicates the number of |
1676 components per vertex (1, 2, 3, or 4), and the \a stride indicates |
1401 components per vertex (1, 2, 3, or 4), and the \a stride indicates |
1677 the number of bytes between vertices. A default \a stride value |
1402 the number of bytes between vertices. A default \a stride value |
1678 of zero indicates that the vertices are densely packed in \a values. |
1403 of zero indicates that the vertices are densely packed in \a values. |
1679 |
1404 |
1680 \sa setAttributeValue(), setUniformValue(), disableAttributeArray() |
1405 The array will become active when enableAttributeArray() is called |
1406 on \a name. Otherwise the value specified with setAttributeValue() |
|
1407 for \a name will be used. |
|
1408 |
|
1409 \sa setAttributeValue(), setUniformValue(), enableAttributeArray() |
|
1410 \sa disableAttributeArray() |
|
1681 */ |
1411 */ |
1682 void QGLShaderProgram::setAttributeArray |
1412 void QGLShaderProgram::setAttributeArray |
1683 (const char *name, const GLfloat *values, int size, int stride) |
1413 (const char *name, const GLfloat *values, int tupleSize, int stride) |
1684 { |
1414 { |
1685 setAttributeArray(attributeLocation(name), values, size, stride); |
1415 setAttributeArray(attributeLocation(name), values, tupleSize, stride); |
1686 } |
1416 } |
1687 |
1417 |
1688 /*! |
1418 /*! |
1689 \overload |
1419 \overload |
1690 |
1420 |
1691 Sets an array of 2D vertex \a values on the attribute called \a name |
1421 Sets an array of 2D vertex \a values on the attribute called \a name |
1692 in this shader program. The \a stride indicates the number of bytes |
1422 in this shader program. The \a stride indicates the number of bytes |
1693 between vertices. A default \a stride value of zero indicates that |
1423 between vertices. A default \a stride value of zero indicates that |
1694 the vertices are densely packed in \a values. |
1424 the vertices are densely packed in \a values. |
1695 |
1425 |
1696 \sa setAttributeValue(), setUniformValue(), disableAttributeArray() |
1426 The array will become active when enableAttributeArray() is called |
1427 on \a name. Otherwise the value specified with setAttributeValue() |
|
1428 for \a name will be used. |
|
1429 |
|
1430 \sa setAttributeValue(), setUniformValue(), enableAttributeArray() |
|
1431 \sa disableAttributeArray() |
|
1697 */ |
1432 */ |
1698 void QGLShaderProgram::setAttributeArray |
1433 void QGLShaderProgram::setAttributeArray |
1699 (const char *name, const QVector2D *values, int stride) |
1434 (const char *name, const QVector2D *values, int stride) |
1700 { |
1435 { |
1701 setAttributeArray(attributeLocation(name), values, stride); |
1436 setAttributeArray(attributeLocation(name), values, stride); |
1707 Sets an array of 3D vertex \a values on the attribute called \a name |
1442 Sets an array of 3D vertex \a values on the attribute called \a name |
1708 in this shader program. The \a stride indicates the number of bytes |
1443 in this shader program. The \a stride indicates the number of bytes |
1709 between vertices. A default \a stride value of zero indicates that |
1444 between vertices. A default \a stride value of zero indicates that |
1710 the vertices are densely packed in \a values. |
1445 the vertices are densely packed in \a values. |
1711 |
1446 |
1712 \sa setAttributeValue(), setUniformValue(), disableAttributeArray() |
1447 The array will become active when enableAttributeArray() is called |
1448 on \a name. Otherwise the value specified with setAttributeValue() |
|
1449 for \a name will be used. |
|
1450 |
|
1451 \sa setAttributeValue(), setUniformValue(), enableAttributeArray() |
|
1452 \sa disableAttributeArray() |
|
1713 */ |
1453 */ |
1714 void QGLShaderProgram::setAttributeArray |
1454 void QGLShaderProgram::setAttributeArray |
1715 (const char *name, const QVector3D *values, int stride) |
1455 (const char *name, const QVector3D *values, int stride) |
1716 { |
1456 { |
1717 setAttributeArray(attributeLocation(name), values, stride); |
1457 setAttributeArray(attributeLocation(name), values, stride); |
1723 Sets an array of 4D vertex \a values on the attribute called \a name |
1463 Sets an array of 4D vertex \a values on the attribute called \a name |
1724 in this shader program. The \a stride indicates the number of bytes |
1464 in this shader program. The \a stride indicates the number of bytes |
1725 between vertices. A default \a stride value of zero indicates that |
1465 between vertices. A default \a stride value of zero indicates that |
1726 the vertices are densely packed in \a values. |
1466 the vertices are densely packed in \a values. |
1727 |
1467 |
1728 \sa setAttributeValue(), setUniformValue(), disableAttributeArray() |
1468 The array will become active when enableAttributeArray() is called |
1469 on \a name. Otherwise the value specified with setAttributeValue() |
|
1470 for \a name will be used. |
|
1471 |
|
1472 \sa setAttributeValue(), setUniformValue(), enableAttributeArray() |
|
1473 \sa disableAttributeArray() |
|
1729 */ |
1474 */ |
1730 void QGLShaderProgram::setAttributeArray |
1475 void QGLShaderProgram::setAttributeArray |
1731 (const char *name, const QVector4D *values, int stride) |
1476 (const char *name, const QVector4D *values, int stride) |
1732 { |
1477 { |
1733 setAttributeArray(attributeLocation(name), values, stride); |
1478 setAttributeArray(attributeLocation(name), values, stride); |
1734 } |
1479 } |
1735 |
1480 |
1736 /*! |
1481 /*! |
1482 Enables the vertex array at \a location in this shader program |
|
1483 so that the value set by setAttributeArray() on \a location |
|
1484 will be used by the shader program. |
|
1485 |
|
1486 \sa disableAttributeArray(), setAttributeArray(), setAttributeValue() |
|
1487 \sa setUniformValue() |
|
1488 */ |
|
1489 void QGLShaderProgram::enableAttributeArray(int location) |
|
1490 { |
|
1491 Q_D(QGLShaderProgram); |
|
1492 Q_UNUSED(d); |
|
1493 if (location != -1) |
|
1494 glEnableVertexAttribArray(location); |
|
1495 } |
|
1496 |
|
1497 /*! |
|
1498 \overload |
|
1499 |
|
1500 Enables the vertex array called \a name in this shader program |
|
1501 so that the value set by setAttributeArray() on \a name |
|
1502 will be used by the shader program. |
|
1503 |
|
1504 \sa disableAttributeArray(), setAttributeArray(), setAttributeValue() |
|
1505 \sa setUniformValue() |
|
1506 */ |
|
1507 void QGLShaderProgram::enableAttributeArray(const char *name) |
|
1508 { |
|
1509 enableAttributeArray(attributeLocation(name)); |
|
1510 } |
|
1511 |
|
1512 /*! |
|
1737 Disables the vertex array at \a location in this shader program |
1513 Disables the vertex array at \a location in this shader program |
1738 that was enabled by a previous call to setAttributeArray(). |
1514 that was enabled by a previous call to enableAttributeArray(). |
1739 |
1515 |
1740 \sa setAttributeArray(), setAttributeValue(), setUniformValue() |
1516 \sa enableAttributeArray(), setAttributeArray(), setAttributeValue() |
1517 \sa setUniformValue() |
|
1741 */ |
1518 */ |
1742 void QGLShaderProgram::disableAttributeArray(int location) |
1519 void QGLShaderProgram::disableAttributeArray(int location) |
1743 { |
1520 { |
1521 Q_D(QGLShaderProgram); |
|
1522 Q_UNUSED(d); |
|
1744 if (location != -1) |
1523 if (location != -1) |
1745 glDisableVertexAttribArray(location); |
1524 glDisableVertexAttribArray(location); |
1746 } |
1525 } |
1747 |
1526 |
1748 /*! |
1527 /*! |
1749 \overload |
1528 \overload |
1750 |
1529 |
1751 Disables the vertex array called \a name in this shader program |
1530 Disables the vertex array called \a name in this shader program |
1752 that was enabled by a previous call to setAttributeArray(). |
1531 that was enabled by a previous call to enableAttributeArray(). |
1753 |
1532 |
1754 \sa setAttributeArray(), setAttributeValue(), setUniformValue() |
1533 \sa enableAttributeArray(), setAttributeArray(), setAttributeValue() |
1534 \sa setUniformValue() |
|
1755 */ |
1535 */ |
1756 void QGLShaderProgram::disableAttributeArray(const char *name) |
1536 void QGLShaderProgram::disableAttributeArray(const char *name) |
1757 { |
1537 { |
1758 disableAttributeArray(attributeLocation(name)); |
1538 disableAttributeArray(attributeLocation(name)); |
1759 } |
1539 } |
1765 |
1545 |
1766 \sa attributeLocation() |
1546 \sa attributeLocation() |
1767 */ |
1547 */ |
1768 int QGLShaderProgram::uniformLocation(const char *name) const |
1548 int QGLShaderProgram::uniformLocation(const char *name) const |
1769 { |
1549 { |
1550 Q_D(const QGLShaderProgram); |
|
1551 Q_UNUSED(d); |
|
1770 if (d->linked) { |
1552 if (d->linked) { |
1771 return glGetUniformLocation(d->programGuard.id(), name); |
1553 return glGetUniformLocation(d->programGuard.id(), name); |
1772 } else { |
1554 } else { |
1773 qWarning() << "QGLShaderProgram::uniformLocation(" << name |
1555 qWarning() << "QGLShaderProgram::uniformLocation(" << name |
1774 << "): shader program is not linked"; |
1556 << "): shader program is not linked"; |
1809 |
1591 |
1810 \sa setAttributeValue() |
1592 \sa setAttributeValue() |
1811 */ |
1593 */ |
1812 void QGLShaderProgram::setUniformValue(int location, GLfloat value) |
1594 void QGLShaderProgram::setUniformValue(int location, GLfloat value) |
1813 { |
1595 { |
1596 Q_D(QGLShaderProgram); |
|
1597 Q_UNUSED(d); |
|
1814 if (location != -1) |
1598 if (location != -1) |
1815 glUniform1fv(location, 1, &value); |
1599 glUniform1fv(location, 1, &value); |
1816 } |
1600 } |
1817 |
1601 |
1818 /*! |
1602 /*! |
1833 |
1617 |
1834 \sa setAttributeValue() |
1618 \sa setAttributeValue() |
1835 */ |
1619 */ |
1836 void QGLShaderProgram::setUniformValue(int location, GLint value) |
1620 void QGLShaderProgram::setUniformValue(int location, GLint value) |
1837 { |
1621 { |
1622 Q_D(QGLShaderProgram); |
|
1623 Q_UNUSED(d); |
|
1838 if (location != -1) |
1624 if (location != -1) |
1839 glUniform1i(location, value); |
1625 glUniform1i(location, value); |
1840 } |
1626 } |
1841 |
1627 |
1842 /*! |
1628 /*! |
1858 |
1644 |
1859 \sa setAttributeValue() |
1645 \sa setAttributeValue() |
1860 */ |
1646 */ |
1861 void QGLShaderProgram::setUniformValue(int location, GLuint value) |
1647 void QGLShaderProgram::setUniformValue(int location, GLuint value) |
1862 { |
1648 { |
1649 Q_D(QGLShaderProgram); |
|
1650 Q_UNUSED(d); |
|
1863 if (location != -1) |
1651 if (location != -1) |
1864 glUniform1i(location, value); |
1652 glUniform1i(location, value); |
1865 } |
1653 } |
1866 |
1654 |
1867 /*! |
1655 /*! |
1883 |
1671 |
1884 \sa setAttributeValue() |
1672 \sa setAttributeValue() |
1885 */ |
1673 */ |
1886 void QGLShaderProgram::setUniformValue(int location, GLfloat x, GLfloat y) |
1674 void QGLShaderProgram::setUniformValue(int location, GLfloat x, GLfloat y) |
1887 { |
1675 { |
1676 Q_D(QGLShaderProgram); |
|
1677 Q_UNUSED(d); |
|
1888 if (location != -1) { |
1678 if (location != -1) { |
1889 GLfloat values[2] = {x, y}; |
1679 GLfloat values[2] = {x, y}; |
1890 glUniform2fv(location, 1, values); |
1680 glUniform2fv(location, 1, values); |
1891 } |
1681 } |
1892 } |
1682 } |
1911 \sa setAttributeValue() |
1701 \sa setAttributeValue() |
1912 */ |
1702 */ |
1913 void QGLShaderProgram::setUniformValue |
1703 void QGLShaderProgram::setUniformValue |
1914 (int location, GLfloat x, GLfloat y, GLfloat z) |
1704 (int location, GLfloat x, GLfloat y, GLfloat z) |
1915 { |
1705 { |
1706 Q_D(QGLShaderProgram); |
|
1707 Q_UNUSED(d); |
|
1916 if (location != -1) { |
1708 if (location != -1) { |
1917 GLfloat values[3] = {x, y, z}; |
1709 GLfloat values[3] = {x, y, z}; |
1918 glUniform3fv(location, 1, values); |
1710 glUniform3fv(location, 1, values); |
1919 } |
1711 } |
1920 } |
1712 } |
1940 \sa setAttributeValue() |
1732 \sa setAttributeValue() |
1941 */ |
1733 */ |
1942 void QGLShaderProgram::setUniformValue |
1734 void QGLShaderProgram::setUniformValue |
1943 (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) |
1735 (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) |
1944 { |
1736 { |
1737 Q_D(QGLShaderProgram); |
|
1738 Q_UNUSED(d); |
|
1945 if (location != -1) { |
1739 if (location != -1) { |
1946 GLfloat values[4] = {x, y, z, w}; |
1740 GLfloat values[4] = {x, y, z, w}; |
1947 glUniform4fv(location, 1, values); |
1741 glUniform4fv(location, 1, values); |
1948 } |
1742 } |
1949 } |
1743 } |
1967 |
1761 |
1968 \sa setAttributeValue() |
1762 \sa setAttributeValue() |
1969 */ |
1763 */ |
1970 void QGLShaderProgram::setUniformValue(int location, const QVector2D& value) |
1764 void QGLShaderProgram::setUniformValue(int location, const QVector2D& value) |
1971 { |
1765 { |
1766 Q_D(QGLShaderProgram); |
|
1767 Q_UNUSED(d); |
|
1972 if (location != -1) |
1768 if (location != -1) |
1973 glUniform2fv(location, 1, reinterpret_cast<const GLfloat *>(&value)); |
1769 glUniform2fv(location, 1, reinterpret_cast<const GLfloat *>(&value)); |
1974 } |
1770 } |
1975 |
1771 |
1976 /*! |
1772 /*! |
1991 |
1787 |
1992 \sa setAttributeValue() |
1788 \sa setAttributeValue() |
1993 */ |
1789 */ |
1994 void QGLShaderProgram::setUniformValue(int location, const QVector3D& value) |
1790 void QGLShaderProgram::setUniformValue(int location, const QVector3D& value) |
1995 { |
1791 { |
1792 Q_D(QGLShaderProgram); |
|
1793 Q_UNUSED(d); |
|
1996 if (location != -1) |
1794 if (location != -1) |
1997 glUniform3fv(location, 1, reinterpret_cast<const GLfloat *>(&value)); |
1795 glUniform3fv(location, 1, reinterpret_cast<const GLfloat *>(&value)); |
1998 } |
1796 } |
1999 |
1797 |
2000 /*! |
1798 /*! |
2015 |
1813 |
2016 \sa setAttributeValue() |
1814 \sa setAttributeValue() |
2017 */ |
1815 */ |
2018 void QGLShaderProgram::setUniformValue(int location, const QVector4D& value) |
1816 void QGLShaderProgram::setUniformValue(int location, const QVector4D& value) |
2019 { |
1817 { |
1818 Q_D(QGLShaderProgram); |
|
1819 Q_UNUSED(d); |
|
2020 if (location != -1) |
1820 if (location != -1) |
2021 glUniform4fv(location, 1, reinterpret_cast<const GLfloat *>(&value)); |
1821 glUniform4fv(location, 1, reinterpret_cast<const GLfloat *>(&value)); |
2022 } |
1822 } |
2023 |
1823 |
2024 /*! |
1824 /*! |
2040 |
1840 |
2041 \sa setAttributeValue() |
1841 \sa setAttributeValue() |
2042 */ |
1842 */ |
2043 void QGLShaderProgram::setUniformValue(int location, const QColor& color) |
1843 void QGLShaderProgram::setUniformValue(int location, const QColor& color) |
2044 { |
1844 { |
1845 Q_D(QGLShaderProgram); |
|
1846 Q_UNUSED(d); |
|
2045 if (location != -1) { |
1847 if (location != -1) { |
2046 GLfloat values[4] = {color.redF(), color.greenF(), color.blueF(), color.alphaF()}; |
1848 GLfloat values[4] = {color.redF(), color.greenF(), color.blueF(), color.alphaF()}; |
2047 glUniform4fv(location, 1, values); |
1849 glUniform4fv(location, 1, values); |
2048 } |
1850 } |
2049 } |
1851 } |
2067 |
1869 |
2068 \sa setAttributeValue() |
1870 \sa setAttributeValue() |
2069 */ |
1871 */ |
2070 void QGLShaderProgram::setUniformValue(int location, const QPoint& point) |
1872 void QGLShaderProgram::setUniformValue(int location, const QPoint& point) |
2071 { |
1873 { |
1874 Q_D(QGLShaderProgram); |
|
1875 Q_UNUSED(d); |
|
2072 if (location != -1) { |
1876 if (location != -1) { |
2073 GLfloat values[4] = {point.x(), point.y()}; |
1877 GLfloat values[4] = {point.x(), point.y()}; |
2074 glUniform2fv(location, 1, values); |
1878 glUniform2fv(location, 1, values); |
2075 } |
1879 } |
2076 } |
1880 } |
2094 |
1898 |
2095 \sa setAttributeValue() |
1899 \sa setAttributeValue() |
2096 */ |
1900 */ |
2097 void QGLShaderProgram::setUniformValue(int location, const QPointF& point) |
1901 void QGLShaderProgram::setUniformValue(int location, const QPointF& point) |
2098 { |
1902 { |
1903 Q_D(QGLShaderProgram); |
|
1904 Q_UNUSED(d); |
|
2099 if (location != -1) { |
1905 if (location != -1) { |
2100 GLfloat values[4] = {point.x(), point.y()}; |
1906 GLfloat values[4] = {point.x(), point.y()}; |
2101 glUniform2fv(location, 1, values); |
1907 glUniform2fv(location, 1, values); |
2102 } |
1908 } |
2103 } |
1909 } |
2121 |
1927 |
2122 \sa setAttributeValue() |
1928 \sa setAttributeValue() |
2123 */ |
1929 */ |
2124 void QGLShaderProgram::setUniformValue(int location, const QSize& size) |
1930 void QGLShaderProgram::setUniformValue(int location, const QSize& size) |
2125 { |
1931 { |
1932 Q_D(QGLShaderProgram); |
|
1933 Q_UNUSED(d); |
|
2126 if (location != -1) { |
1934 if (location != -1) { |
2127 GLfloat values[4] = {size.width(), size.width()}; |
1935 GLfloat values[4] = {size.width(), size.width()}; |
2128 glUniform2fv(location, 1, values); |
1936 glUniform2fv(location, 1, values); |
2129 } |
1937 } |
2130 } |
1938 } |
2148 |
1956 |
2149 \sa setAttributeValue() |
1957 \sa setAttributeValue() |
2150 */ |
1958 */ |
2151 void QGLShaderProgram::setUniformValue(int location, const QSizeF& size) |
1959 void QGLShaderProgram::setUniformValue(int location, const QSizeF& size) |
2152 { |
1960 { |
1961 Q_D(QGLShaderProgram); |
|
1962 Q_UNUSED(d); |
|
2153 if (location != -1) { |
1963 if (location != -1) { |
2154 GLfloat values[4] = {size.width(), size.height()}; |
1964 GLfloat values[4] = {size.width(), size.height()}; |
2155 glUniform2fv(location, 1, values); |
1965 glUniform2fv(location, 1, values); |
2156 } |
1966 } |
2157 } |
1967 } |
2227 |
2037 |
2228 \sa setAttributeValue() |
2038 \sa setAttributeValue() |
2229 */ |
2039 */ |
2230 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value) |
2040 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value) |
2231 { |
2041 { |
2042 Q_D(QGLShaderProgram); |
|
2043 Q_UNUSED(d); |
|
2232 setUniformMatrix(glUniformMatrix2fv, location, value, 2, 2); |
2044 setUniformMatrix(glUniformMatrix2fv, location, value, 2, 2); |
2233 } |
2045 } |
2234 |
2046 |
2235 /*! |
2047 /*! |
2236 \overload |
2048 \overload |
2251 |
2063 |
2252 \sa setAttributeValue() |
2064 \sa setAttributeValue() |
2253 */ |
2065 */ |
2254 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value) |
2066 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value) |
2255 { |
2067 { |
2068 Q_D(QGLShaderProgram); |
|
2069 Q_UNUSED(d); |
|
2256 setUniformGenericMatrix |
2070 setUniformGenericMatrix |
2257 (glUniformMatrix2x3fv, glUniform3fv, location, value, 2, 3); |
2071 (glUniformMatrix2x3fv, glUniform3fv, location, value, 2, 3); |
2258 } |
2072 } |
2259 |
2073 |
2260 /*! |
2074 /*! |
2276 |
2090 |
2277 \sa setAttributeValue() |
2091 \sa setAttributeValue() |
2278 */ |
2092 */ |
2279 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value) |
2093 void QGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value) |
2280 { |
2094 { |
2095 Q_D(QGLShaderProgram); |
|
2096 Q_UNUSED(d); |
|
2281 setUniformGenericMatrix |
2097 setUniformGenericMatrix |
2282 (glUniformMatrix2x4fv, glUniform4fv, location, value, 2, 4); |
2098 (glUniformMatrix2x4fv, glUniform4fv, location, value, 2, 4); |
2283 } |
2099 } |
2284 |
2100 |
2285 /*! |
2101 /*! |
2301 |
2117 |
2302 \sa setAttributeValue() |
2118 \sa setAttributeValue() |
2303 */ |
2119 */ |
2304 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value) |
2120 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value) |
2305 { |
2121 { |
2122 Q_D(QGLShaderProgram); |
|
2123 Q_UNUSED(d); |
|
2306 setUniformGenericMatrix |
2124 setUniformGenericMatrix |
2307 (glUniformMatrix3x2fv, glUniform2fv, location, value, 3, 2); |
2125 (glUniformMatrix3x2fv, glUniform2fv, location, value, 3, 2); |
2308 } |
2126 } |
2309 |
2127 |
2310 /*! |
2128 /*! |
2326 |
2144 |
2327 \sa setAttributeValue() |
2145 \sa setAttributeValue() |
2328 */ |
2146 */ |
2329 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value) |
2147 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value) |
2330 { |
2148 { |
2149 Q_D(QGLShaderProgram); |
|
2150 Q_UNUSED(d); |
|
2331 setUniformMatrix(glUniformMatrix3fv, location, value, 3, 3); |
2151 setUniformMatrix(glUniformMatrix3fv, location, value, 3, 3); |
2332 } |
2152 } |
2333 |
2153 |
2334 /*! |
2154 /*! |
2335 \overload |
2155 \overload |
2350 |
2170 |
2351 \sa setAttributeValue() |
2171 \sa setAttributeValue() |
2352 */ |
2172 */ |
2353 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value) |
2173 void QGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value) |
2354 { |
2174 { |
2175 Q_D(QGLShaderProgram); |
|
2176 Q_UNUSED(d); |
|
2355 setUniformGenericMatrix |
2177 setUniformGenericMatrix |
2356 (glUniformMatrix3x4fv, glUniform4fv, location, value, 3, 4); |
2178 (glUniformMatrix3x4fv, glUniform4fv, location, value, 3, 4); |
2357 } |
2179 } |
2358 |
2180 |
2359 /*! |
2181 /*! |
2375 |
2197 |
2376 \sa setAttributeValue() |
2198 \sa setAttributeValue() |
2377 */ |
2199 */ |
2378 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value) |
2200 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value) |
2379 { |
2201 { |
2202 Q_D(QGLShaderProgram); |
|
2203 Q_UNUSED(d); |
|
2380 setUniformGenericMatrix |
2204 setUniformGenericMatrix |
2381 (glUniformMatrix4x2fv, glUniform2fv, location, value, 4, 2); |
2205 (glUniformMatrix4x2fv, glUniform2fv, location, value, 4, 2); |
2382 } |
2206 } |
2383 |
2207 |
2384 /*! |
2208 /*! |
2400 |
2224 |
2401 \sa setAttributeValue() |
2225 \sa setAttributeValue() |
2402 */ |
2226 */ |
2403 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value) |
2227 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value) |
2404 { |
2228 { |
2229 Q_D(QGLShaderProgram); |
|
2230 Q_UNUSED(d); |
|
2405 setUniformGenericMatrix |
2231 setUniformGenericMatrix |
2406 (glUniformMatrix4x3fv, glUniform3fv, location, value, 4, 3); |
2232 (glUniformMatrix4x3fv, glUniform3fv, location, value, 4, 3); |
2407 } |
2233 } |
2408 |
2234 |
2409 /*! |
2235 /*! |
2425 |
2251 |
2426 \sa setAttributeValue() |
2252 \sa setAttributeValue() |
2427 */ |
2253 */ |
2428 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value) |
2254 void QGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value) |
2429 { |
2255 { |
2256 Q_D(QGLShaderProgram); |
|
2257 Q_UNUSED(d); |
|
2430 setUniformMatrix(glUniformMatrix4fv, location, value, 4, 4); |
2258 setUniformMatrix(glUniformMatrix4fv, location, value, 4, 4); |
2431 } |
2259 } |
2432 |
2260 |
2433 /*! |
2261 /*! |
2434 \overload |
2262 \overload |
2452 |
2280 |
2453 \sa setAttributeValue() |
2281 \sa setAttributeValue() |
2454 */ |
2282 */ |
2455 void QGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4]) |
2283 void QGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4]) |
2456 { |
2284 { |
2285 Q_D(QGLShaderProgram); |
|
2286 Q_UNUSED(d); |
|
2457 if (location != -1) |
2287 if (location != -1) |
2458 glUniformMatrix4fv(location, 1, GL_FALSE, value[0]); |
2288 glUniformMatrix4fv(location, 1, GL_FALSE, value[0]); |
2459 } |
2289 } |
2460 |
2290 |
2461 /*! |
2291 /*! |
2479 To set a QTransform value as a 4x4 matrix in a shader, use |
2309 To set a QTransform value as a 4x4 matrix in a shader, use |
2480 \c{setUniformValue(location, QMatrix4x4(value))}. |
2310 \c{setUniformValue(location, QMatrix4x4(value))}. |
2481 */ |
2311 */ |
2482 void QGLShaderProgram::setUniformValue(int location, const QTransform& value) |
2312 void QGLShaderProgram::setUniformValue(int location, const QTransform& value) |
2483 { |
2313 { |
2314 Q_D(QGLShaderProgram); |
|
2315 Q_UNUSED(d); |
|
2484 if (location != -1) { |
2316 if (location != -1) { |
2485 GLfloat mat[3][3] = { |
2317 GLfloat mat[3][3] = { |
2486 {value.m11(), value.m12(), value.m13()}, |
2318 {value.m11(), value.m12(), value.m13()}, |
2487 {value.m21(), value.m22(), value.m23()}, |
2319 {value.m21(), value.m22(), value.m23()}, |
2488 {value.m31(), value.m32(), value.m33()} |
2320 {value.m31(), value.m32(), value.m33()} |
2512 |
2344 |
2513 \sa setAttributeValue() |
2345 \sa setAttributeValue() |
2514 */ |
2346 */ |
2515 void QGLShaderProgram::setUniformValueArray(int location, const GLint *values, int count) |
2347 void QGLShaderProgram::setUniformValueArray(int location, const GLint *values, int count) |
2516 { |
2348 { |
2349 Q_D(QGLShaderProgram); |
|
2350 Q_UNUSED(d); |
|
2517 if (location != -1) |
2351 if (location != -1) |
2518 glUniform1iv(location, count, values); |
2352 glUniform1iv(location, count, values); |
2519 } |
2353 } |
2520 |
2354 |
2521 /*! |
2355 /*! |
2539 |
2373 |
2540 \sa setAttributeValue() |
2374 \sa setAttributeValue() |
2541 */ |
2375 */ |
2542 void QGLShaderProgram::setUniformValueArray(int location, const GLuint *values, int count) |
2376 void QGLShaderProgram::setUniformValueArray(int location, const GLuint *values, int count) |
2543 { |
2377 { |
2378 Q_D(QGLShaderProgram); |
|
2379 Q_UNUSED(d); |
|
2544 if (location != -1) |
2380 if (location != -1) |
2545 glUniform1iv(location, count, reinterpret_cast<const GLint *>(values)); |
2381 glUniform1iv(location, count, reinterpret_cast<const GLint *>(values)); |
2546 } |
2382 } |
2547 |
2383 |
2548 /*! |
2384 /*! |
2561 } |
2397 } |
2562 |
2398 |
2563 /*! |
2399 /*! |
2564 Sets the uniform variable array at \a location in the current |
2400 Sets the uniform variable array at \a location in the current |
2565 context to the \a count elements of \a values. Each element |
2401 context to the \a count elements of \a values. Each element |
2566 has \a size components. The \a size must be 1, 2, 3, or 4. |
2402 has \a tupleSize components. The \a tupleSize must be 1, 2, 3, or 4. |
2567 |
2403 |
2568 \sa setAttributeValue() |
2404 \sa setAttributeValue() |
2569 */ |
2405 */ |
2570 void QGLShaderProgram::setUniformValueArray(int location, const GLfloat *values, int count, int size) |
2406 void QGLShaderProgram::setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize) |
2571 { |
2407 { |
2408 Q_D(QGLShaderProgram); |
|
2409 Q_UNUSED(d); |
|
2572 if (location != -1) { |
2410 if (location != -1) { |
2573 if (size == 1) |
2411 if (tupleSize == 1) |
2574 glUniform1fv(location, count, values); |
2412 glUniform1fv(location, count, values); |
2575 else if (size == 2) |
2413 else if (tupleSize == 2) |
2576 glUniform2fv(location, count, values); |
2414 glUniform2fv(location, count, values); |
2577 else if (size == 3) |
2415 else if (tupleSize == 3) |
2578 glUniform3fv(location, count, values); |
2416 glUniform3fv(location, count, values); |
2579 else if (size == 4) |
2417 else if (tupleSize == 4) |
2580 glUniform4fv(location, count, values); |
2418 glUniform4fv(location, count, values); |
2581 else |
2419 else |
2582 qWarning() << "QGLShaderProgram::setUniformValue: size" << size << "not supported"; |
2420 qWarning() << "QGLShaderProgram::setUniformValue: size" << tupleSize << "not supported"; |
2583 } |
2421 } |
2584 } |
2422 } |
2585 |
2423 |
2586 /*! |
2424 /*! |
2587 \overload |
2425 \overload |
2588 |
2426 |
2589 Sets the uniform variable array called \a name in the current |
2427 Sets the uniform variable array called \a name in the current |
2590 context to the \a count elements of \a values. Each element |
2428 context to the \a count elements of \a values. Each element |
2591 has \a size components. The \a size must be 1, 2, 3, or 4. |
2429 has \a tupleSize components. The \a tupleSize must be 1, 2, 3, or 4. |
2592 |
2430 |
2593 \sa setAttributeValue() |
2431 \sa setAttributeValue() |
2594 */ |
2432 */ |
2595 void QGLShaderProgram::setUniformValueArray |
2433 void QGLShaderProgram::setUniformValueArray |
2596 (const char *name, const GLfloat *values, int count, int size) |
2434 (const char *name, const GLfloat *values, int count, int tupleSize) |
2597 { |
2435 { |
2598 setUniformValueArray(uniformLocation(name), values, count, size); |
2436 setUniformValueArray(uniformLocation(name), values, count, tupleSize); |
2599 } |
2437 } |
2600 |
2438 |
2601 /*! |
2439 /*! |
2602 Sets the uniform variable array at \a location in the current |
2440 Sets the uniform variable array at \a location in the current |
2603 context to the \a count 2D vector elements of \a values. |
2441 context to the \a count 2D vector elements of \a values. |
2604 |
2442 |
2605 \sa setAttributeValue() |
2443 \sa setAttributeValue() |
2606 */ |
2444 */ |
2607 void QGLShaderProgram::setUniformValueArray(int location, const QVector2D *values, int count) |
2445 void QGLShaderProgram::setUniformValueArray(int location, const QVector2D *values, int count) |
2608 { |
2446 { |
2447 Q_D(QGLShaderProgram); |
|
2448 Q_UNUSED(d); |
|
2609 if (location != -1) |
2449 if (location != -1) |
2610 glUniform2fv(location, count, reinterpret_cast<const GLfloat *>(values)); |
2450 glUniform2fv(location, count, reinterpret_cast<const GLfloat *>(values)); |
2611 } |
2451 } |
2612 |
2452 |
2613 /*! |
2453 /*! |
2629 |
2469 |
2630 \sa setAttributeValue() |
2470 \sa setAttributeValue() |
2631 */ |
2471 */ |
2632 void QGLShaderProgram::setUniformValueArray(int location, const QVector3D *values, int count) |
2472 void QGLShaderProgram::setUniformValueArray(int location, const QVector3D *values, int count) |
2633 { |
2473 { |
2474 Q_D(QGLShaderProgram); |
|
2475 Q_UNUSED(d); |
|
2634 if (location != -1) |
2476 if (location != -1) |
2635 glUniform3fv(location, count, reinterpret_cast<const GLfloat *>(values)); |
2477 glUniform3fv(location, count, reinterpret_cast<const GLfloat *>(values)); |
2636 } |
2478 } |
2637 |
2479 |
2638 /*! |
2480 /*! |
2654 |
2496 |
2655 \sa setAttributeValue() |
2497 \sa setAttributeValue() |
2656 */ |
2498 */ |
2657 void QGLShaderProgram::setUniformValueArray(int location, const QVector4D *values, int count) |
2499 void QGLShaderProgram::setUniformValueArray(int location, const QVector4D *values, int count) |
2658 { |
2500 { |
2501 Q_D(QGLShaderProgram); |
|
2502 Q_UNUSED(d); |
|
2659 if (location != -1) |
2503 if (location != -1) |
2660 glUniform4fv(location, count, reinterpret_cast<const GLfloat *>(values)); |
2504 glUniform4fv(location, count, reinterpret_cast<const GLfloat *>(values)); |
2661 } |
2505 } |
2662 |
2506 |
2663 /*! |
2507 /*! |
2740 |
2584 |
2741 \sa setAttributeValue() |
2585 \sa setAttributeValue() |
2742 */ |
2586 */ |
2743 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x2 *values, int count) |
2587 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x2 *values, int count) |
2744 { |
2588 { |
2589 Q_D(QGLShaderProgram); |
|
2590 Q_UNUSED(d); |
|
2745 setUniformMatrixArray |
2591 setUniformMatrixArray |
2746 (glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2); |
2592 (glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2); |
2747 } |
2593 } |
2748 |
2594 |
2749 /*! |
2595 /*! |
2765 |
2611 |
2766 \sa setAttributeValue() |
2612 \sa setAttributeValue() |
2767 */ |
2613 */ |
2768 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x3 *values, int count) |
2614 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x3 *values, int count) |
2769 { |
2615 { |
2616 Q_D(QGLShaderProgram); |
|
2617 Q_UNUSED(d); |
|
2770 setUniformGenericMatrixArray |
2618 setUniformGenericMatrixArray |
2771 (glUniformMatrix2x3fv, glUniform3fv, location, values, count, |
2619 (glUniformMatrix2x3fv, glUniform3fv, location, values, count, |
2772 QMatrix2x3, 2, 3); |
2620 QMatrix2x3, 2, 3); |
2773 } |
2621 } |
2774 |
2622 |
2791 |
2639 |
2792 \sa setAttributeValue() |
2640 \sa setAttributeValue() |
2793 */ |
2641 */ |
2794 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x4 *values, int count) |
2642 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x4 *values, int count) |
2795 { |
2643 { |
2644 Q_D(QGLShaderProgram); |
|
2645 Q_UNUSED(d); |
|
2796 setUniformGenericMatrixArray |
2646 setUniformGenericMatrixArray |
2797 (glUniformMatrix2x4fv, glUniform4fv, location, values, count, |
2647 (glUniformMatrix2x4fv, glUniform4fv, location, values, count, |
2798 QMatrix2x4, 2, 4); |
2648 QMatrix2x4, 2, 4); |
2799 } |
2649 } |
2800 |
2650 |
2817 |
2667 |
2818 \sa setAttributeValue() |
2668 \sa setAttributeValue() |
2819 */ |
2669 */ |
2820 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x2 *values, int count) |
2670 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x2 *values, int count) |
2821 { |
2671 { |
2672 Q_D(QGLShaderProgram); |
|
2673 Q_UNUSED(d); |
|
2822 setUniformGenericMatrixArray |
2674 setUniformGenericMatrixArray |
2823 (glUniformMatrix3x2fv, glUniform2fv, location, values, count, |
2675 (glUniformMatrix3x2fv, glUniform2fv, location, values, count, |
2824 QMatrix3x2, 3, 2); |
2676 QMatrix3x2, 3, 2); |
2825 } |
2677 } |
2826 |
2678 |
2843 |
2695 |
2844 \sa setAttributeValue() |
2696 \sa setAttributeValue() |
2845 */ |
2697 */ |
2846 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x3 *values, int count) |
2698 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x3 *values, int count) |
2847 { |
2699 { |
2700 Q_D(QGLShaderProgram); |
|
2701 Q_UNUSED(d); |
|
2848 setUniformMatrixArray |
2702 setUniformMatrixArray |
2849 (glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3); |
2703 (glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3); |
2850 } |
2704 } |
2851 |
2705 |
2852 /*! |
2706 /*! |
2868 |
2722 |
2869 \sa setAttributeValue() |
2723 \sa setAttributeValue() |
2870 */ |
2724 */ |
2871 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x4 *values, int count) |
2725 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x4 *values, int count) |
2872 { |
2726 { |
2727 Q_D(QGLShaderProgram); |
|
2728 Q_UNUSED(d); |
|
2873 setUniformGenericMatrixArray |
2729 setUniformGenericMatrixArray |
2874 (glUniformMatrix3x4fv, glUniform4fv, location, values, count, |
2730 (glUniformMatrix3x4fv, glUniform4fv, location, values, count, |
2875 QMatrix3x4, 3, 4); |
2731 QMatrix3x4, 3, 4); |
2876 } |
2732 } |
2877 |
2733 |
2894 |
2750 |
2895 \sa setAttributeValue() |
2751 \sa setAttributeValue() |
2896 */ |
2752 */ |
2897 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x2 *values, int count) |
2753 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x2 *values, int count) |
2898 { |
2754 { |
2755 Q_D(QGLShaderProgram); |
|
2756 Q_UNUSED(d); |
|
2899 setUniformGenericMatrixArray |
2757 setUniformGenericMatrixArray |
2900 (glUniformMatrix4x2fv, glUniform2fv, location, values, count, |
2758 (glUniformMatrix4x2fv, glUniform2fv, location, values, count, |
2901 QMatrix4x2, 4, 2); |
2759 QMatrix4x2, 4, 2); |
2902 } |
2760 } |
2903 |
2761 |
2920 |
2778 |
2921 \sa setAttributeValue() |
2779 \sa setAttributeValue() |
2922 */ |
2780 */ |
2923 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x3 *values, int count) |
2781 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x3 *values, int count) |
2924 { |
2782 { |
2783 Q_D(QGLShaderProgram); |
|
2784 Q_UNUSED(d); |
|
2925 setUniformGenericMatrixArray |
2785 setUniformGenericMatrixArray |
2926 (glUniformMatrix4x3fv, glUniform3fv, location, values, count, |
2786 (glUniformMatrix4x3fv, glUniform3fv, location, values, count, |
2927 QMatrix4x3, 4, 3); |
2787 QMatrix4x3, 4, 3); |
2928 } |
2788 } |
2929 |
2789 |
2946 |
2806 |
2947 \sa setAttributeValue() |
2807 \sa setAttributeValue() |
2948 */ |
2808 */ |
2949 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x4 *values, int count) |
2809 void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x4 *values, int count) |
2950 { |
2810 { |
2811 Q_D(QGLShaderProgram); |
|
2812 Q_UNUSED(d); |
|
2951 setUniformMatrixArray |
2813 setUniformMatrixArray |
2952 (glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4); |
2814 (glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4); |
2953 } |
2815 } |
2954 |
2816 |
2955 /*! |
2817 /*! |
2972 Language (GLSL) are supported on this system; false otherwise. |
2834 Language (GLSL) are supported on this system; false otherwise. |
2973 |
2835 |
2974 The \a context is used to resolve the GLSL extensions. |
2836 The \a context is used to resolve the GLSL extensions. |
2975 If \a context is null, then QGLContext::currentContext() is used. |
2837 If \a context is null, then QGLContext::currentContext() is used. |
2976 */ |
2838 */ |
2977 bool QGLShaderProgram::hasShaderPrograms(const QGLContext *context) |
2839 bool QGLShaderProgram::hasOpenGLShaderPrograms(const QGLContext *context) |
2978 { |
2840 { |
2979 #if !defined(QT_OPENGL_ES_2) |
2841 #if !defined(QT_OPENGL_ES_2) |
2980 if (!context) |
2842 if (!context) |
2981 context = QGLContext::currentContext(); |
2843 context = QGLContext::currentContext(); |
2982 if (!context) |
2844 if (!context) |
2991 /*! |
2853 /*! |
2992 \internal |
2854 \internal |
2993 */ |
2855 */ |
2994 void QGLShaderProgram::shaderDestroyed() |
2856 void QGLShaderProgram::shaderDestroyed() |
2995 { |
2857 { |
2858 Q_D(QGLShaderProgram); |
|
2996 QGLShader *shader = qobject_cast<QGLShader *>(sender()); |
2859 QGLShader *shader = qobject_cast<QGLShader *>(sender()); |
2997 if (shader && !d->removingShaders) |
2860 if (shader && !d->removingShaders) |
2998 removeShader(shader); |
2861 removeShader(shader); |
2999 } |
2862 } |
3000 |
2863 |
2864 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS |
|
2865 /*! \internal */ |
|
2866 void QGLShaderProgram::setUniformValue(int location, QMacCompatGLint value) |
|
2867 { |
|
2868 setUniformValue(location, GLint(value)); |
|
2869 } |
|
2870 |
|
2871 /*! \internal */ |
|
2872 void QGLShaderProgram::setUniformValue(int location, QMacCompatGLuint value) |
|
2873 { |
|
2874 setUniformValue(location, GLuint(value)); |
|
2875 } |
|
2876 |
|
2877 /*! \internal */ |
|
2878 void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLint value) |
|
2879 { |
|
2880 setUniformValue(name, GLint(value)); |
|
2881 } |
|
2882 |
|
2883 /*! \internal */ |
|
2884 void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLuint value) |
|
2885 { |
|
2886 setUniformValue(name, GLuint(value)); |
|
2887 } |
|
2888 |
|
2889 /*! \internal */ |
|
2890 void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLint *values, int count) |
|
2891 { |
|
2892 setUniformValueArray(location, (const GLint *)values, count); |
|
2893 } |
|
2894 |
|
2895 /*! \internal */ |
|
2896 void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLuint *values, int count) |
|
2897 { |
|
2898 setUniformValueArray(location, (const GLuint *)values, count); |
|
2899 } |
|
2900 |
|
2901 /*! \internal */ |
|
2902 void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLint *values, int count) |
|
2903 { |
|
2904 setUniformValueArray(name, (const GLint *)values, count); |
|
2905 } |
|
2906 |
|
2907 /*! \internal */ |
|
2908 void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLuint *values, int count) |
|
2909 { |
|
2910 setUniformValueArray(name, (const GLuint *)values, count); |
|
2911 } |
|
3001 #endif |
2912 #endif |
3002 |
2913 |
2914 #endif // !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) |
|
2915 |
|
3003 QT_END_NAMESPACE |
2916 QT_END_NAMESPACE |