glReadPixels()无缘无故地设置GL_INVALID_OPERATION标志

Ole*_*tov 7 c++ opengl fbo

我正在尝试用FBO实现颜色选择.我有多重采样FBO(fbo [0]),我用它来渲染场​​景,我有非多重采样FBO(fbo [1]),我用它来进行颜色选择.

问题是:当我尝试从fbo [1]读取像素数据时,一切顺利,直到glReadPixels调用设置GL_INVALID_OPERATION标志.我检查了手册,找不到原因.

创建FBO的代码:

glBindRenderbuffer(GL_RENDERBUFFER, rbo[0]);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, GL_RGBA8, resolution[0], resolution[1]);
glBindRenderbuffer(GL_RENDERBUFFER, rbo[1]);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, GL_DEPTH24_STENCIL8, resolution[0], resolution[1]);
glBindRenderbuffer(GL_RENDERBUFFER, rbo[2]);
glRenderbufferStorage(GL_RENDERBUFFER, GL_R32UI, resolution[0], resolution[1]);
glBindRenderbuffer(GL_RENDERBUFFER, rbo[3]);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, resolution[0], resolution[1]);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]);   
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[3]);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[2]);
OGLChecker::checkFBO(GL_DRAW_FRAMEBUFFER);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[0]);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]);
OGLChecker::checkFBO(GL_DRAW_FRAMEBUFFER);
Run Code Online (Sandbox Code Playgroud)

我的检查员保持沉默,以便FBO完成.接下来是拣货代码

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// bla, bla, bla
// do the rendering
unsigned int result;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[1]);
int sb;
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glGetIntegerv(GL_SAMPLE_BUFFERS, &sb);
//    glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
OGLChecker::getGlError();
std::cerr << "Sample buffers " << sb << std::endl;
glReadPixels(pos.x(), resolution.y() - pos.y(), 1, 1, GL_RED, GL_UNSIGNED_INT, &result);
OGLChecker::getGlError();
return result;
Run Code Online (Sandbox Code Playgroud)

输出:

Sample buffers 0
OpenGL Error : Invalid Operation
Run Code Online (Sandbox Code Playgroud)

有趣的事实,如果我取消注释glBindFramebuffer(GL_READ_FRAMEBUFFER,0); 然后没有错误发生,从屏幕上读取像素(但我不需要这个).

这可能有什么问题?

Tar*_*ani 5

您的问题是格式参数。对于具有单通道整数内部格式的纹理,正确的参数不是GL_RED,而是GL_RED_INTEGER

\n
glReadPixels(pos.x(), resolution.y() - pos.y(), 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &result);\n
Run Code Online (Sandbox Code Playgroud)\n

查看OpenGL 文档 wiki(重点是我的):

\n
\n

...

\n

格式

\n

指定像素数据的格式。对于深度、模板或深度/模板数据的传输,您必须在适当的情况下使用 GL_DEPTH_COMPONENT、GL_STENCIL_INDEX 或 GL_DEPTH_STENCIL。对于标准化整数或浮点彩色图像数据的传输,必须使用以下之一:GL_RED、GL_GREEN、G​​L_BLUE、GL_RG、GL_RGB、GL_BGR、GL_RGBA 和 GL_BGRA。对于非标准化整数数据的传输,必须使用以下之一:GL_RED_INTEGER、GL_GREEN_INTEGER、GL_BLUE_INTEGER、GL_RG_INTEGER、GL_RGB_INTEGER、GL_BGR_INTEGER、GL_RGBA_INTEGER 和 GL_BGRA_INTEGER。即使没有进行实际的像素传输(data\xe2\x80\x8b 为 NULL 并且没有缓冲区绑定到 GL_PIXEL_UNPACK_BUFFER),您也必须针对目标图像的内部格式正确设置此参数。

\n

...

\n
\n
\n

注意:官方参考页面不完整/错误。

\n


Jim*_*uck 1

鉴于如果您取消注释该行代码,它是“固定的”,我想知道您的驱动程序是否对您撒谎,说 GL_SAMPLE_BUFFERS 为 0。来自http://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xml :

GL_INVALID_OPERATION is generated if GL_READ_FRAMEBUFFER_BINDING is non-zero, the read framebuffer is complete, and the value of GL_SAMPLE_BUFFERS for the read framebuffer is greater than zero.
Run Code Online (Sandbox Code Playgroud)