Проблема с копированием данных Qt 5.5 QOpenGLTexture

Я работаю с классами-оболочками Qt 5.5 OpenGL. В частности, пытаясь заставить работать QOpenGLTexture. Здесь я создаю белую 2D-текстуру 1x1 для целей маскировки. Это работает:

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 и текстурам push/pop в этом массиве.

  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) пример, если это поможет. Я также не понимаю эти коды ошибок и, очевидно, их сложно отлаживать на графическом процессоре, если это то, что идет не так. Я пробовал всевозможные комбинации PixelType и PixelFormat.

Спасибо!


person Jacob Block    schedule 15.10.2015    source источник


Ответы (2)


Этот вопрос очень старый, но я сам столкнулся с подобной проблемой. Для меня решением было вызвать setFormat перед

m_whiteTexture->setFormat(QOpenGLTexture::RGBA8_UNorm);
person flaiver    schedule 07.04.2019
comment
В моем случае я вынужден использовать QOpenGLTexture::AlphaFormat, и он не работает по той же причине, что и в исходном посте, и для него нет такой альтернативы, как в случае с RGBA. - person Youw; 14.11.2020

Как я узнал здесь: 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), вам нужно либо установить данные текстуры для каждого уровня мип-карты (что вам действительно не нужно в вашем случае), либо отключить использование мип-карт. :

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

сразу после того, как вы выделили хранилище для данных текстуры.

person Youw    schedule 14.11.2020