2015-06-22 8 views
5

Ich versuche einen FrameBuffer mit 2 Texturen zu erstellen (Multi Render Targets). Dann werden in jedem Zeitschritt beide Texturen gelöscht und bemalt, wie im folgenden Code. (Ein Teil wird als Pseudo-Code ersetzt werden, um es kürzer zu machen.)OpenGL - Ist die Modifikation von glDrawBuffers in einem FBO gespeichert? Nein?

Version 1

//beginning of the 1st time step 
initialize(framebufferID12) 
//^ I quite sure it is done correctly, 
//^ Note : there is no glDrawBuffers() calling 

loop , do once every time step { 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID12); 
    //(#1#) a line will be add here in version 2 (see belowed) <------------ 
    glClearColor (0.5f, 0.0f, 0.5f, 0.0f); 
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    // paint a lot of object here , using glsl (Shader .frag, .vert) 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 
} 

Alle Objekte korrekt sowohl Textur gemalt werden, aber nur die erste Textur (ATTACHMENT0) ist löschte jeden Rahmen, was falsch ist.

Version 2

Ich versuche, eine Codezeile einzufügen ...

glDrawBuffers({ATTACHMENT0,ATTACHMENT1}) ; 

an (# 1 #) und es funktioniert wie erwartet das heißt klar alle zwei Texturen.

(Bild http://s13.postimg.org/66k9lr5av/gl_Draw_Buffer.jpg)

Version 3

Ab Version 2, ich dass glDrawBuffers() Anweisung bewegen sich in Frame-Buffer-Initialisierung wie folgt

initialize(int framebufferID12){ 
    int nameFBO = glGenFramebuffersEXT(); 
    int nameTexture0=glGenTextures(); 
    int nameTexture1=glGenTextures(); 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,nameFBO); 
     glBindTexture(nameTexture0); 
     glTexImage2D(....); glTexParameteri(...); 
     glFramebufferTexture2DEXT(ATTACHMENT0, nameTexture0); 
     glBindTexture(nameTexture1); 
     glTexImage2D(....); glTexParameteri(...); 
     glFramebufferTexture2DEXT(ATTACHMENT0, nameTexture1); 
     glDrawBuffers({ATTACHMENT0,ATTACHMENT1}) ; //<--- moved here --- 
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); 
    return nameFBO ; 
} 

zu sein Es funktioniert nicht mehr (Symptom wie Version 1), warum?

Das opengl Handbuch sagte, dass "Änderungen im Kontextstatus in diesem Objekt gespeichert werden", so dass die Zustandsänderung von glDrawBuffers() in "framebufferID12" gespeichert wird, richtig? Dann, warum ich es jedes Mal aufrufen muss (oder jedes Mal, wenn ich FBO ändere)

kann ich einige opengl's Konzept missverstehen, jemand erleuchte mich bitte.

Bearbeiten 1: Vielen Dank j-p. Ich stimme zu, dass es sinnvoll ist, aber sollte der Staat nicht bereits im FBO erfasst werden?

Edit 2 (Antwort akzeptieren): Reto Koradis Antwort ist korrekt! Ich benutze eine nicht so Standard-Bibliothek namens LWJGL.

+0

Es macht für mich Sinn, dass Sie Zeichen Puffer jedes Mal anpassen müssen, wenn Sie an einen neuen Puffer binden, wenn Sie nicht die Standardkonfiguration verwenden. aber ich bin kein Spezialist ... –

Antwort

4

Ja, die Einstellung der Zeichenpuffer ist Teil des Framebuffer-Status. Wenn Sie sich beispielsweise das OpenGL 3.3-Spezifikationsdokument ansehen, wird es in Tabelle 6.23 auf Seite 299 mit dem Titel "Framebuffer (Status pro Framebuffer-Objekt)" aufgeführt. Der Standardwert für FBOs ist ein einzelner Zeichenpuffer, der GL_COLOR_ATTACHMENT0 ist. Aus derselben Spezifikation, Seite 214:

Bei Framebuffer-Objekten ist im Ausgangszustand der Zeichenpuffer für die Fragmentfarbe Null COLOR_ATTACHMENT0. Für die Standard-Framebuffer- und Framebuffer-Objekte ist der Anfangszustand von Zeichenpuffern für andere Fragmentfarben als Null NONE.

Es wird also erwartet, dass Sie, wenn Sie mehr als einen Zeichenpuffer haben, den expliziten Aufruf glDrawBuffers() benötigen.

Nun, warum es scheint nicht für Sie arbeiten, wenn Sie die glDrawBuffers() Aufruf als Teil der FBO-Setup machen, das ist etwas mysteriös. Eine Sache, die ich in Ihrem Code bemerken ist, dass Sie die EXT Form der FBO Anrufe verwenden. Ich vermute, dass dies etwas mit Ihrem Problem zu tun haben könnte.

FBOs sind seit Version 3.0 Bestandteil von Standard-OpenGL. Wenn Sie OpenGL 3.0 oder neuer verwenden können, würde ich Ihnen dringend empfehlen, die Standard-Einstiegspunkte zu verwenden. Während die Erweiterungen normalerweise noch funktionieren, nachdem die Funktionalität zum Standard geworden ist, würde ich immer skeptisch sein, wie sie mit anderen Funktionen interagieren. Insbesondere gab es mehrere Erweiterungen für die FBO-Funktionalität vor 3.0 mit unterschiedlichem Verhalten. Ich wäre nicht überrascht, wenn einige von ihnen anders als die Standard-FBO-Funktionalität mit anderen OpenGL-Aufrufen interagieren würden.

Versuchen Sie also, die Standard-Einstiegspunkte zu verwenden (diejenigen ohne die EXT in ihrem Namen). Das wird hoffentlich dein Problem lösen.