Home · All Classes · Main Classes · Grouped Classes · Modules · Functions

qwindowsurface_ahigl.cpp Example File
qtopiacore/ahigl/qwindowsurface_ahigl.cpp

 /****************************************************************************
 **
 ** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
 **
 ** This file is part of the example classes of the Qt Toolkit.
 **
 ** This file may be used under the terms of the GNU General Public
 ** License version 2.0 as published by the Free Software Foundation
 ** and appearing in the file LICENSE.GPL included in the packaging of
 ** this file.  Please review the following information to ensure GNU
 ** General Public Licensing requirements will be met:
 ** http://www.trolltech.com/products/qt/opensource.html
 **
 ** If you are unsure which license is appropriate for your use, please
 ** review the following information:
 ** http://www.trolltech.com/products/qt/licensing.html or contact the
 ** sales department at sales@trolltech.com.
 **
 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 **
 ****************************************************************************/

 #include "qwindowsurface_ahigl_p.h"
 #include "qscreenahigl_qws.h"

 #include <qwsdisplay_qws.h>
 #include <QtGui/QPaintDevice>
 #include <QtGui/QWidget>
 #include <QtOpenGL/private/qglpaintdevice_qws_p.h>
 #include <QtOpenGL/private/qgl_p.h>

 class QAhiGLWindowSurfacePrivate
 {
 public:
     QAhiGLWindowSurfacePrivate(EGLDisplay eglDisplay, EGLSurface eglSurface,
                                EGLContext eglContext);

     QPaintDevice *device;

     int textureWidth;
     int textureHeight;

     GLuint texture;
     GLuint frameBufferObject;
     GLuint depthbuf;

     EGLDisplay display;
     EGLSurface surface;
     EGLContext context;
 };

 QAhiGLWindowSurfacePrivate::QAhiGLWindowSurfacePrivate(EGLDisplay eglDisplay,
                                                        EGLSurface eglSurface,
                                                        EGLContext eglContext)
     : texture(0), frameBufferObject(0), depthbuf(0), display(eglDisplay),
       surface(eglSurface), context(eglContext)
 {
 }

 inline static int nextPowerOfTwo(uint v)
 {
     v--;
     v |= v >> 1;
     v |= v >> 2;
     v |= v >> 4;
     v |= v >> 8;
     v |= v >> 16;
     ++v;
     return v;
 }

 QAhiGLWindowSurface::QAhiGLWindowSurface(QWidget *widget,
                                          EGLDisplay eglDisplay,
                                          EGLSurface eglSurface,
                                          EGLContext eglContext)
     : QWSGLWindowSurface(widget)
 {
     d_ptr = new QAhiGLWindowSurfacePrivate(eglDisplay, eglSurface, eglContext);
     d_ptr->device = new QWSGLPaintDevice(widget);

     setSurfaceFlags(QWSWindowSurface::Buffered);
 }

 QAhiGLWindowSurface::QAhiGLWindowSurface(EGLDisplay eglDisplay,
                                          EGLSurface eglSurface,
                                          EGLContext eglContext)
 {
     d_ptr = new QAhiGLWindowSurfacePrivate(eglDisplay, eglSurface, eglContext);
     setSurfaceFlags(QWSWindowSurface::Buffered);
 }

 QAhiGLWindowSurface::~QAhiGLWindowSurface()
 {
     if (d_ptr->texture)
         glDeleteTextures(1, &d_ptr->texture);
     if (d_ptr->depthbuf)
         glDeleteRenderbuffersOES(1, &d_ptr->depthbuf);
     if (d_ptr->frameBufferObject)
         glDeleteFramebuffersOES(1, &d_ptr->frameBufferObject);

     delete d_ptr;
 }

 void QAhiGLWindowSurface::setGeometry(const QRect &rect)
 {
     QSize size = rect.size();

     const QWidget *w = window();
     if (w && !w->mask().isEmpty()) {
         const QRegion region = w->mask()
                                & rect.translated(-w->geometry().topLeft());
         size = region.boundingRect().size();
     }

     if (geometry().size() != size) {

         // Driver specific limitations:
         //   FBO maximimum size of 256x256
         //   Depth buffer required

         d_ptr->textureWidth = qMin(256, nextPowerOfTwo(size.width()));
         d_ptr->textureHeight = qMin(256, nextPowerOfTwo(size.height()));

         glGenTextures(1, &d_ptr->texture);
         glBindTexture(GL_TEXTURE_2D, d_ptr->texture);

         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

         const int bufSize = d_ptr->textureWidth * d_ptr->textureHeight * 2;
         GLshort buf[bufSize];
         memset(buf, 0, sizeof(GLshort) * bufSize);

         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d_ptr->textureWidth,
                      d_ptr->textureHeight, 0,
                      GL_RGBA, GL_UNSIGNED_BYTE, buf);

         glGenRenderbuffersOES(1, &d_ptr->depthbuf);
         glBindRenderbufferOES(GL_RENDERBUFFER_EXT, d_ptr->depthbuf);
         glRenderbufferStorageOES(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16,
                                  d_ptr->textureWidth, d_ptr->textureHeight);

         glGenFramebuffersOES(1, &d_ptr->frameBufferObject);
         glBindFramebufferOES(GL_FRAMEBUFFER_EXT, d_ptr->frameBufferObject);

         glFramebufferTexture2DOES(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                   GL_TEXTURE_2D, d_ptr->texture, 0);
         glFramebufferRenderbufferOES(GL_FRAMEBUFFER_EXT,
                                      GL_DEPTH_ATTACHMENT_EXT,
                                      GL_RENDERBUFFER_EXT, d_ptr->depthbuf);
         glBindFramebufferOES(GL_FRAMEBUFFER_EXT, 0);
     }

     QWSGLWindowSurface::setGeometry(rect);
 }

 QByteArray QAhiGLWindowSurface::permanentState() const
 {
     QByteArray array;
     array.resize(sizeof(GLuint));

     char *ptr = array.data();
     reinterpret_cast<GLuint*>(ptr)[0] = textureId();
     return array;
 }

 void QAhiGLWindowSurface::setPermanentState(const QByteArray &data)
 {
     const char *ptr = data.constData();
     d_ptr->texture = reinterpret_cast<const GLuint*>(ptr)[0];
 }

 QPaintDevice *QAhiGLWindowSurface::paintDevice()
 {
     return d_ptr->device;
 }

 GLuint QAhiGLWindowSurface::textureId() const
 {
     return d_ptr->texture;
 }

 void QAhiGLWindowSurface::beginPaint(const QRegion &region)
 {
     QWSGLWindowSurface::beginPaint(region);

     if (d_ptr->frameBufferObject)
         glBindFramebufferOES(GL_FRAMEBUFFER_EXT, d_ptr->frameBufferObject);
 }

 bool QAhiGLWindowSurface::isValid() const
 {
     if (!qobject_cast<QGLWidget*>(window())) {
         const QRect r = window()->frameGeometry();
         if (r.width() > 256 || r.height() > 256)
             return false;
     }
     return true;
 }


Copyright © 2007 Trolltech Trademarks
Qt 4.3.0