PDA

View Full Version : Problem with Deferred Rendering and FBO's



mbl111
12-03-2014, 10:42 PM
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().loadTextureLocation s(0);

DeferredDirectional.getInstance().bind();
DeferredDirectional.getInstance().loadScreenSize(D isplayManager.getWidth(), DisplayManager.getHeight());
DeferredDirectional.getInstance().loadTextureLocat ions(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(sph ere.getVertices(), sphere.getTextureCoords(), sphere.getNormals(), sphere.getIndices()), new Material(TextureManager.createTextureColor(0xFFFFF FFF), 0f, 0f)));
directionalLightBoundingQuad = new GameObject().addComponent(new ModelRenderer(Loader.getInstance().createModel(qua d.getVertices(), quad.getTextureCoords(), quad.getNormals(), quad.getIndices()), new Material(TextureManager.createTextureColor(0xFFFFF FFF), 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.getTrans formation());

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(renderin gCamera);
//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(rende ringCamera);
DeferredDirectional.getInstance().loadDirectionalL ight(directionalLight);

pointLightBoundingSphere.render(DeferredDirectiona l.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 :)