diff options
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 43 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 59 | ||||
-rw-r--r-- | src/opengl/qgl_p.h | 44 | ||||
-rw-r--r-- | src/opengl/qglfunctions.cpp | 4 |
4 files changed, 100 insertions, 50 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 4d1d5dc..18c684f 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -540,27 +540,32 @@ void QGL2PaintEngineEx::beginNativePainting() glDisableVertexAttribArray(i); #ifndef QT_OPENGL_ES_2 - // be nice to people who mix OpenGL 1.x code with QPainter commands - // by setting modelview and projection matrices to mirror the GL 1 - // paint engine - const QTransform& mtx = state()->matrix; - - float mv_matrix[4][4] = + const QGLFormat &fmt = d->device->format(); + if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1) + || fmt.profile() == QGLFormat::CompatibilityProfile) { - { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) }, - { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) }, - { 0, 0, 1, 0 }, - { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) } - }; + // be nice to people who mix OpenGL 1.x code with QPainter commands + // by setting modelview and projection matrices to mirror the GL 1 + // paint engine + const QTransform& mtx = state()->matrix; - const QSize sz = d->device->size(); + float mv_matrix[4][4] = + { + { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) }, + { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) }, + { 0, 0, 1, 0 }, + { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) } + }; + + const QSize sz = d->device->size(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999); - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(&mv_matrix[0][0]); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(&mv_matrix[0][0]); + } #else Q_UNUSED(ctx); #endif @@ -591,7 +596,9 @@ void QGL2PaintEngineExPrivate::resetGLState() ctx->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false); ctx->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); #ifndef QT_OPENGL_ES_2 - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // color may have been changed by glVertexAttrib() + // gl_Color, corresponding to vertex attribute 3, may have been changed + float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + glVertexAttrib4fv(3, color); #endif } diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 684116c..b3b459d 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -5359,12 +5359,69 @@ QGLWidget::QGLWidget(QGLContext *context, QWidget *parent, #endif // QT3_SUPPORT +typedef GLubyte * (*qt_glGetStringi)(GLenum, GLuint); + +#ifndef GL_NUM_EXTENSIONS +#define GL_NUM_EXTENSIONS 0x821D +#endif + +QGLExtensionMatcher::QGLExtensionMatcher(const char *str) +{ + init(str); +} + +QGLExtensionMatcher::QGLExtensionMatcher() +{ + const char *extensionStr = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)); + + if (extensionStr) { + init(extensionStr); + } else { + // clear error state + while (glGetError()) {} + + const QGLContext *ctx = QGLContext::currentContext(); + if (ctx) { + qt_glGetStringi glGetStringi = (qt_glGetStringi)ctx->getProcAddress(QLatin1String("glGetStringi")); + + GLint numExtensions; + glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); + + for (int i = 0; i < numExtensions; ++i) { + const char *str = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i)); + + m_offsets << m_extensions.size(); + + while (*str != 0) + m_extensions.append(*str++); + m_extensions.append(' '); + } + } + } +} + +void QGLExtensionMatcher::init(const char *str) +{ + m_extensions = str; + + // make sure extension string ends with a space + if (!m_extensions.endsWith(' ')) + m_extensions.append(' '); + + int index = 0; + int next = 0; + while ((next = m_extensions.indexOf(' ', index)) >= 0) { + m_offsets << index; + index = next + 1; + } +} + /* Returns the GL extensions for the current context. */ QGLExtensions::Extensions QGLExtensions::currentContextExtensions() { - QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS))); + QGLExtensionMatcher extensions; Extensions glExtensions; if (extensions.match("GL_ARB_texture_rectangle")) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 0bdd6e3..50d13c9 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -852,46 +852,32 @@ private: }; -// This class can be used to match GL extensions without doing any mallocs. The -// class assumes that the GL extension string ends with a space character, -// which it should do on all conformant platforms. Create the object and pass -// in a pointer to the extension string, then call match() on each extension -// that should be matched. The match() function takes the extension name -// *without* the terminating space character as input. - class QGLExtensionMatcher { public: - QGLExtensionMatcher(const char *str) - : gl_extensions(str), gl_extensions_length(qstrlen(str)) - {} + QGLExtensionMatcher(const char *str); + QGLExtensionMatcher(); - bool match(const char *str) { + bool match(const char *str) const { int str_length = qstrlen(str); - const char *extensions = gl_extensions; - int extensions_length = gl_extensions_length; - - while (1) { - // the total length that needs to be matched is the str_length + - // the space character that terminates the extension name - if (extensions_length < str_length + 1) - return false; - if (qstrncmp(extensions, str, str_length) == 0 && extensions[str_length] == ' ') - return true; - int split_pos = 0; - while (split_pos < extensions_length && extensions[split_pos] != ' ') - ++split_pos; - ++split_pos; // added for the terminating space character - extensions += split_pos; - extensions_length -= split_pos; + Q_ASSERT(str); + Q_ASSERT(str_length > 0); + Q_ASSERT(str[str_length-1] != ' '); + + for (int i = 0; i < m_offsets.size(); ++i) { + const char *extension = m_extensions.constData() + m_offsets.at(i); + if (qstrncmp(extension, str, str_length) == 0 && extension[str_length] == ' ') + return true; } return false; } private: - const char *gl_extensions; - int gl_extensions_length; + void init(const char *str); + + QByteArray m_extensions; + QVector<int> m_offsets; }; diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp index 29e32ff..be8219a 100644 --- a/src/opengl/qglfunctions.cpp +++ b/src/opengl/qglfunctions.cpp @@ -229,7 +229,7 @@ static int qt_gl_resolve_features() QGLFunctions::Buffers | QGLFunctions::CompressedTextures | QGLFunctions::Multisample; - QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS))); + QGLExtensionMatcher extensions; if (extensions.match("GL_OES_framebuffer_object")) features |= QGLFunctions::Framebuffers; if (extensions.match("GL_OES_blend_equation_separate")) @@ -244,7 +244,7 @@ static int qt_gl_resolve_features() #else int features = 0; QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags(); - QGLExtensionMatcher extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS))); + QGLExtensionMatcher extensions; // Recognize features by extension name. if (extensions.match("GL_ARB_multitexture")) |