// If copyBack is true, bind will copy the contents of the render // FBO to the texture (which is not bound to the texture, as it's // a multisample FBO). GLuint QGLPixmapData::bind(bool copyBack) const { if (m_renderFbo && copyBack) { copyBackFromRenderFbo(true); } else { ensureCreated(); } GLuint id = m_texture.id; glBindTexture(GL_TEXTURE_2D, id); if (m_hasFillColor) { if (!useFramebufferObjects()) { m_source = QImage(w, h, QImage::Format_ARGB32_Premultiplied); m_source.fill(PREMUL(m_fillColor.rgba())); } m_hasFillColor = false; GLenum format = qt_gl_preferredTextureFormat(); QImage tx(w, h, QImage::Format_ARGB32_Premultiplied); tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format)); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.bits()); } return id; }
void QGLPixmapData::ensureCreated() const { if (!m_dirty) return; m_dirty = false; QGLShareContextScope ctx(qt_gl_share_context()); m_ctx = ctx; 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); 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()) { if (external_format == GL_RGB) { const QImage tx = m_source.convertToFormat(QImage::Format_RGB888).mirrored(false, true); glBindTexture(target, m_texture.id); glTexSubImage2D(target, 0, 0, 0, w, h, external_format, GL_UNSIGNED_BYTE, tx.bits()); } 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(); } m_texture.options &= ~QGLContext::MemoryManagedBindOption; }
GLuint QGLPixmapData::bind(bool copyBack) const { ensureCreated(); GLuint id = m_texture.id; glBindTexture(GL_TEXTURE_2D, id); if (m_hasFillColor) { m_source = QVolatileImage(w, h, QImage::Format_ARGB32_Premultiplied); m_source.fill(PREMUL(m_fillColor.rgba())); m_hasFillColor = false; GLenum format = qt_gl_preferredTextureFormat(); QImage tx(w, h, QImage::Format_ARGB32_Premultiplied); tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format)); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.constBits()); } return id; }
void QGLPixmapData::ensureCreated() const { if (!m_dirty) return; m_dirty = false; if (nativeImageHandleProvider && !nativeImageHandle) const_cast<QGLPixmapData *>(this)->createFromNativeImageHandleProvider(); QGLShareContextScope ctx(qt_gl_share_widget()->context()); m_ctx = ctx; 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; GLenum type = GL_UNSIGNED_BYTE; // Avoid conversion when pixmap is created from CFbsBitmap of EColor64K. if (!m_source.isNull() && m_source.format() == QImage::Format_RGB16) type = GL_UNSIGNED_SHORT_5_6_5; m_texture.options &= ~QGLContext::MemoryManagedBindOption; if (!m_texture.id) { m_texture.id = QGLTexturePool::instance()->createTextureForPixmap( target, 0, internal_format, w, h, external_format, type, const_cast<QGLPixmapData*>(this)); if (!m_texture.id) { failedToAlloc = true; return; } glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); inTexturePool = true; } else if (inTexturePool) { glBindTexture(target, m_texture.id); QGLTexturePool::instance()->useTexture(const_cast<QGLPixmapData*>(this)); } if (!m_source.isNull() && m_texture.id) { if (external_format == GL_RGB) { m_source.beginDataAccess(); QImage tx; if (type == GL_UNSIGNED_BYTE) tx = m_source.imageRef().convertToFormat(QImage::Format_RGB888).mirrored(false, true); else if (type == GL_UNSIGNED_SHORT_5_6_5) tx = m_source.imageRef().mirrored(false, true); m_source.endDataAccess(true); glBindTexture(target, m_texture.id); if (!tx.isNull()) glTexSubImage2D(target, 0, 0, 0, w, h, external_format, type, tx.constBits()); else qWarning("QGLPixmapData: Failed to create GL_RGB image of size %dx%d", w, h); } else { // do byte swizzling ARGB -> RGBA m_source.beginDataAccess(); const QImage tx = ctx->d_func()->convertToGLFormat(m_source.imageRef(), true, external_format); m_source.endDataAccess(true); glBindTexture(target, m_texture.id); if (!tx.isNull()) glTexSubImage2D(target, 0, 0, 0, w, h, external_format, type, tx.constBits()); else qWarning("QGLPixmapData: Failed to create GL_RGBA image of size %dx%d", w, h); } if (useFramebufferObjects()) m_source = QVolatileImage(); } }