2012-11-27 16 views
7

Ich versuche, Farbauswahl mit FBO zu implementieren. Ich habe multisampling FBO (fbo [0]), die ich verwende, um die Szene zu rendern, und ich habe nicht multisampled FBO (fbo [1]), die ich für die Farbauswahl verwenden.glReadPixels() setzt GL_INVALID_OPERATION Flag ohne Grund

Das Problem ist: wenn ich versuche, Pixeldaten von fbo [1] zu lesen, geht alles gut, bis glReadPixels den GL_INVALID_OPERATION Flag aufruft. Ich habe das Handbuch überprüft und kann den Grund nicht finden.

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); 

Mein checker schweigt so die FBOs abgeschlossen sind:

Der Code FBO zu erstellen. Als nächstes wird die Kommissionierung Code

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; 

die Ausgabe:

Sample buffers 0 
OpenGL Error : Invalid Operation 

Die interessante Tatsache, dass, wenn ich Kommentar- glBindFramebuffer (GL_READ_FRAMEBUFFER, 0); dann passiert kein Fehler und Pixel werden vom Bildschirm gelesen (aber ich brauche das nicht).

Was kann hier falsch sein?

+0

Eine weitere interessante Tatsache. Wenn ich das RBO-Format von GL_R32UI zu GL_R32F ändere, funktioniert alles gut, außer dass ich ganze Zahlen speichern und lesen will und die Genauigkeit bei der Konvertierung zwischen uint32 und float nicht verliere. (BTW, die Ausgabe von Fragment Shader ist uvec4) –

+1

Nun, das Problem war mit dem Format von Framebuffer. glReadBuffer() erzeugt nur dann einen Fehler, wenn ich versuche, aus einem Puffer mit Ganzzahlformaten (wie GL_RGBA8I oder GL_RGBA8UI oder GL_R32UI) zu lesen. Keine Probleme beim Lesen von GL_RGBA8 oder GL_R32F. Das könnte die Lösung für das Problem sein, wenn jemand anders darauf stößt. –

Antwort

0

Da es „fixiert“, wenn Sie diese Codezeile Kommentar-, frage ich mich, wenn Ihr Fahrer Sie liegt etwa GL_SAMPLE_BUFFERS 0. Aus http://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xml sein:

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

Nun RBOs Speicherplatz für diese FBO wurden mit glRenderbufferStorage() erstellt. Was ist der Grund für diesen FBO Multisampling? –

+0

Ich habe keine Ahnung. Es war nur eine Theorie angesichts der begrenzten Möglichkeiten für "ungültige Operation". –

0

Wenn Sie mit NVIDIAs Binärtreiber auf Linux und hat zu einer nicht-grafischen virtuellen Konsole (zB CTRL +ALT +F1) dann jeder Versuch, glReadPixels() kehrt GL_INVALID_OPERATION (0x502) geschaltet.

Lösung: zurück zur grafischen Konsole wechseln (in der Regel CTRL +ALT + F7).