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. 使用 allocate + setData 序列作为单独的命令(注释掉的行),例如

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

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

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

关于(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 组合。

谢谢!

4

2 回答 2

0

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

正如@flaiver 所提到的, usingQOpenGLTexture::RGBA8_UNorm有效,但仅仅是因为 Qt 使用不同类型的存储来存储此纹理(实际上它使用glTexStorage2D,根据 OpenGL 文档,这甚至更好),而QOpenGLTexture::RGBA.

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

// 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);

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

于 2020-11-14T14:12:30.130 回答
0

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

m_whiteTexture->setFormat(QOpenGLTexture::RGBA8_UNorm);
于 2019-04-07T11:35:41.427 回答