OpenGL: чтение цветового буфера - PullRequest
0 голосов
/ 30 декабря 2018

Я прикрепил 4 цветовых буфера к кадровому буферу и рендерил в каждом из них.Каждый цветовой буфер имеет размер окна.Я пытаюсь прочитать цвет пикселей одного из этих цветовых буферов, используя координаты указателя мыши.

обработчик события перемещения мыши

void mouseMoveEvent(QMouseEvent *event)
{
    int x = event->pos().x();
    int y = event->pos().y();

    makeCurrent();
    glBindFramebuffer(GL_READ_FRAMEBUFFER, FBOIndex::GEOMETRY);
    {
        // I save the values I'm interested in in the attachment GL_COLOR_ATTACHMENT3
        // but I always get 0 from any other attachment I try
        glReadBuffer(GL_COLOR_ATTACHMENT3);

        QVector<GLubyte> pixel(3);
        glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));

        QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();    
        qDebug() << PixelColor; // => always 0
    }
    glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
    doneCurrent();
}

Но для каждого цветового буфера я всегда читаю значение 0.

Цветовые буферы пишутся правильно во время фазы рендеринга, я тестировал каждый из них, отображая текстуру, к которой они прикреплены.Я также проверил считывание пикселей, выделенное указателем мыши на буфере кадров по умолчанию, и оно работает правильно.

Где я ошибаюсь?Спасибо!

РЕДАКТИРОВАТЬ

Кажется странным то, что, если я использую «выделенный» кадровый буфер, я могу правильно прочитать значения, хранящиеся в текстуре.

void mouseMoveEvent(QMouseEvent *event)
{
    int x = event->pos().x();
    int y = event->pos().y();

    GLuint fbo;

    makeCurrent();
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    {
        GLuint texture = textures[TextureIndex::COLOUR];
        glBindTexture(GL_TEXTURE_2D, texture);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

        QVector<GLubyte> pixel(3);
        glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));

        QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
        qDebug() << PixelColor; // => correct value
    }
    glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
    glDeleteFramebuffers(1, &fbo);
    doneCurrent();
}

Но, очевидно, кажется бесполезным использовать другой фрейм-буфер, когда у меня уже есть тот, который содержит именно ту информацию, которая мне нужна.

Я также пытался непосредственно прочитать значения текстуры (как предложено @Спектре), но и в этом случае я всегда получаю 0.

void mouseMoveEvent(QMouseEvent *event)
{
    int x = event->pos().x();
    int y = event->pos().y();

    makeCurrent();
    {
        GLuint texture = textures[TextureIndex::COLOUR];
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexSubImage2D(GL_TEXTURE_2D, 0, x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));

        QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();
        qDebug() << PixelColor; // => always 0
    }
    doneCurrent();
}

1 Ответ

0 голосов
/ 01 января 2019

Мой подход правильный, но я не связывался с правильным кадровым буфером.

FBOIndex::GEOMETRY - это значение enum, которое я использую для индексации массива FBO, где я храню все имена объектов кадрового буфера, поэтомув общем случае это неверное имя объекта кадрового буфера.

Я определил метод addFBO(index), который создает кадровый буфер и сохраняет его в позиции index в массиве FBOs.Метод возвращает имя объекта кадрового буфера сгенерированного кадрового буфера.Если кадровый буфер уже существует в позиции index, то метод просто возвращает имя связанного объекта кадрового буфера.

Таким образом, изменяя код следующим образом, я наконец получаю желаемый результат.

void mouseMoveEvent(QMouseEvent *event)
{
    int x = event->pos().x();
    int y = event->pos().y();

    makeCurrent();
    glBindFramebuffer(GL_READ_FRAMEBUFFER, addFBO(FBOIndex::GEOMETRY));
    {
        glReadBuffer(GL_COLOR_ATTACHMENT3);

        QVector<GLubyte> pixel(3);
        glReadPixels(x, geometry().height() - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &(pixel[0]));

        QString PixelColor = QColor(pixel[0], pixel[1], pixel[2]).name();    
        qDebug() << PixelColor; // => correct value
    }
    glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
    doneCurrent();
}
...