diff options
author | Rhys Weatherley <rhys.weatherley@nokia.com> | 2009-05-01 00:59:47 (GMT) |
---|---|---|
committer | Rhys Weatherley <rhys.weatherley@nokia.com> | 2009-05-01 00:59:47 (GMT) |
commit | 05ddcb4d40a56878e45bf6a06dd178217fa534f1 (patch) | |
tree | bbce506301799e4767a7ebb347286052da7512de /src/opengl | |
parent | 6e0e3c7312bbceef69e61b745d88076224745a33 (diff) | |
parent | 1092ef425b9ed5835e4863c5ec32f9fc21af8d4d (diff) | |
download | Qt-05ddcb4d40a56878e45bf6a06dd178217fa534f1.zip Qt-05ddcb4d40a56878e45bf6a06dd178217fa534f1.tar.gz Qt-05ddcb4d40a56878e45bf6a06dd178217fa534f1.tar.bz2 |
Merge branch 'shader-api' into gl2engine-new-shaders
Conflicts:
src/opengl/opengl.pro
src/opengl/qglextensions.cpp
src/opengl/qglextensions_p.h
src/opengl/qglshaderprogram.cpp
src/opengl/qglshaderprogram.h
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/qgl.cpp | 175 | ||||
-rw-r--r-- | src/opengl/qglextensions.cpp | 16 | ||||
-rw-r--r-- | src/opengl/qglextensions_p.h | 13 | ||||
-rw-r--r-- | src/opengl/qglshaderprogram.cpp | 148 | ||||
-rw-r--r-- | src/opengl/qglshaderprogram.h | 10 | ||||
-rw-r--r-- | src/opengl/qpaintengine_opengl.cpp | 10 | ||||
-rw-r--r-- | src/opengl/qwindowsurface_gl.cpp | 2 |
7 files changed, 225 insertions, 149 deletions
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index d1cf35d..d74ed95 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1331,13 +1331,21 @@ static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, boo // This is an old legacy fix for PowerPC based Macs, which // we shouldn't remove while (p < end) { - *p = 0xFF000000 | (*p>>8); + *p = 0xff000000 | (*p>>8); ++p; } } } else { // OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB - img = img.rgbSwapped(); + for (int y = 0; y < h; y++) { + uint *q = (uint*)img.scanLine(y); + for (int x=0; x < w; ++x) { + const uint pixel = *q; + *q = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00); + q++; + } + } + } img = img.mirrored(); } @@ -1700,58 +1708,105 @@ static void qt_gl_clean_cache(qint64 cacheKey) static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum texture_format) { - Q_ASSERT(dst.size() == img.size()); Q_ASSERT(dst.depth() == 32); Q_ASSERT(img.depth() == 32); - const int width = img.width(); - const int height = img.height(); - const uint *p = (const uint*) img.scanLine(img.height() - 1); - uint *q = (uint*) dst.scanLine(0); - - if (texture_format == GL_BGRA) { - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { - // mirror + swizzle - for (int i=0; i < height; ++i) { - const uint *end = p + width; - while (p < end) { - *q = ((*p << 24) & 0xff000000) - | ((*p >> 24) & 0x000000ff) - | ((*p << 8) & 0x00ff0000) - | ((*p >> 8) & 0x0000ff00); - p++; - q++; + if (dst.size() != img.size()) { + int target_width = dst.width(); + int target_height = dst.height(); + qreal sx = target_width / qreal(img.width()); + qreal sy = target_height / qreal(img.height()); + + quint32 *dest = (quint32 *) dst.scanLine(0); // NB! avoid detach here + uchar *srcPixels = (uchar *) img.scanLine(img.height() - 1); + int sbpl = img.bytesPerLine(); + int dbpl = dst.bytesPerLine(); + + int ix = 0x00010000 / sx; + int iy = 0x00010000 / sy; + + quint32 basex = int(0.5 * ix); + quint32 srcy = int(0.5 * iy); + + // scale, swizzle and mirror in one loop + while (target_height--) { + const uint *src = (const quint32 *) (srcPixels - (srcy >> 16) * sbpl); + int srcx = basex; + for (int x=0; x<target_width; ++x) { + uint src_pixel = src[srcx >> 16]; + if (texture_format == GL_BGRA) { + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + dest[x] = ((src_pixel << 24) & 0xff000000) + | ((src_pixel >> 24) & 0x000000ff) + | ((src_pixel << 8) & 0x00ff0000) + | ((src_pixel >> 8) & 0x0000ff00); + } else { + dest[x] = src_pixel; + } + } else { // GL_RGBA + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + dest[x] = (src_pixel << 8) | ((src_pixel >> 24) & 0xff); + } else { + dest[x] = ((src_pixel << 16) & 0xff0000) + | ((src_pixel >> 16) & 0xff) + | (src_pixel & 0xff00ff00); + } } - p -= 2 * width; - } - } else { - const uint bytesPerLine = img.bytesPerLine(); - for (int i=0; i < height; ++i) { - memcpy(q, p, bytesPerLine); - q += width; - p -= width; + srcx += ix; } + dest = (quint32 *)(((uchar *) dest) + dbpl); + srcy += iy; } } else { - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { - for (int i=0; i < height; ++i) { - const uint *end = p + width; - while (p < end) { - *q = (*p << 8) | ((*p >> 24) & 0xFF); - p++; - q++; + const int width = img.width(); + const int height = img.height(); + const uint *p = (const uint*) img.scanLine(img.height() - 1); + uint *q = (uint*) dst.scanLine(0); + + if (texture_format == GL_BGRA) { + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + // mirror + swizzle + for (int i=0; i < height; ++i) { + const uint *end = p + width; + while (p < end) { + *q = ((*p << 24) & 0xff000000) + | ((*p >> 24) & 0x000000ff) + | ((*p << 8) & 0x00ff0000) + | ((*p >> 8) & 0x0000ff00); + p++; + q++; + } + p -= 2 * width; + } + } else { + const uint bytesPerLine = img.bytesPerLine(); + for (int i=0; i < height; ++i) { + memcpy(q, p, bytesPerLine); + q += width; + p -= width; } - p -= 2 * width; } } else { - for (int i=0; i < height; ++i) { - const uint *end = p + width; - while (p < end) { - *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00); - p++; - q++; + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + for (int i=0; i < height; ++i) { + const uint *end = p + width; + while (p < end) { + *q = (*p << 8) | ((*p >> 24) & 0xff); + p++; + q++; + } + p -= 2 * width; + } + } else { + for (int i=0; i < height; ++i) { + const uint *end = p + width; + while (p < end) { + *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00); + p++; + q++; + } + p -= 2 * width; } - p -= 2 * width; } } } @@ -1794,19 +1849,18 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint } // Scale the pixmap if needed. GL textures needs to have the - // dimensions 2^n+2(border) x 2^m+2(border). + // dimensions 2^n+2(border) x 2^m+2(border), unless we're using GL + // 2.0 or use the GL_TEXTURE_RECTANGLE texture target int tx_w = qt_next_power_of_two(image.width()); int tx_h = qt_next_power_of_two(image.height()); + bool scale = false; - // Note: the clean param is only true when a texture is bound - // from the QOpenGLPaintEngine - in that case we have to force - // a premultiplied texture format QImage img = image; if (( !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) && !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0) ) && (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height()))) { - img = image.scaled(tx_w, tx_h); + scale = true; } GLuint tx_id; @@ -1838,17 +1892,24 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint ptr = reinterpret_cast<uchar *>(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB)); } - if (ptr) { - QImage::Format target_format = img.format(); - if (clean || img.format() != QImage::Format_ARGB32) - target_format = QImage::Format_ARGB32_Premultiplied; + QImage::Format target_format = img.format(); + // Note: the clean param is only true when a texture is bound + // from the QOpenGLPaintEngine - in that case we have to force + // a premultiplied texture format + if (clean || img.format() != QImage::Format_ARGB32) + target_format = QImage::Format_ARGB32_Premultiplied; + if (img.format() != target_format) + img = img.convertToFormat(target_format); + if (ptr) { QImage buffer(ptr, img.width(), img.height(), target_format); - convertToGLFormatHelper(buffer, img.convertToFormat(target_format), texture_format); + convertToGLFormatHelper(buffer, img, texture_format); glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); - glTexImage2D(target, 0, format, img.width(), img.height(), 0, texture_format, GL_UNSIGNED_BYTE, 0); + glTexImage2D(target, 0, format, img.width(), img.height(), 0, texture_format, + GL_UNSIGNED_BYTE, 0); } else { - QImage tx = convertToGLFormat(img, clean, texture_format); + QImage tx(scale ? QSize(tx_w, tx_h) : img.size(), target_format); + convertToGLFormatHelper(tx, img, texture_format); glTexImage2D(target, 0, format, tx.width(), tx.height(), 0, texture_format, GL_UNSIGNED_BYTE, tx.bits()); } @@ -2439,6 +2500,10 @@ bool QGLContext::create(const QGLContext* shareContext) return false; reset(); d->valid = chooseContext(shareContext); + if (d->valid && d->paintDevice->devType() == QInternal::Widget) { + QWidgetPrivate *wd = qt_widget_private(static_cast<QWidget *>(d->paintDevice)); + wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer(); + } if (d->sharing) // ok, we managed to share qgl_share_reg()->addShare(this, shareContext); return d->valid; diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp index 5fda346..9ec76cb 100644 --- a/src/opengl/qglextensions.cpp +++ b/src/opengl/qglextensions.cpp @@ -188,14 +188,10 @@ bool qt_resolve_glsl_extensions(QGLContext *ctx) glGetProgramiv = (_glGetProgramiv) ctx->getProcAddress(QLatin1String("glGetProgramiv")); glGetProgramInfoLog = (_glGetProgramInfoLog) ctx->getProcAddress(QLatin1String("glGetProgramInfoLog")); - glGetActiveUniform = (_glGetActiveUniform) ctx->getProcAddress(QLatin1String("glGetActiveUniform"));//### REMOVE glGetUniformLocation = (_glGetUniformLocation) ctx->getProcAddress(QLatin1String("glGetUniformLocation")); - glUniform4f = (_glUniform4f) ctx->getProcAddress(QLatin1String("glUniform4f")); //### REMOVE glUniform4fv = (_glUniform4fv) ctx->getProcAddress(QLatin1String("glUniform4fv")); glUniform3fv = (_glUniform3fv) ctx->getProcAddress(QLatin1String("glUniform3fv")); - glUniform2f = (_glUniform2f) ctx->getProcAddress(QLatin1String("glUniform2f")); //### REMOVE glUniform2fv = (_glUniform2fv) ctx->getProcAddress(QLatin1String("glUniform2fv")); - glUniform1f = (_glUniform1f) ctx->getProcAddress(QLatin1String("glUniform1f")); //### REMOVE glUniform1fv = (_glUniform1fv) ctx->getProcAddress(QLatin1String("glUniform1fv")); glUniform1i = (_glUniform1i) ctx->getProcAddress(QLatin1String("glUniform1i")); glUniform1iv = (_glUniform1iv) ctx->getProcAddress(QLatin1String("glUniform1iv")); @@ -209,7 +205,6 @@ bool qt_resolve_glsl_extensions(QGLContext *ctx) glUniformMatrix4x2fv = (_glUniformMatrix4x2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4x2fv")); glUniformMatrix4x3fv = (_glUniformMatrix4x3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4x3fv")); - glGetActiveAttrib = (_glGetActiveAttrib) ctx->getProcAddress(QLatin1String("glGetActiveAttrib")); //### REMOVE glBindAttribLocation = (_glBindAttribLocation) ctx->getProcAddress(QLatin1String("glBindAttribLocation")); glGetAttribLocation = (_glGetAttribLocation) ctx->getProcAddress(QLatin1String("glGetAttribLocation")); glVertexAttrib1fv = (_glVertexAttrib1fv) ctx->getProcAddress(QLatin1String("glVertexAttrib1fv")); @@ -221,7 +216,6 @@ bool qt_resolve_glsl_extensions(QGLContext *ctx) glEnableVertexAttribArray = (_glEnableVertexAttribArray) ctx->getProcAddress(QLatin1String("glEnableVertexAttribArray")); glStencilOpSeparate = (_glStencilOpSeparate) ctx->getProcAddress(QLatin1String("glStencilOpSeparate")); //### Not really a glsl extension, but needed for gl2 - } else { // We may not have the standard shader functions, but we might // have the older ARB functions instead. @@ -246,14 +240,10 @@ bool qt_resolve_glsl_extensions(QGLContext *ctx) glGetProgramiv = (_glGetProgramiv) ctx->getProcAddress(QLatin1String("glGetObjectParameterivARB")); glGetProgramInfoLog = (_glGetProgramInfoLog) ctx->getProcAddress(QLatin1String("glGetInfoLogARB")); - glGetActiveUniform = (_glGetActiveUniform) ctx->getProcAddress(QLatin1String("glGetActiveUniformARB"));//### REMOVE glGetUniformLocation = (_glGetUniformLocation) ctx->getProcAddress(QLatin1String("glGetUniformLocationARB")); - glUniform4f = (_glUniform4f) ctx->getProcAddress(QLatin1String("glUniform4fARB")); //### REMOVE glUniform4fv = (_glUniform4fv) ctx->getProcAddress(QLatin1String("glUniform4fvARB")); glUniform3fv = (_glUniform3fv) ctx->getProcAddress(QLatin1String("glUniform3fvARB")); - glUniform2f = (_glUniform2f) ctx->getProcAddress(QLatin1String("glUniform2fARB")); //### REMOVE glUniform2fv = (_glUniform2fv) ctx->getProcAddress(QLatin1String("glUniform2fvARB")); - glUniform1f = (_glUniform1f) ctx->getProcAddress(QLatin1String("glUniform1fARB")); //### REMOVE glUniform1fv = (_glUniform1fv) ctx->getProcAddress(QLatin1String("glUniform1fvARB")); glUniform1i = (_glUniform1i) ctx->getProcAddress(QLatin1String("glUniform1iARB")); glUniform1iv = (_glUniform1iv) ctx->getProcAddress(QLatin1String("glUniform1ivARB")); @@ -267,7 +257,6 @@ bool qt_resolve_glsl_extensions(QGLContext *ctx) glUniformMatrix4x2fv = (_glUniformMatrix4x2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4x2fvARB")); glUniformMatrix4x3fv = (_glUniformMatrix4x3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4x3fvARB")); - glGetActiveAttrib = (_glGetActiveAttrib) ctx->getProcAddress(QLatin1String("glGetActiveAttribARB")); //### REMOVE glBindAttribLocation = (_glBindAttribLocation) ctx->getProcAddress(QLatin1String("glBindAttribLocationARB")); glGetAttribLocation = (_glGetAttribLocation) ctx->getProcAddress(QLatin1String("glGetAttribLocationARB")); glVertexAttrib1fv = (_glVertexAttrib1fv) ctx->getProcAddress(QLatin1String("glVertexAttrib1fvARB")); @@ -300,21 +289,16 @@ bool qt_resolve_glsl_extensions(QGLContext *ctx) glGetShaderSource && glGetProgramiv && glGetProgramInfoLog && - glGetActiveUniform && //### REMOVE glGetUniformLocation && - glUniform1f && //### REMOVE glUniform1fv && - glUniform2f && //### REMOVE glUniform2fv && glUniform3fv && - glUniform4f && //### REMOVE glUniform4fv && glUniform1i && glUniform1iv && glUniformMatrix2fv && glUniformMatrix3fv && glUniformMatrix4fv && - glGetActiveAttrib && //### REMOVE glBindAttribLocation && glGetAttribLocation && glVertexAttrib1fv && diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index 9249730..793400a 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -741,19 +741,6 @@ struct QGLExtensionFuncs #endif // QT_OPENGL_ES_2 -#define glGetActiveAttrib QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetActiveAttrib -#define glGetAttribLocation QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetAttribLocation -#define glGetActiveUniform QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetActiveUniform -#define glGetProgramInfoLog QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetProgramInfoLog -#define glUniform1f QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform1f -#define glUniform2f QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform2f -#define glUniform4f QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform4f -#define glUniformMatrix2fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix2fv -#define glUniformMatrix3fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix3fv -#define glUniformMatrix4fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix4fv -#define glEnableVertexAttribArray QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glEnableVertexAttribArray -#define glDisableVertexAttribArray QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDisableVertexAttribArray -#define glVertexAttribPointer QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glVertexAttribPointer #define glStencilOpSeparate QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glStencilOpSeparate #if !defined(QT_OPENGL_ES_2) diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index c2be1be..d74b930 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE -#if !defined(QT_OPENGL_ES_1_CL) +#if !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) /*! \class QGLShaderProgram @@ -261,7 +261,7 @@ public: bool compiled; bool isPartial; bool hasPartialSource; - QString errors; + QString log; QByteArray partialSource; bool create(); @@ -309,12 +309,12 @@ bool QGLShaderPrivate::compile() value = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &value); if (!compiled && value > 1) { - char *log = new char [value]; + char *logbuf = new char [value]; GLint len; - glGetShaderInfoLog(shader, value, &len, log); - errors = QString::fromLatin1(log); - qWarning() << "QGLShader::compile:" << errors; - delete [] log; + glGetShaderInfoLog(shader, value, &len, logbuf); + log = QString::fromLatin1(logbuf); + qWarning() << "QGLShader::compile:" << log; + delete [] logbuf; } return compiled; } @@ -696,13 +696,13 @@ bool QGLShader::isCompiled() const } /*! - Returns the errors that occurred during the last compile. + Returns the errors and warnings that occurred during the last compile. \sa setSourceCode() */ -QString QGLShader::errors() const +QString QGLShader::log() const { - return d->errors; + return d->log; } /*! @@ -746,7 +746,7 @@ public: bool linked; bool inited; bool hasPartialShaders; - QString errors; + QString log; QList<QGLShader *> shaders; QList<QGLShader *> anonShaders; QGLShader *vertexShader; @@ -868,13 +868,13 @@ bool QGLShaderProgram::addShader(QGLShader *shader) Compiles \a source as a shader of the specified \a type and adds it to this shader program. Returns true if compilation was successful, false otherwise. The compilation errors - will be made available via errors(). + and warnings will be made available via log(). This function is intended to be a short-cut for quickly adding vertex and fragment shaders to a shader program without creating an instance of QGLShader first. - \sa removeShader(), link(), errors(), removeAllShaders() + \sa removeShader(), link(), log(), removeAllShaders() */ bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const char *source) { @@ -882,7 +882,7 @@ bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const char *source) return false; QGLShader *shader = new QGLShader(type, this); if (!shader->setSourceCode(source)) { - d->errors = shader->errors(); + d->log = shader->log(); delete shader; return false; } @@ -896,13 +896,13 @@ bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const char *source) Compiles \a source as a shader of the specified \a type and adds it to this shader program. Returns true if compilation was successful, false otherwise. The compilation errors - will be made available via errors(). + and warnings will be made available via log(). This function is intended to be a short-cut for quickly adding vertex and fragment shaders to a shader program without creating an instance of QGLShader first. - \sa removeShader(), link(), errors(), removeAllShaders() + \sa removeShader(), link(), log(), removeAllShaders() */ bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const QByteArray& source) { @@ -915,13 +915,13 @@ bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const QByteArray& s Compiles \a source as a shader of the specified \a type and adds it to this shader program. Returns true if compilation was successful, false otherwise. The compilation errors - will be made available via errors(). + and warnings will be made available via log(). This function is intended to be a short-cut for quickly adding vertex and fragment shaders to a shader program without creating an instance of QGLShader first. - \sa removeShader(), link(), errors(), removeAllShaders() + \sa removeShader(), link(), log(), removeAllShaders() */ bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const QString& source) { @@ -1052,14 +1052,14 @@ bool QGLShaderProgram::setProgramBinary(int format, const QByteArray& binary) d->linked = (value != 0); value = 0; glGetProgramiv(d->program, GL_INFO_LOG_LENGTH, &value); - d->errors = QString(); + d->log = QString(); if (value > 1) { - char *log = new char [value]; + char *logbuf = new char [value]; GLint len; - glGetProgramInfoLog(d->program, value, &len, log); - d->errors = QString::fromLatin1(log); - qWarning() << "QGLShaderProgram::setProgramBinary:" << d->errors; - delete [] log; + glGetProgramInfoLog(d->program, value, &len, logbuf); + d->log = QString::fromLatin1(logbuf); + qWarning() << "QGLShaderProgram::setProgramBinary:" << d->log; + delete [] logbuf; } return d->linked; #else @@ -1073,7 +1073,7 @@ bool QGLShaderProgram::setProgramBinary(int format, const QByteArray& binary) Returns the list of program binary formats that are accepted by this system for use with setProgramBinary(). - \sa programBinary, setProgramBinary() + \sa programBinary(), setProgramBinary() */ QList<int> QGLShaderProgram::programBinaryFormats() { @@ -1095,7 +1095,7 @@ QList<int> QGLShaderProgram::programBinaryFormats() Links together the shaders that were added to this program with addShader(). Returns true if the link was successful or false otherwise. If the link failed, the error messages can - be retrieved with errors(). + be retrieved with log(). Subclasses can override this function to initialize attributes and uniform variables for use in specific shader programs. @@ -1103,7 +1103,7 @@ QList<int> QGLShaderProgram::programBinaryFormats() If the shader program was already linked, calling this function again will force it to be re-linked. - \sa addShader(), errors() + \sa addShader(), log() */ bool QGLShaderProgram::link() { @@ -1131,7 +1131,7 @@ bool QGLShaderProgram::link() new QGLShader(QGLShader::VertexShader, this); } if (!d->vertexShader->setSourceCode(vertexSource)) { - d->errors = d->vertexShader->errors(); + d->log = d->vertexShader->log(); return false; } glAttachShader(d->program, d->vertexShader->d->shader); @@ -1148,7 +1148,7 @@ bool QGLShaderProgram::link() new QGLShader(QGLShader::FragmentShader, this); } if (!d->fragmentShader->setSourceCode(fragmentSource)) { - d->errors = d->fragmentShader->errors(); + d->log = d->fragmentShader->log(); return false; } glAttachShader(d->program, d->fragmentShader->d->shader); @@ -1160,14 +1160,14 @@ bool QGLShaderProgram::link() d->linked = (value != 0); value = 0; glGetProgramiv(d->program, GL_INFO_LOG_LENGTH, &value); - d->errors = QString(); + d->log = QString(); if (value > 1) { - char *log = new char [value]; + char *logbuf = new char [value]; GLint len; - glGetProgramInfoLog(d->program, value, &len, log); - d->errors = QString::fromLatin1(log); - qWarning() << "QGLShaderProgram::link:" << d->errors; - delete [] log; + glGetProgramInfoLog(d->program, value, &len, logbuf); + d->log = QString::fromLatin1(logbuf); + qWarning() << "QGLShaderProgram::link:" << d->log; + delete [] logbuf; } return d->linked; } @@ -1183,14 +1183,14 @@ bool QGLShaderProgram::isLinked() const } /*! - Returns the errors that occurred during the last link() + Returns the errors and warnings that occurred during the last link() or addShader() with explicitly specified source code. \sa link() */ -QString QGLShaderProgram::errors() const +QString QGLShaderProgram::log() const { - return d->errors; + return d->log; } /*! @@ -1211,8 +1211,11 @@ bool QGLShaderProgram::enable() return true; } +#undef ctx +#define ctx QGLContext::currentContext() + /*! - Disables this shader program in the currently active QGLContext. + Disables the active shader program in the current QGLContext. This is equivalent to calling \c{glUseProgram(0)}. \sa enable() @@ -1227,6 +1230,9 @@ void QGLShaderProgram::disable() #endif } +#undef ctx +#define ctx d->context + /*! Returns the OpenGL identifier associated with this shader program. @@ -1812,7 +1818,6 @@ void QGLShaderProgram::setUniformValue(const char *name, GLfloat value) /*! Sets the uniform variable at \a location in the current context to \a value. - This function must be used when setting sampler values. \sa setAttributeValue() */ @@ -1826,7 +1831,7 @@ void QGLShaderProgram::setUniformValue(int location, GLint value) \overload Sets the uniform variable called \a name in the current context - to \a value. This function must be used when setting sampler values. + to \a value. \sa setAttributeValue() */ @@ -1837,6 +1842,7 @@ void QGLShaderProgram::setUniformValue(const char *name, GLint value) /*! Sets the uniform variable at \a location in the current context to \a value. + This function should be used when setting sampler values. \sa setAttributeValue() */ @@ -1850,7 +1856,7 @@ void QGLShaderProgram::setUniformValue(int location, GLuint value) \overload Sets the uniform variable called \a name in the current context - to \a value. + to \a value. This function should be used when setting sampler values. \sa setAttributeValue() */ @@ -2045,7 +2051,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QColor& color) /*! Sets the uniform variable at \a location in the current context to - the x() & y() coordinates of \a point. + the x and y coordinates of \a point. \sa setAttributeValue() */ @@ -2060,8 +2066,8 @@ void QGLShaderProgram::setUniformValue(int location, const QPoint& point) /*! \overload - Sets the uniform variable at \a location in the current context to - the x() & y() coordinates of \a point. + Sets the uniform variable associated with \a name in the current + context to the x and y coordinates of \a point. \sa setAttributeValue() */ @@ -2072,7 +2078,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QPoint& point) /*! Sets the uniform variable at \a location in the current context to - the x() & y() coordinates of \a point. + the x and y coordinates of \a point. \sa setAttributeValue() */ @@ -2087,8 +2093,8 @@ void QGLShaderProgram::setUniformValue(int location, const QPointF& point) /*! \overload - Sets the uniform variable at \a location in the current context to - the x() & y() coordinates of \a point. + Sets the uniform variable associated with \a name in the current + context to the x and y coordinates of \a point. \sa setAttributeValue() */ @@ -2099,7 +2105,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QPointF& point) /*! Sets the uniform variable at \a location in the current context to - the width() & height() of the given \a size. + the width and height of the given \a size. \sa setAttributeValue() */ @@ -2114,8 +2120,8 @@ void QGLShaderProgram::setUniformValue(int location, const QSize& size) /*! \overload - Sets the uniform variable at \a location in the current context to - the width() & height() of the given \a size. + Sets the uniform variable associated with \a name in the current + context to the width and height of the given \a size. \sa setAttributeValue() */ @@ -2126,7 +2132,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QSize& size) /*! Sets the uniform variable at \a location in the current context to - the width() & height() of the given \a size. + the width and height of the given \a size. \sa setAttributeValue() */ @@ -2141,8 +2147,8 @@ void QGLShaderProgram::setUniformValue(int location, const QSizeF& size) /*! \overload - Sets the uniform variable at \a location in the current context to - the width() & height() of the given \a size. + Sets the uniform variable associated with \a name in the current + context to the width and height of the given \a size. \sa setAttributeValue() */ @@ -2513,8 +2519,7 @@ void QGLShaderProgram::setUniformValue /*! Sets the uniform variable array at \a location in the current - context to the \a count elements of \a values. This overload - must be used when setting an array of sampler values. + context to the \a count elements of \a values. \sa setAttributeValue() */ @@ -2528,8 +2533,7 @@ void QGLShaderProgram::setUniformValueArray(int location, const GLint *values, i \overload Sets the uniform variable array called \a name in the current - context to the \a count elements of \a values. This overload - must be used when setting an array of sampler values. + context to the \a count elements of \a values. \sa setAttributeValue() */ @@ -2541,6 +2545,34 @@ void QGLShaderProgram::setUniformValueArray /*! Sets the uniform variable array at \a location in the current + context to the \a count elements of \a values. This overload + should be used when setting an array of sampler values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const GLuint *values, int count) +{ + if (location != -1) + glUniform1iv(location, count, reinterpret_cast<const GLint *>(values)); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count elements of \a values. This overload + should be used when setting an array of sampler values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray + (const char *name, const GLuint *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Sets the uniform variable array at \a location in the current context to the \a count elements of \a values. Each element has \a size components. The \a size must be 1, 2, 3, or 4. diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h index 508fd96..b69d28e 100644 --- a/src/opengl/qglshaderprogram.h +++ b/src/opengl/qglshaderprogram.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(OpenGL) -#if !defined(QT_OPENGL_ES_1_CL) && !defined(QT_GL_FIXED_PREFERRED) +#if !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) class QGLShaderProgram; class QGLShaderPrivate; @@ -96,7 +96,7 @@ public: QByteArray sourceCode() const; bool isCompiled() const; - QString errors() const; + QString log() const; GLuint shaderId() const; @@ -136,10 +136,10 @@ public: virtual bool link(); bool isLinked() const; - QString errors() const; + QString log() const; bool enable(); - void disable(); + static void disable(); GLuint programId() const; @@ -248,6 +248,7 @@ public: void setUniformValueArray(int location, const GLfloat *values, int count, int size); void setUniformValueArray(int location, const GLint *values, int count); + void setUniformValueArray(int location, const GLuint *values, int count); void setUniformValueArray(int location, const QVector2D *values, int count); void setUniformValueArray(int location, const QVector3D *values, int count); void setUniformValueArray(int location, const QVector4D *values, int count); @@ -263,6 +264,7 @@ public: void setUniformValueArray(const char *name, const GLfloat *values, int count, int size); void setUniformValueArray(const char *name, const GLint *values, int count); + void setUniformValueArray(const char *name, const GLuint *values, int count); void setUniformValueArray(const char *name, const QVector2D *values, int count); void setUniformValueArray(const char *name, const QVector3D *values, int count); void setUniformValueArray(const char *name, const QVector4D *values, int count); diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 069daac..612168e 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -3539,8 +3539,14 @@ void QOpenGLPaintEngine::drawRects(const QRectF *rects, int rectCount) d->disableClipping(); GLuint program = qt_gl_program_cache()->getProgram(d->drawable.context(), FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA, 0, true); - QGLRectMaskGenerator maskGenerator(path, d->matrix, d->offscreen, program); - d->addItem(qt_mask_texture_cache()->getMask(maskGenerator, d)); + + if (d->matrix.type() >= QTransform::TxProject) { + QGLPathMaskGenerator maskGenerator(path, d->matrix, d->offscreen, program); + d->addItem(qt_mask_texture_cache()->getMask(maskGenerator, d)); + } else { + QGLRectMaskGenerator maskGenerator(path, d->matrix, d->offscreen, program); + d->addItem(qt_mask_texture_cache()->getMask(maskGenerator, d)); + } d->enableClipping(); } diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index e4c38fa..d92241d 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -90,7 +90,7 @@ QT_BEGIN_NAMESPACE // QGLGraphicsSystem // #ifdef Q_WS_WIN -Q_GUI_EXPORT bool qt_win_owndc_required; +extern Q_GUI_EXPORT bool qt_win_owndc_required; #endif QGLGraphicsSystem::QGLGraphicsSystem() : QGraphicsSystem() |