2012-11-27 13 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); 

マイチェッカーがサイレントとどまるのでFBOsが完了しています。ピッキングコード

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 

興味深い事実IがglBindFramebufferコメントを外した場合(GL_READ_FRAMEBUFFERを、0);エラーは発生せず、ピクセルは画面から読み込まれます(ただし、これは必要ありません)。

ここで間違っている可能性がありますか?

+0

もう1つ興味深い事実。 RB0の形式をGL_R32UIからGL_R32Fに変更した場合、整数を格納して読み込み、uint32とfloatの間の変換に精度を失わないことを除いて、すべて正常に動作します。 (BTW、フラグメントシェーダからの出力はuvec4です) –

+1

問題はフレームバッファのフォーマットにありました。 glReadBuffer()は、GL_RGBA8IやGL_RGBA8UIやGL_R32UIのような整数形式のバッファから読み込もうとしたときにのみエラーを生成します。 GL_RGBA8またはGL_R32Fから読み取るときに問題はありません。他の誰かがそれに遭遇した場合、それは問題の修正かもしれません。 –

答えて

0

あなたがそのコード行のコメントを解除する場合は、あなたのドライバがGL_SAMPLE_BUFFERSがhttp://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xmlから、0であることについて、あなたに嘘をついている場合、私は疑問に思う「固定」だということを考える:

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用のRBO記憶スペースはglRenderbufferStorage()で作成されました。このFBOがマルチサンプルされる理由は何ですか? –

+0

私は分かりません。それは、「無効な操作」の可能性が限られているだけの理論だった。 –

0

あなたはNVIDIAのバイナリドライバを使用している場合Linux上および非グラフィカル仮想コンソールに切り替えている(例えばCTRL +ALT +F1)、その後glReadPixels()しようとすると、GL_INVALID_OPERATION(0x502)を返します。

ソリューション:バックグラフィカルコンソール(通常CTRL +ALT +F7)に切り替えます。

関連する問題