QOpenGLTexture::allocateStorage causes GL_INVALID_VALUE error

末鹿安然 提交于 2019-12-12 03:28:59

问题


I've distilled this to trivial Qt code in which the only interesting thing is several lines in synchronize() handling a texture. I get a GL_INVALID_VALUE from the allocateStorage line. Anyone knows why? I suspect it's probably due to the parameters I pass to this function.

My code:

main.cpp:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickFramebufferObject>
#include <QOpenGLFramebufferObject>
#include <QOpenGLFunctions>
#include <QOpenGLTexture>

class MyItem : public QQuickFramebufferObject {
    Q_OBJECT

public:
    Renderer* createRenderer() const;
};

class MyItemRenderer : public QQuickFramebufferObject::Renderer, protected QOpenGLFunctions {
public:
    MyItemRenderer() {
        initializeOpenGLFunctions();
    }

    void render() {
    }

    QOpenGLFramebufferObject* createFramebufferObject(const QSize &size) {
        QOpenGLFramebufferObjectFormat format;
        format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
        return new QOpenGLFramebufferObject(size, format);
    }

protected:
    void synchronize(QQuickFramebufferObject* qqfbo) {
        Q_UNUSED(qqfbo)

        QOpenGLTexture tex(QOpenGLTexture::Target2D);
        tex.setSize(100, 100);
        tex.allocateStorage(QOpenGLTexture::BGRA, QOpenGLTexture::Int8);

        qDebug() << "starting loop";
        GLenum err;
        while ((err = glGetError()) != GL_NO_ERROR) {
            qDebug("\tgl error: 0x%x", err, 0, 16);
        }
    }
};

QQuickFramebufferObject::Renderer* MyItem::createRenderer() const {
    return new MyItemRenderer();
}

int main(int argc, char **argv) {
    QGuiApplication app(argc, argv);

    qmlRegisterType<MyItem>("MyItem", 1, 0, "MyItem");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

#include "main.moc"

main.qml

import QtQuick 2.0
import MyItem 1.0
import QtQuick.Window 2.2

Window {
    visible: true
    width: 400
    height: 400

    MyItem {
        anchors.fill: parent
    }
}

回答1:


After looking at the source of QOpenGLTexture::createMutableTexture and QOpenGLTexture::allocateStorage() (no-argument version) I saw that two-argument allocateStorage overload is really, really misleading. The docs make it seem like its 2 args will be used as the internal format of the texture (3rd arg of the glTexImage2D call in the implementation), when in fact they're used only as the "source-data-to-transfer-from-system-RAM" format/type (7th and 8th args of glTexImage2D), which, in the case of passing a null pointer to glTexImage2D, don't matter at all except in fringe OpenGL ES 2 cases.

The way to actually request a certain internal format for the texture is to call tex.setFormat before calling tex.allocateStorage. So I replaced my allocateStorage line with this:

tex.setFormat(QOpenGLTexture::RGBA8_UNorm);
tex.allocateStorage();

And that fixed the error.




回答2:


You have...

QOpenGLTexture tex(QOpenGLTexture::Target2D);

According to the docs that doesn't actually create the underlying texture object. I think you then need...

tex.create();

before setting the size and allocating storage. So...

QOpenGLTexture tex(QOpenGLTexture::Target2D);
if (!tex.create()) {

  /*
   * Take appropriate action.
   */
}
tex.setSize(100, 100);
tex.allocateStorage(QOpenGLTexture::BGRA, QOpenGLTexture::Int8);

Edit 1:

Actually, looking at the code it appears that tex.allocateStorage should allocate a texture id if necessary. However, if that fails for some reason (no current context for example) then that could be causing the problem you're seeing.




回答3:


During "allocatestorage", You are conveying opeGL driver about the texture storage format.

For the formats "GL_BGRA or GL_RGBA", OpenGL recommends "GL_UNSIGNED_BYTE",

which is in Qt ----- "QOpenGLTexture::BGRA" (for GL_BGRA) and "QOpenGLTexture::UInt8" (for GL_UNSIGNED_BYTE).

https://www.khronos.org/opengl/wiki/Textures_-_more

So your allocate storage function based on (openGL recommendation) should be

tex.allocateStorage(QOpenGLTexture::BGRA, QOpenGLTexture::UInt8);


来源:https://stackoverflow.com/questions/42909159/qopengltextureallocatestorage-causes-gl-invalid-value-error

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!