Problem with Deferred Rendering and FBO's

The past few days I’ve been trying to implement Deferred Rendering. However I’ve hit a snag and can’t seem to find the problem.

It would appear that the only data leaving the geometry pass is the world position data, which is the first texture output from the shader. The odd part is that it is being placed into the last color attachment that I have attached to the FBO. All the other color attachments are blank. If someone could help me with this problem I would really appreciate it *:).

Renderer Class. (The object.render() call at line XXX just ends up sending a model in to be rendered in the renderModelWithTexture function)


public class Renderer {

	public static final int FOV = 70;
	public static final float NEAR_PLANE = 0.01f;
	public static final float FAR_PLANE = 1000;

	private static Renderer instance;
	
	private Vector3f ambientLight;
	private DirectionalLight directionalLight;
	private GBuffer gBuffer;
	private Camera renderingCamera;
	
	private GameObject pointLightBoundingSphere, directionalLightBoundingQuad;
	
	public Renderer() {
		
		gBuffer = new GBuffer(DisplayManager.getWidth(), DisplayManager.getHeight());
		
		GL11.glClearColor(0f, 0f, 0f, 1f);
		//GL11.glEnable(GL11.GL_CULL_FACE);
		//GL11.glFrontFace(GL11.GL_CW);
		//sdGL11.glCullFace(GL11.GL_BACK);
		GL11.glEnable(GL11.GL_DEPTH_TEST);
		GL11.glEnable(GL11.GL_TEXTURE_2D);
		
		DeferredGeometry.getInstance().bind();
		DeferredGeometry.getInstance().setProjectionMatrix(Maths.createPerspectiveMatrix((float) DisplayManager.getWidth()
				/ (float) DisplayManager.getHeight(), NEAR_PLANE, FAR_PLANE, FOV));
		DeferredGeometry.getInstance().loadTextureLocations(0);
		
		DeferredDirectional.getInstance().bind();
		DeferredDirectional.getInstance().loadScreenSize(DisplayManager.getWidth(), DisplayManager.getHeight());
		DeferredDirectional.getInstance().loadTextureLocations(GBuffer.GBUFFER_TEXTURE_TYPE_POSITION, GBuffer.GBUFFER_TEXTURE_TYPE_DIFFUSE, GBuffer.GBUFFER_TEXTURE_TYPE_NORMAL);
		
		ambientLight = new Vector3f(0.2f, 0.2f, 0.2f);
		directionalLight = new DirectionalLight(new Vector3f(1f, 0.5f, 1f), new Vector3f(0, 1, 0), 0.8f, 0.8f);
		
		Sphere sphere = new Sphere(1, 32, 32);
		Quad quad = new Quad(2, 2, 1, 1);
		
		pointLightBoundingSphere = new GameObject().addComponent(new ModelRenderer(Loader.getInstance().createModel(sphere.getVertices(), sphere.getTextureCoords(), sphere.getNormals(), sphere.getIndices()), new Material(TextureManager.createTextureColor(0xFFFFFFFF), 0f, 0f)));
		directionalLightBoundingQuad = new GameObject().addComponent(new ModelRenderer(Loader.getInstance().createModel(quad.getVertices(), quad.getTextureCoords(), quad.getNormals(), quad.getIndices()), new Material(TextureManager.createTextureColor(0xFFFFFFFF), 0f, 0f)));
	}

	public void clearScreen() {
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
	}

	public void renderModelWithTexture(Shader shader, Transform transform, Model model, Material material) {
		GL30.glBindVertexArray(model.getId());
		GL20.glEnableVertexAttribArray(0);
		GL20.glEnableVertexAttribArray(1);
		GL20.glEnableVertexAttribArray(2);

		model.bind();
		material.getTexture().bind();
		shader.loadEntityTransformation(transform.getTransformation());

		GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVertices(), GL11.GL_UNSIGNED_INT, 0);

