2012-11-27 68 views
7

我試圖用FBO實現顏色選擇。我有用於渲染場景的多重採樣FBO(fbo [0]),並且我使用了非多重採樣FBO(fbo [1])來進行顏色拾取。glReadPixels()無故設置GL_INVALID_OPERATION標誌

問題是:當我嘗試從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); 

我檢查保持沉默。接着拾取代碼

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; 

輸出:

Sample buffers 0 
OpenGL Error : Invalid Operation 

的有趣的事實是,如果我去掉glBindFramebuffer(GL_READ_FRAMEBUFFER,0);那麼沒有錯誤發生,並從屏幕上讀取像素(但我不需要)。

這裏可能有什麼問題?

+0

另一個有趣的事實。如果我將RBO的格式從GL_R32UI更改爲GL_R32F,一切正常,但我想存儲和讀取整數,並且不會在uint32和float之間進行轉換時失去精度。 (順便說一下,片段着色器的輸出是uvec4) –

+1

問題是幀緩衝區的格式。 glReadBuffer()僅當我嘗試從整數格式的緩衝區讀取(如GL_RGBA8I或GL_RGBA8UI或GL_R32UI)時纔會生成錯誤。從GL_RGBA8或GL_R32F讀取時沒有問題。如果有其他人遇到問題,這可能是解決問題的方法。 –

回答

0

考慮到它的「固定」,如果你取消註釋行的代碼,我不知道你的驅動程序是騙你關於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. 
+0

這個FBO的RBOs存儲空間是用glRenderbufferStorage()創建的。這個FBO被多采樣的原因是什麼? –

+0

我不知道。這只是一個理論,因爲「無效操作」的可能性有限。 –

0

如果您在使用NVIDIA的二進制驅動程序在Linux和已切換到非圖形虛擬控制檯(例如CTRL + ALT + F1)然後任何企圖glReadPixels()將返回GL_INVALID_OPERATION(0x502)。

解決方案:切換回圖形控制檯(通常CTRL + ALT + F7)。