src/opengl/qglpixelbuffer.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtOpenGL module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00061 #include <qglpixelbuffer.h>
00062 #include <private/qglpixelbuffer_p.h>
00063 #include <private/qpaintengine_opengl_p.h>
00064 #include <qimage.h>
00065 
00066 
00067 void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &format, QGLWidget *shareWidget)
00068 {
00069     Q_Q(QGLPixelBuffer);
00070     if(init(size, format, shareWidget)) {
00071         req_size = size;
00072         req_format = format;
00073         req_shareWidget = shareWidget;
00074         invalid = false;
00075         qctx = new QGLContext(format);
00076         qctx->d_func()->sharing = (shareWidget != 0);
00077         qctx->d_func()->paintDevice = q;
00078     }
00079 }
00080 
00094 QGLPixelBuffer::QGLPixelBuffer(const QSize &size, const QGLFormat &format, QGLWidget *shareWidget)
00095     : d_ptr(new QGLPixelBufferPrivate)
00096 {
00097     Q_D(QGLPixelBuffer);
00098     d->common_init(size, format, shareWidget);
00099 }
00100 
00101 
00116 QGLPixelBuffer::QGLPixelBuffer(int width, int height, const QGLFormat &format, QGLWidget *shareWidget)
00117     : d_ptr(new QGLPixelBufferPrivate)
00118 {
00119     Q_D(QGLPixelBuffer);
00120     d->common_init(QSize(width, height), format, shareWidget);
00121 }
00122 
00123 
00128 QGLPixelBuffer::~QGLPixelBuffer()
00129 {
00130     Q_D(QGLPixelBuffer);
00131 
00132     // defined in qpaintengine_opengl.cpp
00133     extern void qgl_cleanup_glyph_cache(QGLContext *);
00134 
00135     QGLContext *current = const_cast<QGLContext *>(QGLContext::currentContext());
00136     makeCurrent();
00137     qgl_cleanup_glyph_cache(d->qctx);
00138     if (current)
00139         current->makeCurrent();
00140     d->cleanup();
00141     delete d->qctx;
00142     delete d_ptr;
00143 }
00144 
00168 #if defined(Q_WS_X11) || defined(Q_WS_WIN)
00169 GLuint QGLPixelBuffer::generateDynamicTexture() const
00170 {
00171     Q_D(const QGLPixelBuffer);
00172     GLuint texture;
00173     glGenTextures(1, &texture);
00174     glBindTexture(GL_TEXTURE_2D, texture);
00175     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, d->req_size.width(), d->req_size.height(), 0, GL_RGBA, GL_FLOAT, 0);
00176     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00177     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00178     return texture;
00179 }
00180 #endif
00181 
00255 void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
00256 {
00257     Q_D(const QGLPixelBuffer);
00258     if (d->invalid)
00259         return;
00260     glBindTexture(GL_TEXTURE_2D, texture_id);
00261 #ifndef Q_WS_QWS
00262     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, d->req_size.width(), d->req_size.height(), 0);
00263 #else
00264     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0);
00265 #endif
00266 }
00267 
00271 QSize QGLPixelBuffer::size() const
00272 {
00273     Q_D(const QGLPixelBuffer);
00274     return d->req_size;
00275 }
00276 
00280 QImage QGLPixelBuffer::toImage() const
00281 {
00282     Q_D(const QGLPixelBuffer);
00283     if (d->invalid)
00284         return QImage();
00285 
00286     const_cast<QGLPixelBuffer *>(this)->makeCurrent();
00287     QImage::Format image_format = QImage::Format_RGB32;
00288     if (format().alpha())
00289         image_format = QImage::Format_ARGB32_Premultiplied;
00290     QImage img(d->req_size, image_format);
00291     int w = d->req_size.width();
00292     int h = d->req_size.height();
00293     glReadPixels(0, 0, d->req_size.width(), d->req_size.height(), GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
00294     if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
00295   // OpenGL gives RGBA; Qt wants ARGB
00296   uint *p = (uint*)img.bits();
00297   uint *end = p + w*h;
00298   if (1) {
00299       while (p < end) {
00300     uint a = *p << 24;
00301     *p = (*p >> 8) | a;
00302     p++;
00303       }
00304   } else {
00305       while (p < end) {
00306     *p = 0xFF000000 | (*p>>8);
00307     ++p;
00308       }
00309   }
00310     } else {
00311   // OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB
00312   img = img.rgbSwapped();
00313     }
00314     return img.mirrored();
00315 }
00316 
00320 Qt::HANDLE QGLPixelBuffer::handle() const
00321 {
00322     Q_D(const QGLPixelBuffer);
00323     if (d->invalid)
00324         return 0;
00325     return d->pbuf;
00326 }
00327 
00331 bool QGLPixelBuffer::isValid() const
00332 {
00333     Q_D(const QGLPixelBuffer);
00334     return !d->invalid;
00335 }
00336 
00337 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_paintengine)
00338 
00339 
00340 QPaintEngine *QGLPixelBuffer::paintEngine() const
00341 {
00342     return qt_buffer_paintengine();
00343 }
00344 
00345 extern int qt_defaultDpi();
00346 
00348 int QGLPixelBuffer::metric(PaintDeviceMetric metric) const
00349 {
00350     Q_D(const QGLPixelBuffer);
00351 
00352     float dpmx = qt_defaultDpi()*100./2.54;
00353     float dpmy = qt_defaultDpi()*100./2.54;
00354     int w = d->req_size.width();
00355     int h = d->req_size.height();
00356     switch (metric) {
00357     case PdmWidth:
00358         return w;
00359 
00360     case PdmHeight:
00361         return h;
00362 
00363     case PdmWidthMM:
00364         return qRound(w * 1000 / dpmx);
00365 
00366     case PdmHeightMM:
00367         return qRound(h * 1000 / dpmy);
00368 
00369     case PdmNumColors:
00370         return 0;
00371 
00372     case PdmDepth:
00373         return 32;//d->depth;
00374 
00375     case PdmDpiX:
00376         return (int)(dpmx * 0.0254);
00377 
00378     case PdmDpiY:
00379         return (int)(dpmy * 0.0254);
00380 
00381     case PdmPhysicalDpiX:
00382         return (int)(dpmx * 0.0254);
00383 
00384     case PdmPhysicalDpiY:
00385         return (int)(dpmy * 0.0254);
00386 
00387     default:
00388         qWarning("QGLPixelBuffer::metric(), Unhandled metric type: %d\n", metric);
00389         break;
00390     }
00391     return 0;
00392 }
00393 
00405 GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target)
00406 {
00407     Q_D(QGLPixelBuffer);
00408 #ifndef Q_WS_QWS
00409     return d->qctx->bindTexture(image, target, GL_RGBA8);
00410 #else
00411     return d->qctx->bindTexture(image, target, GL_RGBA);
00412 #endif
00413 }
00414 
00415 
00424 GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target)
00425 {
00426     Q_D(QGLPixelBuffer);
00427 #ifndef Q_WS_QWS
00428     return d->qctx->bindTexture(pixmap, target, GL_RGBA8);
00429 #else
00430     return d->qctx->bindTexture(pixmap, target, GL_RGBA);
00431 #endif
00432 }
00433 
00443 GLuint QGLPixelBuffer::bindTexture(const QString &fileName)
00444 {
00445     Q_D(QGLPixelBuffer);
00446     return d->qctx->bindTexture(fileName);
00447 }
00448 
00454 void QGLPixelBuffer::deleteTexture(GLuint texture_id)
00455 {
00456     Q_D(QGLPixelBuffer);
00457     d->qctx->deleteTexture(texture_id);
00458 }
00459 
00464 QGLFormat QGLPixelBuffer::format() const
00465 {
00466     Q_D(const QGLPixelBuffer);
00467     return d->format;
00468 }
00469 

Generated on Thu Mar 15 11:57:23 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1