2012-03-28 10 views
9

Ich habe Rahmenpuffer mit Tiefenkomponente und 4 Farb Anhängen mit 4 TexturesOpenGL, wie depthbuffer von Bildpuffern wie üblich Tiefenpuffer verwenden

I etwas Material hinein ziehen und die Puffer nach unbind, unter Verwendung von 4 Texturen für Fragment Shader (verzögerte Beleuchtung). Später möchte ich noch etwas mehr auf dem Bildschirm zeichnen, mit dem Tiefenpuffer von meinem Framebuffer, ist es möglich?

Ich habe versucht, den Framebuffer erneut zu binden und glDrawBuffer (GL_FRONT) zu spezifizieren, aber es funktioniert nicht.

Antwort

10

Wie Nicol bereits sagte, können Sie keinen FBO-Tiefenpuffer als Standard-Tiefenpuffer des Framebuffers direkt verwenden.

aber Sie können die FBO der Tiefenpuffer über auf den Standardframebuffer mit der EXT_framebuffer_blit Erweiterung kopieren (der Kern seit GL 3 sein soll):

glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); 
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, 
        GL_DEPTH_BUFFER_BIT, GL_NEAREST); 

Wenn diese Erweiterung nicht unterstützt wird (was ich bezweifle, wenn Sie haben bereits FBOs), können Sie eine Tiefenstruktur für den Tiefenanhang des FBO verwenden und diese zum Standard-Framebuffer machen, indem Sie einen texturierten Quadranten und einen einfachen Pass-Through-Fragment-Shader verwenden, der in gl_FragDepth schreibt. Obwohl das langsamer sein könnte, als es nur zu blittern.

+0

yah, Blit Funktion funktioniert gut, danke – ShPavel

2

Sie können keine Bilder (Farbe oder Tiefe) an den Standard-Framebuffer anhängen. Ebenso können Sie keine Bilder vom Standard-Framebuffer aufnehmen und an einen FBO anhängen.

7

Ich habe gerade erfahren, dass das Kopieren eines Tiefenpuffers von einem Renderpuffer in den main (kontextgespeicherten) Tiefenpuffer sehr unzuverlässig ist, wenn glBlitFramebuffer verwendet wird. Nur weil Sie nicht garantieren können, dass das Format passt. Die Verwendung von GL_DEPTH_COMPONENT24 als internes Tiefen-Textur-Format funktionierte bei meinem AMD Radeon 6950 (neuster Treiber) einfach nicht, da Windows (oder der Treiber) sich dafür entschied, das Äquivalent zu GL_DEPTH24_STENCIL8 als Tiefenformat für meinen Front-/Backbuffer zu verwenden Ich habe keine Schablonenpräzision angefordert (Schablonen-Bits wurden im Pixelformat-Deskriptor auf 0 gesetzt). Bei der Verwendung von GL_DEPTH24_STENCIL8 für die Tiefenstruktur meines Framebuffers funktionierte das Blitzen wie erwartet, aber ich hatte andere Probleme mit diesem Format. Der erste Versuch funktionierte gut auf NVIDIA-Karten, also bin ich mir ziemlich sicher, dass ich die Dinge nicht vermasselt habe.

Was am besten (nach meiner Erfahrung) arbeitet, ist das Kopieren über Shader:

Das Fragment-Programm (auch bekannt als Pixel-Shader) [GLSL]

#version 150 

uniform sampler2D depthTexture; 
in vec2 texCoords; //texture coordinates from vertex-shader 

void main(void) 
{ 
    gl_FragDepth = texture(depthTexture, texCoords).r; 
} 

Der C++ Code für das Kopieren wie folgt aussieht:

glDepthMask(GL_TRUE); 
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
glEnable(GL_DEPTH_TEST); //has to be enabled for some reason 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 
depthCopyShader->Enable(); 
DrawFullscreenQuad(depthTextureIndex); 

ich weiß, dass der Thread ist alt, aber es war eine meiner ersten Ergebnisse, wenn mein Problem googeln, so möchte ich es behalten so konsistent wie möglich.

+0

Danke, löste das Problem mit meiner integrierten Intel-Grafik. – joesmoe891

+1

Gibt es eine Möglichkeit, das Standardpufferformat nach seiner Erstellung zu erhalten und das fbo zu erstellen? –

+0

Ich frage mich auch das gleiche wie @LukeB. weil es das Blitting zwischen zwei Framebuffern erlaubt, wenn man weiß, dass die Formate übereinstimmen. Das würde auch für den Fall funktionieren, dass wir vom Standard-Framebuffer, den wir mit einem Shader nicht ausführen können, blitten wollen, da der Tiefenpuffer nicht zugänglich ist. –

Verwandte Themen