Friday, September 22, 2017

opengl - Using two FBOs results in the second FBO having nothing drawn to



I'm writing a deferred renderer, and I use two FBOs: the first one for G-buffer (color, normal, depth) and the second one for lighting (light output), so the first one has three textures bound and the second one has just one.


Now, the geometry pass works just fine and all the three textures are populated correctly. After this, I try to render a full-screen quad in the lighting pass, but nothing comes to the screen - everything is black. I've even tried to use the diffuse shader program in this pass to be sure it's not a shader problem, and it's not - nothing gets drawn no matter which shader I use.


Here's some code (I've pruned out the non-relevant code)-


G-buffer initialization


// Setup buffers and textures
// FBO initialization
geometryFboId = GL.GenFramebuffer();

GL.BindFramebuffer(FramebufferTarget.FramebufferExt, geometryFboId);

// Texture initialization
diffuseTexture = GL.GenTexture();
normalTexture = GL.GenTexture();
depthTexture = GL.GenTexture();

// Diffuse texture
GL.BindTexture(TextureTarget.Texture2D, diffuseTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, scrWidth, scrHeight, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);

GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, diffuseTexture, 0);

// Normal texture
GL.BindTexture(TextureTarget.Texture2D, normalTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, scrWidth, scrHeight, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment1Ext, TextureTarget.Texture2D, normalTexture, 0);

// Depth texture
GL.BindTexture(TextureTarget.Texture2D, depthTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, scrWidth, scrHeight, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);

GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment2Ext, TextureTarget.Texture2D, depthTexture, 0);

DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[] { DrawBuffersEnum.ColorAttachment0, DrawBuffersEnum.ColorAttachment1, DrawBuffersEnum.ColorAttachment2 };
GL.DrawBuffers(3, drawBuffers);

GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);

Lighting buffer initialization


lightsFboId = GL.GenFramebuffer();
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, lightsFboId);

lightsTexture = GL.GenTexture();

GL.BindTexture(TextureTarget.Texture2D, lightsTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, scrWidth, scrHeight, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, lightsTexture, 0);
DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[] { DrawBuffersEnum.ColorAttachment0 };
GL.DrawBuffers(1, drawBuffers);
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);



// Setup a target texture for the render
lightingTexture = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, lightingTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, scrWidth, scrHeight, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
GL.BindTexture(TextureTarget.Texture2D, 0);

Render call


// Bind geometry pass
diffuseShader.Enable();
GL.UniformMatrix4(diffuseShader.GetUniformLocation("view"), false, ref Camera.main.modelview);

GL.UniformMatrix4(diffuseShader.GetUniformLocation("projection"), false, ref Camera.main.projection);
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, geometryFboId);

// Render the scene
currentScene.Render();

// Clear shaders and framebuffer
Shader.ClearShader();
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);


// Bind lighting pass
lightingShader.Enable();
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, lightsFboId);
// Misc. parameter passing here

// Render a full-screen quad
quadRenderer.Render();

// Clear shaders and framebuffer
Shader.ClearShader();

GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);

// Render output
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.ClearColor(0f, 0f, 0f, 0f);

quadRenderer.Render(gBuffer.DiffuseTexture, QuadRenderer.QuadPosition.TOP_LEFT);
quadRenderer.Render(gBuffer.DepthTexture, QuadRenderer.QuadPosition.TOP_RIGHT);
quadRenderer.Render(gBuffer.NormalTexture, QuadRenderer.QuadPosition.BOTTOM_LEFT);
quadRenderer.Render(gBuffer.LightsTexture, QuadRenderer.QuadPosition.BOTTOM_RIGHT); // Draws just black


Hopefully I didn't miss anything important here. I've checked both FBOs, and they are "complete". I've tried to pass a texture to the quad renderer, but it doesn't seem to matter. I've also tried to replace the lighting shader and lighting passes with the geometry ones, and still nothing.




No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...