QOpenGLTexture :: allocateStorage导致GL_INVALID_VALUE错误

时间:2017-03-20 16:38:30

标签: qt opengl textures

我已将其提炼为简单的Qt代码,其中唯一有趣的是处理纹理的synchronize()中的几行。我从allocateStorage行获得了GL_INVALID_VALUE。谁知道为什么?我怀疑这可能是由于我传递给这个函数的参数。

我的代码:

的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
    }
}

3 个答案:

答案 0 :(得分:1)

在查看QOpenGLTexture::createMutableTextureQOpenGLTexture::allocateStorage()(无论证版本)的来源后,我发现两个参数allocateStorage重载确实存在,真的误导。文档看起来它的2个args将被用作纹理的内部格式(实现中glTexImage2D调用的第3个arg),而实际上它们仅被使用作为“源 - 数据到系统RAM的转移”格式/类型(glTexImage2D的第7和第8个args),在将空指针传递给glTexImage2D的情况下,除了在边缘的OpenGL ES 2案例中没有任何关系。

实际请求纹理的某种内部格式的方法是在调用tex.setFormat之前调用tex.allocateStorage。所以我将allocateStorage行替换为:

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

这解决了错误。

答案 1 :(得分:0)

你有......

n [76]: aI = a+0*1j
In [77]: aI
Out[77]: 
array([[ 2.+0.j],
       [ 3.+0.j]])
In [79]: aI.conjugate()
Out[79]: 
array([[ 2.-0.j],
       [ 3.-0.j]])
In [80]: np.matrix(aI)
Out[80]: 
matrix([[ 2.+0.j],
        [ 3.+0.j]])
In [81]: np.matrix(aI).H
Out[81]: matrix([[ 2.-0.j,  3.-0.j]])

根据实际上没有创建底层纹理对象的docs。我想你需要......

QOpenGLTexture tex(QOpenGLTexture::Target2D);

在设置大小和分配存储之前。所以......

tex.create();

修改1

实际上,查看代码似乎QOpenGLTexture tex(QOpenGLTexture::Target2D); if (!tex.create()) { /* * Take appropriate action. */ } tex.setSize(100, 100); tex.allocateStorage(QOpenGLTexture::BGRA, QOpenGLTexture::Int8); 应该在必要时分配纹理ID。但是,如果由于某种原因(例如没有当前的上下文)失败,则可能导致您遇到的问题。

答案 2 :(得分:0)

在&#34; allocatestorage&#34;期间,您正在传达有关纹理存储格式的opeGL驱动程序。

对于格式&#34; GL_BGRA或GL_RGBA&#34;,OpenGL建议&#34; GL_UNSIGNED_BYTE&#34;,

在Qt -----&#34; QOpenGLTexture::BGRA&#34; (对于GL_BGRA)和&#34; QOpenGLTexture::UInt8&#34; (对于GL_UNSIGNED_BYTE)。

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

所以基于(openGL推荐)的分配存储功能应该是

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