QOpenGLTexture::allocateStorage 导致 GL_INVALID_VALUE 错误
QOpenGLTexture::allocateStorage causes GL_INVALID_VALUE error
我已将其提炼为简单的 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
}
}
你有...
QOpenGLTexture tex(QOpenGLTexture::Target2D);
根据 docs 实际上并没有创建底层纹理对象。我想你需要...
tex.create();
在设置大小和分配存储之前。所以...
QOpenGLTexture tex(QOpenGLTexture::Target2D);
if (!tex.create()) {
/*
* Take appropriate action.
*/
}
tex.setSize(100, 100);
tex.allocateStorage(QOpenGLTexture::BGRA, QOpenGLTexture::Int8);
编辑 1:
实际上,查看代码似乎 tex.allocateStorage
应该在必要时分配一个纹理 ID。但是,如果由于某种原因(例如没有当前上下文)而失败,那么这可能会导致您看到的问题。
在"allocatestorage"期间,您正在传送有关纹理存储格式的opeGL驱动程序。
对于格式 "GL_BGRA or GL_RGBA",OpenGL 建议 "GL_UNSIGNED_BYTE"、
在 Qt 中 ----- “QOpenGLTexture::BGRA
”(对于 GL_BGRA)和“QOpenGLTexture::UInt8
”(对于 GL_UNSIGNED_BYTE)。
https://www.khronos.org/opengl/wiki/Textures_-_more
所以你的基于(openGL推荐)的分配存储函数应该是
tex.allocateStorage(QOpenGLTexture::BGRA, QOpenGLTexture::UInt8);
在查看 QOpenGLTexture::createMutableTexture
和 QOpenGLTexture::allocateStorage()
的源代码(无参数版本)后,我发现双参数 allocateStorage
重载确实如此,确实如此误导。文档让它看起来像它的 2 args 将被用作纹理的 内部格式 (实现中 glTexImage2D
调用的第三个 arg),而实际上它们' re 仅用作 "source-data-to-transfer-from-system-RAM" format/type(glTexImage2D
的第 7 个和第 8 个参数),在将空指针传递给 glTexImage2D
的情况下,这无关紧要除了附带的 OpenGL ES 2 案例之外的所有案例。
实际上为纹理请求某种内部格式的方法是在调用[=18之前调用tex.setFormat
=].所以我用这个替换了我的 allocateStorage
行:
tex.setFormat(QOpenGLTexture::RGBA8_UNorm);
tex.allocateStorage();
然后修复了错误。
我已将其提炼为简单的 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
}
}
你有...
QOpenGLTexture tex(QOpenGLTexture::Target2D);
根据 docs 实际上并没有创建底层纹理对象。我想你需要...
tex.create();
在设置大小和分配存储之前。所以...
QOpenGLTexture tex(QOpenGLTexture::Target2D);
if (!tex.create()) {
/*
* Take appropriate action.
*/
}
tex.setSize(100, 100);
tex.allocateStorage(QOpenGLTexture::BGRA, QOpenGLTexture::Int8);
编辑 1:
实际上,查看代码似乎 tex.allocateStorage
应该在必要时分配一个纹理 ID。但是,如果由于某种原因(例如没有当前上下文)而失败,那么这可能会导致您看到的问题。
在"allocatestorage"期间,您正在传送有关纹理存储格式的opeGL驱动程序。
对于格式 "GL_BGRA or GL_RGBA",OpenGL 建议 "GL_UNSIGNED_BYTE"、
在 Qt 中 ----- “QOpenGLTexture::BGRA
”(对于 GL_BGRA)和“QOpenGLTexture::UInt8
”(对于 GL_UNSIGNED_BYTE)。
https://www.khronos.org/opengl/wiki/Textures_-_more
所以你的基于(openGL推荐)的分配存储函数应该是
tex.allocateStorage(QOpenGLTexture::BGRA, QOpenGLTexture::UInt8);
在查看 QOpenGLTexture::createMutableTexture
和 QOpenGLTexture::allocateStorage()
的源代码(无参数版本)后,我发现双参数 allocateStorage
重载确实如此,确实如此误导。文档让它看起来像它的 2 args 将被用作纹理的 内部格式 (实现中 glTexImage2D
调用的第三个 arg),而实际上它们' re 仅用作 "source-data-to-transfer-from-system-RAM" format/type(glTexImage2D
的第 7 个和第 8 个参数),在将空指针传递给 glTexImage2D
的情况下,这无关紧要除了附带的 OpenGL ES 2 案例之外的所有案例。
实际上为纹理请求某种内部格式的方法是在调用[=18之前调用tex.setFormat
=].所以我用这个替换了我的 allocateStorage
行:
tex.setFormat(QOpenGLTexture::RGBA8_UNorm);
tex.allocateStorage();
然后修复了错误。