From 60be72310c0f9469b3201b250b257473184ccf2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 3 Dec 2009 11:53:31 +0100 Subject: Fixed OpenGL graphicssystem issues for OpenGL ES 2.0 platforms. The format and internal_format parameters to glTexImage2D need to always match on OpenGL ES 2.0. Reviewed-by: Tom Cooksey --- src/opengl/qgl_p.h | 3 ++- src/opengl/qpixmapdata_gl.cpp | 38 ++++++++++++++++++++++++++++++-------- src/opengl/qwindowsurface_gl.cpp | 9 ++++----- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index ab72c9c..b2407ba 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -518,7 +518,8 @@ bool qt_gl_preferGL2Engine(); inline GLenum qt_gl_preferredTextureFormat() { - return QSysInfo::ByteOrder == QSysInfo::BigEndian ? GL_RGBA : GL_BGRA; + return (QGLExtensions::glExtensions & QGLExtensions::BGRATextureFormat) && QSysInfo::ByteOrder == QSysInfo::LittleEndian + ? GL_BGRA : GL_RGBA; } inline GLenum qt_gl_preferredTextureTarget() diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index fb55097..ab17789 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -321,25 +321,47 @@ void QGLPixmapData::ensureCreated() const QGLShareContextScope ctx(qt_gl_share_widget()->context()); m_ctx = ctx; - const GLenum format = qt_gl_preferredTextureFormat(); + const GLenum internal_format = m_hasAlpha ? GL_RGBA : GL_RGB; +#ifdef QT_OPENGL_ES_2 + const GLenum external_format = internal_format; +#else + const GLenum external_format = qt_gl_preferredTextureFormat(); +#endif const GLenum target = GL_TEXTURE_2D; if (!m_texture.id) { glGenTextures(1, &m_texture.id); glBindTexture(target, m_texture.id); - GLenum format = m_hasAlpha ? GL_RGBA : GL_RGB; - glTexImage2D(target, 0, format, w, h, 0, - GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexImage2D(target, 0, internal_format, w, h, 0, external_format, GL_UNSIGNED_BYTE, 0); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } if (!m_source.isNull()) { - const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, format); + if (external_format == GL_RGB) { + QImage tx = m_source.convertToFormat(QImage::Format_RGB32); + + QVector pixelData(w * h * 3); + uchar *p = &pixelData[0]; + QRgb *src = (QRgb *)tx.bits(); + + for (int i = 0; i < w * h; ++i) { + *p++ = qRed(*src); + *p++ = qGreen(*src); + *p++ = qBlue(*src); + ++src; + } - glBindTexture(target, m_texture.id); - glTexSubImage2D(target, 0, 0, 0, w, h, format, - GL_UNSIGNED_BYTE, tx.bits()); + glBindTexture(target, m_texture.id); + glTexSubImage2D(target, 0, 0, 0, w, h, external_format, + GL_UNSIGNED_BYTE, &pixelData[0]); + } else { + const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, external_format); + + glBindTexture(target, m_texture.id); + glTexSubImage2D(target, 0, 0, 0, w, h, external_format, + GL_UNSIGNED_BYTE, tx.bits()); + } if (useFramebufferObjects()) m_source = QImage(); diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index e353f5d..7194f9d 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -493,7 +493,6 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & } #endif d_ptr->paintedRegion = QRegion(); - context()->swapBuffers(); } else { glFlush(); @@ -688,11 +687,13 @@ void QGLWindowSurface::updateGeometry() { d_ptr->size = rect.size(); if (d_ptr->ctx) { +#ifndef QT_OPENGL_ES_2 if (d_ptr->destructive_swap_buffers) { glBindTexture(target, d_ptr->tex_id); glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); glBindTexture(target, 0); } +#endif return; } @@ -756,11 +757,7 @@ void QGLWindowSurface::updateGeometry() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); -#ifndef QT_OPENGL_ES glOrtho(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999); -#else - glOrthof(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999); -#endif d_ptr->pb->d_ptr->qctx->d_func()->internal_context = true; return; @@ -774,6 +771,7 @@ void QGLWindowSurface::updateGeometry() { ctx->makeCurrent(); +#ifndef QT_OPENGL_ES_2 if (d_ptr->destructive_swap_buffers) { glGenTextures(1, &d_ptr->tex_id); glBindTexture(target, d_ptr->tex_id); @@ -783,6 +781,7 @@ void QGLWindowSurface::updateGeometry() { glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(target, 0); } +#endif qDebug() << "QGLWindowSurface: Using plain widget as window surface" << this;; d_ptr->ctx = ctx; -- cgit v0.12