OpenGL:正在读取颜色缓冲区

OpenGL : reading color buffer

本文关键字:颜色 缓冲区 读取 OpenGL      更新时间:2023-10-16

我将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();
}

但很明显,当我已经有了一个完全符合我需要的信息的帧缓冲区时,使用另一个帧缓冲区似乎毫无用处。

我也尝试直接读取纹理的值(如@Spektre所建议的),但在这种情况下,我总是得到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();
}

我的方法是正确的,但我没有绑定到正确的帧缓冲区。

FBOIndex::GEOMETRY是一个枚举值,我使用它来索引FBO数组,我在其中存储所有帧缓冲区对象名称,因此通常它不是正确的帧缓冲区目标名称。

我定义了一个方法addFBO(index),它创建一个帧缓冲区并将其存储在FBO数组中的index位置。该方法返回生成的帧缓冲区的帧缓冲区时对象名称。如果在位置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();
}