2016-07-31 25 views
0

Ich habe Schwierigkeiten, meine Shadow Mapping-Implementierung von Vorwärts-Rendering auf verzögertes Rendering umzustellen. Ich habe das Problem gefunden und es wird keine Cubemap an den Shader gesendet. Ich vermute, dass es daran liegt, dass mein "GBuffer" -FBO anstelle der Cubemap FBO gebunden ist.OpenGL - Zugreifen auf eine Cubemap, wenn ein anderer FBO gebunden ist

Wenn GLSL in einem einzigen Zeichenaufruf auf Farbanhänge von zwei verschiedenen FBOs zugreifen kann, würde ich diesen Weg gehen, ist das möglich?

Unten, die Arbeit vorwärts Rendering-Code.

public void NormalPass(Shader shader) 
{ 
    // Reset state 
    GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); 
    GL.BindTexture(TextureTarget.Texture2D, 0); 

    GL.UseProgram(shader.ID); 
    GL.Viewport(0, 0, Width, Height); 
    GL.CullFace(CullFaceMode.Back); 
    GL.ClearColor(0.5f, 0.5f, 0.5f, 1f); 

    // Uniforms 
    Matrix4 viewMatrix = player.GetViewMatrix(); 
    Matrix4 projectionMatrix; 
    Matrix4.CreatePerspectiveFieldOfView((float)Math.PI/4, (float)Width/(float)Height, 0.1f, 100.0f, out projectionMatrix); 
    GL.UniformMatrix4(shader.viewMatrixLocation, false, ref viewMatrix); 
    GL.UniformMatrix4(shader.projectionMatrixLocation, false, ref projectionMatrix); 
    GL.Uniform3(shader.lightPositionLocation, lightPos); 

    GL.BindTexture(TextureTarget.TextureCubeMap, cubeTex); 
    DrawScene(shader, false);        // False = Not shadowpass 
    GL.BindTexture(TextureTarget.TextureCubeMap, 0); 
} 

Und hier die fehlerhafte latente Rendering Änderung

public void Composite(Shader shader) 
{ 
    //Set up FBO reading/writing 
    GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0); 
    GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, gBuffer.FBO); 

    // Bind textures 
    GL.ActiveTexture(TextureUnit.Texture2); 
    GL.BindTexture(TextureTarget.Texture2D, gBuffer.positionTexture); 
    GL.ActiveTexture(TextureUnit.Texture1); 
    GL.BindTexture(TextureTarget.Texture2D, gBuffer.normalTexture); 

    GL.UseProgram(shader.ID); 
    GL.Disable(EnableCap.DepthTest); 
    GL.Viewport(0, 0, Width, Height); 
    GL.CullFace(CullFaceMode.Back); 
    GL.ClearColor(0.5f, 0.5f, 0.5f, 1f); 
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); 

    // Uniforms 
    Matrix4 viewMatrix = player.GetViewMatrix(); 
    GL.UniformMatrix4(shader.viewMatrixLocation, false, ref viewMatrix); 
    GL.Uniform3(shader.lightPositionLocation, lightPos); 

    GL.BindTexture(TextureTarget.TextureCubeMap, cubeTex); 
    Quad2D.drawScreenSizedQuad(); // Draw the combined lighting and diffuse to screen 
    GL.BindTexture(TextureTarget.TextureCubeMap, 0); 
} 

Glücklich mehr Informationen auf Anfrage zur Verfügung zu stellen.

Antwort

2

Wenn GLSL in einem einzigen Zeichenaufruf auf Farbanhänge von zwei verschiedenen FBOs zugreifen kann, möchte ich diese Route gehen, ist das möglich?

Die Frage verrät einen Mangel an Verständnis für das, was vor sich geht. GLSL Zugriff Texturen, keine Farbanhänge von FBOs.

Nun können natürlich Texturen als Farbanhänge verwendet werden. Aber die Unterscheidung ist wichtig, denn GLSL greift auf die gebundenen Texturen zu, nicht auf das, was in einem FBO ist. Die einzigen Regeln, die OpenGL beim Lesen von Texturen hat, die als Farbanhänge an einen FBO angehängt sind, sind folgende: Es funktioniert so lange, wie diese Texturen nicht wirklich an den jeweiligen Framebuffer hängen, der während des Renderings aktiv gezeichnet wird Befehl. Und selbst dann, OpenGL will only care if you break the feedback loop rules.

So dass die Bindung an den Framebuffer lesen ist sinnlos. Das macht die Texturen nicht zum Lesen oder so verfügbar; Das ist nicht der Punkt, an dem der Framebuffer-Bindungspunkt gelesen wird. Es wird nur für framebuffer reading commands und framebuffer blitting operations verwendet.

Also einfach den Standard-Framebuffer an FramebufferTarget.Framebuffer binden, wie Sie im Fall vorwärts getan haben, wäre in Ordnung gewesen.

Ihr Prinzip Problem ist folgendes:

GL.BindTexture(TextureTarget.TextureCubeMap, cubeTex); 

Sie nicht glActiveTexture verwendet haben eine Textureinheit angeben, dass Cubemap zu binden. Das bedeutet, dass es die letzte von Ihnen festgelegte Textureinheit verwendet: TextureUnit.Texture1, und Sie haben dort bereits eine 2D-Textur gebunden. In GLSL ist es verboten, zwei Texturen zweier unterschiedlicher Typen aus derselben Textureinheit zu lesen.

So sind die Chancen gut, das ist nicht, was Sie meinten. Immer Verwenden Sie glActiveTexture vor allen glBindTexture Anrufe. Es sei denn, Sie verwenden glBindTextures from GL 4.4/ARB_multibind oder glBindTextureUnit from GL 4.5/ARB_DSA.

+0

Dies räumt viele meiner Missverständnisse auf und wird mir sicherlich Tage retten, vielen Dank Jason. Es funktioniert jetzt übrigens auch. –