		GL20.glDisableVertexAttribArray(0);
		GL20.glDisableVertexAttribArray(1);
		GL20.glDisableVertexAttribArray(2);
		GL30.glBindVertexArray(0);
	}

	public void render(GameObject object) {
		
		geometryRenderPass(object);
		
		beginLightPass();
		pointLightPass();
		directionalLightPass();
		
		
	}
	
	private void geometryRenderPass(GameObject object){

		DeferredGeometry.getInstance().bind();
		DeferredGeometry.getInstance().loadCamera(renderingCamera);
		//enable geometry shader
		gBuffer.bindToWrite();
		
		GL11.glDepthMask(true);
		clearScreen();
		GL11.glEnable(GL11.GL_DEPTH_TEST);
		GL11.glDisable(GL11.GL_BLEND);
		
		object.render(DeferredGeometry.getInstance());
		
		GL11.glDepthMask(false);
		GL11.glDisable(GL11.GL_DEPTH_TEST);
		
	}
	
	private void beginLightPass(){
	 * *GL11.glEnable(GL11.GL_BLEND);
	 * *GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE);

	 * *gBuffer.unbind();
	 * *gBuffer.bindToRead();
	 * *GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
	}
	
	private void pointLightPass(){
		//Not yet implemented.
	}
	
	private void directionalLightPass(){
		
		DeferredDirectional.getInstance().bind();
		DeferredDirectional.getInstance().loadCamera(renderingCamera);
		DeferredDirectional.getInstance().loadDirectionalLight(directionalLight);
		
		pointLightBoundingSphere.render(DeferredDirectional.getInstance());
		
	}
	
	public static Renderer getInstance() {
		if (instance == null) {
			instance = new Renderer();
		}

		return instance;
	}

}

GBuffer class


public class GBuffer {

	public static final int GBUFFER_TEXTURE_TYPE_POSITION = 0;
	public static final int GBUFFER_TEXTURE_TYPE_DIFFUSE = 1;
	public static final int GBUFFER_TEXTURE_TYPE_NORMAL = 2;
	public static final int GBUFFER_TEXTURE_TYPE_TEXCOORD = 3;
	
	private int fbo, width, height, depthTexture;
	private int[] textures;
	
	public GBuffer(int width, int height) {
		
		this.textures = new int[4];
		this.width = width;
		this.height = height;
		this.fbo = GL30.glGenFramebuffers();
		GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fbo);
		
		FloatBuffer rgbBuffer = BufferUtils.createFloatBuffer(width * height * 4);
		rgbBuffer.position(width * height * 3);
		rgbBuffer.flip();
		
		for (int i = 0; i < textures.length; i++){
			textures[i] = GL11.glGenTextures();
			GL11.glBindTexture(GL11.GL_TEXTURE_2D, textures[i]);
			GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL30.GL_RGB32F, width, height, 0, GL11.GL_RGB, GL11.GL_FLOAT, rgbBuffer);
			
			//GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
			//GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
			//GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
			//GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
			
			GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0 + i, GL11.GL_TEXTURE_2D, textures[i], 0);
		}
		
		FloatBuffer dBuffer = BufferUtils.createFloatBuffer(width * height);
		dBuffer.position(width * height);
		dBuffer.flip();
		
		depthTexture = GL11.glGenTextures();
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, depthTexture);
		GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL30.GL_DEPTH_COMPONENT32F, width, height, 0, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, dBuffer);
		
		//GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
		//GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
		//GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
		//GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
		
		GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, depthTexture, 0);
		
		for (int i = 0; i < textures.length; i++){
			GL20.glDrawBuffers(GL30.GL_COLOR_ATTACHMENT0 + i);
		}
		
		int status = GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER);
		 if (status != GL30.GL_FRAMEBUFFER_COMPLETE) {
		 * * * *System.err.println("FB error, status:" + status);
		 * * * *System.exit(-1);
		 *}
		 
		 unbind();
		
	}
	
	public void bindToWrite(){
		GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, fbo);
	}
	
	public void bindToRead(){
		GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, fbo);
		
	 * *for (int i = 0 ; i < 4; i++) {
	 * * * *GL13.glActiveTexture(GL13.GL_TEXTURE0 + i);	
	 * * * *GL11.glBindTexture(GL11.GL_TEXTURE_2D, textures[i]); *
	 * *}
	}
	
	public void unbind(){
		GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, 0);
	}
	
}

Geometry Fragment Shader


#version 400 core

in vec2 passUVs;
in vec3 passNormal;
in vec3 passWorldPos;

layout (location = 0) out vec3 worldPosOut; * 
layout (location = 1) out vec3 diffuseOut; * * 
layout (location = 2) out vec3 normalOut; * * 
layout (location = 3) out vec3 uvOut; * *

uniform sampler2D textureSampler;

void main(){
	worldPosOut = passWorldPos;
	diffuseOut = texture(textureSampler, passUVs).xyz;
	normalOut = passNormal;
	uvOut = vec3(passUVs, 0.0);
}

Again, any help would be much appreciated :slight_smile: