⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qgl.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
Q_GLOBAL_STATIC(QGLShareRegister, _qgl_share_reg);QGLShareRegister* qgl_share_reg(){    return _qgl_share_reg();}/*!    \class QGLContext    \brief The QGLContext class encapsulates an OpenGL rendering context.    \ingroup multimedia    An OpenGL rendering context is a complete set of OpenGL state    variables. The rendering context's \l {QGL::FormatOption} {format}    is set in the constructor, but it can also be set later with    setFormat(). The format options that are actually set are returned    by format(); the options you asked for are returned by    requestedFormat(). Note that after a QGLContext object has been    constructed, the actual OpenGL context must be created by    explicitly calling the \link create() create()\endlink    function. The makeCurrent() function makes this context the    current rendering context. You can make \e no context current    using doneCurrent(). The reset() function will reset the context    and make it invalid.    You can examine properties of the context with, e.g. isValid(),    isSharing(), initialized(), windowCreated() and    overlayTransparentColor().    If you're using double buffering you can swap the screen contents    with the off-screen buffer using swapBuffers().    Please note that QGLContext is not thread safe.*//*!    \obsolete    Constructs an OpenGL context for the given paint \a device, which    can be a widget or a pixmap. The \a format specifies several    display options for the context.    If the underlying OpenGL/Window system cannot satisfy all the    features requested in \a format, the nearest subset of features    will be used. After creation, the format() method will return the    actual format obtained.    Note that after a QGLContext object has been constructed, \l    create() must be called explicitly to create the actual OpenGL    context. The context will be \l {isValid()}{invalid} if it was not    possible to obtain a GL context at all.*/QGLContext::QGLContext(const QGLFormat &format, QPaintDevice *device){    d_ptr = new QGLContextPrivate(this);    Q_D(QGLContext);    d->init(device, format);}/*!    Constructs an OpenGL context with the given \a format which    specifies several display options for the context.    If the underlying OpenGL/Window system cannot satisfy all the    features requested in \a format, the nearest subset of features    will be used. After creation, the format() method will return the    actual format obtained.    Note that after a QGLContext object has been constructed, \l    create() must be called explicitly to create the actual OpenGL    context. The context will be \l {isValid()}{invalid} if it was not    possible to obtain a GL context at all.    \sa format(), isValid()*/QGLContext::QGLContext(const QGLFormat &format){    d_ptr = new QGLContextPrivate(this);    Q_D(QGLContext);    d->init(0, format);}/*!    Destroys the OpenGL context and frees its resources.*/QGLContext::~QGLContext(){    Q_D(QGLContext);    // remove any textures cached in this context    if (qt_tex_cache) {        QList<QString> keys = qt_tex_cache->keys();        for (int i = 0; i < keys.size(); ++i) {            const QString &key = keys.at(i);            if (qt_tex_cache->object(key)->context == this)                qt_tex_cache->remove(key);        }        // ### thread safety        if (qt_tex_cache->size() == 0) {            qt_pixmap_cleanup_hook_64 = 0;            qt_image_cleanup_hook_64 = 0;            delete qt_tex_cache;            qt_tex_cache = 0;        }    }    QGLProxy::signalProxy()->emitAboutToDestroyContext(this);    reset();    delete d;}/*! \overload    Reads the DirectDrawSurface (DDS) compressed file \a fileName and    generates a 2D GL texture from it.    Only the DXT1, DXT3 and DXT5 DDS formats are supported.    Note that this will only work if the implementation supports the    \c GL_ARB_texture_compression and \c GL_EXT_texture_compression_s3tc    extensions.    \sa deleteTexture()*/GLuint QGLContext::bindTexture(const QString &fileName){    if (!qt_glCompressedTexImage2DARB) {        qWarning("QGLContext::bindTexture(): The GL implementation does not support texture"                 "compression extensions.");        return 0;    }    if (!qt_tex_cache)        qt_tex_cache = new QGLTextureCache(qt_tex_cache_limit);    QString key(fileName);    QGLTexture *texture = qt_tex_cache->object(key);    if (texture && texture->context == this) {        glBindTexture(GL_TEXTURE_2D, texture->id);        return texture->id;    }    QFile f(fileName);    f.open(QIODevice::ReadOnly);    char tag[4];    f.read(&tag[0], 4);    if (strncmp(tag,"DDS ", 4) != 0) {        qWarning("QGLContext::bindTexture(): not a DDS image file.");        return 0;    }    DDSFormat ddsHeader;    f.read((char *) &ddsHeader, sizeof(DDSFormat));    if (!ddsHeader.dwLinearSize) {        qWarning("QGLContext::bindTexture() DDS image size is not valid.");        return 0;    }    int factor = 4;    int bufferSize = 0;    int blockSize = 16;    GLenum format;    switch(ddsHeader.ddsPixelFormat.dwFourCC) {    case FOURCC_DXT1:        format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;        factor = 2;        blockSize = 8;        break;    case FOURCC_DXT3:        format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;        break;    case FOURCC_DXT5:        format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;        break;    default:        qWarning("QGLContext::bindTexture() DDS image format not supported.");        return 0;    }    if (ddsHeader.dwMipMapCount > 1)        bufferSize = ddsHeader.dwLinearSize * factor;    else        bufferSize = ddsHeader.dwLinearSize;    GLubyte *pixels = (GLubyte *) malloc(bufferSize*sizeof(GLubyte));    f.seek(ddsHeader.dwSize + 4);    f.read((char *) pixels, bufferSize);    f.close();    GLuint tx_id;    glGenTextures(1, &tx_id);    glBindTexture(GL_TEXTURE_2D, tx_id);#ifndef Q_WS_QWS    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);#else    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);#endif    int size;    int offset = 0;    int w = ddsHeader.dwWidth;    int h = ddsHeader.dwHeight;    // load mip-maps    for(int i = 0; i < (int) ddsHeader.dwMipMapCount; ++i) {        if (w == 0) w = 1;        if (h == 0) h = 1;        size = ((w+3)/4) * ((h+3)/4) * blockSize;        qt_glCompressedTexImage2DARB(GL_TEXTURE_2D, i, format, w, h, 0,                                     size, pixels + offset);        offset += size;        // half size for each mip-map level        w = w/2;        h = h/2;    }    free(pixels);    int cost = bufferSize/1024;    qt_tex_cache->insert(key, new QGLTexture(this, tx_id, 0), cost);    return tx_id;}/*  a hook that removes textures from the cache when a pixmap/image  is deref'ed*/static void qt_gl_clean_cache(const QString &cacheKey){    // ### remove for 4.4    // Temporary fix to avoid QImages created in a different thread    // cause crashes due to the fact that the QGLTextureCache isn't    // thread-safe.    if (qApp->thread() != QThread::currentThread())        return;    const QList<QString> keys = qt_tex_cache->keys();    for (int i = 0; i < keys.count(); ++i) {        const QString &key = keys.at(i);        if (key.startsWith(cacheKey)) {            if (qt_tex_cache->object(key)->clean)                qt_tex_cache->remove(key);            break;        }    }}static void qt_gl_pixmap_cleanup(qint64 key){    if (qt_tex_cache)        qt_gl_clean_cache(QString().sprintf("p%016llx", key));}static void qt_gl_image_cleanup(qint64 key){    if (qt_tex_cache)        qt_gl_clean_cache(QString().sprintf("i%016llx", key));}QImage QGLContextPrivate::convertToGLFormat(const QImage &image, bool force_premul,                                            GLenum texture_format){    QImage img = image;    if ((force_premul && image.format() != QImage::Format_ARGB32_Premultiplied)        || (!force_premul && image.format() != QImage::Format_ARGB32_Premultiplied            && image.format() != QImage::Format_ARGB32))    {        img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);    }    if (texture_format == GL_BGRA) {        if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {            // mirror + swizzle            QImage res = img.copy();            for (int i=0; i < img.height(); i++) {                uint *p = (uint*) img.scanLine(i);                uint *q = (uint*) res.scanLine(img.height() - i - 1);                uint *end = p + img.width();                while (p < end) {                    *q = ((*p << 24) & 0xff000000)                         | ((*p >> 24) & 0x000000ff)                         | ((*p << 8) & 0x00ff0000)                         | ((*p >> 8) & 0x0000ff00);                    p++;                    q++;                }            }            return res;        } else {            return img.mirrored();        }    } else {        img = img.mirrored();        if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {            for (int i=0; i < img.height(); i++) {                uint *p = (uint*)img.scanLine(i);                uint *end = p + img.width();                while (p < end) {                    *p = (*p << 8) | ((*p >> 24) & 0xFF);                    p++;                }            }        } else {            img = img.rgbSwapped();        }        return img;    }}GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format,                                      const QString &key, qint64 qt_id, bool clean){    Q_Q(QGLContext);    // the GL_BGRA format is only present in GL version >= 1.2    GLenum texture_format = (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2)                            ? GL_BGRA : GL_RGBA;    if (!qt_tex_cache) {        qt_tex_cache = new QGLTextureCache(qt_tex_cache_limit);        qt_pixmap_cleanup_hook_64 = qt_gl_pixmap_cleanup;        qt_image_cleanup_hook_64 = qt_gl_image_cleanup;    }    // Scale the pixmap if needed. GL textures needs to have the    // dimensions 2^n+2(border) x 2^m+2(border).    QImage tx;    int tx_w = qt_next_power_of_two(image.width());    int tx_h = qt_next_power_of_two(image.height());    // Note: the clean param is only true when a texture is bound    // from the QOpenGLPaintEngine - in that case we have to force    // a premultiplied texture format    if (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height()))        tx = convertToGLFormat(image.scaled(tx_w, tx_h), clean, texture_format);    else        tx = convertToGLFormat(image, clean, texture_format);    GLuint tx_id;    glGenTextures(1, &tx_id);    glBindTexture(target, tx_id);    glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    if (QGLExtensions::glExtensions & QGLExtensions::GenerateMipmap        && target == GL_TEXTURE_2D)    {        glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);#ifndef Q_WS_QWS        glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);#else        glTexParameterf(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);#endif        glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);    } else {        glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);    }    glTexImage2D(target, 0, format, tx.width(), tx.height(), 0, texture_format,                 GL_UNSIGNED_BYTE, tx.bits());    // this assumes the size of a texture is always smaller than the max cache size    int cost = tx.width()*tx.height()*4/1024;    if (qt_tex_cache->totalCost() + cost > qt_tex_cache->maxCost()) {        // the cache is full - make an attempt to remove something        const QList<QString> keys = qt_tex_cache->keys();        int i = 0;        while (i < qt_tex_cache->count()               && (qt_tex_cache->totalCost() + cost > qt_tex_cache->maxCost())) {            QGLTexture *tex = qt_tex_cache->object(keys.at(i));            if (tex->context == q)                qt_tex_cache->remove(keys.at(i));            ++i;        }    }    qt_tex_cache->insert(key, new QGLTexture(q, tx_id, qt_id, clean), cost);    return tx_id;}bool QGLContextPrivate::textureCacheLookup(const QString &key, GLuint *id, qint64 *qt_id){    Q_Q(QGLContext);    if (qt_tex_cache) {        QGLTexture *texture = qt_tex_cache->object(key);        if (texture && (texture->context == q                        || qgl_share_reg()->checkSharing(q, texture->context)))        {            *id = texture->id;            *qt_id = texture->qt_id;            return true;        }    }    return false;}/*! \internal */GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format, bool clean){    Q_Q(QGLContext);    const QString key = QString(QLatin1String("%1_%2_%3")).arg(QString().sprintf("i%016llx",image.cacheKey())).arg(target).arg(format);    GLuint id;    qint64 qt_id;    if (textureCacheLookup(key, &id, &qt_id)) {        if (image.cacheKey() == qt_id) {            glBindTexture(target, id);            return id;        } else {            q->deleteTexture(id);        }    }    return bindTexture(image, target, format, key, image.cacheKey(), clean);}/*! \internal */GLuint QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, bool clean){    Q_Q(QGLContext);    const QString key = QString(QLatin1String("%1_%2_%3")).arg(QString().sprintf("p%016llx",pixmap.cacheKey())).arg(target).arg(format);    GLuint id;    qint64 qt_id;    if (textureCacheLookup(key, &id, &qt_id)) {        if (pixmap.cacheKey() == qt_id) {            glBindTexture(target, id);            return id;        } else {            q->deleteTexture(id);        }    }    return bindTexture(pixmap.toImage(), target, format, key, pixmap.cacheKey(), clean);}/*!    Generates and binds a 2D GL texture to the current context, based    on \a image. The generated texture id is returned and can be used    in later \c glBindTexture() calls.    The \a target parameter specifies the texture target. The default    target is \c GL_TEXTURE_2D.    The \a format parameter sets the internal format for the    texture. The default format is \c GL_RGBA8.    If the GL implementation supports the \c GL_SGIS_generate_mipmap    extension, mipmaps will be automatically generated for the    texture. Mipmap generation is only supported for the \c    GL_TEXTURE_2D target.    The texture that is generated is cached, so multiple calls to    bindTexture() with the same QImage will return the same texture    id.    \sa deleteTexture()*/GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format){    Q_D(QGLContext);    return d->bindTexture(image, target, format, false);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -