我正在尝试用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); 然后没有错误发生,从屏幕上读取像素(但我不需要这个).
这可能有什么问题?
您的问题是格式参数。对于具有单通道整数内部格式的纹理,正确的参数不是GL_RED,而是GL_RED_INTEGER:
glReadPixels(pos.x(), resolution.y() - pos.y(), 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &result);\nRun Code Online (Sandbox Code Playgroud)\n查看OpenGL 文档 wiki(重点是我的):
\n\n\n...
\n格式
\n指定像素数据的格式。对于深度、模板或深度/模板数据的传输,您必须在适当的情况下使用 GL_DEPTH_COMPONENT、GL_STENCIL_INDEX 或 GL_DEPTH_STENCIL。对于标准化整数或浮点彩色图像数据的传输,必须使用以下之一:GL_RED、GL_GREEN、GL_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鉴于如果您取消注释该行代码,它是“固定的”,我想知道您的驱动程序是否对您撒谎,说 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)