Qt 5.5 QOpenGLTexture 复制数据问题

4

我正在使用Qt 5.5 OpenGL包装类。具体而言,我正在尝试让QOpenGLTexture正常工作。这里我正在创建一个1x1的2D白色纹理用于遮罩目的。这个是有效的:

void Renderer::initTextures()
{    
    QImage white(1, 1, QImage::Format_RGBA8888);
    white.fill(Qt::white);
    m_whiteTexture.reset(new QOpenGLTexture(QOpenGLTexture::Target2D));
    m_whiteTexture->setSize(1, 1);
    m_whiteTexture->setData(white);
    //m_whiteTexture->allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt32);
    //m_whiteTexture->setData(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, white.bits());

    // Print any errors
    QList<QOpenGLDebugMessage> messages = m_logger->loggedMessages();
    if (messages.size())
    {
        qDebug() << "Start of texture errors";
        foreach (const QOpenGLDebugMessage &message, messages)
            qDebug() << message;
        qDebug() << "End of texture errors";
    }
}

但是我现在需要完成两件事情:

  1. Use allocate + setData sequence as separate commands (the commented out lines), e.g.

    m_whiteTexture->allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt32);
    m_whiteTexture->setData(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, white.bits());
    

为了更复杂的渲染,我希望稍后只更新部分数据而不重新分配内存。与此相关的是(2),我想转移到Target2DArray并在该数组中推送/弹出纹理。

  1. 创建一个Target2DArray纹理,并使用QImage填充图层。最终,我将向上推送/弹出纹理以达到硬件可用的最大尺寸。

关于(1),我从QOpenGLDebugMessage记录器获得以下错误:

Start of texture errors
QOpenGLDebugMessage("APISource", 1280, "Error has been generated. GL error GL_INVALID_ENUM in TextureImage2DEXT: (ID: 2663136273) non-integer <format> 0 has been provided.", "HighSeverity", "ErrorType")
QOpenGLDebugMessage("APISource", 1280, "Error has been generated. GL error GL_INVALID_ENUM in TextureImage2DEXT: (ID: 1978056088) Generic error", "HighSeverity", "ErrorType")
QOpenGLDebugMessage("APISource", 1281, "Error has been generated. GL error GL_INVALID_VALUE in TextureImage2DEXT: (ID: 1978056088) Generic error", "HighSeverity", "ErrorType")
QOpenGLDebugMessage("APISource", 1281, "Error has been generated. GL error GL_INVALID_VALUE in TextureSubImage2DEXT: (ID: 1163869712) Generic error", "HighSeverity", "ErrorType")
End of texture errors

我的遮罩在原始代码中可以正常工作,但我无法使其在(1)和(2)场景中工作。对于(2),我将目标更改为Target2DArray,更改大小以包括深度为1,调整我的着色器使用vec3纹理坐标和sampler3D进行采样等。如果需要,我可以发布更完整的(2)示例。我也不理解这些错误代码,如果问题出在GPU上显然很难调试。我尝试了各种PixelType和PixelFormat组合。
谢谢!
2个回答

0

这个问题很老了,但我最近遇到了一个类似的问题。对我来说,解决方案是在之前调用setFormat。

m_whiteTexture->setFormat(QOpenGLTexture::RGBA8_UNorm);

在我的情况下,我被迫使用 QOpenGLTexture::AlphaFormat,但由于与原帖中相同的原因它无法工作,并且与 RGBA 不同,它没有替代品。 - Youw

0

我在这里发现:https://www.khronos.org/opengl/wiki/Common_Mistakes#Creating_a_complete_texture 原始代码的问题是,纹理不完整

正如@flaiver所提到的,使用QOpenGLTexture::RGBA8_UNorm可以解决问题,但这仅因为Qt对于此纹理使用了不同类型的存储(实际上它使用了glTexStorage2D,根据OpenGL文档,这甚至更好),而对于QOpenGLTexture::RGBA则不是这种情况。

为了使纹理工作,即使您确实需要特定的QOpenGLTexture::RGBA(或其他格式,例如QOpenGLTexture::AlphaFormat),您需要为每个mipmap级别设置纹理数据(对于您的情况您并不真正需要),或禁用使用mipmaps:

// the default is `QOpenGLTexture::NearestMipMapLinear`/`GL_NEAREST_MIPMAP_LINEAR`,
// but it doesn't work, if you set data only for level 0
// alternatively use QOpenGLTexture::Nearest if that suits your needs better
m_whiteTexture->setMagnificationFilter(QOpenGLTexture::Linear);
m_whiteTexture->setMinificationFilter(QOpenGLTexture::Linear);

// // optionally a good practice is to explicitly set the Wrap Mode:
// m_whiteTexture->setWrapMode(QOpenGLTexture::ClampToEdge);

就在您为纹理数据分配存储空间之后。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接