c++ - OpenGL:读取颜色缓冲区
问题描述
我将 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
是一个枚举值,用于索引 FBOs 数组,我在其中存储所有帧缓冲区对象名称,因此通常它不是正确的帧缓冲区对象名称。
我已经定义了一个addFBO(index)
创建帧缓冲区并将其存储在index
FBOs 数组中的位置的方法。该方法返回生成的帧缓冲区的帧缓冲区对象名称。如果在 position 处已经存在帧缓冲区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();
}
推荐阅读
- python - 无论输入如何,Tensorflow 模型每次都保持预测接近相同的值
- javascript - Why does my website shift to the left on Safari?
- macos - macOS 动态链接器加载不需要的 dylib
- terraform - terraform - 如何在属性中使用变量
- sql - Postgresql 性能:使用 pg_timezone_names 的最佳方式是什么?
- python - 对多个值使用逻辑运算符
- python - 使用 Python 下载多个文件
- java - 如何在 Spring Boot 中将 applications.properties 添加到组件中?
- django - Cloudinary 在 Django 中显示不正确的 url
- html - 如何在 ASP.NET MVC 中定义搜索过程的路由?