具有压缩纹理的 QGLBuffer

QGLBuffer with Compressed Textures

我正在尝试将 QT 的 QGLBuffer 与 glCompressedTexImage2D() 和 glCompressedTexSubImage2D() 一起使用,但没有成功。

这是使用 QGLBuffer 和 glTexImage2D() 的工作代码段:

        auto pbo = new QGLBuffer(QGLBuffer::PixelUnpackBuffer);
        pbo->create();
        pbo->bind();
        pbo->allocate(image->pixelsData(), image->pixelDataSize());
        // pixelsData() returns std::vector.data() of uncompressed data,
        // pixelDataSize() returns size of the vector

        GLuint imageTex;
        glGenTextures(1, &imageTex);
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, imageTex);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glPixelStorei(GL_UNPACK_ALIGNMENT,1);
        glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
                     0,
                     GL_RGBA,
                     image->width(), image->height(),
                     0,
                     GL_RGBA, GL_UNSIGNED_BYTE,
                     0);

        pbo->release();

这是另一段使用压缩图像数据的代码,同样有效:

        GLuint imageTex;
        glGenTextures(1, &imageTex);
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, imageTex);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glPixelStorei(GL_UNPACK_ALIGNMENT,1);

        glCompressedTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
                               0,
                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
                               image->width(), image->height(),
                               0,
                               image->pixelDataSize(),
                               image->pixelsData());

        // pixelDataSize() in this case returns std::vector.data() of image compressed to DXT1
        // and pixelDataSize() returns the compressed size
        // saw in another post that you can't pass in NULL and 0 for compressed texture

但是,如果我像这样使用带有 glCompressedTexImage2D() 的 PBO:

        auto pbo = new QGLBuffer(QGLBuffer::PixelUnpackBuffer);
        pbo->create();
        pbo->bind();
        pbo->allocate(image->pixelsData(), image->pixelDataSize());

        GLuint imageTex;
        glGenTextures(1, &imageTex);
        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, imageTex);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glPixelStorei(GL_UNPACK_ALIGNMENT,1);

        glCompressedTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
                               0,
                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
                               image->width(), image->height(),
                               0,
                               image->pixelDataSize(),
                               image->pixelsData());

        pbo->release();

我收到一个无效的操作错误。 QGLBuffer 的文档说它用于 "writing pixel data to the GL server (for example, with glTexImage2D()).",但它没有提及任何关于其他解包命令的信息,例如 glCompressedTexImage2D().

我在网上搜索了有关 QGLBuffer 和 glCompressedTexImage2D() 的更多文档,但找不到有关同时使用它们的任何内容。

我在 linux 下使用 QT4.8 工作。

有人有过成功的经验吗?

glCompressedTexImage2D 的调用看起来不对。当绑定像素解包缓冲区对象时,最后一个参数是该 PUBO 的偏移量(以字节为单位)。这意味着它很可能是 0,因为您在之前的 allocate 调用中从字节 0 上传了纹理数据。